如何获得在Html 5 Canvas中创建的形状的尺寸

时间:2013-05-17 05:02:44

标签: html5 canvas

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

 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;

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

信不信由你!

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

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

enter image description here

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

enter image description here

你要做的是:

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

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>

答案 2 :(得分:0)

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

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

样品: -

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

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

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

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