React-версия инструмента рисования

React.js

предисловие

Я видел инструмент рисования, который поставляется с системой раньше, и это было очень интересно, поэтому я использовал реакцию и холст, чтобы реализовать простой инструмент рисования без реакции.Я в основном использовал реакцию, потому что я написал ее в исходном проекте.

Вот адрес в сети:Paint

Исходный код находится в Библиотеке под проектом:исходный код

выполнить

Функция кисти

<canvas
    id="canvas"
    onMouseDown={mouseEvent}
    onMouseMove={mouseEvent}
    onMouseUp={mouseEvent}
>
</canvas>

Сначала добавьте на холстmousedown, mousemove, mouseupТри слушают события.

Когда мышь нажата,isDrawПереключатель включается и выключается, когда мышь поднимается, так что управлениеmousemove, иначе он сработает, как только вы войдете в область холстаmousemoveмероприятие.

Здесь для краткости отслеживается событие mouseEvent, внутри которого, согласноevent.typeзапускать другую логику.

Мазок кисти к мазку идей:

  1. Нажмите мышь, чтобы включить переключатель isDraw;

  2. Перетащите и удерживайте мышь, чтобы сдвинуть триггерmousemoveмероприятие

  3. Запишите информацию о положении щелчка мыши, здесь я использую двумерный массив, запишите ось X и ось Y соответственно.

  4. Инициализируйте цвет, толщину и форму кисти

  5. Начните рисовать линию, получите информацию о позиции, нарисованную мышью в массиве, и сделайте обводку между каждыми двумя точками, чтобы соединение точка-точка стало линией.

  6. мышь вверх,isDrawвыкл., отключить запускmousemove

Общая идея такова, вот реализация кода:

    const mouseEvent = (e) => {
        let ctx = canvas2D.getContext('2d')

        e.persist()
        if (e.type === 'mousedown') {
            switch (active) {
                case 'spray':
                    return canvas2D.style.backgroundColor = color
                default:
                    isDraw = true
                    arr = []
                    return
            }

        }
        if (e.type === 'mousemove' && isDraw) {
            arr.push([e.pageX - canvas2D.offsetLeft, e.pageY - document.querySelector('.admin-box').offsetTop - 40])

            switch (active) {
                case 'pen':
                    ctx.strokeStyle = color
                    ctx.lineJoin = "round";
                    ctx.lineWidth = 5;
                    ctx.beginPath();
                    arr.length > 1 && ctx.moveTo(arr[arr.length - 2][0], arr[arr.length - 2][1]);
                    ctx.lineTo(arr[arr.length - 1][0], arr[arr.length - 1][1]);
                    ctx.closePath();
                    ctx.stroke();  //描边
                    return
                
                default:
                    return
            }

        }
        if (e.type === 'mouseup') {
            setCanvasUrl(url => {
                url.push(canvas2D.toDataURL())
                return url
            })
            isDraw = false
        }
    }

Резинка

С ластиком здесь немного хитрости: он покрывает цвет кисти фоновым цветом, так что создается впечатление, что он был стерт. Идея такая же, как и идея с кистью, просто измените цвет на цвет фона.

    case 'eraser':
        ctx.strokeStyle = canvas2D.style.backgroundColor || '#ccc'
        ctx.lineJoin = "round";
        ctx.lineWidth = 50;
        ctx.beginPath();
        arr.length > 1 && ctx.moveTo(arr[arr.length - 2][0], arr[arr.length - 2][1]);
        ctx.lineTo(arr[arr.length - 1][0], arr[arr.length - 1][1]);
        ctx.closePath();
        ctx.stroke();  //描边
        return

Ведро краски

Это самое простое, получить цвет на доске цветов, заменить цвет фона, и все в порядке.

нарисовать прямоугольник

Чтобы нарисовать прямоугольникclearRectа такжеstrokeRectДва метода, они принимают 4 параметра, это координаты начальной точки X, Y и длина и ширина прямоугольника.

Идеи:

каждый триггерmousemoveНа самом деле рисуются прямоугольники, но мы можем очистить предыдущую область перед тем, как будет нарисован каждый прямоугольник.

clearRectэто очистить следы в прямоугольнике

Похоже, мы нарисовали прямоугольник

case 'rectangle':
    let left = arr[0][0]
    let top = arr[0][1]
    let prewidth = arr.length > 1 && arr[arr.length - 2][0] - left
    let preheight = arr.length > 1 && arr[arr.length - 2][1] - top
    let width = arr[arr.length - 1][0] - left
    let height = arr[arr.length - 1][1] - top
    ctx.beginPath();
    ctx.lineWidth = "6";
    ctx.strokeStyle = "red";
    ctx.clearRect(left, top, prewidth, preheight)
    ctx.strokeRect(left, top, width, height);
    return

Отменить предыдущую функцию

Это использует холстdrawImageа такжеtoDataURLдва метода.

Идеи:

  1. После каждой операции пропускайте полотно черезtoDataURLМетод IMG Сохранить вверх, чтобы повернуть, нажмите на массив

  2. Когда вы нажимаете вспомнить, пройдитеdrawImageМетод загружает графику холста из последней операции.

  3. Удалите последние данные массива, чтобы облегчить следующую операцию вызова.

  4. Определить, был ли массив опустошен, если он опустошен, операция больше не будет разрешена

код показывает, как показано ниже:

const recallClick = (e) => {
    let ctx = canvas2D.getContext('2d')
    let step = canvasUrl.length - 1
    if (step >= 0) {
        step--;
        ctx.clearRect(0, 0, 1000, 1000);
        let canvasPic = new Image();
        canvasPic.src = canvasUrl[step];
        canvasPic.addEventListener('load', () => {
            ctx.drawImage(canvasPic, 0, 0);
        });

        setCanvasUrl(canvasUrl => {
            canvasUrl.pop()
            return canvasUrl
        })
    } else {
        console.log('不能再继续撤销了');
    }

}

Функция загрузки

пройти черезtoDataURLПолучите текущую графику CANVAS. Создайте вкладку A, назначьте ей адрес, выполните загрузку события клика. Эта реализация относительно проста, но это общая идея, или всплывающее окно также может быть изменено в соответствии со сценой.

код показывает, как показано ниже:

const downloadImg = () => {
    var url = canvas2D.toDataURL('image/png');
    var a = document.createElement('a');
    document.body.appendChild(a);
    a.href = url;
    a.download = '我的绘画';
    a.target = '_blank';
    a.click();
}

палитра цветов

используется здесьreact-colorплагин.

конец

На этом этапе идея простой чертежной доски ясно объяснена, и вы можете разработать на этой основе больше функций в будущем.

fighting~