Okay so I have been trying to wrap my head around this for such as longtime now so I've turned to Stack Overflow for help! Essentially, I am using NuxtJS as the frontend framework for a website I'm building for a client. I have a transition property in my Nuxt.config.js file
Nuxt.config.js
transition: {
mode: 'out-in',
css: false,
beforeEnter: function(el) {
console.log('Pre Enter');
TweenMax.set(".transition--layer",{ transformOrigin: '100% 0%', yPercent: 0})
TweenMax.set(".transition-layer--text h2 span", {opacity:0.75, yPercent:0,force3D:true});
},
enter: function (el, done) {
console.log('Enter');
TweenMax.to(".transition-layer--text h2 span", 0.5, {opacity:0.75, yPercent:-100, delay:0.4, ease:Power3.easeInOut, force3D:true}, 0.2);
TweenMax.to(".transition--layer", .75, {delay:1, yPercent: -100, ease: Power3.easeInOut})
done()
},
beforeLeave: function (el) {
console.log('Before Leave');
TweenMax.set(".transition--layer",{ transformOrigin: '100% 0%', yPercent: 100})
},
leave: function (el, done) {
console.log(' Leave');
var done = done;
TweenMax.to(".transition--layer", .75, { yPercent: 0, ease: Power3.easeInOut})
TweenMax.fromTo(".transition-layer--text h2 span", 0.5, {opacity:0, yPercent:100, force3D:true}, {delay:0.75, ease:Power3.easeInOut, opacity:0.75, yPercent:0,force3D:true, onComplete: function () { console.log('leave'); done() }}, 0.2);
}
},
I am wanting to move this code inside one of my Layouts since, I need this transition to be layout specific rather than global. I've tried moving this inside one of my layouts by doing the below. However, this didn't work? Is this even possible? I found a git feature request on the Nuxt JS Github page however, the issue has been closed https://github.com/nuxt/nuxt.js/issues/1054
<script>
export default {
transition: {
mode: 'out-in',
css: false,
beforeEnter: function(el) {
console.log('Pre Enter');
TweenMax.set(".transition--layer",{ transformOrigin: '100% 0%', yPercent: 0})
TweenMax.set(".transition-layer--text h2 span", {opacity:0.75, yPercent:0,force3D:true});
},
enter: function (el, done) {
console.log('Enter');
TweenMax.to(".transition-layer--text h2 span", 0.5, {opacity:0.75, yPercent:-100, delay:0.4, ease:Power3.easeInOut, force3D:true}, 0.2);
TweenMax.to(".transition--layer", .75, {delay:1, yPercent: -100, ease: Power3.easeInOut})
done()
},
beforeLeave: function (el) {
console.log('Before Leave');
TweenMax.set(".transition--layer",{ transformOrigin: '100% 0%', yPercent: 100})
},
leave: function (el, done) {
console.log(' Leave');
var done = done;
TweenMax.to(".transition--layer", .75, { yPercent: 0, ease: Power3.easeInOut})
TweenMax.fromTo(".transition-layer--text h2 span", 0.5, {opacity:0, yPercent:100, force3D:true}, {delay:0.75, ease:Power3.easeInOut, opacity:0.75, yPercent:0,force3D:true, onComplete: function () { console.log('leave'); done() }}, 0.2);
}
},
}
</script>
It is actually quite easy to have different transitions for different layouts. I will say this with the caveat that I can make it work with what I know, which is basic old vanilla css and I really have no idea what your TweenMax and so forth up above is doing. I will show you an example of how I do it and I'm sure you'll be able to tailor it to your needs.
If I want a universal transition I'd set it up like this:
//nuxt.config.js
transition:
{
name: 'fade',
mode: 'out-in'
},
and a global css file, let's say main.css
//main.css
.fade-enter-active {
animation: acrossIn .30s ease-out both;
}
.fade-leave-active {
animation: acrossOut .30s ease-in both;
}
#keyframes acrossIn {
0% {
transform: translate3d(-100%, 0, 0);
}
100% {
transform: translate3d(0, 0, 0);
}
}
#keyframes acrossOut {
0% {
transform: translate3d(0, 0, 0);
}
100% {
transform: translate3d(100%, 0, 0);
}
}
Now if I want to tailor a transition to a specific layout I'll remove the styles from main.css and put them in the style section of the layout file:
//default.vue
<style>
.fade-enter-active {
animation: acrossIn .30s ease-out both;
}
.fade-leave-active {
animation: acrossOut .30s ease-in both;
}
#keyframes acrossIn {
0% {
transform: translate3d(-100%, 0, 0);
}
100% {
transform: translate3d(0, 0, 0);
}
}
#keyframes acrossOut {
0% {
transform: translate3d(0, 0, 0);
}
100% {
transform: translate3d(100%, 0, 0);
}
}
...
</style>
Each layout file must keep the naming set up in nuxt.config but otherwise it works fine. The only limitation is there is no transition if going from one layout to another.
Related
I came across with this code snippet:
const breakpoints = {
values: {
xs: 0,
sm: 576,
md: 768,
lg: 992,
xl: 1200,
xxl: 1400,
},
};
const drawerOpenStyles = () => ({
background: backgroundValue,
transform: "translateX(0)",
transition: transitions.create("transform", {
easing: transitions.easing.sharp,
duration: transitions.duration.shorter,
}),
[breakpoints.up("xl")]: { // what does [] mean? what does .up() do?
boxShadow: transparentSidenav ? "none" : xxl,
marginBottom: transparentSidenav ? 0 : "inherit",
left: "0",
width: sidebarWidth,
transform: "translateX(0)",
transition: transitions.create(["width", "background-color"], {
easing: transitions.easing.sharp,
duration: transitions.duration.enteringScreen,
}),
},
});
On the line [breakpoints.up("xl")]: {}, I am having trouble understanding:
What does [] do when it wraps an object key?
What does Object.up() do in javascript?
I was able to print by console.log(drawerOpenStyles: ${JSON.stringify( drawerOpenStyles() )}); and I got this result:
{
"background":"linear-gradient(195deg, #42424a, #191919)",
"transform":"translateX(0)",
"transition":"transform 200ms cubic-bezier(0.4, 0, 0.6, 1) 0ms",
"#media (min-width:1200px)":{
"boxShadow":" 0rem 1.25rem 1.6875rem 0rem rgba(0, 0, 0, 0.05)",
"marginBottom":"inherit",
"left":"0",
"width":250,
"transform":"translateX(0)",
"transition":"width 225ms cubic-bezier(0.4, 0, 0.6, 1) 0ms,background-color 225ms cubic-bezier(0.4, 0, 0.6, 1) 0ms"
}
}
How exactly does [breakpoints.up("xl")] give "#media (min-width:1200px)"?
The square brackets [] allows you to put an expression in , that will be computed and used as the property name.
There is no Object.up() in the Standard Object API in JS.
I think breakpoints.up("xl") is related to Material ui breakpoints check https://mui.com/customization/breakpoints/
I have used GSAP 3.0 ScrollTrigger in one of my websites everything is working fine but I want my animations to be reversed when leaving the section or div. I know there is a callback call onLeave but I am not able to figure out how to use it. I am new to the scroll trigger. I am pasting the code sample for you to understand.
armor animation config
let armor = gsap.timeline({
scrollTrigger: {
trigger: '.armor-animation',
pin: true,
pinSpacing: true,
anticipatePin: .5,
scrub: 1,
start: "top 150px",
end: "+=1500",
toggleActions: "play reverse none none",
// scroller: ".smooth-scroll"
// markers: true,
onLeave: () => {
// armor.from(".layer-1", .8, {
// translateY: 200,
// opacity: 0
// }, .5)
// console.log("leave");
}
}
});
armor section animation
armor.from(".layer-1", .8, {
translateX: -200,
opacity: 0
}, .5)
.from(".layer-2", .8, {
translateY: 200,
opacity: 0
}, .6)
.from(".layer-3", .8, {
translateY: -200,
opacity: 0
}, .6)
.from(".crack-effect", 2, {
translateY: -200,
opacity: 0
}, 2)
.from(".method h1", 2, {
translateX: 200,
opacity: 0
}, .6);
//Animation on slider
const tl = gsap.timeline({ defaults: { ease: "power1.out" } })
tl.to(".text", { y: "0%", duration: 1 });
tl.to(".slider", { y: "-100%", duration: 1.5, delay: 0.5 });
tl.to(".intro", { y: "-100%", duration: 1 }, "-=1");
tl.fromTo("nav", { opacity: 0 }, { opacity: 1, duration: 0.5 });
tl.fromTo(".shortDescription", { opacity: 0 }, { opacity: 1, duration: 0.5 });
tl.fromTo("footer", { opacity: 0 }, { opacity: 1, duration: 0.5 });
/*Animation on the Nav Bar
const sections = document.querySelectorAll('.selection');
const bubble = document.querySelector('.bubble');
const gradient = ["linear-gradient(to top, #30cfd0 0%, #330867 100%)"
"linear-gradient(to top, #a8edea 0%, #fed6e3 100%)"
];
const options = {
threshold: 0.7
};
let observer = new IntersectionObserver(navCheck, options);
function navCheck(entries) {
entries.forEach(entry => {
console.log(entry);
});
};
section.forEach(section => {
observe.observe(section);
});*/
This is the whole javascript code that I have, I currently put the nav bar animation to a comment for the gsap slider to work. but when I'm already trying to input the nav bar animation the gsap code stops working so the whole set would be stuck with the color black and it won't slide through, so you won't see the page itself.
I am trying to animate an image with a completion function. The animation works fine but the complete property is not called. I tried looking around and didn't find any result on the matter that says that what i'm doing is wrong. I tried on Chrome and Firefox I am using the code below
document.getElementById("myImageId").animate([{
transform: 'translateY(0px)'
},
{
transform: 'translateY(-300px)'
}
], {
duration: 300,
complete: function () {
alert('end ani')
}
});
Element.animate() returns a Animation object, and you can attach an event handler for finish to the object:
var animation = document.querySelector('#myImageId').animate([{
transform: 'translateY(0px)'
},
{
transform: 'translateY(-300px)'
}
], {
duration: 300,
delay: 300,
fill: 'forwards',
});
animation.addEventListener('finish', () => alert('end ani'));
<div id="myImageId"><img src="https://picsum.photos/200"></div>
Another option, which is only supported by FireFox currently, is the Animation.finished promise:
var animation = document.querySelector('#myImageId').animate([{
transform: 'translateY(0px)'
},
{
transform: 'translateY(-300px)'
}
], {
duration: 300,
delay: 300,
fill: 'forwards',
});
animation.finished.then(() => alert('end ani'));
<div id="myImageId"><img src="https://picsum.photos/200"></div>
I have the following function which increases the size of circles but instead of starting over after they were scaled, I want to scale back to original size. Backwards. So when it reached scale 2, it should go back incrementally to 1.
How can I accomplish this?
function animateCircles() {
var circles = document.getElementsByClassName('circle')
setTimeout(function () {
for(i=0;i<circles.length;i++) {
circles[i].animate([
// keyframes
{ transform: 'translateY(0px)' },
{ transform: 'scale(2)' }
], {
// timing options
duration: 2000,
iterations: Infinity
});
}
},0)
setTimeout(function () {
for(i=0;i<circles.length;i++) {
circles[i].animate([
// keyframes
{ transform: 'translateY(0px)' },
{ transform: 'scale(1.5)' }
], {
// timing options
duration: 2000,
iterations: Infinity
});
}
},2000)
}
Just add another keyframe within your first animation (and adjust time accordingly):
function animateCircles() {
var circles = document.getElementsByClassName('circle')
setTimeout(function() {
for (i = 0; i < circles.length; i++) {
circles[i].animate([
// keyframes
{
transform: 'translateY(0px)'
}, {
transform: 'scale(2)'
}, {
transform: 'scale(1)'
}
], {
// timing options
duration: 2000,
iterations: Infinity
});
}
}, 0)
}
animateCircles();
.circle {
background-color: #F00;
border-radius: 50%;
width: 75px;
height: 75px;
}
<div class="circle"></div>