/** * touch thumbs control class * addon to strip gallery */ function UGTouchThumbsControl(){ var g_parent, g_gallery, g_objGallery, g_objects; var g_objStrip, g_objStripInner, g_options, g_isVertical; var g_functions = new UGFunctions(); //service variables var g_serviceParams = { touch_portion_time:200, //the time in ms that the potion is counts for continue touch movement thumb_touch_slowFactor:0, //set from user minDeltaTime: 70, //don't alow portion less then the minTime minPath: 10, //if less then this path, dont' continue motion limitsBreakAddition: 30, //the limits break addition for second return animation returnAnimateSpeed: 500, //the speed of return animation animationEasing: "easeOutCubic", //animation easing function returnAnimationEasing: "easeOutCubic" //return animation easing function }; var g_temp = { //temp variables touch_active:false, loop_active:false, mousePos:0, innerPos:0, startPos:0, startTime:0, lastTime:0, buttonReleaseTime:0, lastPos:0, lastPortionPos:0, lastDeltaTime:0, lastDeltaPos:0, speed:0, handle:"", touchEnabled: false, isControlEnabled: true }; /** * enable the control */ this.enable = function(){ g_temp.isControlEnabled = true; } /** * disable the control */ this.disable = function(){ g_temp.isControlEnabled = false; } /** * init function for avia controls */ this.init = function(objStrip){ g_parent = objStrip; g_objects = objStrip.getObjects(); g_gallery = g_objects.g_gallery; g_objGallery = g_objects.g_objGallery; //jquery object g_objStrip = g_objects.g_objStrip; g_objStripInner = g_objects.g_objStripInner; g_options = g_objects.g_options; g_isVertical = g_objects.isVertical; setServiceParams(); initEvents(); } /** * get action related variables */ function getActionVars(){ var currentTime = jQuery.now(); var obj = {}; obj.passedTime = g_temp.lastTime - g_temp.startTime; obj.lastActiveTime = currentTime - g_temp.buttonReleaseTime; obj.passedDistance = g_temp.lastPos - g_temp.startPos; obj.passedDistanceAbs = Math.abs(obj.passedDistance); return(obj); } /** * return if passed some significant movement */ this.isSignificantPassed = function(){ var objVars = getActionVars(); if(objVars.passedTime > 300) return(true); if(objVars.passedDistanceAbs > 30) return(true); return(false); } /** * return true if the touch dragging or animate motion is active */ this.isTouchActive = function(){ if(g_temp.touch_active == true) return(true); //check if still animating if(g_objStripInner.is(":animated") == true) return(true); //check if just ended, the touch active continue for a few moments. var objVars = getActionVars(); if(objVars.lastActiveTime < 50) return(true); return(false); } /** * set service parameters from user parameters */ function setServiceParams(){ //set slow factor by sensetivity of touch motion g_serviceParams.thumb_touch_slowFactor = g_functions.normalizeSetting(0.00005, 0.01, 1, 100, g_options.strip_thumb_touch_sensetivity, true); //debugLine("slowfactor "+ g_serviceParams.thumb_touch_slowFactor); } /** * get mouse position based on orientation */ function getMouseOrientPosition(event){ if(g_isVertical == false) return(g_functions.getMousePosition(event).pageX); else return(g_functions.getMousePosition(event).pageY); } /** * position the strip according the touch drag diff */ function handleStripDrag(mousePos){ var diff = g_temp.mousePos - mousePos; var distPos = g_temp.innerPos - diff; //make harder to drag the limits var objLimits = g_parent.getInnerStripLimits(); if(distPos > objLimits.maxPos){ var path = distPos - objLimits.maxPos; distPos = objLimits.maxPos + path/3; } if(distPos < objLimits.minPos){ var path = objLimits.minPos - distPos; distPos = objLimits.minPos - path/3; } g_parent.positionInnerStrip(distPos); } /** * store initial touch values */ function storeInitTouchValues(pagePos){ var currentInnerPos = g_parent.getInnerStripPos(); //remember current mouse position and inner strip position g_temp.mousePos = pagePos; g_temp.innerPos = currentInnerPos; g_temp.lastPortionPos = currentInnerPos; g_temp.lastDeltaTime = 0; g_temp.lastDeltaPos = 0; //init position and time related variables g_temp.startTime = jQuery.now(); g_temp.startPos = g_temp.innerPos; g_temp.lastTime = g_temp.startTime; g_temp.lastPos = g_temp.startPos; g_temp.speed = 0; } /** * store touch portion data */ function storeTouchPortionData(){ //calc speed var currentTime = jQuery.now(); var deltaTime = currentTime - g_temp.lastTime; if(deltaTime >= g_serviceParams.touch_portion_time){ g_temp.lastDeltaTime = currentTime - g_temp.lastTime; if(g_temp.lastDeltaTime > g_serviceParams.touch_portion_time) g_temp.lastDeltaTime = g_serviceParams.touch_portion_time; g_temp.lastDeltaPos = g_temp.lastPos - g_temp.lastPortionPos; g_temp.lastPortionPos = g_temp.lastPos; g_temp.lastTime = currentTime; } } /** * continue touch motion - touch motion ending. */ function continueTouchMotion(){ var slowFactor = g_serviceParams.thumb_touch_slowFactor; //don't alow portion less then the minTime var minDeltaTime = g_serviceParams.minDeltaTime; //if less then this path, dont' continue motion var minPath = g_serviceParams.minPath; var currentInnerPos = g_parent.getInnerStripPos(); var currentTime = jQuery.now(); var deltaTime = currentTime - g_temp.lastTime; var deltaPos = currentInnerPos - g_temp.lastPortionPos; //if time too fast, take last portion values if(deltaTime < minDeltaTime && g_temp.lastDeltaTime > 0){ deltaTime = g_temp.lastDeltaTime; deltaPos = g_temp.lastDeltaPos + deltaPos; } //fix delta time if(deltaTime < minDeltaTime) deltaTime = minDeltaTime; var dir = (deltaPos > 0)?1:-1; var speed = 0; if(deltaTime > 0) speed = deltaPos / deltaTime; var path = (speed * speed) / (slowFactor * 2) * dir; //disable path for very slow motions if(Math.abs(path) <= minPath) path = 0; var innerStripPos = g_parent.getInnerStripPos(); var newPos = innerStripPos + path; var correctPos = g_parent.fixInnerStripLimits(newPos); var objLimits = g_parent.getInnerStripLimits(); //check the off the limits and return (second animation) var limitsBreakAddition = g_serviceParams.limitsBreakAddition; var doQueue = false; var returnPos = correctPos; //fix the first animation position (off the limits) if(newPos > objLimits.maxPos){ doQueue = true; correctPos = limitsBreakAddition; if(newPos < limitsBreakAddition) correctPos = newPos; } if(newPos < objLimits.minPos){ doQueue = true; var maxStopPos = objLimits.minPos - limitsBreakAddition; correctPos = maxStopPos; if(newPos > maxStopPos) correctPos = newPos; } var correctPath = correctPos - innerStripPos; //set animation speed var animateSpeed = Math.abs(Math.round(speed / slowFactor)); //fix animation speed according the paths difference if(path != 0) animateSpeed = animateSpeed * correctPath / path; //Do first animation if(innerStripPos != correctPos){ var animateProps = {"left":correctPos+"px"}; if(g_isVertical == true) animateProps = {"top":correctPos+"px"}; g_objStripInner.animate(animateProps ,{ duration: animateSpeed, easing: g_serviceParams.animationEasing, queue: true, progress:onAnimateProgress }); } //do second animation if off limits if(doQueue == true){ var returnAnimateSpeed = g_serviceParams.returnAnimateSpeed; var returnAnimateProps = {"left":returnPos+"px"}; if(g_isVertical == true) returnAnimateProps = {"top":returnPos+"px"}; g_objStripInner.animate(returnAnimateProps,{ duration: returnAnimateSpeed, easing: g_serviceParams.returnAnimationEasing, queue: true, progress:onAnimateProgress }); } } /** * on animate progress event. store position and trigger event to gallery */ function onAnimateProgress(){ g_temp.lastPos = g_parent.getInnerStripPos(); g_parent.triggerStripMoveEvent(); } /** * start loop while touching strip */ function startStripTouchLoop(){ if(g_temp.loop_active == true) return(true); g_temp.loop_active = true; g_temp.handle = setInterval(storeTouchPortionData,10); } /** * end loop when not touching */ function endStripTouchLoop(event){ if(g_temp.loop_active == false) return(true); if(event){ var pagePos = getMouseOrientPosition(event); continueTouchMotion(pagePos); } g_temp.loop_active = false; g_temp.handle = clearInterval(g_temp.handle); } /** * on tuch end event */ function onTouchEnd(event){ if(g_temp.isControlEnabled == false) return(true); g_temp.buttonReleaseTime = jQuery.now(); if(g_temp.touch_active == false){ endStripTouchLoop(event); return(true); } event.preventDefault(); g_temp.touch_active = false; endStripTouchLoop(event); g_objStrip.removeClass("ug-dragging"); } /** * on touch start - start the motion * @param event */ function onTouchStart(event){ if(g_temp.isControlEnabled == false) return(true); event.preventDefault(); g_temp.touch_active = true; //don't move this up var pagePos = getMouseOrientPosition(event); //stop inner animation if exist g_objStripInner.stop(true); //store initial touch values storeInitTouchValues(pagePos); startStripTouchLoop(); g_objStrip.addClass("ug-dragging"); } /** * on touch move event, move the strip */ function onTouchMove(event){ if(g_temp.isControlEnabled == false) return(true); if(g_temp.touch_active == false) return(true); event.preventDefault(); //detect moving without button press if(event.buttons == 0){ g_temp.touch_active = false; endStripTouchLoop(event); return(true); } //store current position var pagePos = getMouseOrientPosition(event); g_temp.lastPos = g_parent.getInnerStripPos(); handleStripDrag(pagePos); storeTouchPortionData(); } /** * init strip touch events */ function initEvents(){ //strip mouse down - drag start g_objStrip.bind("mousedown touchstart",onTouchStart); //on body mouse up - drag end jQuery(window).add("body").bind("mouseup touchend",onTouchEnd); //on body move jQuery("body").bind("mousemove touchmove", onTouchMove); } /** * destroy the touch events */ this.destroy = function(){ g_objStrip.unbind("mousedown"); g_objStrip.unbind("touchstart"); jQuery(window).add("body").unbind("mouseup").unbind("touchend"); jQuery("body").unbind("mousemove").unbind("touchmove"); } }