动画矢量元素像摆锤一样摆动SVG或画布?

时间:2010-11-07 21:56:35

标签: animation canvas svg

我有一张图片,我想在我的网页上制作动画。

目前我正在使用gif。

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

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

我应该使用canvas还是SVG? 哪个(小)库最好用?

我碰巧知道一点raphael.js 但我不确定如何完成这个效果。

4 个答案:

答案 0 :(得分:5)

我已经做了一些与你想要实现的接近的SVG:http://live.echo-flow.com/stackoverflow/clock.svg

如果我举起这个例子,这是相关的代码。

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>

clock.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();

答案 1 :(得分:1)

使用Raphael.js,您可以这样做:

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);
  });
}());

答案 2 :(得分:1)

使用画布

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

答案 3 :(得分:1)

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>

JS:

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)
}