Permalink
Browse files

Make mouse work on touchscreen devices.

Make touch work in IE 10/11.
Use RequestAnimationFrame for drag and slide animations when supported.
Fixes #6 and fixes #7
  • Loading branch information...
1 parent 1e7aea3 commit afbacdefef7108ad78f3b390aab890431f996f01 Brandon Paddock committed Aug 7, 2015
Showing with 46 additions and 26 deletions.
  1. +2 −2 examples/simple/tinycircleslider.css
  2. +42 −22 lib/jquery.tinycircleslider.js
  3. +2 −2 lib/jquery.tinycircleslider.min.js
@@ -2,11 +2,11 @@ img { border: 0; }
/* Tiny Circleslider */
#rotatescroll { height:300px; position:relative; width:300px; }
-#rotatescroll .viewport{ height:300px; position: relative; margin:0 auto; overflow:hidden; width:300px }
+#rotatescroll .viewport{ height:300px; position: relative; margin:0 auto; overflow:hidden; width:300px; pointer-events: none }
#rotatescroll .overview { position: absolute; width: 798px; list-style: none; margin: 0; padding: 0; left: 0; top: 0; }
#rotatescroll .overview li { height:300px; width:300px; float: left; position: relative; }
#rotatescroll .overlay {background:url(images/bg-rotatescroll.png) no-repeat 0 0; pointer-events: none; position: absolute; left: 0; top: 0; height:300px; width:300px; }
-#rotatescroll .thumb { background:url(images/bg-thumb.png) no-repeat 50% 50%; position: absolute; top: -3px; cursor: pointer; left: 137px; width: 100px; z-index: 200; height: 100px; }
+#rotatescroll .thumb { background:url(images/bg-thumb.png) no-repeat 50% 50%; touch-action: none; -ms-touch-action: none; position: absolute; top: -3px; cursor: pointer; left: 137px; width: 100px; z-index: 200; height: 100px; }
#rotatescroll .dot { background:url(images/bg-dot.png) no-repeat 0 0; display: none; height: 12px; width: 12px; position: absolute; left: 155px; top: 3px; z-index: 100; }
#rotatescroll .dot span { display: none; }
@@ -75,8 +75,9 @@
, intervalTimer = null
, animationTimer = null
- , touchEvents = 'ontouchstart' in window || 'onmsgesturechange' in window
+ , touchEvents = 'ontouchstart' in window
, isTouchEvent = false
+ , hasRequestAnimationFrame = 'requestAnimationFrame' in window
;
/**
@@ -148,26 +149,28 @@
* @private
*/
function _setEvents() {
- var eventType = touchEvents ? "touchstart" : "mousedown";
-
- if(touchEvents) {
+ if (touchEvents) {
$container[0].ontouchstart = _startDrag;
$container[0].ontouchmove = _drag;
$container[0].ontouchend = _endDrag;
}
- else {
- $thumb.bind(eventType, _startDrag);
- }
- $container.delegate(".dot", eventType, function(event) {
+ $thumb.bind("mousedown", _startDrag);
+
+ var snapHandler = function (event) {
event.preventDefault();
event.stopImmediatePropagation();
self.stop();
self.move($(this).attr("data-slide-index"));
return false;
- });
+ };
+
+ if (touchEvents) {
+ $container.delegate(".dot", "touchstart", snapHandler);
+ }
+ $container.delegate(".dot", "mousedown", snapHandler);
}
/**
@@ -357,7 +360,7 @@
var angleDestination = self.dots[slideIndex] && self.dots[slideIndex].angle
, angleDelta = _findShortestPath(angleDestination, self.angleCurrent)[0]
- , angleStep = angleDelta > 0 ? -10 : 10
+ , angleStep = angleDelta > 0 ? -2 : 2
;
self.slideCurrent = slideIndex;
@@ -392,6 +395,10 @@
if(Math.abs(angleStep) > Math.abs(angleDelta)) {
angleStepNew = -angleDelta;
endAnimation = true;
+ } else if(hasRequestAnimationFrame) {
+ requestAnimationFrame(function() {
+ _stepMove(angleStepNew, angleDelta + angleStep);
+ });
} else {
animationTimer = setTimeout(function() {
_stepMove(angleStepNew, angleDelta + angleStep, stepInterval * 0.9);
@@ -425,7 +432,7 @@
, thumbPositionNew = {
left: _page(event).x - containerOffset.left - (containerSize.width / 2)
, top: _page(event).y - containerOffset.top - (containerSize.height / 2)
- }
+ }
;
self.angleCurrent = _sanitizeAngle(
@@ -434,12 +441,14 @@
)
);
- _setCSS(self.angleCurrent);
+ if (!hasRequestAnimationFrame) {
+ _setCSS(self.angleCurrent);
+ }
return false;
}
- /**
+ /**
* @method _setCSS
* @private
* @param {Number} [angle]
@@ -475,12 +484,11 @@
if($(event.target).hasClass("dot")) {
return false;
}
+ self.dragging = false;
event.preventDefault();
- if(!touchEvents) {
- $(document).unbind("mousemove mouseup");
- $thumb.unbind("mouseup");
- }
+ $(document).unbind("mousemove mouseup");
+ $thumb.unbind("mouseup");
if(self.options.dotsHide) {
$dots.stop(true, true).fadeOut("slow");
@@ -491,6 +499,15 @@
}
}
+ function _dragAnimationLoop() {
+ if(self.dragging) {
+ _setCSS(self.angleCurrent);
+ requestAnimationFrame(function() {
+ _dragAnimationLoop();
+ });
+ }
+ }
+
/**
* @method _startDrag
* @private
@@ -499,22 +516,25 @@
function _startDrag(event) {
event.preventDefault();
isTouchEvent = event.type == 'touchstart';
+ self.dragging = true;
if($(event.target).hasClass("dot")) {
return false;
}
self.stop();
- if(!touchEvents) {
- $(document).mousemove(_drag);
- $(document).mouseup(_endDrag);
- $thumb.mouseup(_endDrag);
- }
+ $(document).mousemove(_drag);
+ $(document).mouseup(_endDrag);
+ $thumb.mouseup(_endDrag);
if(self.options.dotsHide) {
$dots.stop(true, true).fadeIn("slow");
}
+
+ if(hasRequestAnimationFrame) {
+ _dragAnimationLoop();
+ }
}
return _initialize();
@@ -1,7 +1,7 @@
-/*! Tiny Circleslider - v2.0.7 - 2015-02-22
+/*! Tiny Circleslider - v2.0.7 - 2015-08-07
* http://www.baijs.com/tinycircleslider
*
* Copyright (c) 2015 Maarten Baijs <wieringen@gmail.com>;
* Licensed under the MIT license */
-!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){function b(b,e){function f(){return k(),v.append(w.first().clone()).css("width",A.width*(w.length+1)),g(),r(0),u.move(u.options.start,u.options.interval),u}function g(){var c=F?"touchstart":"mousedown";F?(b[0].ontouchstart=t,b[0].ontouchmove=q,b[0].ontouchend=s):x.bind(c,t),b.delegate(".dot",c,function(b){return b.preventDefault(),b.stopImmediatePropagation(),u.stop(),u.move(a(this).attr("data-slide-index")),!1})}function h(a){D=setTimeout(function(){u.move(u.slideCurrent+1,!0)},a?50:u.options.intervalTime)}function i(a){return a*(Math.PI/180)}function j(a){return 180*a/Math.PI}function k(){var c=document.createDocumentFragment();y.remove(),w.each(function(b,d){var e=null,f=parseInt(a(d).attr("data-degrees"),10)||360*b/u.slidesTotal,g={top:-Math.cos(i(f))*u.options.radius+z.height/2-C.height/2,left:Math.sin(i(f))*u.options.radius+z.width/2-C.width/2};y.length>0&&(e=y.clone(),e.addClass(a(d).attr("data-classname")).css(g),c.appendChild(e[0])),u.dots.push({angle:f,slide:d,dot:e})}),u.dots.sort(function(a,b){return a.angle-b.angle}),a.each(u.dots,function(b,c){a(c.dot).length>0&&a(c.dot).addClass("dot-"+(b+1)).attr("data-slide-index",b).html("<span>"+(b+1)+"</span>")}),b.append(c),y=b.find(".dot")}function l(a,b){var c,d,e;return a>b?(c=a-b,d=-(b+360-a)):(c=a+360-b,d=-(b-a)),e=c<Math.abs(d)?c:d,[e,d,c]}function m(b){var c=9999,d=9999,e=9999,f=0,g=0,h=0;return a.each(u.dots,function(a,i){var j=l(i.angle,b);Math.abs(j[0])<Math.abs(e)&&(e=j[0],h=a),Math.abs(j[1])<Math.abs(c)&&(c=j[1],f=a),Math.abs(j[2])<Math.abs(d)&&(d=j[2],g=a)}),[[h,f,g],[e,c,d]]}function n(a){return 0>a?360+a%-360:a%360}function o(a,b,c){var d=a,e=!1;Math.abs(a)>Math.abs(b)?(d=-b,e=!0):E=setTimeout(function(){o(d,b+a,.9*c)},c),u.angleCurrent=n(u.angleCurrent-d),r(u.angleCurrent,e)}function p(a){return{x:G?a.targetTouches[0].pageX:a.pageX||a.clientX,y:G?a.targetTouches[0].pageY:a.pageY||a.clientY}}function q(a){var c=b.offset(),d={left:p(a).x-c.left-z.width/2,top:p(a).y-c.top-z.height/2};return u.angleCurrent=n(j(Math.atan2(d.left,-d.top))),r(u.angleCurrent),!1}function r(a,c){closestSlidesAndAngles=m(a),closestSlides=closestSlidesAndAngles[0],closestAngles=closestSlidesAndAngles[1],v.css("left",-(closestSlides[1]*A.width+Math.abs(closestAngles[1])*A.width/(Math.abs(closestAngles[1])+Math.abs(closestAngles[2])))),x.css({top:-Math.cos(i(a))*u.options.radius+(z.height/2-B.height/2),left:Math.sin(i(a))*u.options.radius+(z.width/2-B.width/2)}),c&&b.trigger("move",[w[u.slideCurrent],u.slideCurrent])}function s(b){return a(b.target).hasClass("dot")?!1:(b.preventDefault(),F||(a(document).unbind("mousemove mouseup"),x.unbind("mouseup")),u.options.dotsHide&&y.stop(!0,!0).fadeOut("slow"),u.options.dotsSnap&&u.move(m(u.angleCurrent)[0][0]),void 0)}function t(b){return b.preventDefault(),G="touchstart"==b.type,a(b.target).hasClass("dot")?!1:(u.stop(),F||(a(document).mousemove(q),a(document).mouseup(s),x.mouseup(s)),u.options.dotsHide&&y.stop(!0,!0).fadeIn("slow"),void 0)}this.options=a.extend({},d,e),this._defaults=d,this._name=c;var u=this,v=(b.find(".viewport"),b.find(".overview")),w=v.children(),x=b.find(".thumb"),y=b.find(".dot"),z=(w.find("a"),{width:b.outerWidth(!0),height:b.outerHeight(!0)}),A={width:w.first().outerWidth(!0),height:w.first().outerHeight(!0)},B={width:x.outerWidth(!0),height:x.outerHeight(!0)},C={width:y.outerWidth(),height:y.outerHeight()},D=null,E=null,F="ontouchstart"in window||"onmsgesturechange"in window,G=!1;return this.dots=[],this.slideCurrent=0,this.angleCurrent=0,this.slidesTotal=w.length,this.intervalActive=!1,this.start=function(a){return u.options.interval&&(u.intervalActive=!0,h(a)),u},this.stop=function(){return u.intervalActive=!1,clearTimeout(D),u},this.move=function(a){var b=Math.max(0,isNaN(a)?u.slideCurrent:a);b>=u.slidesTotal&&(b=0);var c=u.dots[b]&&u.dots[b].angle,d=l(c,u.angleCurrent)[0],e=d>0?-10:10;return u.slideCurrent=b,o(e,d,50),u.start(),u},f()}var c="tinycircleslider",d={interval:!1,intervalTime:3500,dotsSnap:!1,dotsHide:!0,radius:140,start:0};a.fn[c]=function(d){return this.each(function(){a.data(this,"plugin_"+c)||a.data(this,"plugin_"+c,new b(a(this),d))})}});
+!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){function b(b,e){function f(){return k(),w.append(x.first().clone()).css("width",B.width*(x.length+1)),g(),r(0),v.move(v.options.start,v.options.interval),v}function g(){G&&(b[0].ontouchstart=u,b[0].ontouchmove=q,b[0].ontouchend=s),y.bind("mousedown",u);var c=function(b){return b.preventDefault(),b.stopImmediatePropagation(),v.stop(),v.move(a(this).attr("data-slide-index")),!1};G&&b.delegate(".dot","touchstart",c),b.delegate(".dot","mousedown",c)}function h(a){E=setTimeout(function(){v.move(v.slideCurrent+1,!0)},a?50:v.options.intervalTime)}function i(a){return a*(Math.PI/180)}function j(a){return 180*a/Math.PI}function k(){var c=document.createDocumentFragment();z.remove(),x.each(function(b,d){var e=null,f=parseInt(a(d).attr("data-degrees"),10)||360*b/v.slidesTotal,g={top:-Math.cos(i(f))*v.options.radius+A.height/2-D.height/2,left:Math.sin(i(f))*v.options.radius+A.width/2-D.width/2};z.length>0&&(e=z.clone(),e.addClass(a(d).attr("data-classname")).css(g),c.appendChild(e[0])),v.dots.push({angle:f,slide:d,dot:e})}),v.dots.sort(function(a,b){return a.angle-b.angle}),a.each(v.dots,function(b,c){a(c.dot).length>0&&a(c.dot).addClass("dot-"+(b+1)).attr("data-slide-index",b).html("<span>"+(b+1)+"</span>")}),b.append(c),z=b.find(".dot")}function l(a,b){var c,d,e;return a>b?(c=a-b,d=-(b+360-a)):(c=a+360-b,d=-(b-a)),e=c<Math.abs(d)?c:d,[e,d,c]}function m(b){var c=9999,d=9999,e=9999,f=0,g=0,h=0;return a.each(v.dots,function(a,i){var j=l(i.angle,b);Math.abs(j[0])<Math.abs(e)&&(e=j[0],h=a),Math.abs(j[1])<Math.abs(c)&&(c=j[1],f=a),Math.abs(j[2])<Math.abs(d)&&(d=j[2],g=a)}),[[h,f,g],[e,c,d]]}function n(a){return 0>a?360+a%-360:a%360}function o(a,b,c){var d=a,e=!1;Math.abs(a)>Math.abs(b)?(d=-b,e=!0):I?requestAnimationFrame(function(){o(d,b+a)}):F=setTimeout(function(){o(d,b+a,.9*c)},c),v.angleCurrent=n(v.angleCurrent-d),r(v.angleCurrent,e)}function p(a){return{x:H?a.targetTouches[0].pageX:a.pageX||a.clientX,y:H?a.targetTouches[0].pageY:a.pageY||a.clientY}}function q(a){var c=b.offset(),d={left:p(a).x-c.left-A.width/2,top:p(a).y-c.top-A.height/2};return v.angleCurrent=n(j(Math.atan2(d.left,-d.top))),I||r(v.angleCurrent),!1}function r(a,c){closestSlidesAndAngles=m(a),closestSlides=closestSlidesAndAngles[0],closestAngles=closestSlidesAndAngles[1],w.css("left",-(closestSlides[1]*B.width+Math.abs(closestAngles[1])*B.width/(Math.abs(closestAngles[1])+Math.abs(closestAngles[2])))),y.css({top:-Math.cos(i(a))*v.options.radius+(A.height/2-C.height/2),left:Math.sin(i(a))*v.options.radius+(A.width/2-C.width/2)}),c&&b.trigger("move",[x[v.slideCurrent],v.slideCurrent])}function s(b){return a(b.target).hasClass("dot")?!1:(v.dragging=!1,b.preventDefault(),a(document).unbind("mousemove mouseup"),y.unbind("mouseup"),v.options.dotsHide&&z.stop(!0,!0).fadeOut("slow"),void(v.options.dotsSnap&&v.move(m(v.angleCurrent)[0][0])))}function t(){v.dragging&&(r(v.angleCurrent),requestAnimationFrame(function(){t()}))}function u(b){return b.preventDefault(),H="touchstart"==b.type,v.dragging=!0,a(b.target).hasClass("dot")?!1:(v.stop(),a(document).mousemove(q),a(document).mouseup(s),y.mouseup(s),v.options.dotsHide&&z.stop(!0,!0).fadeIn("slow"),void(I&&t()))}this.options=a.extend({},d,e),this._defaults=d,this._name=c;var v=this,w=(b.find(".viewport"),b.find(".overview")),x=w.children(),y=b.find(".thumb"),z=b.find(".dot"),A=(x.find("a"),{width:b.outerWidth(!0),height:b.outerHeight(!0)}),B={width:x.first().outerWidth(!0),height:x.first().outerHeight(!0)},C={width:y.outerWidth(!0),height:y.outerHeight(!0)},D={width:z.outerWidth(),height:z.outerHeight()},E=null,F=null,G="ontouchstart"in window,H=!1,I="requestAnimationFrame"in window;return this.dots=[],this.slideCurrent=0,this.angleCurrent=0,this.slidesTotal=x.length,this.intervalActive=!1,this.start=function(a){return v.options.interval&&(v.intervalActive=!0,h(a)),v},this.stop=function(){return v.intervalActive=!1,clearTimeout(E),v},this.move=function(a){var b=Math.max(0,isNaN(a)?v.slideCurrent:a);b>=v.slidesTotal&&(b=0);var c=v.dots[b]&&v.dots[b].angle,d=l(c,v.angleCurrent)[0],e=d>0?-2:2;return v.slideCurrent=b,o(e,d,50),v.start(),v},f()}var c="tinycircleslider",d={interval:!1,intervalTime:3500,dotsSnap:!1,dotsHide:!0,radius:140,start:0};a.fn[c]=function(d){return this.each(function(){a.data(this,"plugin_"+c)||a.data(this,"plugin_"+c,new b(a(this),d))})}});

0 comments on commit afbacde

Please sign in to comment.