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

Sal*_*ode -2 javascript html5 canvas

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

有任何想法吗?

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

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

<!DOCTYPE HTML>
Run Code Online (Sandbox Code Playgroud)

<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>
Run Code Online (Sandbox Code Playgroud)

小智 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);
Run Code Online (Sandbox Code Playgroud)

(如果目标大小与源大小相同,则无需剪切和/或指定宽度和高度).

但是如果您只想翻转图像或将其旋转180,您可以使用scale画布而不是使用负值 - 只需记住反转坐标(这是此技术的演示):

context.scale(-1, -1);
context.drawImage(tempCanvas, -tempCanvas.width, -tempCanvas.height);
Run Code Online (Sandbox Code Playgroud)

更全面的转型(更新)

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

Origo(参见此处的定义)在坐标系中总是指向[0,0](或者更准确地说是轴交叉的点).使用转换时,这是在画布的上下文中转换的点.

这也是你操纵上下文而不是直接操作上下文的原因,因为转换应用于上下文而不是元素(否则当你对它应用旋转变换时,元素会自动旋转 - 你可以通过CSS来完成) .

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

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

Inital

如果我们现在将画布3.5转换为3.5点以获得origo中心,则上下文和坐标系统现在将如下所示:

翻译

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

旋转

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

drawImage非翻译

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

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

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

翻译回来

现在我们可以调用drawImage现在你可以看到origo这个操作似乎处于正确的位置:

最后的转变