1

我正在尝试使用画布和 javascript,并且想知道是否有办法将对象组​​合在一起,以便可以将它们视为一个画布中的单个对象。所以,作为一个非常简单的例子,假设我有一个实心圆,周围是一个更大的空心圆。现在,假设我有 10 个。我想单独移动每个集合,那么有没有办法将每个集合组合为一个对象?我不想打电话单独移动每个对象。

我上面的例子有点简单,因为我实际上有 10 或 11 个对象在每个集群中分组在一起。单独移动集群中的每个对象是一种痛苦,所以我希望能够将它们组合在一起并进行一次调用来移动它们。

任何建议,将不胜感激!

4

4 回答 4

0

好吧,您可以将所有对象放在一个数组中,然后进行循环,如下所示:

var objects = [
  {x: 200, y: 130, radius: 36, color: "red"}
  ,
  {x: 150, y: 80, radius: 31, color: "blue"}
  ,
  {x: 20, y: 210, radius: 22, color: "green"}
];

for (var i = 0; i < objects.length; i++) {
  context.beginPath();
  context.arc(objects[i].x, objects[i].y, objects[i].radius, 0, Math.PI * 2, false);
  context.fillStyle = objects[i].color;
  context.fill();
  context.closePath();
}

:D

于 2013-08-05T16:11:28.930 回答
0

我最近做了类似的事情,我通过将对象组绘制到屏幕外(内存中)画布来解决这个问题。移动这个画布本质上是移动“组”。

根据您的实际目标,这可能是不灵活的 - 但这是另一个需要考虑的选择。

于 2013-04-02T19:25:09.540 回答
0

您可以使用画布的“翻译”功能来绘制您的圆圈组,而无需重新计算!

当您使用“翻译”时,组的位置变得更简单。

翻译只是将整个组拖到画布上的新位置 的“幕后”数学 。

您不必为每个圈子单独计算。相反,您只需进行翻译,然后绘制圆圈,就好像它们处于起始位置一样。

这是隐含翻译的方法:

      // do a translate to mouseX,mouseY
      // all draws will be now be done RELATIVE to mouseX,mouseY
      // so if we ctx.translate(100,100)
      // then a ctx.rect(0,0,10,10) will actually be drawn at 100,100

      ctx.translate(mouseX,mouseY);

      // draw the ball group
      // notice we didn't have to calculate ANY new positions!!

      drawBallGroup();

      // translate back after we're done

      ctx.translate(-mouseX,-mouseY);

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

<!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; padding:10px; }
    canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var canvasOffset=$("#canvas").offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;

    drawBallGroup();

    function drawBallGroup(){
        drawBall(8,10,5,"red");
        drawBall(20,15,10,"green");
        drawBall(25,25,8,"blue");
        drawBall(5,22,10,"orange");
        drawBall(18,30,10,"black");
    }

    function drawBall(x,y,radius,color){
        ctx.beginPath();
        ctx.fillStyle=color;
        ctx.arc(x,y,radius, 0, 2 * Math.PI, false);
        ctx.fill();
    }


    function handleMouseDown(e){
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);

      // clear the canvas
      ctx.clearRect(0,0,canvas.width,canvas.height);

      // do a translate to mouseX,mouseY
      // all draws will be now be done RELATIVE to mouseX,mouseY
      // so if we ctx.translate(100,100)
      // then ctx.rect(0,0,10,10) will actually be drawn at 100,100
      ctx.translate(mouseX,mouseY);

      // draw the ball group
      // notice we didn't have to calculate ANY new positions!!
      drawBallGroup();

      // translate back after we're done
      ctx.translate(-mouseX,-mouseY);
    }

    $("#canvas").mousedown(function(e){handleMouseDown(e);});

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

</head>

<body>
    <p>Click to move the ball group to a new location</p>
    <p>WITHOUT recalculating each new ball position!</p><br/>
    <canvas id="canvas" width=400 height=500></canvas>
</body>
</html>
于 2013-04-01T18:02:10.370 回答
0

正如评论中所指出的,CanvasAPI 中没有任何内容支持对象分组。但是,Canvas您可以查看各种支持此类功能的库。这个stackoverflow 问题可能是开始调查的好地方。

例如, easel.js支持对象的嵌套和分组。如果您熟悉 ActionScript displayList,您会发现它非常直观,因为 API 非常相似。

您将外圈和内圈分组并将其作为单个对象进行操作的示例在画架上看起来像这样:

// Create a stage by getting a reference to the canvas
var stage = new createjs.Stage("canvas");

// Create a container for the circle.
var circle = new createjs.Container();

// Create the outer circle
var outerCircle = new createjs.Shape();
outerCircle.graphics.beginFill("red").drawCircle(0, 0, 40);

// Create the inner circle
var innerCircle = new createjs.Shape();
innerCircle.graphics.beginFill('green').drawCircle(0, 0, 30);

// Add inner and outer circles instance to circle container
circle.addChild(outerCircle);
circle.addChild(innerCircle);

// Now we can move the circle container and its children as a single object
circle.x = circle.y = 40;

// Add circle container instance to stage display list.
stage.addChild(circle);

// Update stage will render next frame
stage.update();
于 2013-04-01T17:13:22.573 回答