繁体   English   中英

保存对html画布路径的引用

[英]Save a reference to a html canvas path

我正在研究一些绘制到画布的代码。 代码的一部分在画布上绘制了一些线条。 这些行的位置和颜色不会改变,但它们通常需要重新绘制,因为其他代码可能会影响它(例如:绘制在它的顶部)。

可以有几百行绘制,在这些情况下,分析显示我需要大约200毫秒绘制,所以我希望有所优化。

我注意到的一件事是,当绘制到画布时,您基本上是在路径上添加点,然后一旦准备好,您就可以填充或描绘该路径。 虽然画布上的像素已经过时,但如果我能够保留对路径的引用,那么更新就像重新描绘先前构建的路径一样简单。

我的问题是:你到底怎么得到一个Path对象?

填充和描边方法似乎接受路径对象 ,规范定义了Path方法 ,但我似乎无法在任何地方找到实际的Path类...

所以,回顾一下:

我有这样的事情:

function update() {
  context.beginPath();
  // lots of lines added to the default path...
  context.moveTo(x1, y1); context.lineTo(somewhere, else);
  context.moveTo(x2, y2); context.lineTo(somewhere, else);

  context.stroke();
}

我想要的是这样的:

function update() {
  if (!this.path) {
    this.path = new Path(); // <-- here's the magic
    this.path.moveTo(x1, y2); this.path.lineTo(somewhere, else); // etc
  }
  this.path.stroke();
}

canvas规范要求尚未在浏览器中实现的Path对象。

BTW,当实现时,Path对象在与context.isPointInPath(myPath)结合使用时将在命中测试中有用; 有一天...

以下是在浏览器赶上之前如何创建自己的Path对象:

  • 创建一个JS对象,其中包含绘制路径笔划的画布。
  • 如果要执行myPath.stroke(),请使用myVisibleContext.drawImage(myPath.context,0,0)将路径的画布“blit”到绘图画布上。

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

码:

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    #canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    function Path(maxWidth,maxHeight,color,linewidth,drawingContext){
        this.width=maxWidth;
        this.height=maxHeight;
        this.drawingCtx=drawingContext;
        this.points=[]
        this.canvas=document.createElement("canvas");
        this.canvas.width=maxWidth;
        this.canvas.height=maxHeight;
        this.ctx=this.canvas.getContext("2d");
        this.ctx.strokeStyle=color;
        this.ctx.lineWidth=linewidth;
        this.lastX;
        this.lastY;
    }
    Path.prototype.moveTo=function(x,y){
        this.lastX=x;
        this.lastY=y;

    }
    Path.prototype.lineTo=function(x,y){
        this.ctx.moveTo(this.lastX,this.lastY);
        this.ctx.lineTo(x,y);
        this.ctx.stroke();
        this.lastX=x;
        this.lastY=y;
    }
    Path.prototype.stroke=function(){
        this.drawingCtx.drawImage(this.canvas,0,0);
    }

    // create a new path object

    var p=new Path(300,300,"blue",2,ctx);

    // set the Path's drawing commands

    p.moveTo(69,91);
    p.lineTo(250,150);
    p.moveTo(69,208);
    p.lineTo(180,54);
    p.lineTo(180,245);
    p.lineTo(69,91);
    p.moveTo(69,208);
    p.lineTo(250,150);

    // draw the Path.canvas to the drawing canvas
    p.stroke();

    // tests...

    $("#stroke").click(function(){
        p.stroke();
    });
    $("#erase").click(function(){
        ctx.clearRect(0,0,canvas.width,canvas.height);
    });

}); // end $(function(){});
</script>

</head>

<body>
    <button id="stroke">Path.stroke</button><br>
    <button id="erase">Erase main canvas</button><br>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

事实证明,根据这篇博客(日期为2013年1月24日),只有没有浏览器支持它.http://www.rgraph.net/blog/2013/january/html5-canvas-path-objects.html

它们在画布中没有路径支持,但为什么不使用svg行并将其zIndex设置为在其他行上。

画布绘制API都不允许您保持对对象的引用。 Canvas允许您在位图中绘制像素,而不是像SVG那样创建和操纵对象。

如果您希望优化性能并且希望一遍又一遍地重用相同的路径,您可能希望在单独的画布对象中绘制一次,然后使用drawImage将该画布绘制到另一个画布中(可以使用画布作为参数)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM