I am experimenting with gsap's ScrollTrigger. I have a custom scroll container and want to use ScrollTiggers scroller proxy to hijack the scroll. The results are very choppy though. Am I doing something wrong? Here is an example of what I have so far. CodeSandbox
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import scrollCtl from "./scrollCtl";
gsap.registerPlugin(ScrollTrigger);
const ctl = new scrollCtl();
ctl.on("scroll", () => ScrollTrigger.update);
ScrollTrigger.scrollerProxy(".container", {
scrollTop(value) {
return ctl.event.scroll; // getter
},
getBoundingClientRect() {
return {
top: 0,
left: 0,
width: window.innerWidth,
height: window.innerHeight
};
}
});
gsap.to(".test", {
scrollTrigger: {
trigger: ".trigger",
scroller: ".container",
scrub: true,
start: "top bottom",
end: "top top",
markers: true
},
scale: "1.5",
ease: "none"
});
As you can see from the codesandbox demo the scroll is very smooth but the markers are bouncing all over the place and the green square is supposed to scale up smoothly but it is bouncing around when you scroll instead of smoothly scaling. There are demo's from other libraries that achieve a very smooth effect like this example ScrollTigger Locomotive Scroll. Here is the documentation page where you can find more examples ScrollTrigger ScrollProxy() I can't figure out why mine is so janky.
Here's the problem:
// BAD
ctl.on("scroll", () => ScrollTrigger.update);
// GOOD
ctl.on("scroll", () => ScrollTrigger.update());
You just forgot to actually call the ScrollTrigger.update() method :)
In the future, it might be worth asking in the GreenSock forums - we're pretty quick to respond there and it's a community totally dedicated to answering GreenSock-related questions.
Happy tweening!
Related
I'll preface this by saying my initial problem is difficult to reproduce.
Brief explanation of my problem following, question is at the bottom.
So I am using the Jquery multislider for a project.
Here is a link to it: Multislider
Now my issue is that the animation of the moving elements seems to lag... Sometimes.
It jumps instead of moving smoothly.
The way the element works is by applying the animate() method to the first item and applies an inline margin-left property to the first .item
With some research I have found that CSS animations often cause problems when margins are used for the animation(among some other properties like top/bottom/left/right, as well as height/width) and that using transform is preferable.
So far so good.
This is the snippet in the javascript that creates the animation:
function singleLeft(){
isItAnimating(function(){
reTargetSlides();
$imgFirst.animate(
{
marginLeft: -animateDistance /* This is the part that causes me problems */
}, {
duration: animateDuration,
easing: "swing",
complete: function(){
$imgFirst.detach().removeAttr('style').appendTo($msContent);
doneAnimating();
}
}
);
});
}
function singleRight(){
isItAnimating(function(){
reTargetSlides();
$imgLast.css('margin-left',-animateDistance).prependTo($msContent);
$imgLast.animate(
{
marginLeft: 0
}, {
duration: animateDuration,
easing: "swing",
complete: function(){
$imgLast.removeAttr("style");
doneAnimating();
}
}
);
});
}
Now if I understand it correctly, I have to replace the marginLeft: -animateDistance portion with a transformX property, is that correct?
But I am failing to make it work.
So my question is, how can I replace the marginLeft: -animateDistance portion with transform: translateX() and add the animateDistance variable between the parentheses?
I have tried something like transform: "translateX(-$(animateDistance))", but that just disables the animation entirely.
Am I missing something?
I'm open for other suggestions to solve the issue of the laggy animation as well, this just is the conclusion I came to.
You can use animate with $(this) and .css() if you use step()
let test = "100";
$('div h2').animate({ pxNumber: test }, {
step: function(pxNumber) {
$(this).css('transform','translateX(-' + pxNumber + 'px )');
},
duration:'slow',
easing: "swing",
complete: function(){
console.log('Animation done');
// doneAnimating();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div><h2>Move it</h2></div>
So I have this GSAP timeline, which should first animate the fade-in text, and onComplete it should trigger the Vivus.js constructor which it does. However, the SVG element is visible before the animation occurs which is not a desired effect. I have tried to manipulate it somehow but the issue is still here - what could I be missing..?
The desired effect would be to fade in while drawing itself..
Here's a pen: https://codepen.io/anon/pen/ELGawo
function initialAnimation() {
var introText = $(".text-intro"),
tlIntro = new TimelineLite({ onComplete: introFadeIn });
tlIntro.from(introText, 1, { autoAlpha: 0 });
}
// Fade in and draw elements
function introFadeIn() {
var graphic1 = $(".graphic1");
tlIntrofadeIn = new TimelineLite({ onComplete: gr1Animate });
tlIntrofadeIn
.from(graphic1Elem, 1, { autoAlpha: 0 });
}
function gr1Animate() {
new Vivus(
"gr1",
{
type: "delayed",
onReady: function(myVivus) {
myVivus.el.style.visibility = "inherit";
}
},
function(obj) {
obj.el.style.visibility = "visible";
}
);
}
initialAnimation();
I'm not familiar with Vivus, but GSAP has a tool (DrawSVGPlugin) that does the same thing (and much more) as a Club GreenSock benefit and it integrates seamlessly, so your 30-ish lines of code could be condensed to 3:
https://codepen.io/GreenSock/pen/de8f2fa2a6813213d0e258113b2b15bd/?editors=0010
var introTL = new TimelineLite({delay:0.5});
introTL.from(".text-intro, #gr1 circle, #gr1 text", 1, {autoAlpha:0})
.from("#gr1 path", 2, {drawSVG:"0%", autoAlpha:0});
If you have any other questions, I'd encourage you to check out the GSAP forums at https://greensock.com/forums/. It's a fantastic community (not that Stack Overflow isn't - it's just that the GreenSock forums are totally dedicated to GSAP-related questions). Happy animating!
i'am using react native animated API to make a smooth transition from left to right position.
this is my initial state
constructor(props) {
super(props);
this.state = {
isDrawerOpened: false,
left: new Animated.Value(-100)
};
this.setDrawer = this.setDrawer.bind(this);
}
its still working fine when componentDidMount has called
componentDidMount() {
Animated.spring(this.state.left, {toValue: 200}).start();
}
But when i'am using event to change the state (also starting animation). The transition become rough (not smooth).
This is my event code
setDrawer() {
this.setState({
isDrawerOpened: !this.state.isDrawerOpened
});
if (this.state.isDrawerOpened) {
this.setState({
left: new Animated.Value(200)
});
Animated.spring(this.state.left, {toValue: -100, speed: 1000}).start();
} else {
this.setState({
left: new Animated.Value(-100)
});
Animated.spring(this.state.left, {toValue: 200, speed: 1000}).start();
}
}
can anyone solve this :( , sorry for my bad english
Try going for useNativeDriver: true. Your animations are now run in the JS thread and might be blocked by other stuff going on in your JS code. This will move animations to the UI thread.
See docs for reference.
I am currently using Joelambert's Flux Slider.
GitHub: https://github.com/joelambert/Flux-Slider
Demo: http://www.joelambert.co.uk/flux/
Basically there are many effects such as Bar, Slide, Swipe. Each of these effects is implemented in its respective function. For instance, the codes for the effect for dissolve (fading) is shown below.
I wish to create the Ken Burns effect using this API, is it possible?
An example of the Ken Burns effect is seen in the link provided (wowslider.com/jquery-slider-bar-kenburns-demo.html). It is a type of zooming and panning effect of an image in a frame.
What I have tried: adding in '-webkit-transform':'rotate(7deg)' under the setup() or execute() function, but the rotation only appears when it transits into the next image.
Would like the images displayed to animate, basically having zooming, rotation and panning. Any guidance is deeply appreciated.
Thank you, Radiance.
(function($) {
flux.transitions.dissolve = function(fluxslider, opts) {
return new flux.transition(fluxslider, $.extend({
setup: function() {
var img = $('<div class="image"></div>').css({
width: '100%',
height: '100%',
'opacity':'1',
'filter':'alpha(opacity=100)',
'zoom':'1',
'-webkit-backface-visibility': 'hidden',
'background-image': this.slider.image1.css('background-image')
}).css3({
'transition-duration': '600ms',
'transition-timing-function': 'ease-in',
'transition-property': 'opacity'
});
this.slider.image1.append(img);
},
execute: function() {
var _this = this,
img = this.slider.image1.find('div.image');
// Get notified when the last transition has completed
$(img).transitionEnd(function(){
_this.finished();
});
setTimeout(function(){
$(img).css({
'opacity': '0.0'
});
}, 50);
}
}, opts));
};
})(window.jQuery || window.Zepto);
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);