在这些元素的拖动上更新连接到两个元素的raphael路径

时间:2014-08-14 02:01:28

标签: jquery raphael elements gsap

我有很多div,用gsap动画。任何两个div都可以与raphael路径连接,因为它们在附加的codepen中。目前,通过每10ms重新绘制一次路径来维护连接,但是在较慢的机器上,这可能会使渲染性能下降一半以上。有没有更好的方法来维持这种联系?

理想情况下,我会在每条路径上附加一个更新功能,每次拖动div时都可以调用,但我无法理解它。 我将不胜感激任何可以提供解决方案或引导我朝着正确方向前进的答案。

最诚挚的问候, 帕特里克。

Codepen:http://codepen.io/mussler/pen/hfIlp

代码:

    RaphaelCont = Raphael("menu", "100%", "100%");

var getXY = function(obj, center) {
    center = center || false;
    var obx;
    var oby;
    obx = $(obj).offset().left - $(obj).parent().offset().left;
    oby = $(obj).offset().top - $(obj).parent().offset().top;
    if (center) {
        obx = obx + $(obj).outerWidth() / 2;
        oby = oby + $(obj).outerHeight() / 2;
    }
    return [obx, oby];
};
// Return Control Point coordinates for Bezier curve between two objects. Takes in array of xy coordinates
var getQP = function(xy, xye) {
    var xq = (xy[0] + xye[0]) / 2;
    var yq = (xy[1] + xye[1]) / 2;
    yq = yq * 1.3; // Create arch
    return [xq, yq];
}
var constructCurve = function(R, obj1, obj2, c) { //Creates a quadratic bezier curve between obj1 and obj2, using CSS ID, in a given Raphael object (R), in c color
    this.obj1 = obj1;
    this.obj2 = obj2;
    var xy = getXY(obj1, true);
    var xye = getXY(obj2, true)
    var xyq = getQP(xy, xye);
    var xq = xyq[0];
    var yq = xyq[1];
    //Create Curve
    var path = [
            ["M", xy[0], xy[1]],
            ["Q", xq, yq, xye[0], xye[1]]
        ],
        curve = R.path(path).attr({
            stroke: c,
            "stroke-width": 12,
            "stroke-linecap": "round"
        });
    setInterval(function() { // Update the curve every 10ms
        var xy = getXY(obj1, true);
        var xye = getXY(obj2, true);
        var xyq = getQP(xy, xye);
        path[0][1] = xy[0];
        path[0][2] = xy[1];
        path[1][1] = xyq[0];
        path[1][2] = xyq[1];
        path[1][3] = xye[0];
        path[1][4] = xye[1];
        curve.attr({
            path: path
        });
    }, 10);
}

// HOME - BEZIER TWEENS
var initMenuTweens = function() {
TweenMax.to($("#menu-home"), 8, {bezier: {type: "cubic",values: [{x: "+=0",y: "+=0"}, {x: "+=20",y: "+=20"}, {x: "+=-20" ,y: "+=0"}, {x: "+=0",y: "+=0"}]}, repeat: -1, ease: SlowMo.ease.config(0.5, 0.1)});
    TweenMax.to($("#menu-projects"), 6, {bezier: {type: "cubic",values: [{x: "+=0",y: "+=0"}, {x: "+=-5",y: "+=5"}, {x: "+=15",y: "+=-5"}, {x: "+=0",y: "+=0"}]},repeat: -1,ease: SlowMo.ease.config(0.5, 0.1)});
    TweenMax.to($("#menu-about"), 4, {bezier: {type: "cubic",values: [{x: "+=0",y: "+=0"}, {x: "+=0",y: "+=-15"}, {x: "+=-15",y: "+=-15"}, {x: "+=0",y: "+=0"}]},repeat: -1,ease: SlowMo.ease.config(0.5, 0.1)});

};


    Draggable.create("#menu-home , #menu-projects, #menu-about", {
        type: "x, y",
        bounds: window,

         onDragEnd:function()
 {
 TweenLite.getTweensOf(this.target)[0].invalidate().play();
 }
    });
 initMenuTweens();
constructCurve(RaphaelCont, "#menu-home", "#menu-projects", "#fff");
constructCurve(RaphaelCont, "#menu-home", "#menu-about", "#fff");

1 个答案:

答案 0 :(得分:0)

好的,我想出了一种避免使用setInterval的方法。

首先,我将更新功能推送为Raphael自定义属性:

    RaphaelCont = Raphael("menu", "100%", "100%");
    RaphaelCont.customAttributes.update = function(){
            var xy = getXY(this.data('startObj'), true);
            var xye = getXY(this.data('endObj'), true);
            var xyq = getQP(xy, xye);
            var path = [["M", xy[0], xy[1]],["Q", xyq[0], xyq[1], xye[0], xye[1]]];
            this.attr({path: path});};

函数getXY和getQP保持不变。

然后,我修改custructCurve函数,如下所示:

    var constructCurve = function(R, obj1, obj2, c) { //Creates a quadratic bezier curve between obj1 and obj2, using CSS ID, in a given Raphael object (R), in c color
    var xy = getXY(obj1, true);
    var xye = getXY(obj2, true)
    var xyq = getQP(xy, xye);
    //Create Curve
    var path = [
            ["M", xy[0], xy[1]],
            ["Q", xyq[0], xyq[1], xye[0], xye[1]]
        ];
    var curve = R.path(path).attr({
            stroke: c,
            "stroke-width": 8,
            "stroke-linecap": "round"
        });
        curve.data('startObj', obj1);
        curve.data('endObj', obj2);
    return curve;
}

我将startObj和endObj数据添加到曲线中。

最后,在创建曲线时,我将它们分配给变量并将它们推入数组“

var RaphaelCurves = [];
RaphaelCurves.push(constructCurve(RaphaelCont, menu_home, menu_projects, "#fff"));
    RaphaelCurves.push(constructCurve(RaphaelCont, menu_home, menu_skills, "#fff"));
    RaphaelCurves.push(constructCurve(RaphaelCont, menu_home, menu_contact, "#fff"));
    RaphaelCurves.push(constructCurve(RaphaelCont, menu_home, menu_about, "#fff"));

现在,我可以在任何时候调用RaphaelCurves [index] .attr({update:“foo”})(foo只是匹配Raphael的填充符,如果更新后没有任何内容则抛出错误:)。

在我的情况下,我将它链接到TweenMax.tick事件:

    TweenMax.ticker.addEventListener("tick", myFunction);
        function myFunction(event) {
         for(var i=0; i<RaphaelCurves.length; i++) {
             RaphaelCurves[i].attr({update: "foo"});
            }
        }

这是更新后的码本:http://codepen.io/mussler/pen/JgcEh