2

我想知道有什么方法可以获得在画布中创建的形状的宽度、高度吗?例子:-

 var theCanvas = document.getElementById("canvasOne");
 var context = theCanvas.getContext("2d");

 context.beginPath();
  context.moveTo(170, 80);
  context.bezierCurveTo(130, 100, 130, 150, 230, 150);
  context.bezierCurveTo(250, 180, 320, 180, 340, 150);
  context.bezierCurveTo(420, 150, 420, 120, 390, 100);
  context.bezierCurveTo(430, 40, 370, 30, 340, 50);
  context.bezierCurveTo(320, 5, 250, 20, 250, 50);
  context.bezierCurveTo(200, 5, 150, 20, 170, 80);

  // complete custom shape
  context.closePath();
  context.lineWidth = 5;
  context.strokeStyle = 'blue';
  context.stroke();

现在我想访问上面创建的形状的尺寸(宽度和高度),这样我就可以只清除这个形状然后重绘它。我不想清除整个画布。

我想要类似的东西,比如图像(我可以访问它的宽度和高度):-

            pointImage = new Image();
            pointImage.src = "stone.png";
            image_x = (theCanvas.width - pointImage.width) / 2;
            image_y = (theCanvas.height - pointImage.height) / 2;
4

3 回答 3

1

您不能简单地清除形状并重新绘制它。画布不会将您的形状识别为对象,并且不会仅保留特定于该形状的任何数据。如果您只想在特定区域的顶部绘制,则必须存储形状的区域坐标。清除它相当于用背景颜色填充该区域,但这仅在您有重叠的形状或背景是图像时才有效。然后重新绘制它的工作方式与第一次绘制它的方式相同。

于 2013-05-17T05:21:01.403 回答
1

信不信由你!

html canvas 的概念是清空整个屏幕并将每个单独的图形组件重新绘制回屏幕上。看起来很浪费,但画布通过非常快速地绘制来处理这个问题。

假设您在一个场景中构图,其中有背景图像和白色蓬松的云。

在此处输入图像描述

然后你想把蓬松的云变成雨云。

在此处输入图像描述

你会做的是:

擦除包含白色蓬松云的整个画布:

context.clearRect(0,0,canvas.width,canvas.height);

重绘天空和草地的背景图像:

context.drawImage(img,0,0,img.width,img.height,0,0,canvas.width,canvas.height);

最后用下雨填充而不是白色填充重新绘制云

context.moveTo(170, 80);
context.bezierCurveTo(130, 100, 130, 150, 230, 150);
context.bezierCurveTo(250, 180, 320, 180, 340, 150);
context.bezierCurveTo(420, 150, 420, 120, 390, 100);
context.bezierCurveTo(430, 40, 370, 30, 340, 50);
context.bezierCurveTo(320, 5, 250, 20, 250, 50);
context.bezierCurveTo(200, 5, 150, 20, 170, 80);
context.closePath();
context.lineWidth = 5;
context.strokeStyle = 'blue';
context.fillStyle=”gray”;
context.stroke();
context.fill();

为了使您的场景可重用,您可以将重绘包装到一个函数中。

这就是为什么您通常不需要云的坐标的原因。

您只需将绘制云的代码放入一个函数中,并在每次要重绘云时调用该函数。

function redraw(fill){
  context.clearRect(0,0,canvas.width,canvas.height);
  context.beginPath();
  // redraw the background image
  context.drawImage(img,0,0,img.width,img.height,0,0,canvas.width,canvas.height);
  // redraw the cloud
  context.moveTo(170, 80);
  context.bezierCurveTo(130, 100, 130, 150, 230, 150);
  ...
  ...
  context.fill();
}

顺便说一句,如果您真的想知道云的边界矩形,您可以使用context.getImageData. 这将为您提供画布上每个像素的 rgba 颜色。要找到左边界,您只需从最左边的像素列开始检查蓝云。如果您没有找到蓝色,请移至第二列像素并检查蓝色。当您确实在一列中找到一个蓝色像素时:那是您的云的左 X 坐标!

这是代码和小提琴:http: //jsfiddle.net/m1erickson/Yze44/

<!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 context=canvas.getContext("2d");

    var img=new Image();
    img.onload=function(){
        redraw("transparent");
    }
    img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/skyGrass.png";


    function redraw(fill){
      context.clearRect(0,0,canvas.width,canvas.height);
      context.beginPath();
      // redraw the background image
      context.drawImage(img,0,0,img.width,img.height,0,0,canvas.width,canvas.height);
      // redraw the cloud
      context.moveTo(170, 80);
      context.bezierCurveTo(130, 100, 130, 150, 230, 150);
      context.bezierCurveTo(250, 180, 320, 180, 340, 150);
      context.bezierCurveTo(420, 150, 420, 120, 390, 100);
      context.bezierCurveTo(430, 40, 370, 30, 340, 50);
      context.bezierCurveTo(320, 5, 250, 20, 250, 50);
      context.bezierCurveTo(200, 5, 150, 20, 170, 80);

      // complete custom shape
      context.closePath();
      context.lineWidth = 5;
      context.strokeStyle = 'blue';
      context.fillStyle=fill;
      context.stroke();
      context.fill();
      console.log(fill);
    }

    $("#light").click(function(){ redraw("white"); })
    $("#dark").click(function(){ redraw("gray"); })

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

</head>

<body>
    <canvas id="canvas" width=420 height=300></canvas><br>
    <button id="light">Redraw as Light Cloud</button>
    <button id="dark">Redraw as Dark Cloud</button>
</body>
</html>
于 2013-05-17T06:17:03.977 回答
0

你们分享的不同想法,我想出了一个适合我的解决方案。我在这里提到,以便其他人可以改进它。

  • 绘制形状
  • 跟踪它的坐标
  • 使用这些坐标在形状周围绘制一个隐藏的矩形(可选)
  • 现在使用 clear.Rect() 清除矩形。:-)

样本:-

            context.strokeStyle = '#fff';
            context.strokeRect(130, 15, 300, 165);

这将在形状周围形成一个矩形。现在我将使用以下方法清除此矩形:-

context.clearRect(130, 15, 300, 165);

这将只清除这个区域不是整个画布

于 2013-05-18T06:22:07.663 回答