簡體   English   中英

如何提高繪制動畫路徑的性能?

[英]How can i improve the performance of drawing an animation path?

我用dynamic.js繪制了一個矩形,並在圓形路徑中對其進行了動畫處理。 在每個動畫幀中,我減小它的半徑,並通過dynamicJS Line繪制該對象的動畫路徑。 但是,此Kinetics動畫循環會產生不希望的暫停“交錯”現象。 這種差異在Chrome中很小,在IE中非常明顯,而在FireFox中則很糟糕。 這似乎是由於Kinetic.Line無法平滑添加+繪制數千個變化的數據點所致。 如何使此動畫完美無瑕,流暢。 如果您給我一個jsfiddle的鏈接,那將是很大的幫助。 提前致謝。

碼:

var R= 80;

$(document).ready(function(){
var stage= new Kinetic.Stage({
    container: 'container',
    width:500,
    height:500
});

var layer = new Kinetic.Layer();
var line = new Kinetic.Line({
    points:[0,0,0,0],
    stroke:'blue',
    strokeWidth:2
});
var rect = new Kinetic.Rect({
    x:10,
    y:10,
    width:10,
    height: 10,
    fill:'black',
    stroke:'red'
});
layer.add(rect);
layer.add(line);
stage.add(layer);

var centerX = stage.width()/2;
var points=[];
var anim = new Kinetic.Animation(
        function(f){
            var cX= stage.width()/2;
            var cY= stage.height()/2;
            R=R-1/100;
            var X = cX + R*Math.cos(f.time/1000);
            var Y = cY+ R*Math.sin(f.time/1000);
            points.push(X,Y);
            line.setPoints(points);
            rect.setX(X);
            rect.setY(Y);
        }
,layer);
anim.start();
});

JSFIDDLE: http : //jsfiddle.net/tanvirgeek/n8z8N/7/

提前致謝。

如您所見,更新和繪制包含數千個線段的Kinetic.Line會導致明顯的滯后。

我很少見的一種動力學技巧對創建數千行線段的無滯后動畫很有用。

首先,在屏幕外的html5畫布上繪制線段。 當需要新的線段時,只需將該線段添加到所有現有的線段中即可。 這是非常有效的,因為僅需要繪制最后的線段。

您可以使用Kinetic.Image在屏幕上顯示屏幕外的html5畫布。

訣竅是將Kinetic.Image圖像源設置為html canvas: myKineticImage.setImage(myOffscreenCanvas) 之所以可行,是因為Kinetic.Image在“幕后”使用了context.drawImage來顯示其圖像。 由於context.drawImage也可以接受另一個畫布作為其圖像源,因此您可以有效地顯示當前的屏幕外畫布圖形。

演示: http : //jsfiddle.net/m1erickson/rYC96/

在此處輸入圖片說明

和示例代碼:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Prototype</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
    <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.0.1.min.js"></script>

<style>
body{padding:20px;}
#container{
  border:solid 1px #ccc;
  margin-top: 10px;
  width:350px;
  height:350px;
}
</style>        
<script>
$(function(){

    var stage = new Kinetic.Stage({
        container: 'container',
        width: 350,
        height: 350
    });
    var layer = new Kinetic.Layer();
    stage.add(layer);

    // variables used to set the stage and animate
    var rectSize=15;
    var cx=stage.getWidth()/2;
    var cy=stage.getHeight()/2;
    var R=100;
    var A=0;
    var deltaA=Math.PI/180;
    var lastX=cx+R*Math.cos(A);
    var lastY=cy+R*Math.sin(A);

    // the html canvas incrementally draws the line segments
    // which are in turn displayed as a Kinetic.Image (called line)
    var canvas=document.createElement("canvas");
    var ctx=canvas.getContext("2d");
    canvas.width=stage.getWidth();
    canvas.height=stage.getHeight();
    ctx.strokeStyle="blue";
    ctx.lineWidth=2;


    // this Kinetic.Image exactly displays the current html canvas drawings
    // (this trick cures the lags)
    var line=new Kinetic.Image({
        x:0,
        y:0,
        width:canvas.width,
        height:canvas.height,
        image:canvas
    });
    layer.add(line);


    // the rotating Kinetic.Rectangle
    var rect = new Kinetic.Rect({
        x:lastX,
        y:lastY,
        width:rectSize,
        height:rectSize,
        fill:'black',
        stroke:'red'
    });
    layer.add(rect);


    // use requestAnimationFrame (RAF) to drive the animation
    // RAF efficiently schedules animation frames with display 
    function animate(){

        // stop animating when rect reaches center
        if(R<=rectSize/2){return;}

        // schedule another animation frame even before this one is done
        requestAnimationFrame(animate);

        // calc the new XY position
        R=R-.01;
        A+=deltaA;
        var X=cx+R*Math.cos(A);
        var Y=cy+R*Math.sin(A);

        // animate the rect and line to their next position

        // draw just the latest line segment to the canvas
        // (all the previous line segments are still there--no need to redraw them)
        ctx.beginPath();
        ctx.moveTo(lastX,lastY);
        ctx.lineTo(X,Y);
        ctx.stroke();
        // set lastXY for next frame
        lastX=X;
        lastY=Y;

        // update the rect position
        rect.setX(X);
        rect.setY(Y);

        // draw the changed line-image and rect to the kinetic layer
        layer.draw();
    }

    // start animating!
    animate();

}); // end $(function(){});
</script>       
</head>
<body>
    <div id="container"></div>
</body>
</html>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM