【问题标题】:Kinetic.js masked image with slow performance on firefoxKinetic.js 蒙版图像在 Firefox 上性能缓慢
【发布时间】:2013-05-25 17:39:49
【问题描述】:

我是动力学新手,不知道性能问题。

我制作了this example,你只需点击黑白图像并拖动它,就会出现一个彩色圆圈。

在 chrome、ipad 上的 safari 甚至 android 手机上的 Opera Mobile 中的表现都相当不错。在firefox中它启动正常,但是如果你移动鼠标一段时间它会变慢并且不能正常工作。萤火虫探查器没有多大帮助...我怎样才能以更好的方式调试这个问题?

在绘图函数中有一个内部方法 onMove 来完成这项艰苦的工作。我相信这就是性能问题,但我不知道如何以更好的方式实现相同的效果。

有什么想法吗?

function draw(images) {

    var stage = new Kinetic.Stage({
        container : 'container',
        width : 1024,
        height : 483
    }), bn_layer = new Kinetic.Layer(), color_layer = new Kinetic.Layer(), circle_layer = new Kinetic.Layer(), bn = new Kinetic.Image({
        x : 0,
        y : 0,
        image : images.bn,
        width : 1024,
        heigth : 483
    }), tmp_circle = null, movable = false;
    bn_layer.add(bn);
    tmp_circle = addCircle(circle_layer, images);

    var onMove = function() {
        if (movable) {
            var pos = getMousePosition(stage);
            circle_layer.draw();
            tmp_circle.remove();

            tmp_circle.setPosition(pos.x, pos.y)
            tmp_circle.setFillPatternImage(images.color);
            tmp_circle.setFillPatternOffset(pos.x, pos.y);
            circle_layer.add(tmp_circle);
        }
    }
    stage.on("mousemove touchmove", onMove);

    stage.on("mousedown touchstart", function() {
        debug("activo")
        circle_layer.show();
        movable = true;
        onMove();
        circle_layer.draw();
    });

    stage.on("mouseup touchend", function() {
        debug("inactivo")
        circle_layer.draw();
        tmp_circle.remove();
        circle_layer.hide();
        movable = false;
    })
    //stage.add(color_layer);
    stage.add(bn_layer);

    stage.add(circle_layer);
    circle_layer.hide();
}



更新:更改由标志控制的 requestAnimationFrame 方法的鼠标事件,在 windows 上的 firefox 中性能提高很多。在 Linux 上的 Firefox 中,性能仍然很糟糕。

我认为这可能与本主题中的评论有关: Poor Canvas2D performance with Firefox on Linux

他们正在谈论与 cairo 库相关的 Firefox 中可能存在的错误: http://blog.mozilla.org/joe/2011/04/26/introducing-the-azure-project/ https://bugzilla.mozilla.org/show_bug.cgi?id=781731

更新代码

function Anim(layer, funcion){
        var run = false;
        var callback = funcion;
        this.layer = layer;

        function animate(){
            callback();
            if (!run){
                return;
            }
            requestAnimFrame(function(){
                animate();
            })
        };
        this.start = function(){
            run = true;
            animate();
        };
        this.stop = function(){
            run = false;
        };
    }

    //draw on frames
    function drawAnim(images){
        var stage = new Kinetic.Stage({
            container : 'container',
            width : 1024,
            height : 483
        }), bn_layer = new Kinetic.Layer(), 
        hitareas_layer = new Kinetic.Layer(), 
        circle_layer = new Kinetic.Layer(), 
        bn = createImage(images.bn), 
        tmp_circle = null, 
        movable = false, 
        hit_areas = null, 
        c = 0,
        colorArea = function() {
            if (movable) {

                var pos = getMousePosition(stage);
                debug("posicion: "+pos.x+" "+pos.y+" " +c+ " " +tmp_circle.getX()+ " "+tmp_circle.getY());
                if(pos.x !== tmp_circle.getX() || pos.y !== tmp_circle.getY()){
                    c++;
                    circle_layer.draw();
                    tmp_circle.remove();

                    tmp_circle.setPosition(pos.x, pos.y);
                    tmp_circle.setFillPatternImage(images.color);
                    tmp_circle.setFillPatternOffset(pos.x, pos.y);
                    circle_layer.add(tmp_circle);
                }


            }
        },
        anim = new Anim(null, function(){
            colorArea();
        }),
        onPress = function() {
            circle_layer.show();
            //hitareas_layer.hide()
            movable = true;
            colorArea();
            circle_layer.draw();
            anim.start();
        }, onRelease = function() {
            anim.stop();
            circle_layer.draw();
            tmp_circle.remove();
            circle_layer.hide();
            //hitareas_layer.show()
            movable = false;
            c=0;
        };
        //hit_areas = setHitAreas(bn_layer);
        bn_layer.add(bn);
        tmp_circle = addCircle(100, {
            x : 50,
            y : 50
        });
        hit_areas = setHitAreas(hitareas_layer, images.color);
        bn_layer.on(HitArea.HITTED, function(){
            console.log("this");
        })
        //descomentar si queremos efecto al mover el rat�n
        //stage.on("mousemove touchmove", colorArea);
        stage.on("mousedown touchstart", onPress);
        stage.on("mouseup touchend", onRelease);

        stage.add(bn_layer);

        stage.add(circle_layer);
        stage.add(hitareas_layer);
        circle_layer.hide();
    }

【问题讨论】:

    标签: javascript html canvas kineticjs


    【解决方案1】:

    if (movable) 条件放在onMove() 函数之外,这样您就不会每次都检查此功能:

    if (movable) {
              var onMove = function() {
                var pos = getMousePosition(stage);
                circle_layer.draw();
                tmp_circle.remove();
                tmp_circle.setPosition(pos.x, pos.y)
                tmp_circle.setFillPatternImage(images.color);
                tmp_circle.setFillPatternOffset(pos.x, pos.y);
                circle_layer.add(tmp_circle);
            }
      }
    

    【讨论】:

    • 谢谢。这只是一个布尔值。在“mousedown”或“touchdown”事件上设置为真。函数 onMove 是重复的,函数 draw 仅在加载 dom 时执行。如果我把它放在函数之外,即使用户没有按下图像,我也会重复过程。
    猜你喜欢
    • 1970-01-01
    • 2014-05-03
    • 1970-01-01
    • 1970-01-01
    • 2012-07-05
    • 2013-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多