最近项目开发需要前端绘制尺寸图,选择了canvas进行绘画,完了之后需要对尺寸图进行放大缩小的功能,参照了网上的事例,实现了这个放大缩小的功能
这里是需要两个canvas,一个充当容器,一个是拿来绘图的
<canvas v-show="false" id="canvas" :width="getWidth" :height="getHeight - 150"
style="border: 1px solid #ccc;"></canvas>
<canvas id="scaleDragCanvas" :width="getWidth" :height="getHeight - 150" style="border: 1px solid #ccc;"></canvas>
let imgX = 0, imgY = 0, imgScale = 1;
let MINIMUM_SCALE = 1.0, pos: any = {}, posl: any = {}, dragging = false;
let canvas, context,contextMove, canvasMove
2.使用到的方法
// 尺寸图缩放移动 是尺寸图的容器
function initCanvas() {
canvasMove = document.getElementById('scaleDragCanvas');
contextMove = canvasMove.getContext('2d');//画布显⽰⼆维图⽚
drawImage();
canvasEventsInit();
}
3.绘图
// 绘图
function drawImage() {
contextMove.clearRect(0, 0, canvasMove.width, canvasMove.height);
// 边界
if (imgX < canvas.width * (1 - imgScale)) {
imgX = canvas.width * (1 - imgScale);
} else if (imgX > 0) {
imgX = 0
}
if (imgY < canvas.height * (1 - imgScale)) {
imgY = canvas.height * (1 - imgScale);
} else if (imgY > 0) {
imgY = 0
}
contextMove.drawImage(
canvas, // specify the image, canvas or video to make ⽤.
0, 0, // the X coordinate position at which cutting starts.
canvas.width, canvas.height, // the ⾼ degree of the cut image.
imgX, imgY, // place the X and Y coordinate positions of the image on the canvas.
canvas.width * imgScale, canvas.height * imgScale // the width and degree of the image to be ⽤
)
}
4.事件注册 pos变量是当前鼠标按下的坐标
function canvasEventsInit() {
// 鼠标按下
canvasMove.onmousedown = function (event) {
dragging = true;
pos = windowToCanvas(event.clientX, event.clientY); // Coordinate conversion: convert the window coordinate into the coordinate of canvas
};
// 鼠标移动 posl 鼠标移动到当前位置的坐标
canvasMove.onmousemove = function (evt) {
if (dragging) {
posl = windowToCanvas(evt.clientX, evt.clientY)
const x = posl.x - pos.x, y = posl.y - pos.y
imgX += x
imgY += y
pos = JSON.parse(JSON.stringify(posl))
drawImage()//重新绘制图⽚
}
}
// 鼠标放开
canvasMove.onmouseup = function () {
dragging = false
}
// 鼠标滚轮
canvasMove.onmousewheel = canvasMove.onwheel = (event) => {
let pos = windowToCanvas(event.clientX, event.clientY)
let movePos
//wheelDelta的值为正(120.240...)则是鼠标向上;为负(-120,-240)则是向下。
movePos = event.wheelDelta ? event.wheelDelta : (event.deltalY * (-40))
let newPos: any = {x: ((pos.x - imgX) / imgScale).toFixed(2), y: ((pos.y - imgY) / imgScale).toFixed(2)}
if (movePos > 0) {//放⼤
imgScale += 0.1
imgX = (1 - imgScale) * newPos.x + (newPos.x - pos.x)
imgY = (1 - imgScale) * newPos.x + (newPos.x - pos.x)
} else {//缩⼩
imgScale -= 0.1
if (imgScale < MINIMUM_SCALE) {//最⼩缩放1.
imgScale = MINIMUM_SCALE
}
imgX = (1 - imgScale) * newPos.x + (pos.x - newPos.x)
imgY = (1 - imgScale) * newPos.y + (pos.y - newPos.y)
}
drawImage()
}
}
5.因为得到的鼠标在浏览器上的坐标,所以要相对图片放大缩小的所使用到的坐标转换
function windowToCanvas(x, y) {
const box = canvasMove.getBoundingClientRect() // 这个⽅法返回⼀个矩形对象,包含四个属性:left、top、right和bottom。分别表⽰元素各边与页⾯上边和左边的距离
return {
x: x - box.left - (box.width - canvas.width),
y: y - box.top - (box.height - canvas.height)
}
}
onMounted(){
initCanvas()
}