如何沿路徑為 Raphael 對象設置動畫? (How to animate a Raphael object along a path?)


問題描述

如何沿路徑為 Raphael 對象設置動畫? (How to animate a Raphael object along a path?)

The object could be simple, a rect or circle. But the path should be a bezier curve. Please provide javascript/Raphael code if not too much trouble.

It will be nice if there is trailing effect of the moving object during annimation.


參考解法

方法 1:

Just in case you are trying to use this with RaphaelJS 2 (animateAlong doesn't exist anymore), here you can see a possible solution: http://jsfiddle.net/gyeSf/17/.

And here the original discussion: https://groups.google.com/forum/#!searchin/raphaeljs/animatealong/raphaeljs/W9bA0SkArVY/KnPRKi8uFrsJ

Edit: And here another example: http://raphaeljs.com/gear.html

方法 2:

Just use the .animateAlong() method.

It takes 4 arguments: 

  1. path - object or string path element or path string along which the element will be animated  
  2. ms - number - The duration of the animation, given in milliseconds.  
  3. rotate - boolean - [optional] if true, element will be rotated along the path  
  4. callback -  function - [optional]

Essentially from the documentation:

window.onload = function() {
    var r = Raphael("canvas", 200, 200), 
        p = r.path("M10,50C10,100,90,0,90,50C90,100,10,0,10,50Z")
             .attr({stroke: "#ddd"}),
        e = r.ellipse(10, 50, 4, 4).attr({stroke: "none", fill: "#f00"});
    r.rect(0, 0, 200, 200).attr({stroke: "none", fill: "#000", opacity: 0})
     .click(function () {
         e.attr({rx: 5, ry: 3})
          .animateAlong(p, 4000, true, function () {        // Animate along path
              e.attr({rx: 4, ry: 4});
          });
     });
}​;

Try it out with this jsFiddle (click to activate)

方法 3:

There's a nice solution here.

I've copied the code below:

/*

You can copy and paste the below into your codebase somewhere.
As long as Raphael is a global object, it'll just work.

USAGE (same default values for optional parameters as Raphaël's "animate" method)
=====
element.animateAlong({
    path: REQUIRED - Path data string or path element,
    rotate: OPTIONAL - Boolean whether to rotate element with the direction it is moving
                       (this is a beta feature - currently kills existing transformations
                        and rotation may not be perfect),
    duration: OPTIONAL - Number in milliseconds,
    easing: OPTIONAL - String (see Raphaël's docs),
    debug: OPTIONAL - Boolean, when set to true, paints the animating path, which is
                      helpful if it isn't already rendered to the screen
},
props - Object literal containing other properties to animate,
callback - Function where the "this" object refers to the element itself
);

EXAMPLE
=======
var rect = paper.rect(0,0,50,50);
rect.animateAlong({
    path: "M0,0L100,100",
    rotate: true,
    duration: 5000,
    easing: 'ease-out',
    debug: true
},
{
    transform: 's0.25',
    opacity: 0
},
function() {
    alert("Our opacity is now:" + this.attr('opacity'));
});

*/

Raphael.el.animateAlong = function(params, props, callback) {
    var element = this,
        paper = element.paper,
        path = params.path,
        rotate = params.rotate,
        duration = params.duration,
        easing = params.easing,
        debug = params.debug,
        isElem = typeof path !== 'string';

    element.path = 
        isElem
            ? path
            : paper.path(path);
    element.pathLen = element.path.getTotalLength();
    element.rotateWith = rotate;

    element.path.attr({
        stroke: debug ? 'red' : isElem ? path.attr('stroke') : 'rgba(0,0,0,0)',
        'stroke-width': debug ? 2 : isElem ? path.attr('stroke-width') : 0
    });

    paper.customAttributes.along = function(v) {
        var point = this.path.getPointAtLength(v * this.pathLen),
            attrs = {
                x: point.x,
                y: point.y 
            };
        this.rotateWith && (attrs.transform = 'r'+point.alpha);
        // TODO: rotate along a path while also not messing
        //       up existing transformations

        return attrs;
    };

    if(props instanceof Function) {
        callback = props;
        props = null;
    }
    if(!props) {
        props = {
            along: 1
        };
    } else {
        props.along = 1;    
    }

    var startAlong = element.attr('along') || 0;

    element.attr({along: startAlong}).animate(props, duration, easing, function() {
        !isElem && element.path.remove();

        callback && callback.call(element);
    });
};

方法 4:

It seems that you cant do that using Raphaёl animate() method (since it changes object attributes linearly).

I would offer you to implement a function that changes object position each millisecond or so according to Bézier curve formula. Use Raphaёl translate() method and JavaScript timers.

(by jasonwelJosé M. GilgadoPeter AjtaiRichardaztek)

參考文件

  1. How to animate a Raphael object along a path? (CC BY-SA 3.0/4.0)

#raphael #jquery #javascript






相關問題

如何沿路徑為 Raphael 對象設置動畫? (How to animate a Raphael object along a path?)

Raphaël.js:如何縮放圓形的填充圖像以適合圓形? (Raphaël.js: How to scale a circle's fill image to fit the circle?)

如何通過“raphael-svg-import”加載和顯示 SVG 數據? (How to load and display SVG data by "raphael-svg-import"?)

gRaphael 餅圖:添加動畫 (gRaphael Pie Chart : Add animation)

如何在服務器端 Java 中使用 JavaScript 圖表庫,如 D3.js 或 Raphaël (How to use a JavaScript chart library like D3.js or Raphaël in server-side Java)

raphael newbie:彈窗背景在跳躍 (raphael newbie: popup background is jumping)

如何製作流暢的圓弧動畫? (How to create smooth circular arcing animation?)

拉斐爾對角變換對象和無限setIntervals (Raphael transform object diagonally and infinite setIntervals)

Raphael JS 服務器端 (Raphael JS server-side)

Raphael.js:在我的情況下如何拖動路徑的一側? (Raphael.js : How to drag one side of the path in my case?)

如何用 raphael js 繪製曲線? (How to draw curves with raphael js?)

如何用拉斐爾垂直縮放? (How to vertically scale with Raphael?)







留言討論