Play/Pause Css animation with GSAP Scroll trigger - javascript

There are many CSS animations on this website, resulting in a slow page performance. As a solution, I am integrating GSAP scroll-trigger to play these only when in view. I have the same thing for videos and I have basically adapted the code to play/pause CSS instead of videos. If I add the CSS to the animation ('-webkit-animation-play-state','paused') it pauses, however using the function below I get this error:
allCss.css is not a function
const allCssAnimation = gsap.utils.toArray('.ticker-marquee h2')
allCssAnimation.forEach(function(allCss, i) {
ScrollTrigger.create({
trigger: allCss,
start: 'top center',
end: 'bottom center',
markers: true,
onEnter: () => allCss.css('-webkit-animation-play-state','running'),
onEnterBack: () => allCss.css('-webkit-animation-play-state','running'),
onLeave: () => allCss.css('-webkit-animation-play-state','paused'),
onLeaveBack: () => allCss.css('-webkit-animation-play-state','paused'),
});
})

Related

GSAP ScrollTrigger + ASScroll animation stops on page refresh

I'm using GSAP with ASScroll to add a couple of animations to my static site generated with Hugo. All animations work as intended. However when I reload the page only when I'm not scrolled all the way up the animations will go to the last frame and stop. The same thing occurs when the toolbar of Chrome mobile goes all the way up after you scroll down far enough. This occurs on very consistent spots, but not everywhere. For example when scrolling 600px down it would always occur, but at 700px it would never occur.
I'm not getting any errors or warning in the console.
using:
#ashthornton/asscroll 2.0.11
gsap 3.11.3
main.js setup
import ASScroll from '#ashthornton/asscroll'
import gsap from 'gsap';
import ScrollTrigger from 'gsap/ScrollTrigger';
import {
Timeline
} from 'gsap/gsap-core';
gsap.registerPlugin(ScrollTrigger);
const isTouch = ('ontouchstart' in document.documentElement);
const asscroll = new ASScroll({
disableRaf: true,
ease: 0.175,
touchEase: 0.175
});
gsap.ticker.add(asscroll.update);
ScrollTrigger.defaults({
scroller: asscroll.containerElement
});
ScrollTrigger.scrollerProxy(asscroll.containerElement, {
scrollTop(value) {
return arguments.length ? asscroll.currentPos = value : asscroll.currentPos;
},
getBoundingClientRect() {
return {
top: 0,
left: 0,
width: window.innerWidth,
height: window.innerHeight
};
}
});
asscroll.on("update", () => ScrollTrigger.refresh());
ScrollTrigger.addEventListener("refresh", asscroll.resize);
window.addEventListener("load", () => {
// ...
Animation:
const imgMicroservice = document.getElementById('img-microservices');
gsap.timeline({
scrollTrigger: {
trigger: imgMicroservice,
start: "top bottom",
onRefresh: () => {},
end: "bottom top",
invalidateOnRefresh: false,
scrub: 1,
},
})
.fromTo(imgMicroservice, {
y: 150,
scale: 0.96,
ease: "none"
}, {
y: 0,
ease: 0,
scale: 1,
rotate: "0deg",
}, 0)
I tried disabling ASScroll, this solved the problem. Though I want to use it or any other smooth scroll js library.

FullCalendar tooltip bug when dragging event in Resource timeline

I'm using JavaScript FullCalendar library to build my calendar. Now updating my codes to work with FullCalendar V4. When Dragging event in resource timeline view, the tooltip does not work as expected (duplicate tooltips show when dragging). This issue only happens in resource timeline view, not in dayGrid view. I've attached two codepen codes. Daygrid view works fine, but Resource timeline view does not.
https://codepen.io/nmwangxin/pen/WNeRQaX
https://codepen.io/nmwangxin/pen/qBWROKz
eventRender: function(info) {
var tooltip = new Tooltip(info.el, {
title: 'test',
placement: 'top',
trigger: 'hover',
container: 'body'
});
},
When dragging the event it gets re-rendered each time, so basically you are recreating a new tooltip each time thus creating multiple instances which in turn loose their reference to the element that gets destroyed hence it's odd placement.
I would suggest to hook into "eventMouseEnter" and "eventMouseLeave" callbacks and create and destroy a single tooltip object there.
Here is an example:
var tooltip = null;
eventMouseEnter: function(info) {
tooltip = new Tooltip(info.el, {
title: info.event.title,
placement: 'top',
trigger: 'hover',
container: 'body'
});
},
eventMouseLeave: function(info) {
if (tooltip) {
tooltip.dispose();
}
}
https://codepen.io/alex-hazanov/pen/rNBjPyL
Or use bootstrap's tooltip like this :
eventMouseEnter: function (info) {
$(info.el).tooltip({
title: info.event.title + '<br />' + info.event._instance.range.start,
html: true,
placement: 'top',
trigger: 'hover',
container: 'body',
});
}

What is the difference between Lottie Events and Lottie EventListeners and How to use?

The documentation has both Events and EventListeners. I can get the EventListeners to fire but the Events do not have adequate documentation for me to get going. What is the difference and how do you use? Thank you.
https://github.com/airbnb/lottie-web#events
Events (Do not work, how to use?)
// From the Documentation
onComplete
onLoopComplete
onEnterFrame
onSegmentStart
you can also use addEventListener with the following events:
complete
loopComplete
enterFrame
segmentStart
config_ready (when initial config is done)
data_ready (when all parts of the animation have been loaded)
data_failed (when part of the animation can not be loaded)
loaded_images (when all image loads have either succeeded or errored)
DOMLoaded (when elements have been added to the DOM)
destroy
// End Documentation
From the standard addEventListener usage, this works...
birbSequence.addEventListener('loopComplete', (e) => {
console.log(e);
});
although 'complete' does not fire.
But to try out the stuff in Events like onEnterFrame?
var birbSequence = lottie.loadAnimation({
container: bodyMovinContainer1,
loop: true,
renderer: 'svg',
path: 'Birb Sequence 1.json',
onEnterFrame: function(e) { console.log(e); }
});
I am really new to using Lottie though so could use some help.
Just want a way to see how to use Events
Let's say we have our lottie animation:
const anim = lottie.loadAnimation({
container: '#container',
renderer: 'svg',
loop: true,
autoplay: true,
...
})
With Events:
anim.onComplete = function() {
console.log('complete')
}
anim.onLoopComplete = function() {
console.log('loopComplete')
}
With addEventListener:
anim.addEventListener('complete', function() {
console.log('complete')
})
anim.addEventListener('loopComplete', function() {
console.log('loopComplete')
})
You can use the addEventListener method to listen to all the events instead of the on* series of event hooks.
const options = {
container: '#container',
loop: false,
autoplay: false,
renderer: 'svg',
rendererSettings: {
scaleMode: 'noScale',
clearCanvas: false,
progressiveLoad: true,
hideOnTransparent: true,
},
};
try {
const anim = lottie.loadAnimation({ ...options, path: 'URL_TO_JSON' });
anim.addEventListener('complete', () => { console.log('complete'); });
anim.addEventListener('loopComplete', () => { console.log('loopComplete'); });
anim.addEventListener('data_ready ', () => { console.log('data_ready'); });
anim.addEventListener('data_failed', () => { console.log('data_failed'); });
anim.addEventListener('enterFrame', () => {
console.log('enterFrame', anim.currentFrame);
});
// etc ...
} catch (error)
console.log('error loading anim');
}
Hope that helps!

When using React Native Animated, it possible to animate the offset?

I am trying to create an animated drag and drop feature, like this: http://moduscreate.com/animated_drag_and_drop_with_react_native/
I want to change it so that when the user starts the touch, the object moves upwards so that it is no longer hidden under their finger. I want this movement to be animated, but I also want to track the panning gesture during the animation.
Right now I have the animation working, as long as the user doesn't move their finger. I am using this code to animate the object up when the touch starts:
onPanResponderStart: (e, gesture) => {
Animated.spring(
this.state.pan,
{
...animationConstants,
toValue: { x: 0, y: -70 },
}
).start((status) => {
// This part ensures that the offset and value are
// set correctly after the animation.
this.state.pan.y.setOffset(-70);
this.state.pan.y.setValue(0);
});
},
But as soon as they move their finger, it cancels the animation and jumps to the top. I am using this code for onPanResponderMove:
onPanResponderMove: Animated.event([null, {
dx: this.state.pan.x,
dy: this.state.pan.y
}]),
I want the animation to continue, even while the user is moving their finger.
How could I change the code so that I am animating the "offset", instead of the "value"? I think I could solve this problem if Animated.spring had the option to use toOffset: {x: ..., y: ...}, as well as to toValue. But I don't think it has that, and I'm not sure how I should emulate this.
I figured something out. I'm not sure about performance, but it seems to work fine.
I set up a separate Animated.Value to animate the offset. I just added a callback using addListener, which calls setOffset to animate the value.
constructor(props){
super(props);
this.state = {
pan: new Animated.ValueXY(),
offset: new Animated.Value(0)
};
this.state.offset.addListener((value) => {
this.state.pan.y.setOffset(value.value);
});
this.panResponder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderStart: (e, gesture) => {
Animated.spring(
this.state.offset,
{ toValue: -70 }
).start();
},
onPanResponderMove: Animated.event([null, {
dx: this.state.pan.x,
dy: this.state.pan.y
}]),
onPanResponderRelease: (e, gesture) => {
Animated.spring(
this.state.pan,
{
toValue: { x: 0, y: 0 }
}
).start();
Animated.spring(
this.state.offset,
{ toValue: 0 }
).start();
}
});
}

Fancybox responsive horizontally but not vertically. What am i doing wrong?

I have some sample code up at http://defyordie.com/testbed/
This is for my portfolio and I'm working on replacing my old plugin with fancybox. My issue is with the responsiveness of the work sample popups. Scroll down to my 'work' section and click on one of the top 3 boxes since those are finished.
I'm working on a big cinema display, so I've noticed that as i expand my window, the royalslider running the slideshow expands horizontally but doesnt expand vertically until i make the browser window almost entirely fill my screen. I had hoped that it would scale proportionally. I've either initalized the fancybox incorrectly, royalslider incorrectly, or I have some sort of CSS issue.
The code :
$(document).ready(function () {
$('.fancybox').fancybox({
beforeShow: function () {
$(window).on({
'resize.fancybox': function () {
$.fancybox.update();
}
});
},
afterClose: function () {
$(window).off('resize.fancybox');
},
padding: 0,
margin: [60, 15, 0, 15],
nextEffect: 'fade',
prevEffect: 'none',
helpers: {
overlay: {
locked: false
}
},
afterLoad: function () {
$.extend(this, {
type: 'html',
width: '95%',
height: '100%',
minWidth: '930px'
});
}
});
});

Categories

Resources