I have this bit of code which basically defines a loop that rotates an image at the end of a transition: http://jsfiddle.net/bolaoch8/k8XtU/1/
$('#avion').css('left', '0%');
var animacionAvion = TweenMax.to($('#avion'), 5, {css:{left:'100%'}, delay:0, repeat:-1, yoyo:true});
setInterval(giraAvion, 5000);
var rotationValue = 180;
function giraAvion()
{
console.log('giraAvion a:', rotationValue);
TweenMax.to($('#avion'), 0.8, {css:{transform:'rotate('+rotationValue+'deg)'}, delay:5});
rotationValue == 180?rotationValue = 0:rotationValue = 180;
}
giraAvion();
Just wondering why the second time the image rotates it does that weird thing... Any ideas?
I suggest you to use TimelineMax, wich will help you to chain tweens : http://api.greensock.com/js/
It will render your animation much simpler.
var tl = new TimelineMax({repeat:-1});
tl.to($('#avion'), 5, {css:{left:'100%'}});
tl.to($('#avion'), 0.8, {css:{rotation:180}});
tl.to($('#avion'), 5, {css:{left:'0%'}});
tl.to($('#avion'), 0.8, {css:{rotation:0}});
tl.play();
No more intervals and functions!
I modifed your jsfiddle to get the power of it :
http://jsfiddle.net/xavier_seignard/k8XtU/3/
Related
I've been learning how to implement more animations on my sites. I was trying to figure out this code because it is similar to the animation I want to implement but I can't seem to wrap my head around it. Ideally, I want the animation to play just once so the elements don't disappear when I scroll back up. But, I can't figure out what's making the animation "reverse" when you scroll back up.
How can I change up the code to do this?
thanks
// init
var controller = new ScrollMagic.Controller();
// loop
$('.reveal_main').each(function() {
var loaderInit = new TimelineMax();
// tween variables
if ($(this).hasClass('left')) {
var imgSet = 20,
imgBlockFrom = -101,
imgBlockTo = 101,
contTextSet = -30,
textBlockStaggerFrom = 101,
textBlockStaggerTo = -101;
} else {
var imgSet = -20,
imgBlockFrom = 101,
imgBlockTo = -101,
contTextSet = 30,
textBlockStaggerFrom = -101,
textBlockStaggerTo = 101;
}
// build a tween
loaderInit
.set($(this).find('.reveal_cont-img'), {autoAlpha:1,xPercent:imgSet},0)
.from($(this).find('.reveal_block-img'), 0.325,{xPercent:imgBlockFrom, ease:Power1.easeOut})
.set($(this).find('.reveal_img'), {autoAlpha:1})
.to($(this).find('.reveal_block-img'), 0.225,{xPercent:imgBlockTo, ease:Sine.easeOut})
.set($(this).find('.reveal_cont-text'), {autoAlpha:1,xPercent:contTextSet},0.3)
// stagger text blocks and text
.staggerFromTo($(this).find('.reveal_block'), 0.7, {xPercent:textBlockStaggerFrom, ease:Power1.easeOut}, {xPercent:textBlockStaggerTo, ease:Power1.easeOut},0.25)
.add('blocksEnd')
.staggerTo($(this).find('.reveal_text'), 0.1, {autoAlpha:1},0.25,'blocksEnd-=0.75')
// build a scene
var scene = new ScrollMagic.Scene({
triggerElement: this,
triggerHook:'onEnter',
offset:700
})
.setTween(loaderInit)
.addTo(controller)
});
Here's the codepen: https://codepen.io/tayanderson/pen/POVEVJ
I figured it out. All I had to do was add reverse: false when building the scene.
var scene = new ScrollMagic.Scene({
triggerElement: this,
triggerHook:'onEnter',
offset:700,
reverse: false
})
Hi I have Created a Scene in BABYONJS , I am trying to achieve solor system in BABYONjs here i have made earth self rotate but i have tried to move arround that does not work any Idea ?
My Code
Self Rotate
scene.beforeRender = function () {
newEarth.rotate(new BABYLON.Vector3(0, 1, 0) , 0.01,
BABYLON.Space.WORLD);
};
The need is the earth should move arround
Here below i have a solution using pivot matrix
currentMesh.setPivotMatrix(BABYLON.Matrix.Translation(70, 0, 0));
camera.attachControl(canvas, true);
scene.registerBeforeRender(function () {
if (currentMesh) {
currentMesh.rotate(BABYLON.Axis.Y, Math.PI / 64,
BABYLON.Space.LOCAL);
}
});
try this one.
I'm trying to figure out how to use TimelineMax with Scrollmagic.
The problem is easy to explain.
I have similar DOM elements, like particles that have to move slowly than scrolling speed.
This first implementation is WORKING (no Timeline)
var controller = new ScrollMagic.Controller();
var $particles = $("#particles li");
$particles.each(function() {
var tween = TweenMax.to($(this), 1, { y: -100, ease: Linear.easeNone });
var scene = new ScrollMagic.Scene({
triggerElement: ".wrapper",
duration: 1000
});
scene.setTween(tween);
scene.addTo(controller);
});
The second implementation is NOT WORKING (uses Timeline)
var controller = new ScrollMagic.Controller();
var $particles = $("#particles li");
var timeline = new TimelineMax();
$particles.each(function() {
timeline.to($(this), 1, { y: -200, ease: Linear.easeNone });
});
var scene = new ScrollMagic.Scene({
triggerElement: ".wrapper",
duration: 1000
});
scene.setTween(timeline)
scene.addTo(controller);
I'd like to make timeline working but elements are not animating. They move but with null timing.
Thank you for help
--- CODEPENS ---
https://codepen.io/anon/pen/wJOveM (multiple scenes)
https://codepen.io/anon/pen/dvryog?editors=1111 (w/ timeline NOT WORKING)
Can you try to use the TimelineMax .add() method instead of the .to() method in you second implementation? So your code should look like this:
var controller = new ScrollMagic.Controller();
var $particles = $("#particles li");
var timeline = new TimelineMax();
$particles.each(function() {
timeline.add(TweenMax.to($(this), 1, { y: -200, ease: Linear.easeNone }),0);
});
var scene = new ScrollMagic.Scene({
triggerElement: ".wrapper",
duration: 1000
});
scene.setTween(timeline)
scene.addTo(controller);
Also, for better debugging, please add the .addIndicators() method to the scene to see indicators on the screen, which can really help in debugging while scrolling. You can try to play with the duration property as well to see if things work properly.
UPDATE: Since all the particles needed to be moving at the same time, I added a ,0 property at the end of every .add method call. This ensures that all the tweens are triggered at the same positions. You can read more about the position property here:
https://greensock.com/asdocs/com/greensock/TimelineLite.html#add()
Here's hopefully a working example this time :)
https://codepen.io/anon/pen/ryROrv
Hope this helps. Cheers.
I haven't used JS in awhile (2yrs) and I seem to have forgotten some basics;
So my question is: How would I clean-up or 'short-hand' the following javascript?
It would help me out on improving my JS code ( and maybe joggle my brains - LOL ).
var tl = TweenLite.to;
tl("#container", 0, {autoAlpha:0});
tl("#header", 0, {top:"-70px"});
tl("#footer", 0, {bottom:"-180px"});
function showPage() {
tl("#container", .2, {autoAlpha:1, delay:.5});
tl("#header", .2, {top:"0px", delay:.8});
tl("#footer", .2, {bottom:"-150px", delay:.8});
} window.onload = showPage;
...and obviously I am using TweenLite and I am not using jQuery but I am using Zepto. Thnx for your help.
-jason
Something like this:
var tl = TweenLite.to,
duration = 0.2;
// Set starting states in CSS
function showPage() {
tl("#container", duration, {autoAlpha: 1, delay: .5});
tl("#header", duration, {top: "0px", delay: .8});
tl("#footer", duration, {bottom: "-150px", delay: .8});
}
window.onload = showPage;
You could also check out the TweenLite.from method which allows you to do the inverse and set the finished states initially and specify where to tween from.
Please consider the following code snippet:
jQuery(function ()
{
drawLogo();
});
function drawLogo()
{
var paper = Raphael('logo', 100, 100);//creates canvas width=height=100px
var rect = paper.rect(1,1,98,98, 10);//chessboard background
rect.attr("fill","#efd5a4");
var circle1 = paper.circle(20,20,12);
var circle2 = paper.circle(50,20,12);
var circle3 = paper.circle(80,20,12);
var circle4 = paper.circle(20,50,12);
var circle5 = paper.circle(50,50,12);
var circle6 = paper.circle(80,50,12);
var circle7 = paper.circle(20,80,12);
var circle8 = paper.circle(50,80,12);
var circle9 = paper.circle(80,80,12);
paper.path("M35,0 L35,100");
paper.path("M65,0 L65,100");
paper.path("M0,35 L100,35");
paper.path("M0,65 L100,65");
circle1.animate({scale:"0"}, 2000);
//setTimeout(circle1.animate({scale:"1"}, 2000), 2000);
}
The animation I'd like to achieve is a chain of two parts, first, a vertical scale animation from 100% to 0%, second, a vertical scale animation from 0% to 100%. The above code scales down both vertically and horizontally, so it is incorrect.
I've check Raphael's documentation but couldn't get it, particularly because I cannot see the correct syntax... Any good API reference like that of jQuery's?
Also, if I make the following change, then Firefox shows an error saying too many recursions:
transform(circle1);
function transform(item)
{
item.animate({scale:"0"}, 2000, transform(item));
}
I know this is bad, but what is the correct way to get a infinite "loop" of animation?
Edit: I modified the code to the following
transform([circle1, circle3, circle5, circle7, circle9]);
function transform(elements)
{
for(var e in elements)
{
e.animate({scale:"0"}, 2000);
}
}
in the hope that this would at least run the first part of animation for 5 circles, but unfortunately, it only gives an error saying e.animate() is not a function. Probably the reason is that when elements are retrieved back from the array, it "loses its type"? (just like in Java when you get an elements from plain old ArrayList, you must explicitly downcast or everything will be just of type object.)
2nd Edit before going to bed
At least the following works for once!
var elements = [circle1, circle3, circle5, circle7, circle9];
for(var i = 0; i < elements.length; i++)
transform(elements[i]);
function transform(e)
{
e.animate({scale: 0},2000, function(){this.animate({scale:1},
2000, transform(this));});
}
Achieved parts: chained two scaling animations one after another, for five circles;
Failed parts: Still not an infinite loop, still not only vertical scale.
It seems scaling of circle in just one direction is not possible. Instead use an ellipse. The scale attribute takes a string like "1 0" which means scale 100% for x (horizontally) and 0% for y (vertically). See attr-scale
So your animation can be achieved by
ellipse.animate({"50%": {scale: "1 0"}, "100%": {scale: "1 1"}}, 2000);
see 3rd method (keyframes) in animate
which means at 50% of animation the ellipse should be scaled 0% vertically and at 100% animation scale it back to 100%.
When you call a function, it will be evaluated immediately. Your transform calls transform(item) again before passing it to animate. Instead you should wrap it in a function and pass it.
Here's the full source
jQuery(function ()
{
drawLogo();
});
function drawLogo()
{
var paper = Raphael('logo', 100, 100);//creates canvas width=height=100px
var rect = paper.rect(1,1,98,98, 10);//chessboard background
rect.attr("fill","#efd5a4");
var ellipse1 = paper.ellipse(20,20,12, 12);
var ellipse2 = paper.ellipse(50,20,12, 12);
var ellipse3 = paper.ellipse(80,20,12, 12);
var ellipse4 = paper.ellipse(20,50,12, 12);
var ellipse5 = paper.ellipse(50,50,12, 12);
var ellipse6 = paper.ellipse(80,50,12, 12);
var ellipse7 = paper.ellipse(20,80,12, 12);
var ellipse8 = paper.ellipse(50,80,12, 12);
var ellipse9 = paper.ellipse(80,80,12, 12);
paper.path("M35,0 L35,100");
paper.path("M65,0 L65,100");
paper.path("M0,35 L100,35");
paper.path("M0,65 L100,65");
var elements = [ellipse1, ellipse3, ellipse5, ellipse7, ellipse9];
for(var i = 0; i < elements.length; i++)
transform(elements[i]);
}
function transform(e)
{
e.animate({
"50%": {scale: "1 0"},
"100%": {scale: "1 1", callback: function() {transform(e);}}
}, 2000);
}