试图旋转画布,出了点问题

时间:2013-08-28 17:25:18

标签: javascript html5 canvas

所以我试图在HTML5中制作一个很好的交互式地图,用于HTML5文档(跟踪电话分机,端口号等),因为我们的很多办公室和小隔间是相同的,我想我应该只有一种类型的办公室,然后只是为它匹配的所有办公室复制它。我唯一的问题是,我无法正确旋转画布。我已经按照所有教程,但由于某种原因,我的图像不断被切断。我似乎无法找到问题的根源。

有什么想法吗?

到目前为止,这是我的代码:

http://jsfiddle.net/pmcDw/1/

<!DOCTYPE HTML>

<head>
    <title>Test Interactive Office Schematic</title>
    <style>
        html, body {
            margin: 0px;
            padding: 0px;
        }
    </style>
</head>

<body>
    <script>
        function addOffice(type, id, occupentName) { 

            var canvas = document.createElement('canvas');
            canvas.id = id;
            canvas.style.position = "absolute";
            canvas.style.left = "20px";
            canvas.style.class = "office";
            var context = canvas.getContext('2d');
            context.beginPath();
            context.moveTo(0, 0);
            if (type == 1) {
                canvas.width = 80;
                canvas.height = 80;
                context.lineTo(2, 0);
                context.lineTo(2, 20);
                context.quadraticCurveTo(22, 20, 22, 0);
                context.lineTo(60, 0);
                context.lineTo(60, 80);
                context.lineTo(0, 80);
                context.lineTo(0, 0);
            }
            context.lineWidth = 2;
            context.strokeStyle = 'black';
            context.stroke();
            context.textBaseline = "Alphabetic";
            context.textAlign = "center";
            context.fillText(occupentName, canvas.width / 2, canvas.height / 2);
            document.body.appendChild(canvas);
            canvas = document.getElementById("1");
            context = canvas.getContext('2d');
            var tempCanvas = document.createElement("canvas"),
                tempCtx = tempCanvas.getContext("2d");
            tempCanvas.width = canvas.width;
            tempCanvas.height = canvas.height;
            tempCtx.drawImage(canvas, 0, 0, canvas.width, canvas.height);
            context.clearRect(0, 0, canvas.width, canvas.height);
            context.save();
            context.translate(canvas.width / 2, canvas.height / 2);
            context.rotate(180 * Math.PI / 180);
            context.drawImage(tempCanvas, 0, 0, 80, 80, 40, 40, 80, 80);
            context.restore();
        }
        addOffice(1, 1, "test");
    </script>
</body>

2 个答案:

答案 0 :(得分:8)

翻译并旋转上下文后,需要翻译回来:

context.translate(canvas.width / 2, canvas.height / 2);
context.rotate(180 * Math.PI / 180);

/// here, translate back:
context.translate(-canvas.width / 2, -canvas.height / 2);

context.drawImage(tempCanvas, 0, 0);

(如果目的地大小与源大小相同,则无需剪辑和/或指定宽度和高度。)

但是如果您只是想翻转图像或将其旋转180,则可以改为使用scale画布而不是使用负值 - 只需记住反转坐标(here's a demo of this technique):

context.scale(-1, -1);
context.drawImage(tempCanvas, -tempCanvas.width, -tempCanvas.height);

更深入地了解转换(更新)

为了更好地解释转换的工作方式,让我们了解各个阶段。

Origosee definition here)在坐标系中总是指向[0,0](或者更确切地说是轴穿过的点)。当您使用转换时,这是在画布的上下文中转换的点。

这也是您操纵上下文而不是画布的原因,因为转换应用于上下文而不是元素(否则当您应用旋转变换时元素将自动旋转它 - 你可以用CSS做的。)

最初坐标系看起来像这样(白色混合是画布的不可见区域,中心方块是画布,蓝色网格是上下文和当前坐标系):

(注意:忽略负Y轴 - 我在制作图形时不知何故设法忽略了这个细节 - y轴当然是垂直向下的正面。)

Inital

如果我们现在将画布3.5翻译3.5点以使origo位于中心,则上下文和坐标系统现在将如下所示:

translated

如果我们现在想要应用将在origo点发生的轮换。这就是为什么我们需要在旋转之前进行平移,因为当应用旋转时我们得到这个结果:

rotated

如果我们现在只是绘制图像,它将不会居中,因为drawImage从图像的左上角绘制图像。这意味着它会是这样的:

drawImage non translated

这就是我们需要翻译origo以便我们补偿图片角落的原因。

但是,由于我们也应用了旋转,因此origo也将相对于当前的系统方向移动。

我们向后翻译(图像大小的一半以获得图像在前一个origo点的中心点) - 旋转保持不变:

translated back

现在我们可以调用drawImage,因为现在您可以看到origo似乎处于此操作的正确位置:

final transform

答案 1 :(得分:0)

图像不会显示,因为您在画布之外绘制它。试试这个:

context.drawImage(tempCanvas, 0, 0, 80, 80, -40, -40, 80, 80);