JQuery shaking effect with some tilt/rotation - javascript

I am trying to create an effect where on button click, the div would shake left and right and tilt about 10deg each way so it looks like a natural motion when shaking an object with two hands. I am able to create the left and right shaking effect but can't seem to tie it in with rotation. I also need this to work in IE8, so css3 is not an option. I am using JQuery UI and .rotate() but if there is a better way please let me know. I need this to shake about 3-4 times on button click.
<div class="container">
<div class="globe-main" id="globe">
<div class="content"></div><!-- end .content -->
</div><!-- end .globe-main -->
</div><!-- end .container -->
<script>
var times = 4;
var loop = setInterval(rota, 300);
function rota() {
times--;
if(times === 0){clearInterval(loop);}
$(".globe-main").rotate({animateTo:10, duration: 500, });
//$(".globe-main").effect("shake", { times:3, distance:30 }, 800);
}
rota();
</script>
Here is what I have so far FIDDLE
Thank you
UPDATE
Here is the updated FIDDLE

jQuery has no method called rotate. This is probably where the problem lies.
Edit
Based on your comments, you could create your own queue I guess...
rotationAnimationQueue = {
queue: [],
addAnimation: function( $jQueryObject, params ) {
// add animation to the queue
this.queue.push( {
$jQueryObject: $jQueryObject,
params: params
} );
// if only animation in queue, begin processing
if ( this.queue.length === 1 ) this.processQueue();
},
processQueue: function() {
var self = this;
var animation = this.queue[ 0 ];
animation.params.callback = function() {
self.queue.shift();
if ( self.queue.length > 0 ) self.processQueue();
};
animation.$jQueryObject.rotate( animation.params );
}
};
See it in action here: http://jsfiddle.net/UnyYh/1/
You may want to modify the queue code so that it keeps track of one queue per jQuery object. This way if needed you could have shake animations happening on multiple objects at the same time instead of always doing the animations in sequence.

Related

Callback after element moved

I have list that scrolls up using velocity. I want to play sound each time, first visible item of the list scrolled up.
<div class="viewport" data-winner="">
<ul class="participants-holder container" id="ph">
<li>...<li> //many li elements
</ul>
</div>
moveToEl(name) {
...
$(container).velocity({
translateY: -(offsetToScroll)+'px'
}, {
duration: 15000,
easing: [.74,0,.26,1],
complete: (el) => {
...
// complete animation callback
},
progress: (els, complete, remaining, start, tweenVal) => {
console.log(Math.floor(complete * 100) + '%')
// I think some check should do during progress animation
}
})
}
How to handle event or track changes when each element or entire list are scrolled up by certain pixels, for instance 62px. How can I detect this and call callback function on this happened.
You can find the current TranslateY using something like
+this.container.style.transform.replace(/[^0-9.]/g, '');
from https://stackoverflow.com/a/42267490/1544886, and compare it to the previous value plus an offset.
In the Roulette class add this.prevTranslatePos = 0.0; for storing the old value.
progress: (els, complete, remaining, start) => {
// from https://stackoverflow.com/a/42267490/1544886
var translatePos = +this.container.style.transform.replace(/[^0-9.]/g, '');
if (translatePos >= (this.prevTranslatePos + 62))
{
//console.log(translatePos, this.prevTranslatePos);
this.prevTranslatePos = translatePos;
this.sound.pause();
this.sound.currentTime = 0;
this.sound.play();
}
}
Demo applied to the 'Go To' button only: http://codepen.io/anon/pen/yMXwgd?editors=1010
Note that the sound cuts out when it runs too quickly, but that could be handled a few different ways.
Add a scroll eventListener to the parent element of the list (I believe it's participants-holder in your case), and within that do a check for whether the right amount of pixels have moved since the last check. Store the current position, and compare it to the last time you moved the desired amount.
Hope that helps!

Does jquery trigger slidedown animation on an element that is already slidedown?

Well I hope the question is self-explanatory. I have the following code:
$(window).scroll(function () {
var scrollTop = $(window).scrollTop();
if (scrollTop > sliderTop) {
$('#slider').slideDown(1000);
} else {
$('#slider').slideUp(1000);
}
});
If I scroll down after a certain point the slideDown function will be called continuously. does JQuery animates it over and over again or is it smart enough to know that the element is already slide down? (currently I'm using a flag to check whether its already slide down).
The animation won't run again. See lines 459-468 in effect.js in the jquery src
doAnimation = function() {
// Operate on a copy of prop so per-property easing won't be lost
var anim = Animation( this, jQuery.extend( {}, prop ), optall );
// Empty animations, or finishing resolves immediately
if ( empty || data_priv.get( this, "finish" ) ) {
anim.stop( true ); // ** here - stopping right after started.
}
};
doAnimation.finish = doAnimation;
But I would still recommend against it to improve code readability. just use a boolean, it doesn't hurt...

jQuery wait for an action to complete on different functions

I have created a newsfeed. The feed switches every 2 seconds. You can also manually switch left/right, or click the panel from the squares at the bottom. The switching between slides is down using jQuery UI Slide.
Right now, if you are in the middle of a slide, and you click left/right/squares, then another slide occurs on top of the existing, still going slide and the whole system is messed up.
How can I prevent other actions occurring if a slide/switch is already in progress?
This is my code:
$(document).ready(function(){
newsfeedTimer = setInterval(newsfeed, displayDuration);
// Manual change of feed (LEFT)
$('#newsfeeds_wrapper > .left').click(function(event){
event.stopPropagation();
feedLeft();
clearInterval(newsfeedTimer);
newsfeedTimer = setInterval(newsfeed, displayDuration);
});
// Very similar code for feed right
// Ignore the other method of switching (if it works for above, I can implement it for this one)
});
function newsfeed() {
feedRight();
}
// Feed to the Right
// jump is used to jump multiple newsfeed instead of one at a time
function feedRight(jump)
{
jump = typeof jump !== 'undefined' ? jump : 1;
var current = $('.newsfeed:first');
var next = $('.newsfeed:nth(' + jump + ')');
current.hide('slide',{duration: transitionDuration}, function(){
// Append as many needed
for( var i = 0; i < jump; i++ ) {
$('.newsfeed:first').appendTo('#newsfeeds');
}
next.show('slide',{direction : 'right' , duration: transitionDuration});
}
I don't want to stop() an animation! I want to disable changing the slides IF there is animation happening!!
without seeing the full breadth of the code, I am shooting myself in the foot here. But here is a direction I would take it. You could also have two functions, one to bind, another to unbind. When animation is initiated, you unbind the left/right controls. When stopped, you bind. Or, set a global variable... ala.
var config = {'inProgress': false};
$('#newsfeeds_wrapper > .left').click(function(event){
if(!config.inProgress){
event.stopPropagation();
feedLeft();
clearInterval(newsfeedTimer);
newsfeedTimer = setInterval(newsfeed, displayDuration);
}
});
in your animation function. Seems like when you cut/paste, some of the code is lost, so lets just assume some animation.
when you enter your animation functions, set config.inProgress = true;
function feedRight(jump)
{
config.inProgress = true;
// removed your code, but just using for simplicity sake
// added a callback
next.show('slide',{direction : 'right' , duration: transitionDuration},
function() {
// Animation complete. Set inProgress to false
config.inProgress = false;
});
)
}

Bouncer plugins in jquery

I am looking for a jquery plugin that bounces a div element periodically infinite times. I have no such example website to show, but what I want is a div element that bounces to right(say) and bounces back to left. And at the time of bounce I want to change the content. Also bounce should go on. It should not stop or slow down.
I searched in
http://jquery.com/
http://mootools.net/
but found nothing that I wanted. There is bounce that stops after sometime.
Can you please help me?
If I have interpret your description correctly, you want a div that moves left and right continuously and changes content on "arrival". I'm still not sure if you want to toggle content or loop through more content.
A little illustration to clarify:
__________ __________
| | >>>>>>>>>>>>>>>>>> | |
| content1 | | content2 |
|__________| <<<<<<<<<<<<<<<<<< |__________|
|---------------------------------|
content change content change
Now, because the VERY specific request, I highly doubt there's such a plugin available. You just have to be creative yourself! Luckily, I'm a nice guy and save you some work.
See the online demo.
My javascript function:
function startBouncing(selector, content, duration, easing) {
// get the required movement (parent width - element width)
var movement = $(selector).parent().width() - $(selector).width();
var contentIndex = 0; // we want to start with content index 0
// define function that makes element go forth
var goForth = function() {
// start animation and change text
$(selector).animate({
'margin-left': movement
}, duration, easing, goBack).children('p:first').html(content[contentIndex % content.length]);
contentIndex++; // increment index for next time
};
// define function that makes element go back
var goBack = function() {
// start animation and change text
$(selector).animate({
'margin-left': 0
}, duration, easing, goForth).children('p:first').html(content[contentIndex % content.length]);
contentIndex++; // increment index for next time
};
// start the sequence
goForth();
}
Which I call using:
var content = [
'content #1',
'content #2',
'content #3'
]; // if you wish to toggle, just use 2 elements
// calling the function
startBouncing('#bouncer', content, 2000, 'linear');
And finally, the HTML:
<div style="background-color: gray; height: 50px; width: 500px;">
<div id="bouncer" style="background-color: #ff0000; height: 50px; width: 50px;">
<p>content</p>
</div>
</div>
It might not look good, but it works. I haven't spend a second in optimizing the code.
edit
I've edited the function so you specify a different duration and easing per side.
function startBouncing(selector, content, duration1, duration2, easing1, easing2) {
// get the required movement (parent width - element width)
var movement = $(selector).parent().width() - $(selector).width();
var contentIndex = 0; // we want to start with content index 0
// define function that makes element go forth
var goForth = function() {
// start animation and change text
$(selector).animate({
'margin-left': movement
}, duration1, easing1, goBack).children('p:first').html(content[contentIndex % content.length]);
contentIndex++; // increment index for next time
};
// define function that makes element go back
var goBack = function() {
// start animation and change text
$(selector).animate({
'margin-left': 0
}, duration2, easing2, goForth).children('p:first').html(content[contentIndex % content.length]);
contentIndex++; // increment index for next time
};
// start the sequence
goForth();
}
For more advanced easing strings, you should use an plugin that adds more easing strings like this one.
use should combine the animate function using an cool bouncing easing effect (requires jquery ui). i order to make it bounce repeatedly, use the setTimeout function..

Is there any way to make two jQuery animations run (properly) simultaneously?

I have an event listener that calls two animation actions. Unfortunately their starts are staggered by a small amount (e.g. the first in the function starts first).
Does anyone know a way to properly sync them up?
Here's my code:
$("#nav ul li a").hover(
function(){
$(lastBlock).children("div").animate({width: "0px"}, { queue:false, duration:400, easing:"swing" });
$(this).children("div").animate({width: maxWidth+"px"}, { queue:false, duration:400, easing:"swing"});
lastBlock = this;
}
);
Because the first animation runs slightly before the second, it causes the overall width to become momentarily unequal, which looks a bit funky.
There was a recent disussion about this exact topic on the jQuery dev list. They created a few test cases you might wanna look at. Specially the Johns test.
Here's the discussion topic btw.
The trick is to have a single interval/callback in which all elements are updated.
You can find an example in my post here:
Can I implement a callback with each animation step in jQuery?
What you end up is basically:
var el1 = $("#element1");
var el2 = $("#element2");
var animation = new AnimationTimeline( {
easing: "swing"
, onstep: function( stepValue, animprops )
{
// This is called for every animation frame. Set the elements:
el1.css( { left: ..., top: ... } );
el2.css( { left: ..., top: ... } );
}
});
// And start it.
animation.start();

Categories

Resources