首先,我英语不好。谢谢您的理解。
现在让我解释一下我目前遇到的困难。
我目前正在开发一个使用鼠标在画布上绘制矩形的函数(使用
strokeRect
函数)。
正常情况下运行良好,但是点击旋转按钮时出现问题(出现鼠标坐标处未绘制矩形的问题)。
作为参考,当您单击旋转按钮时,它会使用 css
transform = 'rotate(90deg)'
进行旋转,并在 calcCanvasRect
函数中检索画布的大小(使用 getBoundingClientRect
函数)。
我需要一些建议来解决这个问题。帮忙!
供参考,HT结构如下。
<div class="myContainer">
<div class="rotation-wrapper">
<div id="canvasParent">
<canvas id="view_canvas"></canvas>
</div>
</div>
</div>
这是完整的源代码。
let mode = 'off';
let wwViewCanvas;
let wwCanvasRect;
let isDown = false;
let mousedown, mouseup, mousemove;
let zoombox;
let post_obj;
function calcCanvasRect() {
if(wwViewCanvas) {
let rect = wwViewCanvas.canvas.getBoundingClientRect();
let scrollY = window.scrollY;
wwCanvasRect = {
left: rect.left,
top: rect.top + scrollY,
right: rect.right,
bottom: rect.bottom + scrollY,
width: rect.width,
height: rect.height,
};
if(mode === '90') {
//To do anything..
}
}
}
function appendViewCanvas() {
let width, height;
if(mode === '90') {
width = 338;
height = 600;
}
else if(mode === 'off') {
width = 600;
height = 338;
}
$('#canvasParent').append(
`<canvas id="view_canvas" width="${width}" height="${height}" style="cursor:crosshair; position:absolute; top:0; left:0; z-index:10;">
</canvas>`
);
}
function getViewCanvas() {
let element = document.getElementById('view_canvas');
if(!element) {
appendViewCanvas();
element = document.getElementById('view_canvas');
}
return element;
}
function initViewCanvas() {
let ctx;
let canvas = getViewCanvas();
ctx = canvas.getContext('2d');
ctx.lineWidth = 3;
ctx.strokeStyle = '#00B0F0';
wwViewCanvas = {
canvas: canvas,
context: ctx,
};
}
function getEventPosition(event) {
let eventCoordinateX, eventCoordinateY;
let pageX = event.pageX;
let pageY = event.pageY;
if (pageX > wwCanvasRect.right) {
pageX = wwCanvasRect.right;
}
else if (pageX < wwCanvasRect.left) {
pageX = wwCanvasRect.left;
}
if (pageY > wwCanvasRect.bottom) {
pageY = wwCanvasRect.bottom;
}
else if (pageY < wwCanvasRect.top) {
pageY = wwCanvasRect.top;
}
eventCoordinateX = pageX - wwCanvasRect.left;
eventCoordinateY = pageY - wwCanvasRect.top;
return {
x: Math.floor(eventCoordinateX),
y: Math.floor(eventCoordinateY),
};
}
function getZoombox(start, end) {
return {
width: end.x - start.x,
height: end.y - start.y,
};
}
function clearCanvas() {
wwViewCanvas.context.clearRect(0, 0, wwViewCanvas.canvas.width, wwViewCanvas.canvas.height);
}
function getCoordinatesBox(center_x, center_y) {
return {
Coordinates_box: {
x: center_x,
y: center_y,
box_w: Math.abs(zoombox.width),
box_h: Math.abs(zoombox.height),
w: wwCanvasRect.width,
h: wwCanvasRect.height,
},
};
}
function canvasMousedown(event) {
mousedown = getEventPosition(event);
isDown = true;
}
function canvasMouseup(event) {
if (!isDown) {
return;
}
mouseup = getEventPosition(event);
zoombox = getZoombox(mousedown, mouseup);
let center_x, center_y;
center_x = Math.round(zoombox.width / 2) + mousedown.x;
center_y = Math.round(zoombox.height / 2) + mousedown.y;
post_obj = getCoordinatesBox(center_x, center_y);
clearCanvas();
isDown = false;
}
function canvasMousemove(event) {
if (!isDown) {
return;
}
mousemove = getEventPosition(event);
zoombox = getZoombox(mousedown, mousemove);
clearCanvas();
wwViewCanvas.context.strokeRect(mousedown.x, mousedown.y, zoombox.width, zoombox.height);
}
function getTransformHeight(rect) {
return rect.container_rect.height + (rect.wrapper_rect.width - rect.container_rect.height);
}
function getTranslateValueOfTopBottom(rect) {
return (rect.wrapper_rect.width - rect.container_rect.height) / 2;
}
function calcRotationLayoutRect(container, wrapper) {
return {
container_rect: container.getBoundingClientRect(),
wrapper_rect: wrapper.getBoundingClientRect(),
};
}
$(document).ready(function() {
initViewCanvas();
wwViewCanvas.canvas.addEventListener('mousedown', canvasMousedown);
wwViewCanvas.canvas.addEventListener('mouseup', canvasMouseup);
wwViewCanvas.canvas.addEventListener('mousemove', canvasMousemove);
let myContainer = document.getElementsByClassName('myContainer')[0];
let rotationWrapper = document.getElementsByClassName('rotation-wrapper')[0];
rotationLayoutRect = calcRotationLayoutRect(myContainer, rotationWrapper);
let transformHeight = getTransformHeight(rotationLayoutRect);
let translateValue = getTranslateValueOfTopBottom(rotationLayoutRect);
const noTransitionCallback = function () {
if (mode === 'off') {
rotationWrapper.style.transform = 'rotate(0deg)';
myContainer.style.height = `${rotationLayoutRect.container_rect.height}px`;
mode = '90';
}
else if (mode === '90') {
rotationWrapper.style.transform = `rotate(90deg) translate(${translateValue}px, 0px)`;
myContainer.style.height = `${transformHeight}px`;
mode = 'off';
}
calcCanvasRect();
};
$('#rotation_btn').click(noTransitionCallback);
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<title>canvas rotation</title>
<style>
.myContainer{
background-color: yellowgreen;
}
canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<div class="myContainer" style="width:620px; height:374px">
<div class="rotation-wrapper">
<div id="canvasParent" style="width:600px; height:338px;"></div>
</div>
</div>
<div class="text-center">
<button type="button" id="rotation_btn" style="width:64px">
rotation button
</button>
</div>
</body>
</html>
我尝试使用画布平移和旋转功能,但找不到解决方案。有更好的办法吗?
还是有什么我不知道的事情?
一旦画布旋转,您将需要更新
canvasMousemove
函数以考虑 strokeRect
的不同坐标。
if (mode === '90') {
wwViewCanvas.context.strokeRect(mousedown.x, mousedown.y, zoombox.width, zoombox.height);
}
else{
let rect = wwViewCanvas.canvas.getBoundingClientRect();
wwViewCanvas.context.strokeRect(mousedown.y, rect.width-mousedown.x, zoombox.height, -1*zoombox.width);
}
下面是完整的运行代码片段,也适用于旋转的画布。
let mode = 'off';
let wwViewCanvas;
let wwCanvasRect;
let isDown = false;
let mousedown, mouseup, mousemove;
let zoombox;
let post_obj;
function calcCanvasRect() {
if(wwViewCanvas) {
let rect = wwViewCanvas.canvas.getBoundingClientRect();
let scrollY = window.scrollY;
wwCanvasRect = {
left: rect.left,
top: rect.top + scrollY,
right: rect.right,
bottom: rect.bottom + scrollY,
width: rect.width,
height: rect.height,
};
if(mode === '90') {
//To do anything..
}
}
}
function appendViewCanvas() {
let width, height;
if(mode === '90') {
width = 338;
height = 600;
}
else if(mode === 'off') {
width = 600;
height = 338;
}
$('#canvasParent').append(
`<canvas id="view_canvas" width="${width}" height="${height}" style="cursor:crosshair; position:absolute; top:0; left:0; z-index:10;">
</canvas>`
);
}
function getViewCanvas() {
let element = document.getElementById('view_canvas');
if(!element) {
appendViewCanvas();
element = document.getElementById('view_canvas');
}
return element;
}
function initViewCanvas() {
let ctx;
let canvas = getViewCanvas();
ctx = canvas.getContext('2d');
ctx.lineWidth = 3;
ctx.strokeStyle = '#00B0F0';
wwViewCanvas = {
canvas: canvas,
context: ctx,
};
}
function getEventPosition(event) {
let eventCoordinateX, eventCoordinateY;
let pageX = event.pageX;
let pageY = event.pageY;
if (pageX > wwCanvasRect.right) {
pageX = wwCanvasRect.right;
}
else if (pageX < wwCanvasRect.left) {
pageX = wwCanvasRect.left;
}
if (pageY > wwCanvasRect.bottom) {
pageY = wwCanvasRect.bottom;
}
else if (pageY < wwCanvasRect.top) {
pageY = wwCanvasRect.top;
}
eventCoordinateX = pageX - wwCanvasRect.left;
eventCoordinateY = pageY - wwCanvasRect.top;
//console.log(eventCoordinateX);
//console.log(eventCoordinateY);
return {
x: Math.floor(eventCoordinateX),
y: Math.floor(eventCoordinateY),
};
}
function getZoombox(start, end) {
return {
width: end.x - start.x,
height: end.y - start.y,
};
}
function clearCanvas() {
wwViewCanvas.context.clearRect(0, 0, wwViewCanvas.canvas.width, wwViewCanvas.canvas.height);
}
function getCoordinatesBox(center_x, center_y) {
return {
Coordinates_box: {
x: center_x,
y: center_y,
box_w: Math.abs(zoombox.width),
box_h: Math.abs(zoombox.height),
w: wwCanvasRect.width,
h: wwCanvasRect.height,
},
};
}
function canvasMousedown(event) {
mousedown = getEventPosition(event);
isDown = true;
}
function canvasMouseup(event) {
if (!isDown) {
return;
}
mouseup = getEventPosition(event);
zoombox = getZoombox(mousedown, mouseup);
let center_x, center_y;
center_x = Math.round(zoombox.width / 2) + mousedown.x;
center_y = Math.round(zoombox.height / 2) + mousedown.y;
post_obj = getCoordinatesBox(center_x, center_y);
clearCanvas();
isDown = false;
}
function canvasMousemove(event) {
if (!isDown) {
return;
}
mousemove = getEventPosition(event);
zoombox = getZoombox(mousedown, mousemove);
clearCanvas();
if (mode === '90') {
wwViewCanvas.context.strokeRect(mousedown.x, mousedown.y, zoombox.width, zoombox.height);
}
else{
let rect = wwViewCanvas.canvas.getBoundingClientRect();
wwViewCanvas.context.strokeRect(mousedown.y, rect.width-mousedown.x, zoombox.height, -1*zoombox.width);
}
}
function getTransformHeight(rect) {
return rect.container_rect.height + (rect.wrapper_rect.width - rect.container_rect.height);
}
function getTranslateValueOfTopBottom(rect) {
return (rect.wrapper_rect.width - rect.container_rect.height) / 2;
}
function calcRotationLayoutRect(container, wrapper) {
return {
container_rect: container.getBoundingClientRect(),
wrapper_rect: wrapper.getBoundingClientRect(),
};
}
$(document).ready(function() {
initViewCanvas();
wwViewCanvas.canvas.addEventListener('mousedown', canvasMousedown);
wwViewCanvas.canvas.addEventListener('mouseup', canvasMouseup);
wwViewCanvas.canvas.addEventListener('mousemove', canvasMousemove);
let myContainer = document.getElementsByClassName('myContainer')[0];
let rotationWrapper = document.getElementsByClassName('rotation-wrapper')[0];
rotationLayoutRect = calcRotationLayoutRect(myContainer, rotationWrapper);
let transformHeight = getTransformHeight(rotationLayoutRect);
let translateValue = getTranslateValueOfTopBottom(rotationLayoutRect);
const noTransitionCallback = function () {
if (mode === 'off') {
rotationWrapper.style.transform = 'rotate(0deg)';
myContainer.style.height = `${rotationLayoutRect.container_rect.height}px`;
mode = '90';
}
else if (mode === '90') {
rotationWrapper.style.transform = `rotate(90deg) translate(${translateValue}px, 0px)`;
myContainer.style.height = `${transformHeight}px`;
mode = 'off';
}
calcCanvasRect();
};
$('#rotation_btn').click(noTransitionCallback);
});
.myContainer{
background-color: yellowgreen;
}
canvas {
border: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div class="myContainer" style="width:620px; height:374px">
<div class="rotation-wrapper">
<div id="canvasParent" style="width:600px; height:338px;"></div>
</div>
</div>
<div class="text-center">
<button type="button" id="rotation_btn" style="width:64px">
rotation button
</button>
</div>