#纯 CSS 实现动画,童年玩具 “跳跳杆”
本文介绍了如何使用纯CSS实现一个动画效果,模拟童年玩具“跳跳杆”。通过HTML和CSS代码,创建了一个具有立体效果的场景,展示了跳跳杆的动态表现。代码中包含了多种CSS动画效果和关键帧定义,展示了如何利用CSS的强大功能来实现复杂的动画效果。
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
</head>
<body>
<div class="scene">
<div class="floor">
<div class="shadow"></div>
</div>
<div class="stick hex">
<i></i><i></i><i></i><i></i><i></i><i></i>
<div class="shaft hex">
<i></i><i></i><i></i><i></i><i></i><i></i>
<div class="stand cube">
<i></i><i></i><i></i><i></i><i></i><i></i>
<div class="robot">
<div class="foot cube">
<i></i><i></i><i></i><i></i><i></i><i></i>
<div class="calf cube">
<i></i><i></i><i></i><i></i><i></i><i></i>
<div class="thigh cube">
<i></i><i></i><i></i><i></i><i></i><i></i>
<div class="thorax cube">
<i></i><i></i><i></i><i></i><i></i><i></i>
<div class="arm cube">
<i></i><i></i><i></i><i></i><i></i><i></i>
<div class="hand cube">
<i></i><i></i><i></i><i></i><i></i><i></i>
</div>
</div>
<div class="arm cube">
<i></i><i></i><i></i><i></i><i></i><i></i>
<div class="hand cube">
<i></i><i></i><i></i><i></i><i></i><i></i>
</div>
</div>
<div class="neck cube">
<i></i><i></i><i></i><i></i><i></i><i></i>
<div class="head cube">
<i></i><i></i><i></i><i></i><i></i><i></i>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="foot cube">
<i></i><i></i><i></i><i></i><i></i><i></i>
<div class="calf cube">
<i></i><i></i><i></i><i></i><i></i><i></i>
<div class="thigh cube">
<i></i><i></i><i></i><i></i><i></i><i></i>
</div>
</div>
</div>
</div>
</div>
<div class="handle cube">
<i></i><i></i><i></i><i></i><i></i><i></i>
</div>
<div class="handle2 cube">
<i></i><i></i><i></i><i></i><i></i><i></i>
</div>
</div>
</div>
</div>
<style>
*, *::before, *::after {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
background-color: #000;
height: 75vh;
display: grid;
place-items: center;
perspective: 800px;
overflow: hidden;
* {
transform-style: preserve-3d;
}
--duration: 1.5s;
}
.scene {
position: relative;
translate: 0 3em;
-webkit-animation: scene 32s infinite linear;
animation: scene 32s infinite linear;
* {
position: absolute;
}
}
@-webkit-keyframes scene {
to { rotate: y -1turn; }
}
@keyframes scene {
to { rotate: y -1turn; }
}
.floor {
inset: -100em;
background-color: #333;
background-image:
radial-gradient(closest-side, transparent, #000),
repeating-linear-gradient(#0003 0, #0000, #0003 2em),
repeating-linear-gradient(90deg, #0003 0, #0000, #0003 2em);
transform: translateY(12em) rotateX(-90deg);
-webkit-animation: floor calc(var(--duration) * 2) infinite ease-in-out;
animation: floor calc(var(--duration) * 2) infinite ease-in-out;
}
@-webkit-keyframes floor {
0%, 5% { background-position-x: 0; }
95%, 100% { background-position-x: 0, 0, -8em; }
}
@keyframes floor {
0%, 5% { background-position-x: 0; }
95%, 100% { background-position-x: 0, 0, -8em; }
}
.shadow {
inset: 95em;
background-image: radial-gradient(closest-side, #000a, transparent);
-webkit-animation: shadow var(--duration) infinite ease-in-out alternate;
animation: shadow var(--duration) infinite ease-in-out alternate;
}
@-webkit-keyframes shadow {
to {
scale: 3;
opacity: 0.3;
}
}
@keyframes shadow {
to {
scale: 3;
opacity: 0.3;
}
}
.stick {
--width: 1em;
--height: 4em;
left: -0.5em; top: 0;
transform-origin: bottom;
-webkit-animation:
stickJump var(--duration) infinite ease-out alternate,
stickAngle var(--duration) calc(var(--duration) * -0.5) infinite ease-in-out alternate;
animation:
stickJump var(--duration) infinite ease-out alternate,
stickAngle var(--duration) calc(var(--duration) * -0.5) infinite ease-in-out alternate;
}
@-webkit-keyframes stickJump {
0%, 25% { translate: 0 8em; }
100% { translate: 0 0em; }
}
@keyframes stickJump {
0%, 25% { translate: 0 8em; }
100% { translate: 0 0em; }
}
@-webkit-keyframes stickAngle {
from { rotate: -5deg; }
to { rotate: 15deg; }
}
@keyframes stickAngle {
from { rotate: -5deg; }
to { rotate: 15deg; }
}
.shaft {
--width: 1.5em;
--height: 11.5em;
left: -0.25em; bottom: 100%;
-webkit-animation: shaft var(--duration) infinite ease-in alternate;
animation: shaft var(--duration) infinite ease-in alternate;
}
@-webkit-keyframes shaft {
0% { translate: 0 3em; }
25%, 100% { translate: 0 0em; }
}
@keyframes shaft {
0% { translate: 0 3em; }
25%, 100% { translate: 0 0em; }
}
.stand {
--width: 1.5em;
--height: 0.5em;
--depth: 5em;
--color: #0ff;
left: 0; top: 100%;
}
.handle {
--width: 0.5em;
--height: 0.5em;
--depth: 8em;
--color: #0ff;
left: 0.5em; top: -0.5em;
}
.handle2 {
--width: 1.75em;
--height: 0.25em;
--depth: 1.75em;
--color: #0ff;
left: -0.125em; top: -0.25em;
}
.robot {
--color: #fff;
}
.foot {
--width: 2em;
--height: 1em;
--depth: 1em;
right: -1em; bottom: 0;
transform-origin: bottom right;
-webkit-animation: foot calc(var(--duration) * 2) infinite ease-in-out;
animation: foot calc(var(--duration) * 2) infinite ease-in-out;
&:nth-child(2) { --tz: -1.5em; --rx: 10deg}
}
@-webkit-keyframes foot {
0%, 100% { transform: translateZ(var(--tz, 1.5em)) rotate(0deg); }
15%, 90% { transform: translateZ(var(--tz, 1.5em)) rotate(15deg); }
}
@keyframes foot {
0%, 100% { transform: translateZ(var(--tz, 1.5em)) rotate(0deg); }
15%, 90% { transform: translateZ(var(--tz, 1.5em)) rotate(15deg); }
}
.calf {
--width: 4em;
--height: 1em;
--depth: 1em;
right: 100%; top: -0.5em;
transform-origin: bottom right;
-webkit-animation: calf calc(var(--duration) * 2) infinite ease-in-out;
animation: calf calc(var(--duration) * 2) infinite ease-in-out;
}
@-webkit-keyframes calf {
0%, 100% { transform: rotate(110deg); }
15% { transform: rotate(70deg); }
90% { transform: rotate(90deg); }
}
@keyframes calf {
0%, 100% { transform: rotate(110deg); }
15% { transform: rotate(70deg); }
90% { transform: rotate(90deg); }
}
.thigh {
--width: 5em;
--height: 1em;
--depth: 1em;
right: 100%; top: 0;
transform-origin: top right;
-webkit-animation: thigh calc(var(--duration) * 2) infinite ease-in-out;
animation: thigh calc(var(--duration) * 2) infinite ease-in-out;
}
@-webkit-keyframes thigh {
0%, 100% { transform: rotateZ(-50deg) rotateY(var(--rx, -10deg)); }
15% { transform: rotateZ(-10deg) rotateY(var(--rx, -10deg)); }
}
@keyframes thigh {
0%, 100% { transform: rotateZ(-50deg) rotateY(var(--rx, -10deg)); }
15% { transform: rotateZ(-10deg) rotateY(var(--rx, -10deg)); }
}
.thorax {
--width: 6em;
--height: 2em;
--depth: 4em;
right: 100%; top: -0.5em;
transform-origin: bottom right;
-webkit-animation: thorax calc(var(--duration) * 2) infinite ease-in-out;
animation: thorax calc(var(--duration) * 2) infinite ease-in-out;
}
@-webkit-keyframes thorax {
0%, 100% { transform: translateZ(-0.65em) rotateY(10deg) rotateZ(20deg); }
15% { transform: translateZ(-0.65em) rotateY(10deg) rotateZ(0deg); }
90% { transform: translateZ(-0.65em) rotateY(10deg) rotateZ(30deg); }
}
@keyframes thorax {
0%, 100% { transform: translateZ(-0.65em) rotateY(10deg) rotateZ(20deg); }
15% { transform: translateZ(-0.65em) rotateY(10deg) rotateZ(0deg); }
90% { transform: translateZ(-0.65em) rotateY(10deg) rotateZ(30deg); }
}
.arm {
--width: 4em;
--height: 1em;
--depth: 1em;
right: 5em; top: 0.5em;
transform-origin: bottom right;
-webkit-animation: arm calc(var(--duration) * 2) infinite ease-in-out;
animation: arm calc(var(--duration) * 2) infinite ease-in-out;
&:nth-child(8) { --dir: -1; }
}
@-webkit-keyframes arm {
0%, 100% { transform: rotateY(calc(var(--dir, 1) * -90deg)) translateX(-2em) rotatex(calc(var(--dir, 1) * 10deg)) rotateZ(30deg); }
15% { transform: rotateY(calc(var(--dir, 1) * -90deg)) translateX(-2em) rotatex(calc(var(--dir, 1) * 40deg)) rotateZ(40deg); }
}
@keyframes arm {
0%, 100% { transform: rotateY(calc(var(--dir, 1) * -90deg)) translateX(-2em) rotatex(calc(var(--dir, 1) * 10deg)) rotateZ(30deg); }
15% { transform: rotateY(calc(var(--dir, 1) * -90deg)) translateX(-2em) rotatex(calc(var(--dir, 1) * 40deg)) rotateZ(40deg); }
}
.hand {
--width: 3em;
--height: 1em;
--depth: 1em;
right: 100%; top: 0;
transform-origin: center right;
-webkit-animation: hand calc(var(--duration) * 2) infinite ease-in-out;
animation: hand calc(var(--duration) * 2) infinite ease-in-out;
}
@-webkit-keyframes hand {
0%, 90%, 100% { transform: rotateZ(130deg); }
15% { transform: rotateZ(110deg); }
}
@keyframes hand {
0%, 90%, 100% { transform: rotateZ(130deg); }
15% { transform: rotateZ(110deg); }
}
.neck {
--width: 2em;
--height: 1em;
--depth: 1em;
right: 5.5em; top: 0.5em;
transform-origin: center right;
-webkit-animation: head calc(var(--duration) * 2) infinite ease-in-out;
animation: head calc(var(--duration) * 2) infinite ease-in-out;
}
.head {
--width: 3em;
--height: 2em;
--depth: 2em;
right: 1.5em; top: -0.5em;
transform-origin: center right;
transform: rotateZ(30deg);
-webkit-animation: head calc(var(--duration) * 2) infinite ease-in-out;
animation: head calc(var(--duration) * 2) infinite ease-in-out;
}
@-webkit-keyframes head {
0%, 100% { transform: rotateZ(10deg); }
15% { transform: rotateZ(5deg); }
}
@keyframes head {
0%, 100% { transform: rotateZ(10deg); }
15% { transform: rotateZ(5deg); }
}
/* --- */
.hex {
width: var(--width); height: var(--height);
& > i {
--ry: calc(var(--i) * 60deg);
--tz: calc(var(--width) * 0.425);
width: 50%; height: 100%;
left: 25%;
transform: rotateY(var(--ry)) translateZ(var(--tz));
background-color: #0ff7;
box-shadow: 0 0 calc(var(--width) * 0.25) #0007 inset;
&:nth-child(1) { --i: 0; }
&:nth-child(2) { --i: 1; }
&:nth-child(3) { --i: 2; }
&:nth-child(4) { --i: 3; }
&:nth-child(5) { --i: 4; }
&:nth-child(6) { --i: 5; }
}
}
.cube {
width: var(--width);
height: var(--height);
& > i {
left: 50%; top: 50%;
background-color: var(--color, #fff);
box-shadow: 0 0 0.5em #0007 inset;
&:nth-child(1) {
inset: 0;
transform: translateZ(calc(var(--depth) * 0.5));
}
&:nth-child(2) {
width: var(--depth); height: 100%;
transform: translate(-50%, -50%) rotateY(90deg) translateZ(calc(var(--width) * 0.5));
}
&:nth-child(3) {
inset: 0;
transform: rotateY(180deg) translateZ(calc(var(--depth) * 0.5));
}
&:nth-child(4) {
width: var(--depth); height: 100%;
transform: translate(-50%, -50%) rotateY(270deg) translateZ(calc(var(--width) * 0.5));
}
&:nth-child(5) {
width: var(--width); height: var(--depth);
transform: translate(-50%, -50%) rotateX(90deg) translateZ(calc(var(--height) * 0.5));
}
&:nth-child(6) {
width: var(--width); height: var(--depth);
transform: translate(-50%, -50%) rotateX(270deg) translateZ(calc(var(--height) * 0.5));
}
}
}
</style>
</body>
</html>