拉菲尔(viewbox)动态缩放动画

3

我正在用JavaScript和Raphael库构建一种JavaScript地图。当点击对象时,我能够缩放它,但是我希望它可以动画化(比如慢慢地深入等)。有没有方法可以在不重复制造轮子的情况下实现这个目标?


1
请参考类似问题:https://dev59.com/IGsz5IYBdhLWcg3wrJ0x - Joan Charmant
我的意思更多的是像“animate(...)”这样的方式,这样我就可以做更多不仅仅是平滑缩放。 - Almog Dubin
我觉得你应该回去再看一下Joan的链接——@patrics的答案(如果你问我的话,也同样值得采纳!)看起来非常符合你的需求。添加缓动函数也很简单明了... - Kevin Nielsen
2个回答

6

SVG对象的视图框(viewbox)可以被动画化,没有任何理由不能这样做--Raphael只是默认没有提供这样的功能。不过,创建一个插件是相当简单的。例如:

Raphael.fn.animateViewBox = function animateViewBox( x, y, w, h, duration, easing_function, callback )
{
    var cx = this._viewBox ? this._viewBox[0] : 0,
        dx = x - cx,
        cy = this._viewBox ? this._viewBox[1] : 0,
        dy = y - cy,
        cw = this._viewBox ? this._viewBox[2] : this.width,
        dw = w - cw,
        ch = this._viewBox ? this._viewBox[3] : this.height,
        dh = h - ch,
        self = this;;
    easing_function = easing_function || "linear";

    var interval = 25;
    var steps = duration / interval;
    var current_step = 0;
    var easing_formula = Raphael.easing_formulas[easing_function];

    var intervalID = setInterval( function()
        {
            var ratio = current_step / steps;
            self.setViewBox( cx + dx * easing_formula( ratio ),
                             cy + dy * easing_formula( ratio ),
                             cw + dw * easing_formula( ratio ),
                             ch + dh * easing_formula( ratio ), false );
            if ( current_step++ >= steps )
            {
                clearInterval( intervalID );
                callback && callback();
            }
        }, interval );
}

任何在安装此插件后实例化的图纸都可以像Raphael内置的animate方法一样使用animateViewBox。例如...
var paper = Raphael( 0, 0, 640, 480 );
paper.animateViewBox( 100, 100, 320, 240, 5000, '<>', function()
    {
        alert("View box updated!  What's next?" );
    } );

演示在这里展示。


太棒了!但是现在我遇到了一个新的问题。 - Almog Dubin
很高兴看到新问题被轻松解决了! - Kevin Nielsen

0

Raphael动画通过动画元素属性来工作。当您调用element.animate时,您提供最终对象参数、到达时间以及可能的缓动函数(如果您不希望它是线性的)。

例如,要缩放圆形,您可以考虑使用此示例:http://jsfiddle.net/eUfCg/

// Creates canvas 320 × 200 at 10, 50
var paper = Raphael(10, 50, 320, 200);

// Creates circle at x = 50, y = 40, with radius 10
var circle = paper.circle(50, 40, 10);
// Sets the fill attribute of the circle to red (#f00)
circle.attr("fill", "#f00");

// Sets the stroke attribute of the circle to white
circle.attr("stroke", "#fff");


var zoomed = false;

circle.click(function () { 
    if (zoomed) {
        this.animate({ transform: "s1" }, 500);
        zoomed = false;
    } else {
        this.animate({ transform: "s4" }, 500);
        zoomed = true;
    }
});​

这段代码涉及到圆形的变换属性。如果要缩放地图,您应该将所有元素放在一个组内,并动画化组的变换属性,考虑您想要达到的比例和平移。

有关变换属性的更多信息,请参见http://raphaeljs.com/reference.html#Element.transform


这对于单个对象来说是可以的,但对于多个对象来说,它们只会增长而不会移动。 - Almog Dubin
你可以使用 paper.set() 将所有内容放入一个集合中,并对该集合进行缩放。因此,它只适用于一个对象,但你可以将所有内容分组到一个对象中。 - Matt Esch
另外,还有许多实现动画视图框的方法 https://groups.google.com/forum/?fromgroups=#!topic/raphaeljs/7eA9xq4enDo - Matt Esch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接