CSS 和 JS 与 GSAP 的转换
CSS and JS Transitions with GSAP
https://codepen.io/thatfemicode/pen/MWpwaRQ
https://twitter.com/P_h_l_i_x/status/1353659923834544128
晚上,经过大量的实践,我想出了一个解决方案,但我仍然不满意我所拥有的,我正在努力做到这一点,正如 TWITTER 的影响者部分所示 link 下面的页面看看每个循环如何在离开视口之前将 class 更改为前一个元素的 class,我该如何实现?谢谢,任何建议将不胜感激
<div id="container">
<div class="fakeImages" id="fake1"></div>
<div class="fakeImages" id="fake2"></div>
<div class="fakeImages" id="fake3"></div>
<img
src="https://images.unsplash.com/photo-1494548162494-384bba4ab999?ixid=MnwxMjA3fDB8MHxzZWFyY2h8MXx8c3VucmlzZXxlbnwwfHwwfHw%3D&ixlib=rb-1.2.1&w=1000&q=80"
alt="view"
id="img1"
class="images"
/>
<img
src="https://media.istockphoto.com/photos/colored-powder-explosion-abstract-closeup-dust-on-backdrop-colorful-picture-id1072093690?k=6&m=1072093690&s=612x612&w=0&h=Eyk67XBt4sr3Bk1MubM6dHpvEVNICX4L7FumWhcTwuY="
alt="powder"
id="img2"
class="images"
/>
<img
src="https://media3.s-nbcnews.com/j/newscms/2019_41/3047866/191010-japan-stalker-mc-1121_06b4c20bbf96a51dc8663f334404a899.fit-760w.JPG"
alt="powder"
id="img3"
class="images"
/>
<img
src="https://cdn.jpegmini.com/user/images/slider_puffin_before_mobile.jpg"
alt="bird"
id="img4"
class="images"
/>
</div>
CSS
#container {
.images {
position: absolute;
top: 50%;
left: 50%;
width: 300px;
height: 300px;
transform: translate(-50%, -50%);
}
#img4 {
z-index: -5;
}
.fakeImages {
position: absolute;
top: 50%;
left: 50%;
width: 300px;
height: 300px;
z-index: -9;
}
#fake1 {
background: lightgrey;
transform: translate(-50%, -50%) rotate(20deg);
}
#fake2 {
background: grey;
transform: translate(-50%, -50%) rotate(-10deg);
}
#fake3 {
background: darkgrey;
transform: translate(-50%, -50%) rotate(-15deg);
}
}
Javascript
function play() {
let images = gsap.utils.toArray('.images');
let fakes = gsap.utils.toArray('.fakeImages');
let tl = gsap.timeline({ repeat: -1, repeatDelay: 1 });
let tl2 = gsap.timeline({ repeat: -1, repeatDelay: 0 });
tl.set(images, {
zIndex: (i) => i * -1,
rotation: (i) => Math.random() * 30 - 15,
});
tl.to(images, {
duration: 1,
rotation: 0,
delay: (i) => i * 1 + 1,
x: 2000,
// scale: 0,
// css: { className: '+=active' },
});
}
play();
在 GSAP 的某人对代码进行了改进并且我也添加了我的修改后,可以在 codepen.io 上找到解决方案。
https://codepen.io/thatfemicode/pen/OJpNXEr
HTML
<div id="container">
<!-- <div class="fakeImages" id="fake1"></div>
<div class="fakeImages" id="fake2"></div>
<div class="fakeImages" id="fake3"></div> -->
<img
src="https://images.unsplash.com/photo-1494548162494-384bba4ab999?ixid=MnwxMjA3fDB8MHxzZWFyY2h8MXx8c3VucmlzZXxlbnwwfHwwfHw%3D&ixlib=rb-1.2.1&w=1000&q=80"
alt="view"
id="img1"
class="images"
/>
<img
src="https://media.istockphoto.com/photos/colored-powder-explosion-abstract-closeup-dust-on-backdrop-colorful-picture-id1072093690?k=6&m=1072093690&s=612x612&w=0&h=Eyk67XBt4sr3Bk1MubM6dHpvEVNICX4L7FumWhcTwuY="
alt="powder"
id="img2"
class="images"
/>
<img
src="https://media3.s-nbcnews.com/j/newscms/2019_41/3047866/191010-japan-stalker-mc-1121_06b4c20bbf96a51dc8663f334404a899.fit-760w.JPG"
alt="powder"
id="img3"
class="images"
/>
<img
src="https://cdn.jpegmini.com/user/images/slider_puffin_before_mobile.jpg"
alt="bird"
id="img4"
class="images"
/>
</div>
CSS
body {
overflow-x: hidden;
}
.active {
border: 1px solid red;
}
#container {
.images {
position: absolute;
top: 50%;
left: 50%;
width: 300px;
height: 300px;
transform: translate(-50%, -50%);
}
#img4 {
z-index: -5;
}
.fakeImages {
position: absolute;
top: 50%;
left: 50%;
width: 300px;
height: 300px;
z-index: -9;
}
#fake1 {
background: lightgrey;
transform: translate(-50%, -50%) rotate(20deg);
}
#fake2 {
background: grey;
transform: translate(-50%, -50%) rotate(-10deg);
}
#fake3 {
background: darkgrey;
transform: translate(-50%, -50%) rotate(-15deg);
}
}
使用 GSAP 的 Javsscript
function play() {
let images = gsap.utils.toArray('.images');
let fakes = gsap.utils.toArray('.fakeImages');
let all = images.concat(fakes);
let tl = gsap.timeline({ delay: 1, repeat: -1, repeatDelay: 1 });
gsap.set(images, {
zIndex: (i) => i * -1,
// rotation: "random(-15,15)",
});
// make sure the "top" image is exactly 8 degrees
gsap.set(images[0], {rotation: 8});
gsap.set(images[1], {rotation: -8})
gsap.set(images[2], {rotation: 8})
gsap.set(images[3], {rotation: -8})
// at the start, remove all "active" classes
tl.call(() => images.forEach(el => el.classList.remove("active")));
tl.to(images, {
x: 2000,
duration: 1,
ease: "power2.in",
stagger: {
each: 1.5,
onStart() {
let leavingEl = this.targets()[0],
enteringEl = all[all.indexOf(leavingEl) + 1];
// console.log(leavingEl)
console.log(this.targets())
//leavingEl.classList.add("active"); // if you want to set a class on the one animating out, you could do it like this.
gsap.to(all, {
ease: "power2.inOut",
duration: 0.6,
// rotation: 0
// function-based value - if it's the entering element, make it exactly 8 degrees. Otherwise, randomize it between -15 and 15 degrees.
// rotation: (i, target) => target === enteringEl ? 8 : gsap.utils.random(-15, 15)
rotation: (i, target) => target === enteringEl ? 8 : gsap.utils.random([4, -4,])
// });
})
}
}
});
}
play();
https://codepen.io/thatfemicode/pen/MWpwaRQ
https://twitter.com/P_h_l_i_x/status/1353659923834544128
晚上,经过大量的实践,我想出了一个解决方案,但我仍然不满意我所拥有的,我正在努力做到这一点,正如 TWITTER 的影响者部分所示 link 下面的页面看看每个循环如何在离开视口之前将 class 更改为前一个元素的 class,我该如何实现?谢谢,任何建议将不胜感激
<div id="container">
<div class="fakeImages" id="fake1"></div>
<div class="fakeImages" id="fake2"></div>
<div class="fakeImages" id="fake3"></div>
<img
src="https://images.unsplash.com/photo-1494548162494-384bba4ab999?ixid=MnwxMjA3fDB8MHxzZWFyY2h8MXx8c3VucmlzZXxlbnwwfHwwfHw%3D&ixlib=rb-1.2.1&w=1000&q=80"
alt="view"
id="img1"
class="images"
/>
<img
src="https://media.istockphoto.com/photos/colored-powder-explosion-abstract-closeup-dust-on-backdrop-colorful-picture-id1072093690?k=6&m=1072093690&s=612x612&w=0&h=Eyk67XBt4sr3Bk1MubM6dHpvEVNICX4L7FumWhcTwuY="
alt="powder"
id="img2"
class="images"
/>
<img
src="https://media3.s-nbcnews.com/j/newscms/2019_41/3047866/191010-japan-stalker-mc-1121_06b4c20bbf96a51dc8663f334404a899.fit-760w.JPG"
alt="powder"
id="img3"
class="images"
/>
<img
src="https://cdn.jpegmini.com/user/images/slider_puffin_before_mobile.jpg"
alt="bird"
id="img4"
class="images"
/>
</div>
CSS
#container {
.images {
position: absolute;
top: 50%;
left: 50%;
width: 300px;
height: 300px;
transform: translate(-50%, -50%);
}
#img4 {
z-index: -5;
}
.fakeImages {
position: absolute;
top: 50%;
left: 50%;
width: 300px;
height: 300px;
z-index: -9;
}
#fake1 {
background: lightgrey;
transform: translate(-50%, -50%) rotate(20deg);
}
#fake2 {
background: grey;
transform: translate(-50%, -50%) rotate(-10deg);
}
#fake3 {
background: darkgrey;
transform: translate(-50%, -50%) rotate(-15deg);
}
}
Javascript
function play() {
let images = gsap.utils.toArray('.images');
let fakes = gsap.utils.toArray('.fakeImages');
let tl = gsap.timeline({ repeat: -1, repeatDelay: 1 });
let tl2 = gsap.timeline({ repeat: -1, repeatDelay: 0 });
tl.set(images, {
zIndex: (i) => i * -1,
rotation: (i) => Math.random() * 30 - 15,
});
tl.to(images, {
duration: 1,
rotation: 0,
delay: (i) => i * 1 + 1,
x: 2000,
// scale: 0,
// css: { className: '+=active' },
});
}
play();
在 GSAP 的某人对代码进行了改进并且我也添加了我的修改后,可以在 codepen.io 上找到解决方案。
https://codepen.io/thatfemicode/pen/OJpNXEr
HTML
<div id="container">
<!-- <div class="fakeImages" id="fake1"></div>
<div class="fakeImages" id="fake2"></div>
<div class="fakeImages" id="fake3"></div> -->
<img
src="https://images.unsplash.com/photo-1494548162494-384bba4ab999?ixid=MnwxMjA3fDB8MHxzZWFyY2h8MXx8c3VucmlzZXxlbnwwfHwwfHw%3D&ixlib=rb-1.2.1&w=1000&q=80"
alt="view"
id="img1"
class="images"
/>
<img
src="https://media.istockphoto.com/photos/colored-powder-explosion-abstract-closeup-dust-on-backdrop-colorful-picture-id1072093690?k=6&m=1072093690&s=612x612&w=0&h=Eyk67XBt4sr3Bk1MubM6dHpvEVNICX4L7FumWhcTwuY="
alt="powder"
id="img2"
class="images"
/>
<img
src="https://media3.s-nbcnews.com/j/newscms/2019_41/3047866/191010-japan-stalker-mc-1121_06b4c20bbf96a51dc8663f334404a899.fit-760w.JPG"
alt="powder"
id="img3"
class="images"
/>
<img
src="https://cdn.jpegmini.com/user/images/slider_puffin_before_mobile.jpg"
alt="bird"
id="img4"
class="images"
/>
</div>
CSS
body {
overflow-x: hidden;
}
.active {
border: 1px solid red;
}
#container {
.images {
position: absolute;
top: 50%;
left: 50%;
width: 300px;
height: 300px;
transform: translate(-50%, -50%);
}
#img4 {
z-index: -5;
}
.fakeImages {
position: absolute;
top: 50%;
left: 50%;
width: 300px;
height: 300px;
z-index: -9;
}
#fake1 {
background: lightgrey;
transform: translate(-50%, -50%) rotate(20deg);
}
#fake2 {
background: grey;
transform: translate(-50%, -50%) rotate(-10deg);
}
#fake3 {
background: darkgrey;
transform: translate(-50%, -50%) rotate(-15deg);
}
}
使用 GSAP 的 Javsscript
function play() {
let images = gsap.utils.toArray('.images');
let fakes = gsap.utils.toArray('.fakeImages');
let all = images.concat(fakes);
let tl = gsap.timeline({ delay: 1, repeat: -1, repeatDelay: 1 });
gsap.set(images, {
zIndex: (i) => i * -1,
// rotation: "random(-15,15)",
});
// make sure the "top" image is exactly 8 degrees
gsap.set(images[0], {rotation: 8});
gsap.set(images[1], {rotation: -8})
gsap.set(images[2], {rotation: 8})
gsap.set(images[3], {rotation: -8})
// at the start, remove all "active" classes
tl.call(() => images.forEach(el => el.classList.remove("active")));
tl.to(images, {
x: 2000,
duration: 1,
ease: "power2.in",
stagger: {
each: 1.5,
onStart() {
let leavingEl = this.targets()[0],
enteringEl = all[all.indexOf(leavingEl) + 1];
// console.log(leavingEl)
console.log(this.targets())
//leavingEl.classList.add("active"); // if you want to set a class on the one animating out, you could do it like this.
gsap.to(all, {
ease: "power2.inOut",
duration: 0.6,
// rotation: 0
// function-based value - if it's the entering element, make it exactly 8 degrees. Otherwise, randomize it between -15 and 15 degrees.
// rotation: (i, target) => target === enteringEl ? 8 : gsap.utils.random(-15, 15)
rotation: (i, target) => target === enteringEl ? 8 : gsap.utils.random([4, -4,])
// });
})
}
}
});
}
play();