предисловие
Я видел инструмент рисования, который поставляется с системой раньше, и это было очень интересно, поэтому я использовал реакцию и холст, чтобы реализовать простой инструмент рисования без реакции.Я в основном использовал реакцию, потому что я написал ее в исходном проекте.
Вот адрес в сети:Paint
Исходный код находится в Библиотеке под проектом:исходный код
выполнить
Функция кисти
<canvas
id="canvas"
onMouseDown={mouseEvent}
onMouseMove={mouseEvent}
onMouseUp={mouseEvent}
>
</canvas>
Сначала добавьте на холстmousedown, mousemove, mouseup
Три слушают события.
Когда мышь нажата,isDraw
Переключатель включается и выключается, когда мышь поднимается, так что управлениеmousemove
, иначе он сработает, как только вы войдете в область холстаmousemove
мероприятие.
Здесь для краткости отслеживается событие mouseEvent, внутри которого, согласноevent.type
запускать другую логику.
Мазок кисти к мазку идей:
-
Нажмите мышь, чтобы включить переключатель isDraw;
-
Перетащите и удерживайте мышь, чтобы сдвинуть триггер
mousemove
мероприятие -
Запишите информацию о положении щелчка мыши, здесь я использую двумерный массив, запишите ось X и ось Y соответственно.
-
Инициализируйте цвет, толщину и форму кисти
-
Начните рисовать линию, получите информацию о позиции, нарисованную мышью в массиве, и сделайте обводку между каждыми двумя точками, чтобы соединение точка-точка стало линией.
-
мышь вверх,
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
два метода.
Идеи:
-
После каждой операции пропускайте полотно через
toDataURL
Метод IMG Сохранить вверх, чтобы повернуть, нажмите на массив -
Когда вы нажимаете вспомнить, пройдите
drawImage
Метод загружает графику холста из последней операции. -
Удалите последние данные массива, чтобы облегчить следующую операцию вызова.
-
Определить, был ли массив опустошен, если он опустошен, операция больше не будет разрешена
код показывает, как показано ниже:
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~