How would one make a slide and fade in animation like in seen in the green and pink boxes on sharethis.com? In particular I like the one in the blue box with the arrows. Are there a set of JavaScript codes or CSS effects?
The easiest would probably be to use a library like this:
http://janpaepke.github.io/ScrollMagic/
I see that for the arrows effect the css-height property is animated when you scroll. This is done in javascript. But you can also achieve this effect through CSS3-transitions.
Update: Slide and wipe effects from the demo page:
// ani
var pinani = new TimelineMax()
// wipe
.add(TweenMax.to("#wipe", 1, {
width: "100%"
}))
// slide
.add(TweenMax.to("#slide", 1, {
top: "0%",
ease: Bounce.easeOut,
delay: 0.2
}));
// pin
new ScrollScene({
triggerElement: "section#pin",
duration: 1100
})
.on("progress", function () {
// keep centered even though width changes
$("#wipe h3").width($("#pin>h3").width());
})
.setTween(pinani)
.setPin("section#pin")
.addTo(controller);
Related
I am using Bodymovin in combination with ScrollMagic and GSAP to animate through series of images as you scroll back and forth. Everything works great, except, when I reach the end it doesn't stay on the final image, but goes white.
Libraries that I load first:
<script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.5.9/lottie.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.7/ScrollMagic.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.7/plugins/animation.gsap.js"></script>
Then my code:
var controller = new ScrollMagic.Controller();
var animation = bodymovin.loadAnimation({
container: document.getElementById('hero-anim'),
animationData: animationframes,
renderer: 'svg',
autoplay: false,
});
var tl = new TimelineMax();
tl.to({frame:0}, 1, {
frame: animation.totalFrames-1,
onUpdate:function(){
animation.goToAndStop((Math.round(this.progress() * 60)), true)
},
ease: Linear.easeNone
})
var lottieScene = new ScrollMagic.Scene({
duration: '100%',
offset: 600
})
.setPin("#hero-anim")
.setTween(tl)
.addTo(controller);
Any ideas what could be causing that? Looking at browser's Inspect Element, it basically adds display:block to the image that is supposed to be currently visible and applies display:none to the previous image, but at the end, they all have display:none, and it doesn't stay visible
RESOLVED
As Zach pointed out, I tried Math.floor and at first it didn't help, but afterwards I tried adjusting animation.goToAndStop((Math.floor(this.progress() * 60)), true) to * 59 (one frame less than the total frame count and now it works, perfectly. Math.round with * total frame count or even * total frames - 1 didn't work, strangely.
I'm new to ScrollMagic so not sure if there's something obvious that I'm overlooking.
I've set up a codepen which illustrates what I'm trying to achieve, and an alternative version that almost does what I want, except there's a huge gap that I can't seem to get rid of.
Essentially looking to have 3 slides that are stacked on top of each other. When the user scrolls, the slides one-by-one transition up to reveal the one underneath.
When scrolling past the final slide, the remaining content on the page should scroll up as if it's attached to the bottom of the final slide, and should from then on function like a normal page.
Currently, the container with all the slides in it transparently overlaps the rest of the body content until the final slide has disappeared off the top of the viewport, and it's ScrollMagic that is doing this.
The pink bar in the codepen is intended to show where the bottom of the slide container finishes.
Here's the relevant code:
function initController() {
controller = new ScrollMagic.Controller({
globalSceneOptions: {
triggerHook: "onLeave"
}
});
controller.scrollTo(function(pos) {
TweenMax.to(window, 1, {
scrollTo: {
y: pos,
autoKill: true
}
});
});
}
function initAnimation() {
wipeAnimation = new TimelineMax();
$.each(ui.slides, function(i, slide) {
wipeAnimation
.add(TweenMax.to(slide, 2000, {y: '0'}))
.add(TweenMax.fromTo(slide, 5000, {y: '0'}, {
y: '-100%',
onComplete: function() {
if (i < ui.slideCount - 1) { // don't run on last slide
updateActiveSlide(ui.slides[i + 1]); // activate next slide
}
},
onReverseComplete: function() {
updateActiveSlide(slide);
}
}));
});
}
function initScene() {
scene = new ScrollMagic.Scene({
triggerElement: ui.el,
duration: '100%'
})
.setTween(wipeAnimation)
.setPin(ui.el, {
pushFollowers: false
})
.addTo(controller);
}
This is designed by default to stop the pinned elements overlapping the following elements in the document.
You need set the 'pushFollowers' property to false:
function initScene() {
scene = new ScrollMagic.Scene({
triggerElement: ui.el,
duration: '100%'
})
.setTween(wipeAnimation)
.setPin(ui.el, {
pushFollowers: false
})
.addTo(controller);
}
See documentation: http://janpaepke.github.io/ScrollMagic/docs/ScrollMagic.Scene.html#setPin
// pin element and push all following elements down by the amount of the pin duration.
scene.setPin("#pin");
// pin element and keeping all following elements in their place. The pinned element will move past them.
scene.setPin("#pin", {pushFollowers: false});
Working example: https://codepen.io/alexgill/pen/MyOMKP (forked from your codepen)
I am creating a pulsating effect with velocity.js as fallback for IE9, (see box2 for CSS animation )
When mouse leaves the box before the animation has finished ( stay until pulse grows than move out ) the pulsating element stays visible. https://jsfiddle.net/02vu80kc/1/
$(".box").hover(function () {
$(this).find('.effect-holder').velocity({
scale: [1.2, 0.9],
opacity: [1, 0]
}, {
easing: 'ease-out',
duration: 800,
loop: true
}, {
queue: false
}).velocity("reverse");
}, function () {
$(this).find('.effect-holder').velocity("stop");
});
How do I stop the animation on mouseout after the effect has finished ?
I am trying to stay away from .removeAttr('style') and would like the animation to finish and than stop. Any help is appreciated.
If I use this
$(this).find('.effect-holder').velocity('reverse').velocity("stop");
and you move the mouse fast the animation begins again and sometimes pauses in between.
Either use .velocity("finish") instead of .velocity("stop"), or have a different on and off animation, with both animations calling "stop" (ie, catch when the mouse moves properly).
Also note that the {... loop:true ...} means that the first animation never ends, and hence the "stop" will have the "reverse" happen immediately after stopping (call .velocity("stop", true) to prevent that)
edit: Open issue on the "finish" bug - https://github.com/julianshapiro/velocity/issues/495
edit2: Add simple example:
$("box").hover(function() {
// over
this.velocity("stop", true).velocity({
scale: [1.2, 0.9]
}, {
duration: 800,
loop: true
})
}, function() {
// out
this.velocity("stop", true).velocity({
scale: 0.9
}, {
easing: "ease-out",
duration: 800
})
});
I have a simple wrapper div that I animate in using velocity.js UI pack. In the complete callback function, I am using a combination of UI pack and blast.js to animate three sentences.
The problem is that my sentences are initially shown, and only after that they are animated. They shouldn't be visible after the wrapper div is animated into view.
Everything is working fine if I don't animate the wrapper div, guess the opacity settings during animation are messing with child elements.
$('.wrap').velocity('transition.slideUpIn', {
delay: 1000,
display: null,
complete : function(){
$(".animated")
.blast({ delimiter: "character" })
.velocity("transition.fadeIn", {
display: null,
duration: 1000,
stagger: 60,
delay: 400
});
}
})
Here is the fiddle to see the problem : http://jsfiddle.net/vcsr6aqj/1/
The problem is that your p tags aren't at opacity: 0, but only their characters, which are inside a span having as class blast. Since your invisible characters are only created when you call $(".animated").blast({ delimiter: "character" }), which means once your wrapper has completed its apparition, the sentences will be visible until then. So you have two possibilities that I can think of.
Create your span characters with blast at the page load, instead at the wrapper velocity complete and then call velocity on your created spans:
$(document).ready(function() {
$(".animated").blast({ delimiter: "character" });
$('.wrap').velocity('transition.slideUpIn', {
delay: 1000,
display: null,
complete : function(){
$(".animated .blast").velocity("transition.fadeIn", {
display: null,
duration: 1000,
stagger: 60,
delay: 400
});
}
})
});
JSFiddle example
Add a class to your p tags having opacity: 0:
<p class="animated no-opacity">Sentence number one.</p>
<p class="animated no-opacity">Sentence number two.</p>
<p class="animated no-opacity">Just one sentence more.</p>
CSS:
.no-opacity {
opacity: 0;
}
When your wrapper has completed the velocity, remove the class from your p tags. Also, remove delay: 400 from your velocity attributes, otherwise the sentences will show for 400 milliseconds:
$(document).ready(function() {
$('.wrap').velocity('transition.slideUpIn', {
delay: 1000,
display: null,
complete : function(){
$animated = $(".animated");
$animated.removeClass("no-opacity");
$animated.blast({ delimiter: "character" })
.velocity("transition.fadeIn", {
display: null,
duration: 1000,
stagger: 60
});
}
})
});
JSFiddle example
Here you go (fiddle). I'm sure there are more elegant solutions.
It appears that the slideUpIn animates opacity from 0 to 1, including the opacity of .animated which is probably 'inherited'. Setting it to 0 to hide it fixes it, but then .blast() doesn't work, so we enable it again.
http://jsfiddle.net/E6cUF/
The idea is that after the page finished loading the grey box slides left from behind the green box, if possible bounce a little.
Edit: made a new version based on changes people made to the jsfiddle and the comment from Nicola
http://jsfiddle.net/RBD3K/
However the grey one should be behind the green one and slide from right to left so it appears
To have it bounce you are missing two things i think:
1) you need to load jquery UI.
2) put the bounce effect after the animate effect:
$('#test').click(function() {
var $marginLefty = $('.left');
$marginLefty.animate({
marginLeft: parseInt($marginLefty.css('marginLeft'),10) == 0 ?
$marginLefty.outerWidth() :
0
}).effect("bounce", { times:5 }, 300);
});
updated fiddle: http://jsfiddle.net/nicolapeluchetti/E6cUF/4/
Try this . Not sure if this is what you want.
$('#test').click(function() {
var $marginLefty = $('.left');
var $marginRight = $('.right');
$marginLefty.animate({
marginLeft: 0
},{ duration: 200, queue: false });
$marginRight.animate({
marginLeft: 100
},{ duration: 200, queue: false });
});
Update: from your updated fiddle,add for .right position :absolute;z-index:1000 as css
http://jsfiddle.net/E6cUF/11/