当前位置:首页 > 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()来保存状态。

实现橡皮擦功能

添加橡皮擦工具:

js实现涂鸦面板

let isErasing = false;

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

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

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

相关文章

react实现折叠面板

react实现折叠面板

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

vue实现面板拖拽

vue实现面板拖拽

Vue 实现面板拖拽的方法 使用 HTML5 原生拖拽 API HTML5 提供了原生的拖拽 API,可以通过 draggable 属性和相关事件实现拖拽功能。在 Vue 中,可以通过绑定这些事件来实…

vue实现滑动面板

vue实现滑动面板

Vue 实现滑动面板的方法 使用第三方库(如 vue-swipe) 安装 vue-swipe 库: npm install vue-swipe --save 在组件中引入并使用: <temp…

vue实现面板收缩效果

vue实现面板收缩效果

使用 Vue 实现面板收缩效果 使用 v-show 指令 通过 v-show 控制面板的显示与隐藏,结合按钮切换状态。 <template> <div> <…

vue实现折叠面板

vue实现折叠面板

Vue 实现折叠面板的方法 使用 v-show 或 v-if 控制显示 通过 Vue 的指令 v-show 或 v-if 结合点击事件切换面板的展开与折叠状态。v-show 通过 CSS 的 disp…

java如何设置面板

java如何设置面板

设置面板的基本方法 在Java中创建面板通常使用JPanel类,它是Swing库的一部分。JPanel是一个轻量级容器,用于组织其他组件。 import javax.swing.*; public…