有趣的动画代码分享

目录

前言

1. 口香糖吹泡泡

 2.实现一只手表

3.激光汇聚成爱心 


前言

        平时也会看一些论坛或是公众号文章或是论坛来看一些自己感兴趣的知识来学习,下面是我最近看到的几个有趣的代码片段分享

1. 口香糖吹泡泡

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>口香糖吹泡泡</title>
    <style>:root{--primary:#80e36b;--secondary:#50bc37;--bubble:#dc7f94;--blush:#ee9a96;--sizeMultiplicator:2;}@media (max-width:1400px),(max-height:1000px){:root{--sizeMultiplicator:1;}}@media (max-width:700px),(max-height:500px){:root{--sizeMultiplicator:0.5;}}@media (max-width:350px),(max-height:250px){:root{--sizeMultiplicator:0.3;}}*{box-sizing:border-box;}body{overflow:hidden;}#main{scale:var(--sizeMultiplicator);transform-origin:91% 91%;bottom:0;right:0;position:absolute;padding:65px 65px 0 0;margin:0 -50px -50px 0;}#head{width:500px;aspect-ratio:1;background-color:var(--primary);border-radius:100%;border:10px solid black;}#eyes{position:absolute;top:300px;left:50px;width:300px;height:50px;display:flex;justify-content:space-between;z-index:1;align-items:center;}#eyes .eye,#eyes .blush{width:50px;height:50px;border-radius:100%;}#eyes .eye{background-color:black;animation:blink 10s linear infinite;}#eyes .blush{position:absolute;background-color:var(--blush);z-index:-1;top:24px;}#eyes #blush-0{left:-26px;}#eyes #blush-1{right:-26px;}@keyframes blink{50%{height:50px;}50.1%{height:10px;}50.7%{height:50px;}70%{height:50px;}71%{height:10px;}72%{height:50px;}73%{height:50px;}74%{height:10px;}75%{height:50px;}}#mouth{position:absolute;top:310px;left:190px;}#mouth .lip{width:25px;aspect-ratio:1;border:5px solid black;border-radius:100%;}#lip-1{margin-top:-6px;position:relative;visibility:hidden;animation:mouth-show 10s infinite linear;}#lip-1:after{content:'';position:absolute;left:5px;top:-100%;height:25px;width:20px;border-radius:40%;background-color:var(--primary);}@keyframes mouth-show{0%{visibility:visible;}50%{visibility:hidden;}}.hair{background-color:var(--secondary);position:absolute;border:10px solid black;z-index:-1;border-radius:50%;}#hair-0{top:0px;left:220px;width:110px;height:230px;rotate:10deg;}#hair-1{top:70px;left:350px;width:110px;height:210px;rotate:40deg;}#hair-2{top:200px;left:400px;width:100px;height:190px;rotate:80deg;}#hair-3{top:320px;left:380px;width:90px;height:190px;rotate:110deg;}#bubble{aspect-ratio:1;position:absolute;top:59%;right:65%;border-radius:100%;transform:translateY(-50%);animation:bubbleSize 10s infinite ease-out;visibility:hidden;z-index:2;}#bubble:before{content:'';position:absolute;width:100%;height:100%;background-color:var(--bubble);border-radius:100%;animation:bubbleOpacity 10s infinite ease-out;}#bubble:after{content:'';position:absolute;border:5px solid var(--bubble);width:100%;height:100%;box-sizing:border-box;border-radius:100%;}#highlight{aspect-ratio:1;position:absolute;width:100%;animation:highlightOpacity 10s infinite ease-out;}#highlight:before,#highlight:after{content:'';background-color:white;border-radius:100%;position:absolute;}#highlight:before{width:7%;height:12%;top:10%;left:26%;rotate:45deg;}#highlight:after{width:6%;height:8%;top:26%;left:14%;rotate:33deg;}@keyframes bubbleSize{0%{width:10px;visibility:visible;}50%{visibility:hidden;}55%{width:350px;}}@keyframes bubbleOpacity{0%{opacity:0.9;}50%{opacity:0.5;}}@keyframes highlightOpacity{0%{opacity:0;}50%{opacity:0.9;}}#popped{background-color:var(--bubble);opacity:0.6;width:200px;height:200px;scale:2.8;transform-origin:0 0;left:-24px;position:absolute;top:41px;z-index:2;clip-path:path(
          'M135.6,42.4C146.6,44.6,156.3,53.3,162.7,63.9C169,74.6,172.1,87.3,169.7,98.6C167.3,109.9,159.3,119.8,153.8,131.9C148.2,144,145.1,158.4,136.6,163.6C128,168.9,114,164.9,101.1,163C88.2,161,76.5,161.1,66.4,156.7C56.2,152.4,47.7,143.8,38.5,133.6C29.2,123.4,19.3,111.7,18.3,99.4C17.4,87.2,25.4,74.4,33.1,61.5C40.7,48.6,48.1,35.7,59.2,33.6C70.3,31.4,85.1,40,98.7,42.2C112.3,44.4,124.7,40.2,135.6,42.4Z'
        );visibility:hidden;animation:popped 10s infinite;}@keyframes popped{50%{visibility:hidden;}100%{visibility:visible;}}#shock{position:absolute;width:200px;height:200px;background-color:yellow;top:160px;left:-170px;clip-path:polygon(
          50% 0%,62% 29%,98% 35%,71% 41%,89% 63%,47% 52%,31% 84%,29% 42%,9% 31%,43% 22%
        );visibility:hidden;animation:shock 10s infinite;}@keyframes shock{49.7%{visibility:hidden;}50.3%{visibility:visible;}50.4%{visibility:hidden;}}</style>
  </head>
  <body>
    <div id="main"><div id="head"><div id="eyes"><div class="eye"><div class="blush"id="blush-0"></div></div><div class="eye"><div class="blush"id="blush-1"></div></div></div><div id="mouth"><div class="lip"id="lip-0"></div><div class="lip"id="lip-1"></div></div><div id="popped"></div></div><div id="hair"><div class="hair"id="hair-0"></div><div class="hair"id="hair-1"></div><div class="hair"id="hair-2"></div><div class="hair"id="hair-3"></div></div><div id="bubble"><div id="highlight"></div></div><div id="shock"></div></div>
  </body>
</html>

 2.实现一只手表

 

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>手表</title>
    <style>
      .watch {
        --watch-color: white;
        --screen-color: black;
        font-size: 4.5vmin;
        font-family: monospace;
        color: #fff;
        padding: 2em 1.5em;
        border: 2px solid var(--watch-color);
        border-radius: 2em;
        box-shadow: inset 0 0 0 0.5em black,
          inset 0 0 1rem 1em hsl(0 0% 100% / 0.25);
        background-color: var(--screen-color);
        background-image: linear-gradient(
          to bottom right,
          #fff0 50%,
          hsl(0 0% 100% / 0.25)
        );
        position: relative;
      }
      .watch::before,
      .watch::after {
        content: '';
        position: absolute;
        background-color: var(--watch-color);
        z-index: -1;
      }
      .watch::after {
        inset: -0.5em 20%;
        border-radius: 0.5em;
        background-image: linear-gradient(
          #fff0,
          hsl(0 0% 0% / 0.5) 0.5em calc(100% - 0.5em),
          #fff0
        );
      }
      .watch::before {
        inset: -50vh 25%;
        background-image: repeating-linear-gradient(
            #fff0 0 0.3em,
            hsl(0 0% 0% / 0.125) 0.3em 0.5em,
            #fff0 0.5em 0.8em
          ),
          radial-gradient(circle, #fff0, hsl(0 0% 0% / 0.25) 50%);
      }
      .keyword {
        color: #ddca7e;
      }
      .def {
        color: #809bbd;
      }
      .operator {
        color: #cccccc;
      }
      .property {
        color: #9a8297;
      }
      .string {
        color: #96b38a;
      }
      .number {
        color: #d0782a;
      }
      * {
        box-sizing: border-box;
      }
      body {
        margin: 0;
        padding: 1em;
        min-height: 100vh;
        background-color: #1d1e22;
        display: grid;
        place-items: center;
        overflow: hidden;
      }
    </style>
  </head>
  <body>
    <div class="watch"></div>

    <script>
      clock();

      function clock() {
        const date = new Date();
        const indent = 2;
        const clockObj = {
          am_pm: date.getHours() >= 12 ? 'pm' : 'am',
          hours: date.getHours() % 12 || 12,
          minutes: date.getMinutes(),
          seconds: date.getSeconds(),
          day: date.toLocaleDateString('en-us', { weekday: 'long' }),
          date: date.getDate(),
          month: date.toLocaleDateString('en-us', { month: 'long' }),
          year: date.getFullYear(),
        };
        const entryFormat = ([key, val]) => {
          return `${'&nbsp'.repeat(
            indent
          )}<span class="property">${key}</span>: ${valFormat(val)}`;
        };
        const valFormat = (val) => {
          if (typeof val == 'number')
            return `<span class="number">${val}</span>`;
          else if (typeof val == 'string')
            return `<span class="string">"${val}"</span>`;
        };
        document.querySelector('.watch').innerHTML = `
    <span class="keyword">const</span> <span class="def">clock</span> = {<br>
    ${Object.entries(clockObj).reduce(
      (str, entry) => str + entryFormat(entry) + ',<br>',
      ''
    )}};`;

        requestAnimationFrame(clock);
      }
    </script>
  </body>

3.激光汇聚成爱心 

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>激光汇聚成爱心</title>
    <style>
      canvas {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.2);
      }
    </style>
  </head>
  <body>
    <canvas id="heart"></canvas>
    <script>window.requestAnimationFrame=window.__requestAnimationFrame||window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||(function(){return function(callback,element){var lastTime=element.__lastTime;if(lastTime===undefined){lastTime=0}var currTime=Date.now();var timeToCall=Math.max(1,33-(currTime-lastTime));window.setTimeout(callback,timeToCall);element.__lastTime=currTime+timeToCall}})();window.isDevice=/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test((navigator.userAgent||navigator.vendor||window.opera).toLowerCase());var loaded=false;var init=function(){if(loaded)return;loaded=true;var mobile=window.isDevice;var koef=mobile?1.5:1;var canvas=document.getElementById('heart');var ctx=canvas.getContext('2d');var width=(canvas.width=koef*innerWidth);var height=(canvas.height=koef*innerHeight);var rand=Math.random;ctx.fillStyle='rgba(0,0,0,1)';ctx.fillRect(0,0,width,height);var heartPosition=function(rad){return[Math.pow(Math.sin(rad),3),-(15*Math.cos(rad)-5*Math.cos(2*rad)-2*Math.cos(3*rad)-Math.cos(4*rad)),]};var scaleAndTranslate=function(pos,sx,sy,dx,dy){return[dx+pos[0]*sx,dy+pos[1]*sy]};window.addEventListener('resize',function(){width=canvas.width=koef*innerWidth;height=canvas.height=koef*innerHeight;ctx.fillStyle='rgba(0,0,0,1)';ctx.fillRect(0,0,width,height)});var traceCount=50;var pointsOrigin=[];var i;var dr=0.1;for(i=0;i<Math.PI*2;i+=dr)pointsOrigin.push(scaleAndTranslate(heartPosition(i),105,6.5,0,0));for(i=0;i<Math.PI*2;i+=dr)pointsOrigin.push(scaleAndTranslate(heartPosition(i),75,4.5,0,0));for(i=0;i<Math.PI*2;i+=dr)pointsOrigin.push(scaleAndTranslate(heartPosition(i),45,2.5,0,0));var heartPointsCount=pointsOrigin.length;var targetPoints=[];var pulse=function(kx,ky){for(i=0;i<pointsOrigin.length;i++){targetPoints[i]=[];targetPoints[i][0]=kx*pointsOrigin[i][0]+width/2;targetPoints[i][1]=ky*pointsOrigin[i][1]+height/2}};var e=[];for(i=0;i<heartPointsCount;i++){var x=rand()*width;var y=rand()*height;e[i]={vx:0,vy:0,R:2,speed:rand()+5,q:~~(rand()*heartPointsCount),D:2*(i%2)-1,force:0.2*rand()+0.7,f:'hsla(0,'+~~(40*rand()+60)+'%,'+~~(60*rand()+20)+'%,.3)',trace:[],};for(var k=0;k<traceCount;k++)e[i].trace[k]={x:x,y:y}}var config={traceK:0.4,timeDelta:0.01,};var time=0;var loop=function(){var n=-Math.cos(time);pulse((1+n)*0.5,(1+n)*0.5);time+=(Math.sin(time)<0?9:n>0.8?0.2:1)*config.timeDelta;ctx.fillStyle='rgba(0,0,0,.1)';ctx.fillRect(0,0,width,height);for(i=e.length;i--;){var u=e[i];var q=targetPoints[u.q];var dx=u.trace[0].x-q[0];var dy=u.trace[0].y-q[1];var length=Math.sqrt(dx*dx+dy*dy);if(10>length){if(0.95<rand()){u.q=~~(rand()*heartPointsCount)}else{if(0.99<rand()){u.D*=-1}u.q+=u.D;u.q%=heartPointsCount;if(0>u.q){u.q+=heartPointsCount}}}u.vx+=(-dx/length)*u.speed;u.vy+=(-dy/length)*u.speed;u.trace[0].x+=u.vx;u.trace[0].y+=u.vy;u.vx*=u.force;u.vy*=u.force;for(k=0;k<u.trace.length-1;){var T=u.trace[k];var N=u.trace[++k];N.x-=config.traceK*(N.x-T.x);N.y-=config.traceK*(N.y-T.y)}ctx.fillStyle=u.f;for(k=0;k<u.trace.length;k++){ctx.fillRect(u.trace[k].x,u.trace[k].y,1,1)}}window.requestAnimationFrame(loop,canvas)};loop()};var s=document.readyState;if(s==='complete'||s==='loaded'||s==='interactive')init();else document.addEventListener('DOMContentLoaded',init,false);</script>
  </body>
</html>

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XError_xiaoyu

你的支持,使我更好的创作

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值