我有一个canvas元素,在上面可以绘制许多图像并将其与文本重叠。不幸的是,问题要求这些图像和相应的文本中的一些被旋转。除此之外,某些图像上必须具有相应的背景色(图像是平面图的办公桌的简单轮廓)
这是我构建的用于将单个办公桌添加到计划中的功能。我遇到的问题是,当我使用旋转时,文本和背景色都不会显示,而如果我不旋转图像,则正确显示,除非它们没有旋转并且背景fillRect()定向为90度关闭。
function redrawDesk(desk, ctx, color) {
var rotate = desk.rotation == 90 || desk.rotation == 270;
if (rotate) {
ctx.save();
ctx.rotate(Math.PI / 2);
ctx.clearRect(desk.left, desk.top, desk.width, desk.height);
ctx.restore()
}
var img = $("#desk_" + desk.rowID)[0];
ctx.drawImage(img, desk.left, desk.top, desk.height, desk.width);
var x = desk.left;
var y = desk.top;
var h = desk.height;
var w = desk.width;
if (rotate) {
//ctx.save()
ctx.rotate(Math.PI / 2);
var tmp=x;
x=y;
y=tmp;
tmp=h;
h=w;
w=tmp;
}
ctx.textAlign = "center";
ctx.fillText(desk.deskID, x + w / 2,y + h/ 2);
if (color) {
ctx.fillStyle = color;
ctx.fillRect(x, y, w, h);
}
//ctx.restore();
if (rotate) {
ctx.rotate(Math.PI / -2);
}
}
谢谢
答案 0 :(得分:0)
在我的代码中,我测试了是否需要轮换。如果是这样,我在画布上设置了一个笔译以给我一个新的起点:ctx.translate(x,y);这使我可以简化放置文本和背景色的位置设置,这意味着它们可以正确显示。这是更改后的代码,可与原始代码进行比较:
if (rotate) {
ctx.save();
tmp = h;
h = w;
w = tmp;
ctx.translate(x, y);
}
if (color) {
ctx.fillStyle = color;
ctx.fillRect(0, 0, w, h);
}
ctx.font = "bold " + w / 2 + "px Calibri";
ctx.textAlign = "center";
ctx.fillStyle = "#000";
var c=ctx.canvas;
ctx.rotate(Math.PI / -2);
ctx.fillText(desk.deskID, 0-h/2, w/2); //x + w / 2, y + h / 2);
ctx.restore();
答案 1 :(得分:0)
主要问题是您要将桌子和文本定义为绝对坐标。
在局部坐标系中定义对象。例如,桌子有高度和宽度,但没有位置。它相对于自身的绘制(约0,0)
const desk = {
w : 10, h : 10,
color : "blue",
draw() {
ctx.fillStyle = this.color;
ctx.fillRect(-this.w / 2, -this.h / 2, this.w, this.h);
}
};
然后您可以通过定义桌子的中心位置,将桌子放置在世界坐标系(画布)中。
function drawObj(obj, x, y) { // what to draw and where
ctx.setTransform(1,0,0,1,x,y); // Same as ctx.translate if 2D API is in default context
// The means you do not have to use ctx.save and
// ctx.restore in this function
obj.draw(); // draw desk
}
要进行完全转换,其效果几乎相同
function drawObj(obj, x, y, scale, rotate) { // rotate is in radians
ctx.setTransform(scale, 0, 0, scale, x, y);
ctx.rotate(rotate);
obj.draw();
}
要添加文本,您可以将其作为对象添加到桌面,并将其绘制到其自己的本地坐标系
desk.name = {
text : "Desk",
color : "black",
font : "bold " + 20 + "px Calibri",
draw() {
ctx.font = this.font;
ctx.textAlign = "center";
ctx.fillStyle = this.color;
ctx.fillText(this.text, 0,0);
}
};
您现在可以使用绘图对象功能
绘制办公桌和名称drawObj(desk,200, 200, 1, Math.PI / 2); // Draw at 200,200 rotated 90deg CW
drawObj(desk.name, 200, 200, 1, Math.PI / 2); // draw the text rotated same and centered over desk
// Or if the text should be above and not rotated
drawObj(desk.name, 200, 200 - 30, 1, 0);
由于上述函数使用setTransform
,因此您可能需要恢复转换。有两种方法可以做到这一点。
ctx.resetTransform(); // Check browser support for this call
ctx.setTransform(1,0,0,1,0,0); // same as above just does it manaly