【问题标题】:How to create an animated stackoverflow icon如何创建动画的stackoverflow图标
【发布时间】:2020-06-05 05:52:06
【问题描述】:

在我的代码图标下方:

<svg xmlns="http://www.w3.org/2000/svg" width="240" height="240" viewBox="0 0 120 120">
  <style>.st0{fill:#bcbbbb}.st1{fill:#f48023}  </style>
  <path class="st0" d="M84.4 93.8V70.6h7.7v30.9H22.6V70.6h7.7v23.2z"/>
  <path class="st1" d="M38.8 68.4l37.8 7.9 1.6-7.6-37.8-7.9-1.6 7.6zm5-18l35 16.3 3.2-7-35-16.4-3.2 7.1zm9.7-17.2l29.7 24.7 4.9-5.9-29.7-24.7-4.9 5.9zm19.2-18.3l-6.2 4.6 23 31 6.2-4.6-23-31zM38 86h38.6v-7.7H38V86z"/>
</svg>

动画脚本:

  1. 购物车轮廓绘制动画
  2. 用篮子填充轮廓颜色
  3. 5 条彩色条纹出现的顺序动画
  4. 条带以相反的顺序消失。
  5. 环状外观,彩色条纹消失。

这是我的尝试:

<svg id="svg1" xmlns="http://www.w3.org/2000/svg" width="240" height="240" viewBox="0 0 120 120" style="border:1px solid;">
  <style>
    .st0{fill:white; stroke:#BCBBBB; stroke-width:2;}
	.st1{fill:#f48023;opacity:1;}

  </style>
  <path class="st0"  d="M84.4 93.8V70.6h7.7v30.9H22.6V70.6h7.7v23.2z" stroke-dasharray="0,123.5 0,123.5" stroke-dashoffset="150"> 
        <!-- Cart outline drawing animation -->
     <animate id="bask" attributename="stroke-dasharray" dur="4s" begin="svg1.click" values="0,123.5 0,123.5;0,0,247,0" fill="freeze" />  
	     <!--  Filling  baskets of the icon color -->
	   <animate id="bask_fill"  attributename="fill" dur="1s" begin="bask.end" values="white;#BCBBBB" fill="freeze" />
  </path>   
  
  <path class="st1"  d="M38 86H76.6V78.3H38V86Z">
    <animateTransform attributeName="transform" type="rotate" begin="bask_fill.end" dur="4s" values="0 100 100;45 100 100;0 100 100" repeatCount="indefinite" />
   </path>	

<text x="30" y="115" font-size="14px" fill="#BCBBBB" >Click me</text>    
   </svg>

我希望彩色条纹一个接一个地出现,在最后一个条纹出现后,它们应该以相反的顺序消失。
我没有成功应用轮换来解决这个问题。

任何解决方案的帮助将不胜感激。

【问题讨论】:

    标签: javascript css svg


    【解决方案1】:

    首先我来实现题中脚本3点到5点的图标动画

    1. 彩条的外观——从opacity: 0;opacity:1;的动画

    2. 不透明度为0的彩条动画消失

    3. 然后在一个出现、消失的循环结束后,将开始重复该过程

    begin="svg1.click;Back5.end+1.5s"

    请阅读代码中的cmets

    <svg id="svg1" xmlns="http://www.w3.org/2000/svg" width="240" height="240" viewBox="0 0 120 120" style="border:1px solid;">
      <style>
        .st0{fill:#bcbbbb}.st1{fill:#f48023;opacity:0;}
    
      </style>
      <path class="st0"  d="M84.4 93.8V70.6h7.7v30.9H22.6V70.6h7.7v23.2z">
      </path>   
      
      <path class="st1"  d="M38 86H76.6V78.3H38V86Z"> 
               <!-- 3.   Animation of the appearance of the first color strip -->
           <animate id="an1" attributeName="opacity" to="1" dur="0.001s" begin="svg1.click;Back5.end+1.5s" fill="freeze" />  
                <!-- 4. The animation disappearance of the color bars of the opacity to 0 -->
             <animate id="Back1" attributeName="opacity" to="0" dur="0.001s" begin="Back2.end+0.125s" fill="freeze" />
        </path>   
      <path class="st1" d="M38.8 68.4L76.6 76.3 78.2 68.7 40.4 60.8 38.8 68.4Z" >
          <animate id="an2" attributeName="opacity" to="1" dur="0.001s" begin="an1.end+0.125s" fill="freeze" /> 
             <animate id="Back2" attributeName="opacity" to="0" dur="0.001s" begin="Back3.end+0.125s" fill="freeze" />
      </path>     
        <path class="st1" d="M43.8 50.4L78.8 66.7 82 59.7 47 43.3 43.8 50.4Z" >
           <animate id="an3" attributeName="opacity" to="1" dur="0.001s" begin="an2.end+0.125s" fill="freeze" />
             <animate id="Back3" attributeName="opacity" to="0" dur="0.001s" begin="Back4.end+0.125s" fill="freeze" />
      </path>   
        
      <path class="st1"  d="M53.5 33.2L83.2 57.9 88.1 52 58.4 27.3 53.5 33.2Z" >
          <animate id="an4" attributeName="opacity" to="1" dur="0.001s" begin="an3.end+0.125s" fill="freeze" />
            <animate id="Back4" attributeName="opacity" to="0" dur="0.001s" begin="Back5.end+0.125s" fill="freeze" />
      </path>
      
      <path class="st1"  d="M72.7 14.9L66.5 19.5 89.5 50.5 95.7 45.9 72.7 14.9Z" >
         <animate id="an5" attributeName="opacity" dur="0.001s" to="1" begin="an4.end+0.125s" fill="freeze" /> 
           <animate id="Back5" attributeName="opacity" dur="0.001s" to="0"  begin="an5.end+1s" fill="freeze" />
      </path>      
      
       <text x="30" y="115" font-size="14px" fill="#BCBBBB" >Click me</text>  
    </svg>

    循环图标动画

    1. 等高线绘制基于改变 stroke-dasharray 参数

    2. 从背景颜色到篮子颜色图标的轮廓填充

    <path class="st0"  d="M84.4 93.8V70.6h7.7v30.9H22.6V70.6h7.7v23.2z" stroke-dasharray="0,123.5 0,123.5" stroke-dashoffset="150"> 
            <!-- Cart outline drawing animation -->
         <animate id="bask" attributename="stroke-dasharray" dur="4s" begin="svg1.click" values="0,123.5 0,123.5;0,0,247,0" fill="freeze" />  
             <!--  Filling  baskets of the icon  color -->
           <animate id="bask_fill"  attributename="fill" dur="1s" begin="bask.end" values="white;#BCBBBB" fill="freeze" />
      </path>   
    

    下面是stackoverflow图标的完整代码

    <svg id="svg1" xmlns="http://www.w3.org/2000/svg" width="240" height="240" viewBox="0 0 120 120" style="border:1px solid;">
      <style>
        .st0{fill:white; stroke:#BCBBBB; stroke-width:2;}
        .st1{fill:#f48023;opacity:0;}
    
      </style>
      <path class="st0"  d="M84.4 93.8V70.6h7.7v30.9H22.6V70.6h7.7v23.2z" stroke-dasharray="0,123.5 0,123.5" stroke-dashoffset="150"> 
            <!-- Cart outline drawing animation -->
         <animate id="bask" attributename="stroke-dasharray" dur="4s" begin="svg1.click" values="0,123.5 0,123.5;0,0,247,0" fill="freeze" restart="never" />  
             <!--  Filling  baskets of the icon color -->
           <animate id="bask_fill"  attributename="fill" dur="1s" begin="bask.end" values="white;#BCBBBB" fill="freeze" restart="whenNotActive" />
      </path>   
       
      
        <path class="st1"  d="M38 86H76.6V78.3H38V86Z"> 
             <!--  Animation of the appearance of the first color strip -->
               <!--  Looping appearance, fading bands `begin="bask_fill.end;Back5.end+1.5s` -->
           <animate id="an1" attributeName="opacity" to="1" dur="0.001s" begin="bask_fill.end;Back5.end+1.5s" fill="freeze" restart="whenNotActive" /> 
                <!--  Animation of the disappearance of the first color strip -->
             <animate id="Back1" attributeName="opacity" to="0" dur="0.001s" begin="Back2.end+0.125s" fill="freeze" restart="whenNotActive" />
        </path>   
      <path class="st1" d="M38.8 68.4L76.6 76.3 78.2 68.7 40.4 60.8 38.8 68.4Z" >
             <!--  Animation of the appearance of the second colored strip -->
           <animate id="an2" attributeName="opacity" to="1" dur="0.001s" begin="an1.end+0.125s"
               fill="freeze" restart="whenNotActive" />     <!--  Animation of the disappearance of the second colored strip -->
             <animate id="Back2" attributeName="opacity" to="0" dur="0.001s"
                 begin="Back3.end+0.125s"  fill="freeze" restart="whenNotActive" />
      </path>     
        <path class="st1" d="M43.8 50.4L78.8 66.7 82 59.7 47 43.3 43.8 50.4Z" >
           <animate id="an3" attributeName="opacity" to="1" dur="0.001s" begin="an2.end+0.125s"
               fill="freeze" restart="whenNotActive" />
             <animate id="Back3" attributeName="opacity" to="0" dur="0.001s"
                 begin="Back4.end+0.125s" fill="freeze" restart="whenNotActive" />
      </path>   
        
      <path class="st1"  d="M53.5 33.2L83.2 57.9 88.1 52 58.4 27.3 53.5 33.2Z" >
          <animate id="an4" attributeName="opacity" to="1" dur="0.001s" begin="an3.end+0.125s" fill="freeze" />
            <animate id="Back4" attributeName="opacity" to="0" dur="0.001s" begin="Back5.end+0.125s" fill="freeze" />
      </path>
      
      <path class="st1"  d="M72.7 14.9L66.5 19.5 89.5 50.5 95.7 45.9 72.7 14.9Z" >
         <animate id="an5" attributeName="opacity" dur="0.001s" to="1" begin="an4.end+0.125s" fill="freeze" /> 
           <animate id="Back5" attributeName="opacity" dur="0.001s" to="0"  begin="an5.end+1s" fill="freeze" />
      </path> 
        <text x="30" y="115" font-size="14px" fill="#BCBBBB" >Click me</text>  
    </svg>

    其他配色方案

    .container {
         width:30vw;
         height:30vh;
         }
        .st0{
        fill:#005999;
        stroke:white;
        stroke-width:2;}
        .st1 {
        fill:white;
        opacity:0;
        }
    <div class="container">
    <svg id="svg1" xmlns="http://www.w3.org/2000/svg"  viewBox="0 0 120 120" style="border:1px solid;">
      
        
        <rect width="100%" height="100%" fill="#005999" />
      <path class="st0"  d="M84.4 93.8V70.6h7.7v30.9H22.6V70.6h7.7v23.2z" 
            stroke-dasharray="0,123.5 0,123.5"   stroke-dashoffset="150"> 
            
         <animate id="bask" attributename="stroke-dasharray" dur="4s" begin="svg1.click" values="0,123.5 0,123.5;0,0,247,0" fill="freeze" restart="never" />  
             
           <animate id="bask_fill"  attributename="fill" dur="1s" begin="bask.end"
               values="#005999;white" fill="freeze" restart="whenNotActive" />
      </path>   
        
        <path class="st1"  d="M38 86H76.6V78.3H38V86Z"> 
             
           <animate id="an1" attributeName="opacity" to="1" dur="0.001s"
               begin="bask_fill.end;Back5.end+1.5s" fill="freeze" restart="whenNotActive" /> 
                
             <animate id="Back1" attributeName="opacity" to="0" dur="0.001s"
                 begin="Back2.end+0.125s" fill="freeze" restart="whenNotActive" />
        </path>   
      <path class="st1" d="M38.8 68.4L76.6 76.3 78.2 68.7 40.4 60.8 38.8 68.4Z" >
             
           <animate id="an2" attributeName="opacity" to="1" dur="0.001s" 
             begin="an1.end+0.125s" fill="freeze" restart="whenNotActive" />    
             <animate id="Back2" attributeName="opacity" to="0" dur="0.001s" begin="Back3.end+0.125s" fill="freeze" restart="whenNotActive" />
      </path>     
        <path class="st1" d="M43.8 50.4L78.8 66.7 82 59.7 47 43.3 43.8 50.4Z" >
           <animate id="an3" attributeName="opacity" to="1" dur="0.001s" begin="an2.end+0.125s" fill="freeze" />
             <animate id="Back3" attributeName="opacity" to="0" dur="0.001s" begin="Back4.end+0.125s" fill="freeze" restart="whenNotActive" />
      </path>   
        
      <path class="st1"  d="M53.5 33.2L83.2 57.9 88.1 52 58.4 27.3 53.5 33.2Z" >
          <animate id="an4" attributeName="opacity" to="1" dur="0.001s" begin="an3.end+0.125s" fill="freeze" />
            <animate id="Back4" attributeName="opacity" to="0" dur="0.001s" begin="Back5.end+0.125s" fill="freeze" restart="whenNotActive" />
      </path>
      
      <path class="st1"  d="M72.7 14.9L66.5 19.5 89.5 50.5 95.7 45.9 72.7 14.9Z" >
         <animate id="an5" attributeName="opacity" dur="0.001s" to="1"
         begin="an4.end+0.125s" fill="freeze" restart="whenNotActive"/> 
           <animate id="Back5" attributeName="opacity" dur="0.001s" to="0" 
               begin="an5.end+1s" fill="freeze" restart="whenNotActive" />
      </path>   
          <text x="38" y="115" font-size="10px" fill="white" >Click me</text>  
    </svg>
    </div>

    【讨论】:

    • 我认为,在&lt;defs&gt; 部分中使用单个条形实体并通过旋转和位移对其进行&lt;use&gt; 可以显着减少代码。
    【解决方案2】:

    let s = c.width, // icon size
      w = s / 2.3, // block width
      h = s / 13, // block height
      start = Date.now(), // start time stamp
      fall = 900, // fall duration
      spring=200, // spring duration
      jump = 2000, // jump duration
      jumpDelay = 2700, // jump delay
      delay = i => i * (600 - i * 50), // block delay func
      clamp = (v, t) => Math.min(1, Math.max(0, v) / t), // clamp to 0-1 interval
      ctx = c.getContext("2d");
    
    function draw() {
      let time = Date.now() - start; // frame timestamp 
      ctx.clearRect(0, 0, s, s); // clear
      ctx.fillStyle = "white"; // fill color
    
      // blocks
      [0, 1, 2, 3, 4].forEach(block => {
    
        // fall
        let t = clamp(time - delay(block), fall); // fall time
        let y = s * (t * t * t * 1.5 - 1.65 - .1 * block); // fall easing y = t^3
    
        // spring effect
        for (let i = 0; i < 5; i++) { // 5 times
          t = clamp(time - fall - delay(i), spring) - .6; // spring time
          y += (1 - t * t) * s * .09; // easing y = 1 - t^2
        }
    
        // jump
        t = clamp(time - jumpDelay, jump); // jump time
        // funny easing func "elastic"
        t = Math.pow(2, -10 * t) * Math.sin((t - .4 / 4) * (2 * Math.PI) / .4) + 1;
        let r = t * block * .075 * Math.PI; // block angle
        let x = s * .6 - Math.cos(r) * s * .6; // block x
        y -= Math.sin(r) * s * .6 - s * .1 * block * t; // block y
    
        // draw blocks
        ctx.save();
        ctx.translate(s / 2 + x, s / 2 + y);
        ctx.rotate(r);
        ctx.fillRect(-w / 2, -h / 2, w, h);
        ctx.restore();
      });
    
      // bin
      let y = s * 0.14;
      [
        [-w / 2 - h * 2, y, h, s * 0.25],
        [w / 2 + h, y, h, s * 0.25],
        [-w / 2 - h * 2, y + s * 0.2, w + h * 4, h]
      ]
      .forEach(r => ctx.fillRect(s / 2 + r[0], s / 2 + r[1], r[2], r[3]));
    
      requestAnimationFrame(draw);
    }
    
    addEventListener('click', () => start = Date.now());
    draw();
    &lt;canvas id=c width=175 height=175 style='background:steelblue'&gt;&lt;canvas&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-09
      • 1970-01-01
      • 2011-05-19
      • 2020-05-27
      • 2015-04-06
      • 1970-01-01
      • 2017-01-29
      相关资源
      最近更新 更多