当前位置:首页 > JavaScript

js插件实现画笔绘图

2026-01-31 04:49:05JavaScript

使用HTML5 Canvas实现画笔绘图

HTML5的Canvas API是浏览器原生支持的绘图工具,无需额外插件即可实现画笔功能。以下是一个基础实现示例:

const canvas = document.getElementById('drawingCanvas');
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();
    ctx.beginPath();
    ctx.moveTo(e.offsetX, e.offsetY);
}

function stopDrawing() {
    isDrawing = false;
}

使用第三方库Fabric.js

Fabric.js是一个功能强大的Canvas库,提供更高级的绘图功能:

const canvas = new fabric.Canvas('drawingCanvas');
let isDrawing = false;

canvas.on('mouse:down', (o) => {
    isDrawing = true;
    const pointer = canvas.getPointer(o.e);
    canvas.freeDrawingBrush.startFrom({ x: pointer.x, y: pointer.y });
});

canvas.on('mouse:move', (o) => {
    if (!isDrawing) return;
    const pointer = canvas.getPointer(o.e);
    canvas.freeDrawingBrush.moveTo({ x: pointer.x, y: pointer.y });
});

canvas.on('mouse:up', () => {
    isDrawing = false;
});

// 设置画笔样式
canvas.freeDrawingBrush = new fabric.PencilBrush(canvas);
canvas.freeDrawingBrush.color = '#000000';
canvas.freeDrawingBrush.width = 5;

使用SVG实现矢量绘图

SVG也是浏览器原生支持的矢量绘图方案:

const svg = document.getElementById('drawingSvg');
let isDrawing = false;
let currentPath;

svg.addEventListener('mousedown', (e) => {
    isDrawing = true;
    currentPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
    currentPath.setAttribute('stroke', 'black');
    currentPath.setAttribute('fill', 'none');
    currentPath.setAttribute('stroke-width', '2');
    const startPoint = `M ${e.offsetX} ${e.offsetY} `;
    currentPath.setAttribute('d', startPoint);
    svg.appendChild(currentPath);
});

svg.addEventListener('mousemove', (e) => {
    if (!isDrawing) return;
    const newPoint = `L ${e.offsetX} ${e.offsetY}`;
    const existingPath = currentPath.getAttribute('d');
    currentPath.setAttribute('d', existingPath + newPoint);
});

svg.addEventListener('mouseup', () => {
    isDrawing = false;
});

添加触摸屏支持

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

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

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

canvas.addEventListener('touchend', (e) => {
    e.preventDefault();
    const mouseEvent = new MouseEvent('mouseup', {});
    canvas.dispatchEvent(mouseEvent);
});

实现撤销重做功能

为绘图工具添加历史记录功能:

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

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

function undo() {
    if (historyIndex <= 0) return;
    historyIndex--;
    const img = new Image();
    img.onload = () => {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.drawImage(img, 0, 0);
    };
    img.src = history[historyIndex];
}

function redo() {
    if (historyIndex >= history.length - 1) return;
    historyIndex++;
    const img = new Image();
    img.onload = () => {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.drawImage(img, 0, 0);
    };
    img.src = history[historyIndex];
}

添加画笔样式选项

提供多种画笔样式选择:

js插件实现画笔绘图

function setBrushColor(color) {
    ctx.strokeStyle = color;
    ctx.fillStyle = color;
}

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

function setBrushType(type) {
    switch(type) {
        case 'pencil':
            ctx.globalCompositeOperation = 'source-over';
            ctx.lineCap = 'round';
            ctx.lineJoin = 'round';
            break;
        case 'marker':
            ctx.globalCompositeOperation = 'multiply';
            ctx.lineCap = 'square';
            ctx.lineJoin = 'bevel';
            break;
        case 'eraser':
            ctx.globalCompositeOperation = 'destination-out';
            ctx.lineCap = 'round';
            ctx.lineJoin = 'round';
            break;
    }
}

标签: 画笔插件
分享给朋友:

相关文章

vue实现预热插件

vue实现预热插件

Vue 预热插件实现方法 预热插件(Preheat Plugin)通常用于在 Vue 应用初始化前预加载数据或执行必要操作,提升用户体验。以下是实现方案: 插件基本结构 创建 preheat-plu…

vue实现图片插件

vue实现图片插件

Vue 图片插件实现方案 在 Vue 中实现图片插件通常涉及图片展示、懒加载、预览等功能。以下是几种常见的实现方式: 基础图片组件封装 创建一个可复用的图片组件,支持默认图片、加载失败处理等基础功能…

vue如何实现插件

vue如何实现插件

Vue 插件实现方法 Vue 插件是一种可复用的功能模块,可以通过全局或局部方式注入到 Vue 应用中。以下是实现 Vue 插件的详细方法。 插件基本结构 Vue 插件通常是一个对象或函数,必须包含…

vue实现代码插件

vue实现代码插件

Vue 实现代码插件的方法 使用第三方库(如 Prism.js 或 Highlight.js) 安装 Prism.js 或 Highlight.js 库,这些库专门用于代码高亮显示。在 Vue 项目中…

vue使用插件实现拖拽

vue使用插件实现拖拽

安装拖拽插件 推荐使用vuedraggable插件,它是基于Sortable.js的Vue组件,支持拖拽排序功能。通过npm或yarn安装: npm install vuedraggable --s…

vue实现瀑布流插件

vue实现瀑布流插件

Vue实现瀑布流插件的方法 使用现有库(如vue-waterfall) 安装vue-waterfall库: npm install vue-waterfall --save 在Vue组件中使用:…