效果演示
源代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>会滑行的小球</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js"></script>
<style>
:root{--clr-0:#CCCCCC;--clr-1:#f5f5f5;--clr-2:#232323}body{font-family:'Montserrat',sans-serif;font-size:1rem;background-color:var(--clr-0)}body.light .cover{background-color:var(--clr-0)}#stick-figure-svg{opacity:0;visibility:hidden}body.light .theme-toggle-button{border-color:white;background-color:var(--clr-0)}body.dark .cover{background-color:var(--clr-2)}body.dark .theme-toggle-button{border-color:#b8b1a7;background-color:var(--clr-2)}body.dark #R-leg,body.dark #L-leg{stroke:white}body.light #R-leg,body.light #L-leg{stroke:#232323}.cover{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:75px;height:75px;background-color:black;z-index:-1}.container{display:flex;justify-content:center;align-items:center;height:100vh;flex-direction:column;gap:2rem;position:relative;overflow:hidden}button{padding:2rem;cursor:pointer}.theme-toggle-button{width:15rem;height:5rem;border:4px solid white;border-radius:50px;display:flex;align-items:flex-end;padding:0;background-color:var(--clr-0)}#stick-figure-svg{width:147%;height:147%}.template-footer{position:fixed;bottom:0;right:0;height:2rem;width:15rem;border-radius:5px 0 0 0;background-color:#ffffba;display:flex;justify-content:space-between;align-items:center;padding:0.8rem 1.6rem}
</style>
</head>
<body>
<div class="container">
<div class="cover"></div>
<button type="submit" class="theme-toggle-button">
<svg width="100%" id="stick-figure-svg" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 150 200">
<defs>
<linearGradient id="linear-gradient" x1="27.6" y1="49.33" x2="125.11" y2="135.42"
gradientTransform="matrix(1, 0, 0, 1, 0, 0)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#f0b402" />
<stop offset=".26" stop-color="#f1a508" />
<stop offset=".69" stop-color="#f39210" />
<stop offset=".99" stop-color="#f48c13" />
</linearGradient>
<mask id="faceClip">
<circle id="face-clip" cx="58" cy="142" r="57"></circle>
</mask>
</defs>
<g id="stick-figure">
<g id="R-leg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="4">
<line id="R-thigh" x1="70" y1="168" x2="70" y2="138" />
<line id="R-calf" x1="70" y1="168" x2="70" y2="198" />
<line id="R-foot" x1="70" y1="198" x2="82" y2="198" />
</g>
<g id="L-leg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="4">
<line id="L-thigh" x1="46" y1="168" x2="46" y2="138" />
<line id="L-calf" x1="46" y1="168" x2="46" y2="198" />
<line id="L-foot" x1="46" y1="198" x2="34" y2="198" />
</g>
<!-- <circle id="face" cx="75" cy="91.18" r="60" fill="url(#linear-gradient)" /> -->
<circle id="face" cx="58" cy="132" r="68" fill="url(#linear-gradient)"></circle>
<g id="eyes-mouth">
<circle id="L-eye" cx="57.68" cy="83.18" r="3.5" />
<circle id="R-eye" cx="90.68" cy="83.18" r="3.5" />
<path id="mouth"
d="M79.53,91.98c.15,0,.25,.22,.22,.45-.27,2-2.29,3.55-4.74,3.55s-4.48-1.55-4.74-3.55c-.03-.23,.07-.45,.22-.45h9.05Z"
fill="#fff" transform-origin="center" transform="scale(1.3)" />
</g>
<g id="highlights" stroke="white" fill="none" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2">
<path id="hl-1" d="M76.06,145.54l-13.33-13.33" />
<path id="hl-2" d="M92.73,132.21l-13.33,13.33" />
<path id="hl-3" d="M63.63,161.31l13.33-13.33" />
<path id="hl-4" d="M92.73,161.31l-13.33-13.33" />
</g>
</g>
</svg>
</button>
</div>
</body>
<script>
gsap.set("#stick-figure-svg", { autoAlpha: 1 });
gsap.set("#stick-figure", { x: -135 });
gsap.set("#eyes-mouth", { transformOrigin: "50% 50%" })
gsap.set("#L-foot", { attr: { x1: 46, x2: 58 } });
gsap.set("#highlights", { autoAlpha: 0 })
gsap.set(["#R-foot", "#L-foot", "#R-thigh", "#R-calf", "#L-thigh", "#L-calf"], { autoAlpha: 0 })
gsap.set(".cover", { xPercent: -50, yPercent: -50 })
let readyForDrag = gsap.timeline({ defaults: { ease: "power1.in", duration: 0.2 } });
readyForDrag
.to(
"#eyes-mouth",
{ x: "+=20" },
"<"
)
.to(["#R-calf"], { attr: { x2: 95, y2: 198 } })
.to(["#R-foot"], { attr: { x2: 95, x1: 107 } }, "<")
.to(["#R-foot"], { attr: { y2: 198, y1: 190 } })
.to(["#L-calf"], { attr: { x2: 71, y2: 198 } })
.to(["#L-foot"], { attr: { x1: 74, x2: 86 } }, "<")
.to(["#L-foot"], { attr: { y2: 190 } })
let highlight_tl = gsap.timeline({ paused: true, defaults: { ease: "power4.in", duration: 0.2 } })
highlight_tl
.to("#highlights", { autoAlpha: 1, duration: 0.1 })
.to("#hl-1", { drawSVG: "0% 100%" })
.to(["#hl-2", "#hl-3", "#hl-4"], { drawSVG: "100% 0%" }, "<")
.to("#hl-1", { drawSVG: "50% 100%", autoAlpha: 0 }, "<")
.to(["#hl-2", "#hl-3", "#hl-4"], { drawSVG: "50% 0%", autoAlpha: 0 }, "<")
let wakeup_tl = gsap.timeline({ paused: true, defaults: { ease: "power1.in", duration: 0.4 } });
wakeup_tl
.to(["#R-foot", "#L-foot", "#R-thigh", "#R-calf", "#L-thigh", "#L-calf"], { autoAlpha: 1, duration: 0.1 })
.to("#face", { attr: { cy: 90 }, duration: 0.2 })
.fromTo(
["#R-thigh", "#R-calf"],
{ attr: { x1: 85, y1: 198 } },
{ attr: { x1: 85, y1: 173 }, duration: 0.2 },
"<"
)
.fromTo(
["#L-thigh", "#L-calf"],
{ attr: { x1: 61, y1: 198 } },
{ attr: { x1: 61, y1: 173 }, duration: 0.2 },
"<"
)
.from(
"#eyes-mouth",
{ x: 25, y: 40, autoAlpha: 0 },
"<"
)
.from(["#L-eye", "#R-eye"], {
transformOrigin: "50% 50%",
scaleY: 0,
})
.fromTo(["#L-eye", "#R-eye"], { scaleY: 0 }, { scaleY: 1, duration: 0.1, transformOrigin: "50% 50%" })
.add(readyForDrag.play())
.to("#stick-figure", { x: 142.5, duration: 0.8 })
.to(["#R-foot", "#L-foot"], { attr: { y1: 198, y2: 198 }, duration: 0.1 })
.to(["#L-foot"], { attr: { x1: 71, x2: 59 }, duration: 0.2 }, "<")
.to(["#L-calf", "#L-thigh"], { attr: { x1: 71, x2: 71 }, duration: 0.1 }, "<")
.to(["#R-calf", "#R-thigh"], { attr: { x1: 95, x2: 95 }, duration: 0.1 }, "<")
.to("#face", { attr: { cx: 83, cy: 75 }, ease: "back" }, "<")
.to("#eyes-mouth", { x: "-=9", y: "-=5" }, "<")
.addLabel("goingtosleep")
.to(["#L-calf", "#L-thigh"], { attr: { x1: 61, x2: 71 } })
.to(["#R-calf", "#R-thigh"], { attr: { x1: 105, x2: 95 } }, "<")
.to("#eyes-mouth", { y: "+=60", transformOrigin: "50% 50%", autoAlpha: 0 })
.to("#face", { attr: { cx: 83, cy: 132 } }, "-=0.2");
wakeup_tl.timeScale(1.5)
let playButton = document.querySelector(".theme-toggle-button");
let themeDark = false
let cover = document.querySelector(".cover");
function turnOnDarkModeHandler() {
document.body.classList.add("dark");
document.body.classList.remove("light");
gsap.to(".cover", { width: "100vw", height: "100vh", duration: 1 }).then(() => document.body.style.backgroundColor = "#232323")
}
function turnOnLightModeHandler() {
document.body.classList.add("light");
document.body.classList.remove("dark");
gsap.to(".cover", { width: "100vw", height: "100vh", duration: 1 }).then(() => document.body.style.backgroundColor = "#CCCCCC")
}
playButton.addEventListener("click", () => {
gsap.set(".cover", { width: "75px", height: "75px" })
themeDark = !themeDark
if (themeDark) {
wakeup_tl.play().eventCallback("onComplete", turnOnDarkModeHandler)
highlight_tl.play()
} else {
wakeup_tl.reverse().then(turnOnLightModeHandler)
highlight_tl.restart()
}
});
</script>
</html>
标签:body,x1,attr,50%,小球,gsap,duration,源代码,滑行
From: https://blog.csdn.net/lcy1619260/article/details/142094781