【问题标题】:svg gradient fill animation percentage jquerysvg 渐变填充动画百分比 jquery
【发布时间】:2019-06-27 08:29:45
【问题描述】:

我正在尝试使用 jquery 获得一些 svg 动画,对于每个“检查”类,我需要对渐变的百分比偏移求和,当删除此类时需要减少百分比偏移渐变。这一切都需要在添加类时向下动画,在移除类时向上向下动画。

所以我得到了,渐变并获得 5% 百分比的偏移量。试图获得阵列但卡住了。考虑使用类“检查”获取所有元素并尝试对每个类求和。

 var firstStop = document.getElementById('F1gst1');
 percentage = '5%'; firstStop.setAttribute('offset',percentage);

$(".analysis-li").click(function(){

       $(this).toggleClass("check");
          if($(this).hasClass('check')){
        
          }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

    <li class="analysis-li"></li>
    <li class="analysis-li"></li>
    <li class="analysis-li"></li>
    <li class="list analysis-li"></li>
    <li class="analysis-li"></li>
    <li class="list analysis-li"></li>
    <li class="analysis-li" ></li>
 
    <svg class="thermometr" id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 44.3 333.8">
                <linearGradient y2="0%" x2="0%" y1="100%" x1="0%" id="F1g"><stop stop-color="#00FF00" offset="0%" id="F1gst1"/><stop stop-color="#FFFFFF" offset="0%" id="F1gst2"/></linearGradient>
                <path fill="url(#F1g)" class="st0" d="M30.5 297.5V4.6c0-2.5-2.1-4.6-4.6-4.6-2.5 0-4.6 2.1-4.6 4.6v292.9c-7.9 2-13.8 9.2-13.8 17.8 0 10.2 8.2 18.4 18.4 18.4s18.4-8.2 18.4-18.4c0-8.5-5.9-15.7-13.8-17.8"/><path fill="url(#F1g)" class="st0"  d="M9 290.2h7.5v.5H9zM9 284.3h7.5v.6H9zM9 278.4h7.5v.5H9zM9 272.5h7.5v.6H9zM0 266.6h16.5v.6H0zM9 260.7h7.5v.5H9zM9 254.8h7.5v.6H9zM9 248.9h7.5v.5H9zM9 243h7.5v.6H9zM0 237.1h16.5v.6H0zM9 231.3h7.5v.5H9zM9 225.4h7.5v.6H9zM9 219.5h7.5v.6H9zM9 213.6h7.5v.6H9zM0 207.7h16.5v.6H0zM9 201.8h7.5v.6H9zM9 195.9h7.5v.6H9zM9 190h7.5v.6H9zM9 184.1h7.5v.5H9zM0 178.2h16.5v.6H0zM9 172.3h7.5v.6H9zM9 166.4h7.5v.5H9zM9 160.5h7.5v.6H9zM9 154.7h7.5v.6H9zM0 148.8h16.5v.6H0zM9 142.9h7.5v.6H9zM9 137h7.5v.5H9zM9 131.1h7.5v.5H9zM9 125.2h7.5v.6H9zM0 119.3h16.5v.5H0zM9 113.4h7.5v.6H9zM9 107.5h7.5v.6H9zM9 101.6h7.5v.5H9zM9 95.7h7.5v.6H9zM0 89.8h16.5v.6H0zM9 83.9h7.5v.6H9zM9 78.1h7.5v.6H9zM9 72.2h7.5v.6H9zM9 66.3h7.5v.6H9zM0 60.4h16.5v.6H0zM9 54.8h7.5v.6H9zM9 48.9h7.5v.6H9zM9 43h7.5v.5H9zM9 37.1h7.5v.6H9zM0 31.2h16.5v.5H0zM9 26h7.5v.6H9zM9 20.1h7.5v.5H9zM9 14.2h7.5v.6H9zM9 8.3h7.5v.6H9zM0 2.4h16.5V3H0z"/>
    </svg>

【问题讨论】:

    标签: javascript jquery svg linear-gradients


    【解决方案1】:

    我会这样做。为了使渐变动画化,我使用了requestAnimationFrame。我正在为 10% 和 100% 之间的第二个停止偏移设置动画,但您可以选择所需的值。

    请阅读代码中的cmets。

     // the second stop
     let laststop = document.getElementById('F1gst2');
     // a variable used to toggle the animation
     let n = 0;
     // the target value of the offset attribute
     let target;
     // the actual value of the offset attribute
     let val = 10;
     //the request animation frame id
     let rid = null;
    
    $(".analysis-li").click(function(){
       
       n++;
       // set the target value
       if(n%2 == 1){
         target = 100; 
       }else{target = 10}
        // if there is an animation stop it  
        if(rid){cancelAnimationFrame(rid); rid="null"}
        // call the frame function
        frame()      
    });
    
    
    function frame(){
      rid = requestAnimationFrame(frame);
      //the distance between the value and the target value
      dist = target - val;
      //increase the value
      val += dist/10;
      // set the offset value
      laststop.setAttributeNS(null,"offset",`${val}%`)
    }
    svg{border:1px solid; width:30px}
    path{stroke:black;}
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <p class="analysis-li">click here</p>
    <svg class="thermometr" id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 44.3 333.8" >
                    <linearGradient y2="0%" x2="0%" y1="100%" x1="0%" id="F1g">
                      <stop stop-color="#00FF00" offset="0%" id="F1gst1"/>
                      <stop stop-color="#FFFFFF" offset="10%" id="F1gst2"/>
                    </linearGradient>
                    <path fill="url(#F1g)" class="st0" d="M30.5 297.5V4.6c0-2.5-2.1-4.6-4.6-4.6-2.5 0-4.6 2.1-4.6 4.6v292.9c-7.9 2-13.8 9.2-13.8 17.8 0 10.2 8.2 18.4 18.4 18.4s18.4-8.2 18.4-18.4c0-8.5-5.9-15.7-13.8-17.8"/>
      <path fill="url(#F1g)" class="st0"  d="M9 290.2h7.5v.5H9zM9 284.3h7.5v.6H9zM9 278.4h7.5v.5H9zM9 272.5h7.5v.6H9zM0 266.6h16.5v.6H0zM9 260.7h7.5v.5H9zM9 254.8h7.5v.6H9zM9 248.9h7.5v.5H9zM9 243h7.5v.6H9zM0 237.1h16.5v.6H0zM9 231.3h7.5v.5H9zM9 225.4h7.5v.6H9zM9 219.5h7.5v.6H9zM9 213.6h7.5v.6H9zM0 207.7h16.5v.6H0zM9 201.8h7.5v.6H9zM9 195.9h7.5v.6H9zM9 190h7.5v.6H9zM9 184.1h7.5v.5H9zM0 178.2h16.5v.6H0zM9 172.3h7.5v.6H9zM9 166.4h7.5v.5H9zM9 160.5h7.5v.6H9zM9 154.7h7.5v.6H9zM0 148.8h16.5v.6H0zM9 142.9h7.5v.6H9zM9 137h7.5v.5H9zM9 131.1h7.5v.5H9zM9 125.2h7.5v.6H9zM0 119.3h16.5v.5H0zM9 113.4h7.5v.6H9zM9 107.5h7.5v.6H9zM9 101.6h7.5v.5H9zM9 95.7h7.5v.6H9zM0 89.8h16.5v.6H0zM9 83.9h7.5v.6H9zM9 78.1h7.5v.6H9zM9 72.2h7.5v.6H9zM9 66.3h7.5v.6H9zM0 60.4h16.5v.6H0zM9 54.8h7.5v.6H9zM9 48.9h7.5v.6H9zM9 43h7.5v.5H9zM9 37.1h7.5v.6H9zM0 31.2h16.5v.5H0zM9 26h7.5v.6H9zM9 20.1h7.5v.5H9zM9 14.2h7.5v.6H9zM9 8.3h7.5v.6H9zM0 2.4h16.5V3H0z"/>
        </svg>

    【讨论】:

      【解决方案2】:

      SVG 以编程方式创建,传入值仅转换一个形状:

      let path = (y, d, extra) => `<path d="${d}" transform="translate(0,${y})" ${extra||''}></path>`
      let multi = (count, html) => Array(count).fill(0).map((e, i) => html(i)).join('');
      let toggle = el => el.classList.toggle('on') | 
         rect.setAttribute('y', 14.6*(7-document.querySelectorAll("path.on").length)+8)
      scale.innerHTML = multi(10, i => path(i*10, 'M60,10h10M65,12h5M65,14h5M65,16h5M65,18h5'));
      checks.innerHTML = multi(7, i => path(i*12, 'M10,10v8h8v-8z', 'class="on" onclick="toggle(this)"') +
                                       path(i*12, 'M12,14l2.2,2l2.2,-4'))
      g#scale path { 
        stroke: white; 
        stroke-width: 0.7; 
      }
      
      #checks { 
        position: absolute; 
        top: 20px; 
        left: 20px; 
      }
      
      #checks path {
        fill: none;
        pointer-events: all;
        stroke: #f5b53a;
        cursor:pointer;
        stroke-linejoin:round;
      }
      
      #checks path.on + path {
        opacity:1;
      }
      
      #checks path:nth-child(2n) {
       opacity: 0;
       pointer-events: none;
       transition: 0.5s;
       stroke: white;
      }
      <svg viewbox="0 0 135 135" height="90vh" style="background-color:purple">
        <defs><mask id="termometer">
          <path d="M80,10v100" stroke="white" stroke-width="5" stroke-linecap="round"></path>
          <circle r="10" cy="120" cx="80" fill="white"></circle>
          <g id="scale"></g>
        </mask></defs>
        <rect width="130" height="130" mask="url(#termometer)" fill="white"></rect>
        <rect id="rect" style="transition:1s" y="8" width="130" height="130" 
              mask="url(#termometer)" fill="#f5b53a"></rect>
        <g id="checks"></g>
      </svg>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-06-15
        • 2021-10-24
        • 2021-12-05
        • 2020-03-16
        • 1970-01-01
        • 1970-01-01
        • 2016-09-16
        • 2022-01-19
        相关资源
        最近更新 更多