Canvas滚轮缩放和拖动画布【2023年度总结:一个疲惫的程序员】

992 阅读5分钟

Canvas滚轮缩放和拖动画布

2023年度总结:一个疲惫的程序员

2023,留给这一年的时间不多了,总结一下吧。

从前我是一名WebGL动效工程师,在公司负责可视化大屏动效的开发。从年初开始就被迫转岗,调到普通的前端开发岗位,从此开始了一段!愉快的经历

项目样式调整和切图变成了我的主要工作。项目是从AngularJS开始写的,那是一个古老的框架,然后慢慢的迭代,一直到现在的Angular12版本。项目经过N多人的手,里面的样式文件几十个,静态以及npm包依赖上百个,各种奇奇怪怪的隐藏问题,各种奇奇怪怪的需求,各种奇奇怪怪的问题都在里面。有的时候,提一个样式修改的需求,代码一行没写,测试就已经提出一堆的bug了。有时候,一个小小的需求,需要改动几十个文件,几百行代码。有时候,一个小小样式变更,就影响了整个项目的布局,而且还不知道影响范围有多大。工作真的挺有意思的,我很喜欢,总结起来就是非常的疲惫。

我把关键词告诉AI:

一个疲惫不堪的程序员,漫画风格,男,秃头。

很快啊,它给了我一张照片,我觉得很满意,因为它忽视了秃头关键字。而是用大肚腩来代替,还有那布满血丝的大眼睛,疲惫值直接拉满!满桌子的TODO便签很是刺眼。

image.png

开始今天的正题,用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函数中可以进行其他绘制操作,如绘制图片、矩形边框和文字等。

眼球太红,就用疲惫两个字遮挡一下吧。

image.png

疲惫的程序员.gif

移动的时候 图片会变成随机的偏红色,那是我添加的一个警告,警告生命是自己的,不要被别人的所束缚,不要被别人所影响,不要被别人所左右,不要被别人所控制,不要被别人所伤害,不要被别人所限制,不要被别人所压迫。

实现方式如下:

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年最后一更。