代码之家  ›  专栏  ›  技术社区  ›  adardesign

用SVG或画布使向量元素像钟摆一样摆动?

  •  0
  • adardesign  · 技术社区  · 14 年前

    我有一个图像,我想在我的网页动画。

    http://dev.thepenline.com/TEMP/Hol_10_swingingBell.gif

    我想对它的动画有更多的控制,哪个js lib/framework最适合帮助我?

    哪个(小)图书馆最好用?

    我碰巧知道一点 raphael.js

    4 回复  |  直到 14 年前
        1
  •  5
  •   jbeard4    14 年前

    我用SVG做了一些事情,这接近于您想要实现的目标: http://live.echo-flow.com/stackoverflow/clock.svg

    以防我把这个例子拿下来,这是相关的代码。

    <?xml version="1.0"?>
    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" viewBox="0 0 100 100">
    
    <rect x="0" y="0" height="100" width="100" fill="none" stroke="blue" id="border"/>
    
    <script type="text/ecmascript" xlink:href="clock.js"></script>
    
    </svg>
    

    时钟.js:

    var svgRoot = document.documentElement;
    var svgNS = "http://www.w3.org/2000/svg";
    
    var ident = svgRoot.createSVGMatrix();
    
    function Pendulum(thetaZero,period,tempo,fillColor){
    
            //sensible default values
            thetaZero = thetaZero || 0;
            period = period || 20;
            tempo = tempo || 20;
            fillColor = fillColor || "red";
    
            if(fillColor == "randomize"){
                    fillColor = "rgb(" + Math.random() * 254 +
                                    "," + Math.random() * 254 +
                                    "," + Math.random() * 254 + ")";
            }
    
            //construct his representation in DOM
            var g = document.createElementNS(svgNS,"g");
            g.setAttributeNS(null,"transform","translate(50,20) rotate(" + thetaZero + ")");
    
            var rotateTransform = g.transform.baseVal.getItem(1);
    
            var path = document.createElementNS(svgNS,"line");
            path.setAttributeNS(null,"x1",0);
            path.setAttributeNS(null,"y1",0);
            path.setAttributeNS(null,"x2",0);
            path.setAttributeNS(null,"y2",40);
            path.setAttributeNS(null,"stroke","black");
    
            var c = document.createElementNS(svgNS,"circle");
            var styleString = "fill:" +fillColor;
            //console.log(styleString);
            c.setAttributeNS(null,"cx",0);
            c.setAttributeNS(null,"cy",50);
            c.setAttributeNS(null,"r",10);
            c.setAttributeNS(null,"style",styleString);
            c.setAttributeNS(null,"stroke","black");
            c.setAttributeNS(null,"opacity",.5);
            g.appendChild(path);
            g.appendChild(c);
    
            svgRoot.appendChild(g);
    
            this.node=g;
    
            //timeout
    
            var timeStep = 10; //in milliseconds
            var timeCount = 0;
            var _animateTimeStep = function(){
                    timeCount++;
    
                    var adjustedTimeCount = timeCount/tempo;
    
                    //compute theta
                    //theta(t) = period * sin(t + thetaZero)
                    var theta = period * Math.sin(adjustedTimeCount  + thetaZero);
    
                    //set his current rotate transformation to the new theta
                    rotateTransform.setMatrix(ident.rotate(theta));
            }
    
            var timerId = null;
    
            //method definitions
            this.go=function(){
                    timerId = window.setInterval(_animateTimeStep,timeStep);
            };
    
            this.stop=function(){
                    window.clearInterval(timerId);
            };
    }
    
    
    //Pendulum(thetaZero,period,tempo,fillColor)
    var p1 = new Pendulum(-10,20,40,"red");
    p1.go();
    
    var p2 = new Pendulum(20,20,40,"yellow");
    p2.go();
    
    var p3 = new Pendulum(-20,20,40,"blue");
    p3.go();
    
    var p4 = new Pendulum(10,20,40,"purple");
    p4.go();
    
        2
  •  1
  •   Han Seoul-Oh    14 年前

    var img = paper.image("image.png", 10, 10, 80, 80);
    (function swingRight(){
      img.animate({'rotation': 30}, 1000, '<>', function swingLeft(){
        img.animate({'rotation': -30}, 1000, '<>', swingRight);
      });
    }());
    
        3
  •  1
  •   user372551 user372551    14 年前

    使用画布

    window.onload    = function() {
      var canvas   = document.getElementById('canvas');
      var ctx      = canvas.getContext('2d');
      var width    = canvas.width = 500;
      var height   = canvas.height  = 300;
      var fixedx   = width/2;
      var fixedy   = 20;
      var radius   = 150;
      var dir      = 2;
      var minangle = 45;
      var maxangle = 135;
      var color = rgb();  
      var x = minangle;
      (draw = function() {
        var posx = fixedx + radius * Math.cos(x * Math.PI / 180);
        var posy = fixedy + radius * Math.sin(x * Math.PI / 180);
    
        with(ctx) {
          fillStyle   = '#000';
          fillRect(0, 0, width, height);
          fill();
          beginPath();
          strokeStyle = '#fff';
          moveTo(fixedx, fixedy);
          lineWidth   = 5;
          lineCap     = 'round';
          lineTo(posx, posy);  
          stroke();
          closePath();
          beginPath();  
          fillStyle   = color;
          arc(posx, posy, 20, 0, Math.PI * 2, 0);
          fill();
          closePath();
        }  
        x += 1 * dir;
        if(x >= maxangle || x <= minangle) {
          dir = -dir;
          if(Math.abs(dir) == dir) {
            color = rgb();
          }  
        }
        setTimeout(draw, 1000/30);    
      })();
    
      function rgb() {
        var clr = 'rgb(';
        for(var i =0; i< 3; i++) {
          clr  += Math.floor(Math.random() * 255) + ',';
        }
        return clr.replace(/\,$/,')');
      }
    };
    

    Simple Demo

        4
  •  1
  •   mortalis    7 年前

    CodePen

    HTML格式:

    <svg id="clock" viewBox="0 0 100 100" width="500" height="500"> 
      <circle id="face" cx="50" cy="50" r="45"/>  
      <g id="pendulum">
        <line id="stick" x1="50" y1="50" x2="50" y2="80"/>
        <circle id="end" cx="50" cy="85" r="5"/>  
      </g>
    </svg>
    

    var amplitude=90,startAngle=90,wtime=700,timeout=40
    var animation,start,correction,running=false
    
    var pendulum = document.getElementById("pendulum")
    pendulum.setAttribute("transform", "rotate(" + startAngle + ",50,50)")
    
    correction=2*Math.asin(startAngle/amplitude)
    start=(new Date()).getTime()
    movePendulum()
    
    function movePendulum(){
        var angle
        var pi=Math.PI,sin=Math.sin,asin=Math.asin,abs=Math.abs
    
        var now=(new Date()).getTime()
        var time=now-start
        time=time/wtime
        time=(time-correction)/2
    
        var easeVal=sin(time)
        angle=-amplitude*easeVal
    
        var pendulum = document.getElementById("pendulum")
        pendulum.setAttribute("transform", "rotate(" + angle + ",50,50)")
        animation=setTimeout(movePendulum,timeout)
    }