jquery animate if element is in viewport - javascript

What I need here is to trigger the animation when the element is visible (in viewport).
I have a function called openAnimation() that runs a GSPA TweenMax.
that should animate nicely my elements, but it does't work.
Basically I need to trigger the openAnimation() when my element in inview.
Demo-codepen
function inView( opt ) {
if( opt.selector === undefined ) {
console.log( 'Valid selector required for inView' );
return false;
}
var elems = [].slice.call( document.querySelectorAll( opt.selector ) ),
once = opt.once === undefined ? true : opt.once,
offsetTop = opt.offsetTop === undefined ? 0 : opt.offsetTop,
offsetBot = opt.offsetBot === undefined ? 0 : opt.offsetBot,
count = elems.length,
winHeight = 0,
ticking = false;
function update() {
var i = count;
while( i-- ) {
var elem = elems[ i ],
rect = elem.getBoundingClientRect();
if( rect.bottom >= offsetTop && rect.top <= winHeight - offsetBot ) {
elem.classList.add( 'in-view' );
if( once ) {
count--;
elems.splice( i, 1 );
}
} else {
elem.classList.remove( 'in-view' );
}
}
ticking = false;
}
function onResize() {
winHeight = window.innerHeight;
requestTick();
}
function onScroll() {
requestTick();
}
function requestTick() {
if( !ticking ) {
requestAnimationFrame( update );
ticking = true;
}
}
window.addEventListener( 'resize', onResize, false );
document.addEventListener( 'scroll', onScroll, false );
document.addEventListener( 'touchmove', onScroll, false );
onResize();
}
inView({
selector: '.view-poll', // an .in-view class will get toggled on these elements
once: true, // set this to false to have the .in-view class be toggled on AND off
offsetTop: 0, // top threshold to be considered "in view"
offsetBot: 0 // bottom threshold to be considered "in view"
});
function openAnimation() {
var rotate = $('.rotate.in-view');
var scale = $('.scale.in-view');
var translate = $('.translate.in-view');
//feature Left
TweenLite.from(rotate, 1.2, {y:-400, opacity: 0.0, delay:0.0, }, 0.05);
TweenLite.from(scale, 1.2, {y:-400, opacity: 0.0, delay:0.0, }, 0.05);
TweenLite.from(translate, 1.2, {y:-400, opacity: 0.0, delay:0.0, }, 0.05);
}

Related

Prevent click when dragging

Im using Three.js to display a 3d model which users can drag the camera around and click objects to zoom in on them. The issue I'm having is that when you click and drag it reads it as a click and triggers the animation, I need to prevent clicking when dragging, so clicks are only registered when it is just a click and no mouse movement.
function onClick(event) {
event.preventDefault();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
raycaster.setFromCamera( mouse, camera );
var intersects = raycaster.intersectObjects( scene.children, true );
if ( intersects.length > 0 && intersects[0].object.name==="Tree006") {
var object = intersects[0].object;
gsap.to( camera.position, {
duration: 1,
x: mesh["Tree006"].position.x,
y: mesh["Tree006"].position.y,
z: mesh["Tree006"].position.z,
onUpdate: function() {
controls.enabled = false;
camera.lookAt(0,0,0);
}
} );
console.log( 'Intersection:', intersects[ 0 ] );
}
if ( intersects.length > 0 && intersects[0].object.name!=="Tree006") {
var object = intersects[0].object;
gsap.to( camera.position, {
duration: 1, // seconds
x: 6,
y: 4,
z: 6,
onUpdate: function() {
controls.enabled = true;
camera.lookAt( 0,0,0 );
}
} );
}
}
Event click is only fired when you release the mouse button over the element. So you can set some flag on mousedown and reset that flag on mouseup. This flag would tell the click handler not to do anything.
var btn1 = document.querySelector("#btn1");
var flag = false;
btn1.addEventListener('click', function(ev) {
if (!flag) {
alert(1);
}
ev.preventDefault();
})
btn1.addEventListener('mousedown', function(ev) {
flag = true;
console.log("flag to disable click is true");
})
btn1.addEventListener('mouseup', function(ev) {
// this is dirty hack, until i find a better solution:
setTimeout(function() {
flag = false
console.log("flag to disable click is false");
});
})
<button id="btn1">no click</button>
<button id="btn2" onclick="alert(2)">click</button>

JQuery trigger function if element is in viewport

I'm trying to make a function openAnimation() working, when the element is "in viewport"!
Now, this particular function is GSAP. Every time I run openAnimation() doesn't work as aspected.
Runs twice and repeats each time the in-view class is been added.
-So how can I run my GSAP function with this plug in?
https://codepen.io/davide77/pen/qPLoKP
function inView( opt ) {
if( opt.selector === undefined ) {
console.log( 'Valid selector required for inView' );
return false;
}
var elems = [].slice.call( document.querySelectorAll( opt.selector ) ),
once = opt.once === undefined ? true : opt.once,
offsetTop = opt.offsetTop === undefined ? 0 : opt.offsetTop,
offsetBot = opt.offsetBot === undefined ? 0 : opt.offsetBot,
count = elems.length,
winHeight = 0,
ticking = false;
function update() {
var i = count;
while( i-- ) {
var elem = elems[ i ],
rect = elem.getBoundingClientRect();
if( rect.bottom >= offsetTop && rect.top <= winHeight - offsetBot ) {
elem.classList.add( 'in-view' );
if( once ) {
count--;
elems.splice( i, 1 );
}
} else {
elem.classList.remove( 'in-view' );
}
}
ticking = false;
}
function onResize() {
winHeight = window.innerHeight;
requestTick();
}
function onScroll() {
requestTick();
}
function requestTick() {
if( !ticking ) {
requestAnimationFrame( update );
ticking = true;
}
}
window.addEventListener( 'resize', onResize, false );
document.addEventListener( 'scroll', onScroll, false );
document.addEventListener( 'touchmove', onScroll, false );
onResize();
}
inView({
selector: '.view-poll', // an .in-view class will get toggled on these elements
once: true, // set this to false to have the .in-view class be toggled on AND off
offsetTop: 0, // top threshold to be considered "in view"
offsetBot: 0 // bottom threshold to be considered "in view"
});
// HOW CAN I RUN THIS FUNCTION NOW?
function openAnimation() {
var rotate = $('.rotate.in-view');
var scale = $('.scale.in-view');
var translate = $('.translate.in-view');
//feature Left
TweenLite.from(rotate, 1.2, {y:-400, opacity: 0.0, delay:0.0, }, 0.05);
TweenLite.from(scale, 1.2, {y:-400, opacity: 0.0, delay:0.0, }, 0.05);
TweenLite.from(translate, 1.2, {y:-400, opacity: 0.0, delay:0.0, }, 0.05);
}
You can use the library jQuery-visible. With its help, you can create a window event onScroll and check if your element is "visible", then call your function.
You can use http://scrollmagic.io/. With this you can initiate any function on scroll or when its in view.

Javascript - scroll direction Detect in addEventListener 'scroll'

I have Fixed Header ,That Work With Mouse Scroll
How Change This code That Work only With Scroll UP
function init() {
window.addEventListener( 'scroll', function( event ) {
if( !didScroll ) {
didScroll = true;
setTimeout( scrollPage, 250 ); //Scroll Page
}
}, false );
}
//Scroll Function
function scrollPage() {
var sy = scrollY();
if ( sy >= changeHeaderOn ) {
if(!$('.template-content').hasClass('fixed-active') && (!$('.header-wrapper').hasClass('slider-overlap') || $('body').hasClass('breadcrumbs-type-9') || $('body').hasClass('breadcrumbs-type-default')) )
etTheme.headerHeight('set');
classie.add( wrapper, 'fixed-active' );
setTimeout( function() {
classie.add( wrapper, 'fixed-active-animate' );
},250);
}
else {
classie.remove( wrapper, 'fixed-active' );
classie.remove( wrapper, 'fixed-active-animate' );
etTheme.headerHeight('unset');
}
didScroll = false;
}
//Scroll Position
function scrollY() {
return window.pageYOffset || docElem.scrollTop;
}
//Call Function
init();
function scrollPage() {
var sy = scrollY();
if ( sy >= changeHeaderOn && LastscrollY > sy) {
if(!$('.template-content').hasClass('fixed-active') && (!$('.header-wrapper').hasClass('slider-overlap') || $('body').hasClass('breadcrumbs-type-9') || $('body').hasClass('breadcrumbs-type-default')) )
etTheme.headerHeight('set');
classie.add( wrapper, 'fixed-active' );
setTimeout( function() {
classie.add( wrapper, 'fixed-active-animate' );
},250); //150
}
else {
classie.remove( wrapper, 'fixed-active' );
classie.remove( wrapper, 'fixed-active-animate' );
etTheme.headerHeight('unset');
}
didScroll = false;
LastscrollY = sy;
}

Three.js OrbitControls Orthographic Panning

In my program, the further out you zoom, the slower you can pan around. So, I want to increase the panning speed based on the zoom level. I've tried .panSpeed, but that doesn't work, and .panSpeed doesn't seem to exist anymore in OrbitControls.js. Is there another function that I can use?
Here is the documentation I looked at for Three.js OrbitControls:
https://github.com/mrdoob/three.js/blob/master/examples/js/controls/OrbitControls.js
If you look in the documentation you just linked youll'find
// Set to false to disable panning
this.enablePan = true;
this.keyPanSpeed = 7.0; // pixels moved per arrow key push
Maybe .keyPanSpeed is what you're looking for.
UPDATE 1:
In the OrbitControls.js you have the following function to handle pan:
function pan( deltaX, deltaY ) {
var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
constraint.pan( deltaX, deltaY, element.clientWidth, element.clientHeight );
}
So if for example you multiply deltaX and deltaY by 10 you'll see the pan going 10 times faster:
constraint.pan( deltaX * 10, deltaY * 10, element.clientWidth, element.clientHeight );
Try to insert your calculations based on zoom right there, it should work.
UPDATE 2:
Actually I'm using an older version of OrbitControls, which is slightly different from the current one. Here it is:
/**
* #author qiao / https://github.com/qiao
* #author mrdoob / http://mrdoob.com
* #author alteredq / http://alteredqualia.com/
* #author WestLangley / http://github.com/WestLangley
* #author erich666 / http://erichaines.com
*/
/*global THREE, console */
( function () {
function OrbitConstraint ( object ) {
this.object = object;
// "target" sets the location of focus, where the object orbits around
// and where it pans with respect to.
this.target = new THREE.Vector3();
// Limits to how far you can dolly in and out ( PerspectiveCamera only )
this.minDistance = 0;
this.maxDistance = Infinity;
// Limits to how far you can zoom in and out ( OrthographicCamera only )
this.minZoom = 0;
this.maxZoom = Infinity;
// How far you can orbit vertically, upper and lower limits.
// Range is 0 to Math.PI radians.
this.minPolarAngle = 0; // radians
this.maxPolarAngle = Math.PI; // radians
// How far you can orbit horizontally, upper and lower limits.
// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].
this.minAzimuthAngle = - Infinity; // radians
this.maxAzimuthAngle = Infinity; // radians
// Set to true to enable damping (inertia)
// If damping is enabled, you must call controls.update() in your animation loop
this.enableDamping = false;
this.dampingFactor = 0.25;
////////////
// internals
var scope = this;
var EPS = 0.000001;
// Current position in spherical coordinate system.
var theta;
var phi;
// Pending changes
var phiDelta = 0;
var thetaDelta = 0;
var scale = 1;
var panOffset = new THREE.Vector3();
var zoomChanged = false;
// API
this.getPolarAngle = function () {
return phi;
};
this.getAzimuthalAngle = function () {
return theta;
};
this.rotateLeft = function ( angle ) {
thetaDelta -= angle;
};
this.rotateUp = function ( angle ) {
phiDelta -= angle;
};
// pass in distance in world space to move left
this.panLeft = function() {
var v = new THREE.Vector3();
return function panLeft ( distance ) {
var te = this.object.matrix.elements;
// get X column of matrix
v.set( te[ 0 ], te[ 1 ], te[ 2 ] );
v.multiplyScalar( - distance );
panOffset.add( v );
};
}();
// pass in distance in world space to move up
this.panUp = function() {
var v = new THREE.Vector3();
return function panUp ( distance ) {
var te = this.object.matrix.elements;
// get Y column of matrix
v.set( te[ 4 ], te[ 5 ], te[ 6 ] );
v.multiplyScalar( distance );
panOffset.add( v );
};
}();
// pass in x,y of change desired in pixel space,
// right and down are positive
this.pan = function ( deltaX, deltaY, screenWidth, screenHeight ) {
if ( scope.object instanceof THREE.PerspectiveCamera ) {
// perspective
var position = scope.object.position;
var offset = position.clone().sub( scope.target );
var targetDistance = offset.length();
// half of the fov is center to top of screen
targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );
// we actually don't use screenWidth, since perspective camera is fixed to screen height
scope.panLeft( 2 * deltaX * targetDistance / screenHeight );
scope.panUp( 2 * deltaY * targetDistance / screenHeight );
} else if ( scope.object instanceof THREE.OrthographicCamera ) {
// orthographic
scope.panLeft( deltaX * ( scope.object.right - scope.object.left ) / screenWidth );
scope.panUp( deltaY * ( scope.object.top - scope.object.bottom ) / screenHeight );
} else {
// camera neither orthographic or perspective
console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );
}
};
this.dollyIn = function ( dollyScale ) {
if ( scope.object instanceof THREE.PerspectiveCamera ) {
scale /= dollyScale;
} else if ( scope.object instanceof THREE.OrthographicCamera ) {
scope.object.zoom = Math.max( this.minZoom, Math.min( this.maxZoom, this.object.zoom * dollyScale ) );
scope.object.updateProjectionMatrix();
zoomChanged = true;
} else {
console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
}
};
this.dollyOut = function ( dollyScale ) {
if ( scope.object instanceof THREE.PerspectiveCamera ) {
scale *= dollyScale;
} else if ( scope.object instanceof THREE.OrthographicCamera ) {
scope.object.zoom = Math.max( this.minZoom, Math.min( this.maxZoom, this.object.zoom / dollyScale ) );
scope.object.updateProjectionMatrix();
zoomChanged = true;
} else {
console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
}
};
this.update = function() {
var offset = new THREE.Vector3();
// so camera.up is the orbit axis
var quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );
var quatInverse = quat.clone().inverse();
var lastPosition = new THREE.Vector3();
var lastQuaternion = new THREE.Quaternion();
return function () {
var position = this.object.position;
offset.copy( position ).sub( this.target );
// rotate offset to "y-axis-is-up" space
offset.applyQuaternion( quat );
// angle from z-axis around y-axis
theta = Math.atan2( offset.x, offset.z );
// angle from y-axis
phi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y );
theta += thetaDelta;
phi += phiDelta;
// restrict theta to be between desired limits
theta = Math.max( this.minAzimuthAngle, Math.min( this.maxAzimuthAngle, theta ) );
// restrict phi to be between desired limits
phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, phi ) );
// restrict phi to be betwee EPS and PI-EPS
phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );
var radius = offset.length() * scale;
// restrict radius to be between desired limits
radius = Math.max( this.minDistance, Math.min( this.maxDistance, radius ) );
// move target to panned location
this.target.add( panOffset );
offset.x = radius * Math.sin( phi ) * Math.sin( theta );
offset.y = radius * Math.cos( phi );
offset.z = radius * Math.sin( phi ) * Math.cos( theta );
// rotate offset back to "camera-up-vector-is-up" space
offset.applyQuaternion( quatInverse );
position.copy( this.target ).add( offset );
this.object.lookAt( this.target );
if ( this.enableDamping === true ) {
thetaDelta *= ( 1 - this.dampingFactor );
phiDelta *= ( 1 - this.dampingFactor );
} else {
thetaDelta = 0;
phiDelta = 0;
}
scale = 1;
panOffset.set( 0, 0, 0 );
// update condition is:
// min(camera displacement, camera rotation in radians)^2 > EPS
// using small-angle approximation cos(x/2) = 1 - x^2 / 8
if ( zoomChanged ||
lastPosition.distanceToSquared( this.object.position ) > EPS ||
8 * ( 1 - lastQuaternion.dot( this.object.quaternion ) ) > EPS ) {
lastPosition.copy( this.object.position );
lastQuaternion.copy( this.object.quaternion );
zoomChanged = false;
return true;
}
return false;
};
}();
};
// This set of controls performs orbiting, dollying (zooming), and panning. It maintains
// the "up" direction as +Y, unlike the TrackballControls. Touch on tablet and phones is
// supported.
//
// Orbit - left mouse / touch: one finger move
// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish
// Pan - right mouse, or arrow keys / touch: three finter swipe
THREE.OrbitControls = function ( object, domElement ) {
var constraint = new OrbitConstraint( object );
this.domElement = ( domElement !== undefined ) ? domElement : document;
// API
Object.defineProperty( this, 'constraint', {
get: function() {
return constraint;
}
} );
this.getPolarAngle = function () {
return constraint.getPolarAngle();
};
this.getAzimuthalAngle = function () {
return constraint.getAzimuthalAngle();
};
// Set to false to disable this control
this.enabled = true;
// center is old, deprecated; use "target" instead
this.center = this.target;
// This option actually enables dollying in and out; left as "zoom" for
// backwards compatibility.
// Set to false to disable zooming
this.enableZoom = true;
this.zoomSpeed = 1.0;
// Set to false to disable rotating
this.enableRotate = true;
this.rotateSpeed = 1.0;
// Set to false to disable panning
this.enablePan = true;
this.keyPanSpeed = 7.0; // pixels moved per arrow key push
// Set to true to automatically rotate around the target
// If auto-rotate is enabled, you must call controls.update() in your animation loop
this.autoRotate = false;
this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60
// Set to false to disable use of the keys
this.enableKeys = true;
// The four arrow keys
this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };
// Mouse buttons
this.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };
////////////
// internals
var scope = this;
var rotateStart = new THREE.Vector2();
var rotateEnd = new THREE.Vector2();
var rotateDelta = new THREE.Vector2();
var panStart = new THREE.Vector2();
var panEnd = new THREE.Vector2();
var panDelta = new THREE.Vector2();
var dollyStart = new THREE.Vector2();
var dollyEnd = new THREE.Vector2();
var dollyDelta = new THREE.Vector2();
var STATE = { NONE : - 1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };
var state = STATE.NONE;
// for reset
this.target0 = this.target.clone();
this.position0 = this.object.position.clone();
this.zoom0 = this.object.zoom;
// events
var changeEvent = { type: 'change' };
var startEvent = { type: 'start' };
var endEvent = { type: 'end' };
// pass in x,y of change desired in pixel space,
// right and down are positive
function pan( deltaX, deltaY ) {
var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
constraint.pan( deltaX, deltaY, element.clientWidth, element.clientHeight );
}
this.update = function () {
if ( this.autoRotate && state === STATE.NONE ) {
constraint.rotateLeft( getAutoRotationAngle() );
}
if ( constraint.update() === true ) {
this.dispatchEvent( changeEvent );
}
};
this.reset = function () {
state = STATE.NONE;
this.target.copy( this.target0 );
this.object.position.copy( this.position0 );
this.object.zoom = this.zoom0;
this.object.updateProjectionMatrix();
this.dispatchEvent( changeEvent );
this.update();
};
function getAutoRotationAngle() {
return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
}
function getZoomScale() {
return Math.pow( 0.95, scope.zoomSpeed );
}
function onMouseDown( event ) {
if ( scope.enabled === false ) return;
event.preventDefault();
if ( event.button === scope.mouseButtons.ORBIT ) {
if ( scope.enableRotate === false ) return;
state = STATE.ROTATE;
rotateStart.set( event.clientX, event.clientY );
} else if ( event.button === scope.mouseButtons.ZOOM ) {
if ( scope.enableZoom === false ) return;
state = STATE.DOLLY;
dollyStart.set( event.clientX, event.clientY );
} else if ( event.button === scope.mouseButtons.PAN ) {
if ( scope.enablePan === false ) return;
state = STATE.PAN;
panStart.set( event.clientX, event.clientY );
}
if ( state !== STATE.NONE ) {
document.addEventListener( 'mousemove', onMouseMove, false );
document.addEventListener( 'mouseup', onMouseUp, false );
scope.dispatchEvent( startEvent );
}
}
function onMouseMove( event ) {
if ( scope.enabled === false ) return;
event.preventDefault();
var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
if ( state === STATE.ROTATE ) {
if ( scope.enableRotate === false ) return;
rotateEnd.set( event.clientX, event.clientY );
rotateDelta.subVectors( rotateEnd, rotateStart );
// rotating across whole screen goes 360 degrees around
constraint.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );
// rotating up and down along whole screen attempts to go 360, but limited to 180
constraint.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );
rotateStart.copy( rotateEnd );
} else if ( state === STATE.DOLLY ) {
if ( scope.enableZoom === false ) return;
dollyEnd.set( event.clientX, event.clientY );
dollyDelta.subVectors( dollyEnd, dollyStart );
if ( dollyDelta.y > 0 ) {
constraint.dollyIn( getZoomScale() );
} else if ( dollyDelta.y < 0 ) {
constraint.dollyOut( getZoomScale() );
}
dollyStart.copy( dollyEnd );
} else if ( state === STATE.PAN ) {
if ( scope.enablePan === false ) return;
panEnd.set( event.clientX, event.clientY );
panDelta.subVectors( panEnd, panStart );
pan( panDelta.x, panDelta.y );
panStart.copy( panEnd );
}
if ( state !== STATE.NONE ) scope.update();
}
function onMouseUp( /* event */ ) {
if ( scope.enabled === false ) return;
document.removeEventListener( 'mousemove', onMouseMove, false );
document.removeEventListener( 'mouseup', onMouseUp, false );
scope.dispatchEvent( endEvent );
state = STATE.NONE;
}
function onMouseWheel( event ) {
if ( scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE ) return;
event.preventDefault();
event.stopPropagation();
var delta = 0;
if ( event.wheelDelta !== undefined ) {
// WebKit / Opera / Explorer 9
delta = event.wheelDelta;
} else if ( event.detail !== undefined ) {
// Firefox
delta = - event.detail;
}
if ( delta > 0 ) {
constraint.dollyOut( getZoomScale() );
} else if ( delta < 0 ) {
constraint.dollyIn( getZoomScale() );
}
scope.update();
scope.dispatchEvent( startEvent );
scope.dispatchEvent( endEvent );
}
function onKeyDown( event ) {
if ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;
switch ( event.keyCode ) {
case scope.keys.UP:
pan( 0, scope.keyPanSpeed );
scope.update();
break;
case scope.keys.BOTTOM:
pan( 0, - scope.keyPanSpeed );
scope.update();
break;
case scope.keys.LEFT:
pan( scope.keyPanSpeed, 0 );
scope.update();
break;
case scope.keys.RIGHT:
pan( - scope.keyPanSpeed, 0 );
scope.update();
break;
}
}
function touchstart( event ) {
if ( scope.enabled === false ) return;
switch ( event.touches.length ) {
case 1: // one-fingered touch: rotate
if ( scope.enableRotate === false ) return;
state = STATE.TOUCH_ROTATE;
rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
break;
case 2: // two-fingered touch: dolly
if ( scope.enableZoom === false ) return;
state = STATE.TOUCH_DOLLY;
var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
var distance = Math.sqrt( dx * dx + dy * dy );
dollyStart.set( 0, distance );
break;
case 3: // three-fingered touch: pan
if ( scope.enablePan === false ) return;
state = STATE.TOUCH_PAN;
panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
break;
default:
state = STATE.NONE;
}
if ( state !== STATE.NONE ) scope.dispatchEvent( startEvent );
}
function touchmove( event ) {
if ( scope.enabled === false ) return;
event.preventDefault();
event.stopPropagation();
var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
switch ( event.touches.length ) {
case 1: // one-fingered touch: rotate
if ( scope.enableRotate === false ) return;
if ( state !== STATE.TOUCH_ROTATE ) return;
rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
rotateDelta.subVectors( rotateEnd, rotateStart );
// rotating across whole screen goes 360 degrees around
constraint.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );
// rotating up and down along whole screen attempts to go 360, but limited to 180
constraint.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );
rotateStart.copy( rotateEnd );
scope.update();
break;
case 2: // two-fingered touch: dolly
if ( scope.enableZoom === false ) return;
if ( state !== STATE.TOUCH_DOLLY ) return;
var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
var distance = Math.sqrt( dx * dx + dy * dy );
dollyEnd.set( 0, distance );
dollyDelta.subVectors( dollyEnd, dollyStart );
if ( dollyDelta.y > 0 ) {
constraint.dollyOut( getZoomScale() );
} else if ( dollyDelta.y < 0 ) {
constraint.dollyIn( getZoomScale() );
}
dollyStart.copy( dollyEnd );
scope.update();
break;
case 3: // three-fingered touch: pan
if ( scope.enablePan === false ) return;
if ( state !== STATE.TOUCH_PAN ) return;
panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
panDelta.subVectors( panEnd, panStart );
pan( panDelta.x, panDelta.y );
panStart.copy( panEnd );
scope.update();
break;
default:
state = STATE.NONE;
}
}
function touchend( /* event */ ) {
if ( scope.enabled === false ) return;
scope.dispatchEvent( endEvent );
state = STATE.NONE;
}
function contextmenu( event ) {
event.preventDefault();
}
this.dispose = function() {
this.domElement.removeEventListener( 'contextmenu', contextmenu, false );
this.domElement.removeEventListener( 'mousedown', onMouseDown, false );
this.domElement.removeEventListener( 'mousewheel', onMouseWheel, false );
this.domElement.removeEventListener( 'MozMousePixelScroll', onMouseWheel, false ); // firefox
this.domElement.removeEventListener( 'touchstart', touchstart, false );
this.domElement.removeEventListener( 'touchend', touchend, false );
this.domElement.removeEventListener( 'touchmove', touchmove, false );
document.removeEventListener( 'mousemove', onMouseMove, false );
document.removeEventListener( 'mouseup', onMouseUp, false );
window.removeEventListener( 'keydown', onKeyDown, false );
}
this.domElement.addEventListener( 'contextmenu', contextmenu, false );
this.domElement.addEventListener( 'mousedown', onMouseDown, false );
this.domElement.addEventListener( 'mousewheel', onMouseWheel, false );
this.domElement.addEventListener( 'MozMousePixelScroll', onMouseWheel, false ); // firefox
this.domElement.addEventListener( 'touchstart', touchstart, false );
this.domElement.addEventListener( 'touchend', touchend, false );
this.domElement.addEventListener( 'touchmove', touchmove, false );
window.addEventListener( 'keydown', onKeyDown, false );
// force an update at start
this.update();
};
THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );
THREE.OrbitControls.prototype.constructor = THREE.OrbitControls;
Object.defineProperties( THREE.OrbitControls.prototype, {
object: {
get: function () {
return this.constraint.object;
}
},
target: {
get: function () {
return this.constraint.target;
},
set: function ( value ) {
console.warn( 'THREE.OrbitControls: target is now immutable. Use target.set() instead.' );
this.constraint.target.copy( value );
}
},
minDistance : {
get: function () {
return this.constraint.minDistance;
},
set: function ( value ) {
this.constraint.minDistance = value;
}
},
maxDistance : {
get: function () {
return this.constraint.maxDistance;
},
set: function ( value ) {
this.constraint.maxDistance = value;
}
},
minZoom : {
get: function () {
return this.constraint.minZoom;
},
set: function ( value ) {
this.constraint.minZoom = value;
}
},
maxZoom : {
get: function () {
return this.constraint.maxZoom;
},
set: function ( value ) {
this.constraint.maxZoom = value;
}
},
minPolarAngle : {
get: function () {
return this.constraint.minPolarAngle;
},
set: function ( value ) {
this.constraint.minPolarAngle = value;
}
},
maxPolarAngle : {
get: function () {
return this.constraint.maxPolarAngle;
},
set: function ( value ) {
this.constraint.maxPolarAngle = value;
}
},
minAzimuthAngle : {
get: function () {
return this.constraint.minAzimuthAngle;
},
set: function ( value ) {
this.constraint.minAzimuthAngle = value;
}
},
maxAzimuthAngle : {
get: function () {
return this.constraint.maxAzimuthAngle;
},
set: function ( value ) {
this.constraint.maxAzimuthAngle = value;
}
},
enableDamping : {
get: function () {
return this.constraint.enableDamping;
},
set: function ( value ) {
this.constraint.enableDamping = value;
}
},
dampingFactor : {
get: function () {
return this.constraint.dampingFactor;
},
set: function ( value ) {
this.constraint.dampingFactor = value;
}
},
// backward compatibility
noZoom: {
get: function () {
console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );
return ! this.enableZoom;
},
set: function ( value ) {
console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );
this.enableZoom = ! value;
}
},
noRotate: {
get: function () {
console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );
return ! this.enableRotate;
},
set: function ( value ) {
console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );
this.enableRotate = ! value;
}
},
noPan: {
get: function () {
console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );
return ! this.enablePan;
},
set: function ( value ) {
console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );
this.enablePan = ! value;
}
},
noKeys: {
get: function () {
console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );
return ! this.enableKeys;
},
set: function ( value ) {
console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );
this.enableKeys = ! value;
}
},
staticMoving : {
get: function () {
console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );
return ! this.constraint.enableDamping;
},
set: function ( value ) {
console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );
this.constraint.enableDamping = ! value;
}
},
dynamicDampingFactor : {
get: function () {
console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );
return this.constraint.dampingFactor;
},
set: function ( value ) {
console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );
this.constraint.dampingFactor = value;
}
}
} );
}() );

How to make a element follow another element when dragging with jquery?

I need make a element follow another element when dragging, but with delay in the animation, is similar to "Chat heads of facebook's messenger", you know, the bubbles on Android.
This is my jQuery plugin:
// Draggable plugin
(function($) {
$.fn.drag = function(options) {
options = $.extend({
handle: null,
cursor: 'move',
draggingClass: 'dragging',
heads: null
}, options);
var $handle = this,
$drag = this;
if( options.handle ) {
$handle = $(options.handle);
}
$handle
.css('cursor', options.cursor)
.on("mousedown", function(e) {
var x = $drag.offset().left - e.pageX,
y = $drag.offset().top - e.pageY,
z = $drag.css('z-index');
$drag.css('z-index', 100000);
$(document.documentElement)
.on('mousemove.drag', function(e) {
var chats = $($(options.heads).get().reverse());
chats.each(function(i) {
$(chats[i]).css({ left: $drag.position().left - (10*i)});
$(chats[i]).css({top: $drag.position().top});
});
$drag.offset({
left: x + e.pageX,
top: y + e.pageY
});
})
.one('mouseup', function() {
$(this).off('mousemove.drag');
$drag.css('z-index', z);
var window_width = $(window).width();
var window_height = $(window).height();
var head_wpostion = $(options.heads).position().left;
var head_hposition = $(options.heads).position().top;
if( head_wpostion > (window_width / 2) )
{
$(options.heads).animate({left: (window_width-40)+"px"}, 300 );
$(options.heads).animate({left: (window_width-50)+"px"}, 300 );
}
else
{
$(options.heads).animate({left: "-15px"}, 300 );
$(options.heads).animate({left: "-5px"}, 300 );
}
if( head_hposition > (window_height - 50) )
{
$(options.heads).animate({top: (window_height-75)+"px"}, 200 );
$(options.heads).animate({top: (window_height-65)+"px"}, 200 );
}
if( head_hposition < 0 )
{
$(options.heads).animate({top: "15px"}, 150 );
$(options.heads).animate({top: "5px"}, 150 );
}
});
// disable selection
e.preventDefault();
});
};
})(jQuery);
the only way you can do that is if you position the element you want to to be dragged along relevant to the drag-able element.

Categories