当前位置:首页 > JavaScript

js实现画笔功能

2026-01-30 23:55:21JavaScript

实现基础画布与画笔功能

使用HTML5的Canvas API创建画布,并通过JavaScript监听鼠标事件实现画笔功能。以下代码展示如何初始化画布和基本绘图:

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

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

function startDrawing(e) {
    isDrawing = true;
    ctx.beginPath();
    ctx.moveTo(e.offsetX, e.offsetY);
}

function draw(e) {
    if (!isDrawing) return;
    ctx.lineTo(e.offsetX, e.offsetY);
    ctx.stroke();
}

function stopDrawing() {
    isDrawing = false;
}

自定义画笔样式

扩展基础功能以支持自定义画笔属性,包括颜色、粗细和线条样式:

// 设置默认样式
ctx.strokeStyle = '#000000';
ctx.lineWidth = 5;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';

// 动态修改样式示例
function setBrushColor(color) {
    ctx.strokeStyle = color;
}

function setBrushSize(size) {
    ctx.lineWidth = size;
}

实现触摸屏支持

为移动设备添加触摸事件处理,需注意坐标获取方式的差异:

js实现画笔功能

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

function handleTouchStart(e) {
    e.preventDefault();
    const touch = e.touches[0];
    const mouseEvent = {
        offsetX: touch.clientX - canvas.offsetLeft,
        offsetY: touch.clientY - canvas.offsetTop
    };
    startDrawing(mouseEvent);
}

function handleTouchMove(e) {
    e.preventDefault();
    const touch = e.touches[0];
    const mouseEvent = {
        offsetX: touch.clientX - canvas.offsetLeft,
        offsetY: touch.clientY - canvas.offsetTop
    };
    draw(mouseEvent);
}

function handleTouchEnd() {
    stopDrawing();
}

添加撤销与重做功能

通过保存绘图状态实现历史记录功能:

const drawingHistory = [];
let historyIndex = -1;

function saveState() {
    historyIndex++;
    if (historyIndex < drawingHistory.length) {
        drawingHistory.length = historyIndex;
    }
    drawingHistory.push(canvas.toDataURL());
}

function undo() {
    if (historyIndex <= 0) return;
    historyIndex--;
    restoreState();
}

function redo() {
    if (historyIndex >= drawingHistory.length - 1) return;
    historyIndex++;
    restoreState();
}

function restoreState() {
    const img = new Image();
    img.onload = function() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.drawImage(img, 0, 0);
    };
    img.src = drawingHistory[historyIndex];
}

// 在每次绘制结束时调用saveState()
function stopDrawing() {
    isDrawing = false;
    saveState();
}

实现压力敏感绘图(适用于支持压感的设备)

通过PointerEvent获取压力值,增强绘图体验:

js实现画笔功能

canvas.addEventListener('pointerdown', startDrawing);
canvas.addEventListener('pointermove', draw);
canvas.addEventListener('pointerup', stopDrawing);

function draw(e) {
    if (!isDrawing) return;

    // 获取压力值(0-1),不支持时默认为1
    const pressure = e.pressure || 1;
    ctx.lineWidth = baseWidth * pressure;

    ctx.lineTo(e.offsetX, e.offsetY);
    ctx.stroke();
}

清除画布与导出图像

添加实用功能完善画笔应用:

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

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

性能优化建议

对于复杂绘图场景,考虑以下优化措施:

// 使用requestAnimationFrame节流绘制操作
let lastX = 0;
let lastY = 0;

function draw(e) {
    if (!isDrawing) return;

    requestAnimationFrame(() => {
        ctx.beginPath();
        ctx.moveTo(lastX, lastY);
        ctx.lineTo(e.offsetX, e.offsetY);
        ctx.stroke();

        lastX = e.offsetX;
        lastY = e.offsetY;
    });
}

以上实现方案可根据具体需求进行组合或扩展,例如添加多种画笔类型(毛笔、铅笔等)、实现图层功能或集成到现有Web应用中。

标签: 画笔功能
分享给朋友:

相关文章

vue实现答题功能

vue实现答题功能

Vue实现答题功能的基本思路 在Vue中实现答题功能通常需要以下几个核心模块:题目数据管理、用户交互处理、答题状态跟踪和结果计算。通过组件化开发可以更好地组织代码结构。 数据结构设计 答题功能的基础…

vue实现倒计时功能

vue实现倒计时功能

vue实现倒计时功能 在Vue中实现倒计时功能可以通过多种方式完成,以下是几种常见的方法: 方法一:使用setInterval和clearInterval 创建一个倒计时组件,利用setInter…

vue实现分页功能

vue实现分页功能

Vue 分页功能实现 在 Vue 中实现分页功能通常需要结合后端 API 或前端数据分页逻辑。以下是两种常见的实现方式: 前端分页实现 适用于数据量较小的情况,直接在 Vue 组件中处理分页逻辑。…

vue实现app功能

vue实现app功能

Vue 实现 App 功能的常见方法 使用 Capacitor 或 Cordova 进行混合开发 Vue 结合 Capacitor 或 Cordova 可以将 Web 应用打包成原生 App。Capa…

vue实现全选功能

vue实现全选功能

实现全选功能的基本思路 在Vue中实现全选功能通常需要绑定一个全选复选框的状态,并通过v-model或事件监听控制子选项的选中状态。核心逻辑包括全选按钮与子选项的双向数据绑定,以及状态同步。 数据准…

vue实现的功能

vue实现的功能

Vue.js 的核心功能 Vue.js 是一个渐进式 JavaScript 框架,专注于构建用户界面。其核心功能包括数据绑定、组件化开发、指令系统和状态管理,适用于从简单交互到复杂单页应用(SPA)的…