当前位置:首页 > 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 插件的方法 Vue 插件的实现通常涉及一个包含 install 方法的对象或函数。以下是具体步骤: 定义插件对象 插件可以是一个对象或函数,但必须包含 install 方法。该方法接收…

vue表单检验插件实现

vue表单检验插件实现

Vue 表单验证插件实现 Vue 表单验证可以通过多种方式实现,包括使用第三方插件或自定义验证逻辑。以下是几种常见的方法: 使用 VeeValidate 插件 VeeValidate 是一个流行的…

vue实现扫码插件

vue实现扫码插件

Vue 实现扫码功能的插件与方法 使用 vue-qrcode-reader 插件 安装插件: npm install vue-qrcode-reader 在组件中引入: import { Qrco…

vue实现标签云插件

vue实现标签云插件

实现标签云插件的方法 安装依赖 需要安装 vue-tag-cloud 或 vue-wordcloud 等现成插件,或手动实现。以 vue-tag-cloud 为例: npm install vue-…

vue插件实现轮播图

vue插件实现轮播图

使用 vue-awesome-swiper 实现轮播图 vue-awesome-swiper 是基于 Swiper 的 Vue 轮播组件,功能强大且配置灵活。需要安装 Swiper 和 vue-awe…

vue分页插件的实现

vue分页插件的实现

实现基础分页功能 在Vue中实现分页功能,可以通过计算属性动态计算分页数据。创建一个Pagination组件,接收total(总条目数)、currentPage(当前页)和pageSize(每页显示数…