Canvas滚轮缩放和拖动画布
2023年度总结:一个疲惫的程序员
2023,留给这一年的时间不多了,总结一下吧。
从前我是一名WebGL动效工程师,在公司负责可视化大屏动效的开发。从年初开始就被迫转岗,调到普通的前端开发岗位,从此开始了一段!愉快的经历。
项目样式调整和切图变成了我的主要工作。项目是从AngularJS开始写的,那是一个古老的框架,然后慢慢的迭代,一直到现在的Angular12版本。项目经过N多人的手,里面的样式文件几十个,静态以及npm包依赖上百个,各种奇奇怪怪的隐藏问题,各种奇奇怪怪的需求,各种奇奇怪怪的问题都在里面。有的时候,提一个样式修改的需求,代码一行没写,测试就已经提出一堆的bug了。有时候,一个小小的需求,需要改动几十个文件,几百行代码。有时候,一个小小样式变更,就影响了整个项目的布局,而且还不知道影响范围有多大。工作真的挺有意思的,我很喜欢,总结起来就是非常的疲惫。
我把关键词告诉AI:
一个疲惫不堪的程序员,漫画风格,男,秃头。
很快啊,它给了我一张照片,我觉得很满意,因为它忽视了秃头关键字。而是用大肚腩来代替,还有那布满血丝的大眼睛,疲惫值直接拉满!满桌子的TODO便签很是刺眼。
开始今天的正题,用canvas来实现画布的缩放和拖动吧。
在Canvas中实现鼠标缩放和移动画布的功能
Canvas是一个HTML5元素,可以通过JavaScript绘制2D图形。本文将介绍如何在Canvas中实现鼠标缩放和移动画布的功能。
首先,我们需要一个Canvas元素和一个2D绘图上下文。可以通过以下代码获取Canvas元素并获取上下文:
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
在这里,我们给Canvas元素添加了一个ID为canvas
,以便获取它。然后,我们使用getContext('2d')
方法获取了2D绘图上下文。
接下来,我们加载一张图片到Canvas中,并在加载完成后调用draw
函数绘制图片:
const img = new Image();
img.src = './疲惫的程序员.png';
img.onload = function () {
draw(0, 0, 0.5);
};
在draw
函数中,我们使用ctx.save()
和ctx.restore()
方法来保存和恢复绘图状态。然后,我们使用ctx.translate()
方法来移动Canvas中绘制的内容,以实现Canvas的移动效果。在我们的示例中,Canvas通过鼠标拖拽移动。
let isDrag = false;
let lastX = 0, _lastX = 0;
let lastY = 0, _lastY = 0;
canvas.addEventListener('mousedown', function (e) {
isDrag = true;
lastX = e.clientX - _lastX;
lastY = e.clientY - _lastY;
});
canvas.addEventListener('mousemove', function (e) {
if (isDrag) {
const x = e.clientX;
const y = e.clientY;
const dx = x - lastX;
const dy = y - lastY;
_lastX = dx;
_lastY = dy;
draw(dx, dy, scale);
}
});
canvas.addEventListener('mouseup', function (e) {
isDrag = false;
});
在代码中,我们使用鼠标事件监听器来获取鼠标的位置,并计算鼠标移动的距离。然后,我们通过调用draw
函数来绘制Canvas的内容,并传递移动的距离作为参数。
除了移动Canvas之外,我们还可以通过鼠标滚轮来缩放Canvas中的内容。在代码中,我们使用canvas.onmousewheel
监听鼠标滚轮事件,并通过ctx.scale()
方法来实现缩放效果。
let scale = 0.5;
canvas.onmousewheel = function (e) {
e.preventDefault();
const delta = e.wheelDelta / 1800;
scale += delta;
scale = Math.max(0.1, scale);
scale = Math.min(scale, 4);
draw(_dx, _dy, scale);
};
在代码中,我们首先阻止了鼠标滚轮的默认行为,然后根据鼠标滚轮的滚动方向和滚动速度来计算缩放的变化量delta
。我们将变化量累加到缩放比例scale
上,并限制缩放比例在0.1到4之间。最后,我们调用draw
函数来重新绘制Canvas的内容,并传递缩放比例作为参数。
在draw
函数中,我们首先清除Canvas上的内容,然后进行绘制操作。
function draw(dx, dy, scale) {
// 清除Canvas上的内容
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 保存当前绘图状态
ctx.save();
// 移动Canvas的绘制内容
ctx.translate(x + dx, y + dy);
// 缩放Canvas的绘制内容
ctx.scale(scale, scale);
// 绘制图片
ctx.drawImage(img, -img.width / 2, -img.height / 2, img.width, img.height);
// 进行其他绘制操作,如绘制矩形边框、文字等
// 恢复绘图状态
ctx.restore();
}
在绘制之前,我们首先保存了当前的绘图状态,包括平移、缩放等变换。然后,我们使用ctx.translate()
方法移动Canvas的绘制内容,以实现Canvas的拖拽效果。接着,我们使用ctx.scale()
方法缩放Canvas的绘制内容,根据传入的缩放比例。最后,我们绘制图片、矩形边框、文字等其他内容。
通过以上代码,我们实现了在Canvas中通过鼠标缩放和移动画布的功能。用户可以通过鼠标滚轮来缩放画布的内容,通过鼠标拖拽来移动画布的内容。同时,我们在draw
函数中可以进行其他绘制操作,如绘制图片、矩形边框和文字等。
眼球太红,就用疲惫两个字遮挡一下吧。
移动的时候 图片会变成随机的偏红色,那是我添加的一个警告,警告生命是自己的,不要被别人的所束缚,不要被别人所影响,不要被别人所左右,不要被别人所控制,不要被别人所伤害,不要被别人所限制,不要被别人所压迫。
实现方式如下:
if (Math.random() > 0.5) {
// 获取图片的像素数据
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const idata = imageData.data;
// 通过遍历data数组,修改rgba的值,实现红移效果
let k = Math.random();
for (let i = 0; i < idata.length; i += 4) {
idata[i] = idata[i] * 1.5 * k;
idata[i + 1] = idata[i + 1] * 0.7 * k;
idata[i + 2] = idata[i + 2] * 0.7 * k;
}
ctx.putImageData(imageData, 0, 0);
}
夜已深:快一点了,睡吧。最近一年每天睡眠时间很少很少。2023年最后一更。