当前位置:首页 > JavaScript

js实现涂鸦面板

2026-02-02 14:30:32JavaScript

实现涂鸦面板的基本思路

涂鸦面板的核心功能包括鼠标事件监听、路径绘制和画布操作。使用HTML5的Canvas API可以高效实现这一功能。

初始化画布和上下文

在HTML中创建Canvas元素并获取2D渲染上下文:

<canvas id="drawingCanvas" width="800" height="600"></canvas>
const canvas = document.getElementById('drawingCanvas');
const ctx = canvas.getContext('2d');

设置绘制状态和样式

定义绘制状态变量和默认样式:

let isDrawing = false;
let lastX = 0;
let lastY = 0;

ctx.strokeStyle = '#000000';
ctx.lineWidth = 5;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';

实现鼠标事件处理

绑定鼠标事件来实现绘制功能:

canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', stopDrawing);
canvas.addEventListener('mouseout', stopDrawing);

function startDrawing(e) {
    isDrawing = true;
    [lastX, lastY] = [e.offsetX, e.offsetY];
}

function draw(e) {
    if (!isDrawing) return;
    ctx.beginPath();
    ctx.moveTo(lastX, lastY);
    ctx.lineTo(e.offsetX, e.offsetY);
    ctx.stroke();
    [lastX, lastY] = [e.offsetX, e.offsetY];
}

function stopDrawing() {
    isDrawing = false;
}

添加触摸屏支持

为移动设备添加触摸事件支持:

canvas.addEventListener('touchstart', handleTouchStart);
canvas.addEventListener('touchmove', handleTouchMove);
canvas.addEventListener('touchend', handleTouchEnd);

function handleTouchStart(e) {
    e.preventDefault();
    const touch = e.touches[0];
    const mouseEvent = new MouseEvent('mousedown', {
        clientX: touch.clientX,
        clientY: touch.clientY
    });
    canvas.dispatchEvent(mouseEvent);
}

function handleTouchMove(e) {
    e.preventDefault();
    const touch = e.touches[0];
    const mouseEvent = new MouseEvent('mousemove', {
        clientX: touch.clientX,
        clientY: touch.clientY
    });
    canvas.dispatchEvent(mouseEvent);
}

function handleTouchEnd(e) {
    e.preventDefault();
    const mouseEvent = new MouseEvent('mouseup', {});
    canvas.dispatchEvent(mouseEvent);
}

实现清除功能

添加清除画布的功能:

function clearCanvas() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
}

添加颜色选择功能

实现颜色选择器:

<input type="color" id="colorPicker" value="#000000">
const colorPicker = document.getElementById('colorPicker');
colorPicker.addEventListener('change', (e) => {
    ctx.strokeStyle = e.target.value;
});

实现线宽调整

添加线宽调整滑块:

<input type="range" id="lineWidth" min="1" max="50" value="5">
const lineWidth = document.getElementById('lineWidth');
lineWidth.addEventListener('change', (e) => {
    ctx.lineWidth = e.target.value;
});

保存绘制内容

实现画布内容保存为图片:

function saveDrawing() {
    const link = document.createElement('a');
    link.download = 'drawing.png';
    link.href = canvas.toDataURL('image/png');
    link.click();
}

优化绘制性能

对于复杂绘制场景,可以使用requestAnimationFrame优化性能:

function drawOptimized(e) {
    if (!isDrawing) return;
    requestAnimationFrame(() => {
        ctx.beginPath();
        ctx.moveTo(lastX, lastY);
        ctx.lineTo(e.offsetX, e.offsetY);
        ctx.stroke();
        [lastX, lastY] = [e.offsetX, e.offsetY];
    });
}

添加撤销功能

实现简单的撤销功能:

const undoStack = [];
const MAX_UNDO_STEPS = 20;

function saveState() {
    if (undoStack.length >= MAX_UNDO_STEPS) {
        undoStack.shift();
    }
    undoStack.push(canvas.toDataURL());
}

function undo() {
    if (undoStack.length > 0) {
        const img = new Image();
        img.onload = function() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            ctx.drawImage(img, 0, 0);
        };
        img.src = undoStack.pop();
    }
}

在绘制事件中调用saveState()来保存状态。

实现橡皮擦功能

添加橡皮擦工具:

let isErasing = false;

function toggleEraser() {
    isErasing = !isErasing;
    if (isErasing) {
        ctx.globalCompositeOperation = 'destination-out';
    } else {
        ctx.globalCompositeOperation = 'source-over';
    }
}

这个实现提供了完整的涂鸦面板功能,包括基本绘制、样式调整、触摸支持、撤销和保存等功能。可以根据需要进一步扩展功能或优化性能。

js实现涂鸦面板

标签: 涂鸦面板
分享给朋友:

相关文章

vue实现面板收缩效果

vue实现面板收缩效果

Vue 实现面板收缩效果 使用 v-show 和 v-if 控制显示 在 Vue 中,可以利用 v-show 或 v-if 指令来控制面板的显示与隐藏。v-show 通过 CSS 的 displa…

vue实现折叠面板

vue实现折叠面板

实现折叠面板的基本思路 使用Vue实现折叠面板的核心是通过数据驱动视图变化,结合CSS过渡效果或动画实现展开/折叠的平滑效果。主要依赖v-show或v-if控制内容显示,通过点击事件切换状态。 基…

react实现切换面板

react实现切换面板

使用状态管理切换面板 在React中,可以通过useState钩子来管理当前显示的面板状态。定义一个状态变量存储当前激活的面板标识,通过点击事件切换状态值。 import React, { useS…

react实现树形权限面板

react实现树形权限面板

实现思路 树形权限面板通常用于管理系统中的角色权限分配,需要展示层级结构的权限列表,并支持勾选操作。React 结合第三方库如 antd 的 Tree 组件可以高效实现。 安装依赖 确保项目中已安装…

react怎么实现树形面板

react怎么实现树形面板

实现树形面板的方法 使用React实现树形面板可以通过递归组件、状态管理和第三方库等多种方式完成。以下是几种常见的方法: 递归组件实现 递归组件是处理树形结构的自然方式,通过组件调用自身来渲染子节…

react实现折叠面板

react实现折叠面板

React 实现折叠面板的方法 使用 useState 管理状态 通过 React 的 useState 钩子管理折叠面板的展开/折叠状态。定义一个布尔值状态变量(如 isExpanded)和对应的更…