-2

所以我正在尝试用 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>

4

2 回答 2

9

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

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画布代替负值 - 只需记住反转坐标(这里是该技术的演示):

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

更深入地了解一般转型(更新)

为了更好地解释转换是如何工作的,让我们来看看各个阶段。

Origo参见此处的定义)始终是坐标系中的点 [0, 0](或更准确地说是轴相交的点)。当您使用转换时,这是在画布的上下文中转换的点。

这也是为什么当转换应用于上下文而不是元素时直接操作上下文而不是画布的原因(否则,当您对其应用旋转转换时,元素会自行旋转 - 您可以通过 CSS 完成) .

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

(注意:忽略负 Y 轴 - 我在制作图形时设法忽略了该细节 - y 轴当然垂直向下为正)。

初始

如果我们现在将画布 3.5 平移 3.5 点以到达origo中心,那么上下文和坐标系现在将如下所示:

翻译的

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

旋转

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

drawImage 未翻译

这就是为什么我们需要翻译回来origo以便我们补偿图像角落。

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

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

翻译回来

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

最终变换

于 2013-08-28T22:02:59.383 回答
0

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

context.drawImage(tempCanvas, 0, 0, 80, 80, -40, -40, 80, 80);
于 2013-08-28T21:06:38.243 回答