HTML+CSS制作一个动画(一)https://developer.aliyun.com/article/1382469
CSS部分结构如下:
:root { --background-color: #f5f5f5; --border-color: #7591AD; --text-color: #34495e; --color1: #EC3E27; --color2: #fd79a8; --color3: #6aa6d4; --color4: #00b894; --color5: #fdcb6e; --color6: #e056fd; --color7: #04a704; --color8: #BDC581; } *, ::after, ::before { margin: 0; padding: 0; box-sizing: border-box; } html { font-size: 14px; } body { width: 100vw; height: 100vh; background-color: var(--background-color); display: flex; justify-content: center; align-items: center; font-family: 'Montserrat', sans-serif, Arial, 'Microsoft Yahei'; } .channel { position: absolute; width: 80%; text-align: center; top: 10vh; left: 50%; transform: translateX(-50%); font-size: 5vmin; font-weight: bold; color: #35353588; z-index: 10000; } .container { position: absolute; width: 100vw; height: 100vh; /* background-color: #00b894; */ display: flex; justify-content: center; align-items: center; flex-direction: column; } /* ********** * 速度切换开关 * 不用checkbox实现,我们用js控制样式来实现 * **********/ #switch { position: relative; width: 60px; height: 30px; border: 2px solid #333; border-radius: 30px; cursor: pointer; } #switch::before, #switch::after { position: absolute; line-height: 26px; text-transform: uppercase; font-weight: 800; padding: 0 20px; /* background-color: #0984e3; */ /* 取消前后状态名称的鼠标效果以及点击事件响应 */ cursor: initial; pointer-events: none; } #switch::before { content: 'fast'; right: 100%; color: var(--color8); } #switch::after { content: 'slow'; left: 100%; color: var(--color3); } /* 默认情况 */ #switch .circle { position: absolute; top: 3px; left: 3px; width: 20px; height: 20px; border: 2px solid #333; border-radius: 50%; box-shadow: inset 4px -2px 0 0 var(--color8); transition: all .3s cubic-bezier(.86, 1.51, .74, 1); } /* 点击选中的情况 */ #switch.switched .circle { left: calc(100% - 20px - 3px); box-shadow: inset 4px -2px 0 0 var(--color3); } /* ********** * 这里是主画布外框 * **********/ .main { position: relative; width: 400px; height: 300px; border: 2px solid #333; margin-top: 20px; overflow: hidden; } /* ********** * 这里是太阳 * **********/ .sun { position: absolute; width: 20px; height: 20px; border: 2px solid #333; border-radius: 50%; left: 270px; top: 50px; display: flex; justify-content: center; align-items: center; animation: sun_rotate 10s linear infinite; } @keyframes sun_rotate { 0% { transform: rotate(0deg); } 100% { transform: rotate(-360deg); } } .sun span { position: absolute; display: block; height: 2px; width: 16px; background-color: #333; box-shadow: 4px 4px 0 0 var(--color5); transform: rotate(calc(var(--i) * 45deg)) translateX(-20px); animation: sun_ray 1s linear infinite; animation-delay: calc(var(--i) * -0.5s); } @keyframes sun_ray { 0% { transform: rotate(calc(var(--i) * 45deg)) translateX(-20px) scaleX(1) } 50% { transform: rotate(calc(var(--i) * 45deg)) translateX(-20px) scaleX(0.6) } 100% { transform: rotate(calc(var(--i) * 45deg)) translateX(-20px) scaleX(1) } } /* ********** * 这里是群山 * **********/ .mountain { position: absolute; border: 2px solid #333; transform: rotate(45deg); } .mountain.a { width: 14px; height: 14px; left: 80px; bottom: 35px; } .mountain.b { width: 18px; height: 18px; left: 130px; bottom: 45px; } .mountain.c { width: 20px; height: 20px; left: 190px; bottom: 60px; } .mountain.d { width: 2px; height: 2px; left: 240px; bottom: 62px; border-bottom: none; } .mountain.e { width: 14px; height: 14px; left: 285px; bottom: 41px; } .mountain.a::after, .mountain.b::after, .mountain.c::after, .mountain.d::after, .mountain.e::after, .mountain.a::before, .mountain.b::before, .mountain.c::before, .mountain.d::before, .mountain.e::before { position: absolute; content: ''; background-color: #333; } .mountain.a::after, .mountain.b::after, .mountain.c::after, .mountain.d::after, .mountain.e::after { left: -2px; top: 100%; width: 2px; } .mountain.a::after { height: 70px; } .mountain.b::after { height: 50px; } .mountain.c::after { height: 70px; } .mountain.d::after { height: 14px; } .mountain.e::after { height: 18px; } .mountain.a::before, .mountain.b::before, .mountain.c::before, .mountain.d::before, .mountain.e::before { top: -2px; left: 100%; height: 2px; } .mountain.a::before { width: 14px; box-shadow: -5px -5px 0 0 var(--color4); } .mountain.b::before { width: 14px; box-shadow: -5px -5px 0 0 var(--color4); } .mountain.c::before { width: 36px; box-shadow: -14px -5px 0 0 var(--color4); } .mountain.d::before { width: 55px; box-shadow: 5px 5px 0 0 var(--color4); } .mountain.e::before { width: 70px; box-shadow: 5px 5px 0 0 var(--color4); } /* ********** * 这里是云和风 * **********/ /* .main { overflow: visible; } */ .cloud_wind_wrap_fast { /* (画布大小-去两个边框)*3 */ width: 1188px; height: 100%; /* background-color: #af401455; */ animation: fly 3s linear infinite; animation-play-state: running; } .slow .cloud_wind_wrap_fast { animation-play-state: paused; } .cloud_wind_wrap_slow { width: 1188px; height: 100%; /* background-color: #56fd7255; */ display: flex; justify-content: flex-start; align-items: center; animation: fly 6s linear infinite; animation-play-state: paused; } .slow .cloud_wind_wrap_slow { animation-play-state: running; } .cloud_wind_group { position: relative; width: 100%; height: 100%; /* background-color: #00b894; */ /* animation: fly 12s linear infinite; */ /* animation-delay: calc(var(--i) * -6s); */ } @keyframes fly { 0% { transform: translateX(0%); } 100% { transform: translateX(-33.33333333333333%); } } /* ********** * 今天只做云,明天风会来 * **********/ .cloud { position: absolute; width: 60px; height: 45px; } .cloud.a { left: 60px; top: 20px; } .cloud.b { left: 160px; top: 80px; transform: rotateY(180deg); } .cloud.c { left: 280px; top: 50px; } .cloud span { position: absolute; display: block; background-color: #fff; border: 2px solid #333; border-radius: 50%; } .cloud span:nth-child(1) { width: 20px; height: 20px; left: 0; bottom: 0; border-right-color: transparent; border-bottom-color: transparent; transform: rotate(-45deg); } .cloud span:nth-child(2) { width: 20px; height: 20px; left: 10px; bottom: 10px; border-top-color: transparent; border-right-color: transparent; border-bottom-color: transparent; transform: rotate(45deg); } .cloud span:nth-child(3) { width: 30px; height: 30px; left: 15px; bottom: 12px; border-right-color: transparent; border-bottom-color: transparent; transform: rotate(50deg); box-shadow: 0 -3px 0 0 var(--color3); } .cloud span:nth-child(4) { width: 27px; height: 27px; left: 31px; bottom: 0px; border-left-color: transparent; transform: rotate(0deg); box-shadow: 2px -1px 0 0 var(--color3); } .cloud span:nth-child(5) { width: 35px; height: 15px; left: 10px; bottom: 0; border-radius: 0; border-width: 0 0 2px 0; } /* 中间云的阴影 */ .cloud.b span:nth-child(1) { box-shadow: 0px -3px 0 0 var(--color3); } .cloud.b span:nth-child(2) { box-shadow: -2px -1px 0 0 var(--color3); } .cloud.b span:nth-child(3) { box-shadow: -3px -1px 0 0 var(--color3); } .cloud.b span:nth-child(4) { box-shadow: none; } /* ********** * 风来了 * **********/ /* 大风 */ .wind { position: absolute; width: 10px; height: 10px; /* background-color: #EC3E27; */ } .wind.a { top: 100px; left: 40px; } .wind.b { top: 140px; left: 260px; } /* 大风纹理 */ .wind span, .wind span::before, .wind span::after { position: absolute; background-color: #555; height: 3px; } .wind span::before, .wind span::after { content: ''; } .wind span, .wind span::after { box-shadow: 4px 4px 0 -1px var(--color3); } /* 大风纹理1 */ .wind span:nth-child(1) { top: 0; left: 0; width: 40px; } .wind span:nth-child(1)::before { width: 10px; height: 10px; left: -4px; bottom: 1px; background-color: transparent; border: 3px solid #555; border-radius: 50%; border-color: transparent transparent #555 #555; transform: rotate(45deg); } .wind span:nth-child(1)::after { width: 10px; top: 0; left: 110%; } /* 大风纹理2 */ .wind span:nth-child(2) { top: 8px; left: -20px; width: 40px; } .wind span:nth-child(2)::before { width: 10px; height: 10px; left: -4px; bottom: 1px; background-color: transparent; border: 3px solid #555; border-radius: 50%; border-color: transparent transparent #555 #555; transform: rotate(45deg); } .wind span:nth-child(2)::after { width: 50px; top: 0; left: 110%; } /* 大风纹理3 */ .wind span:nth-child(3) { top: 15px; left: 50px; width: 10px; } .wind span:nth-child(3)::before { width: 40px; top: 0; right: 140%; } .wind span:nth-child(3)::after { width: 40px; top: 0; left: 140%; } /* 大风纹理4 */ .wind span:nth-child(4) { top: 20px; left: 30px; width: 40px; } .wind span:nth-child(4)::before { width: 10px; top: 0; right: 120%; } .wind span:nth-child(4)::after { width: 10px; top: 0; left: 120%; } /* 小风 */ .wind_small { position: absolute; width: 100%; height: 100%; /* background-color: #00b894; */ } /* 小风纹理 */ .wind_small span, .wind_small span::after { position: absolute; height: 3px; background-color: #555; box-shadow: 4px 4px 0 -1px var(--color3); } .wind_small span::after { content: ''; width: 50%; top: 0; left: 120%; } .wind_small span:nth-child(1) { top: 12px; left: 5px; width: 50px; } .wind_small span:nth-child(2) { top: 32px; left: 120px; width: 20px; } .wind_small span:nth-child(3) { top: 152px; left: 120px; width: 20px; } .wind_small span:nth-child(3)::after { display: none; } .wind_small span:nth-child(4) { top: 172px; left: 60px; width: 20px; } .wind_small span:nth-child(5) { top: 60px; left: 140px; width: 10px; } .wind_small span:nth-child(5)::after { display: none; } .wind_small span:nth-child(6) { top: 20px; left: 300px; width: 30px; } .wind_small span:nth-child(7) { top: 115px; left: 330px; width: 30px; } .wind_small span:nth-child(8) { top: 170px; left: 200px; width: 10px; } .wind_small span:nth-child(8)::after { display: none; } /* ********** * 这是四棵树 * **********/ .tree_wrap, .tree { position: absolute; width: 100%; height: 60px; left: 0; bottom: 0; /* background-color: #00b89466; */ transform-origin: bottom; transition: all 0.2s linear; } .tree { /* background-color: #e056fd55; */ animation: tree_move 1s linear infinite; transform-origin: bottom; } .slow .tree_wrap { transform: skewX(-10deg); } @keyframes tree_move { 0%, 100% { transform: skewX(16deg); } 20% { transform: skewX(18deg); } 40% { transform: skewX(20deg); } 60% { transform: skewX(17deg); } 80% { transform: skewX(18deg); } } .tree span { position: absolute; display: block; width: 2px; height: 10px; bottom: 0; background-color: #333; display: flex; justify-content: center; align-items: center; } .tree span:nth-child(1) { left: 70px; } .tree span:nth-child(2) { left: 150px; } .tree span:nth-child(3) { left: 180px; } .tree span:nth-child(4) { left: 330px; } .tree span::before, .tree span::after { position: absolute; content: ''; border: 2px solid #333; width: 12px; height: 26px; bottom: 100%; border-radius: 50%; background-color: #fff; box-shadow: inset -3px 4px 2px 0 var(--color7); } .tree span::after { border-color: transparent var(--color7) transparent transparent; background-color: transparent; transform: rotate(-15deg) translate(5px, -4px); box-shadow: none; } /* ********** * 这是三个风车 * **********/ .windmill_wrap { position: absolute; width: 100%; height: 120px; left: 0; bottom: 0; /* background-color: #00b89466; */ } .windmill { position: absolute; /* width: 114px; */ height: 100px; left: 220px; bottom: 0; /* background-color: #BDC581; */ display: flex; justify-content: center; align-items: center; } .windmill.left { left: 100px; transform: scale(0.75); transform-origin: bottom; } .windmill.right { left: 300px; transform: scale(0.8); transform-origin: bottom; } /* 风车柱子 */ .windmill .pole { position: absolute; width: 14px; height: 120px; bottom: 0px; /* background-color: #535c0f; */ perspective: 70px; } .windmill .pole::after { position: absolute; content: ''; width: 100%; height: 100%; background-color: #fff; border: 3px solid #333; border-width: 0 3px; transform-origin: bottom; transform: rotateX(15deg); } /* 风车头部 */ .windmill .head { position: absolute; width: 10px; height: 10px; top: 0; /* background-color: #EC3E27; */ transform: translateY(-50%); display: flex; justify-content: center; align-items: center; animation: windmill_fan_rotate 4s linear infinite; animation-play-state: paused; } .slow .windmill .head { animation-play-state: running; } /* 扇叶组合 */ .windmill .head .fan { position: absolute; width: 10px; height: 10px; /* background-color: #27ec72; */ display: flex; justify-content: center; align-items: center; animation: windmill_fan_rotate 2s linear infinite; animation-play-state: running; } .slow .windmill .head .fan { animation-play-state: paused; } /* 扇叶组合中心圆 */ .windmill .head .fan::after { position: absolute; content: ''; width: 15px; height: 15px; background-color: #fff; border: 3px solid #333; border-radius: 50%; } /* 扇叶 */ .windmill .head .fan span { position: absolute; width: 70px; height: 15px; background-color: #fff; border: 3px solid #333; border-radius: 100%; transform: rotate(calc(var(--i) * 120deg)) translateX(30px); } /* 旋转动画 */ @keyframes windmill_fan_rotate { 0% { transform: rotate(0deg); } 100% { transform: rotate(-360deg); } }