Пример редактора тапа «Paint» с картинкой-подложкой, на которой можно рисовать мышью с последующей отправкой на сервер.
Основой редактора является элемент <canvas>
, также понадобятся кнопки для отмены действий и полной очистки холста.
<a href="#" id="undo">Отменить</a>
<a href="#" id="clear">Очистить</a>
<form id="form" action="" method="post">
<div class="paint-canvas">
<canvas id="canvas" width="705" height="353"></canvas>
<input id="canvas_img" type="hidden" name="canvas_img" value="">
</div>
<div class="paint-submit">
<input type="submit" name="send" value="Отправить форму">
</div>
</form>
JS-код редактора (c jQuery):
window.addEventListener("load", function onWindowLoad(){
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var points = [];
// Загрузка изображения в canvas
var img = new Image();
img.src = 'https://snipp.ru/demo/730/bg.jpg';
img.addEventListener('load', function(){
ctx.drawImage(img, 0, 0);
var mouseX = 0;
var mouseY = 0;
// Стиль линии
ctx.strokeStyle = 'red';
ctx.lineWidth = 2;
var isDrawing = false;
// Обработчики рисования мышкой
canvas.addEventListener('mousedown', function(event) {
setMouseCoordinates(event);
isDrawing = true;
ctx.beginPath();
ctx.moveTo(mouseX, mouseY);
points.push({
x: mouseX,
y: mouseY,
mode: "begin"
});
});
canvas.addEventListener('mousemove', function(event) {
setMouseCoordinates(event);
if(isDrawing){
ctx.lineTo(mouseX, mouseY);
ctx.stroke();
points.push({
x: mouseX,
y: mouseY,
mode: "draw"
});
}
});
canvas.addEventListener('mouseup', function(event) {
setMouseCoordinates(event);
isDrawing = false;
points.push({
x: mouseX,
y: mouseY,
mode: "end"
});
});
function setMouseCoordinates(event) {
mouseX = event.offsetX;
mouseY = event.offsetY;
}
// Кнопка «Очистить»
$('#clear').click(function(){
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0);
return false;
});
// Функции для кнопки «Отменить»
function redrawAll() {
if (points.length == 0) {
return;
}
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0);
for (var i = 0; i < points.length; i++) {
var pt = points[i];
if (pt.mode == "begin") {
ctx.beginPath();
ctx.moveTo(pt.x, pt.y);
}
ctx.lineTo(pt.x, pt.y);
if (pt.mode == "end" || (i == points.length - 1)) {
ctx.stroke();
}
}
ctx.stroke();
}
function undoLast() {
points.pop();
redrawAll();
}
// Кнопка «Отменить»
var interval;
$("#undo").mousedown(function(){
interval = setInterval(undoLast, 50);
}).mouseup(function(){
clearInterval(interval);
}).click(function(){
return false;
});
$('#form').submit(function(){
$('#canvas_img').val(canvas.toDataURL("image/jpg"));
return true;
});
});
});
CSS-стили для canvas:
#canvas {
display: block;
box-sizing: border-box;
border: 1px solid #e0e0e0;
cursor: crosshair;
margin: 0 0 20px;
}
Результат:
Сохранение canvas на сервере
При отправки формы, с помощью метода toDataURL
содержимое canvas помещается в скрытое поле <input id="canvas_img" type="hidden" name="canvas_img" value="">
в виде строки base64:
data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNby....
На сервере остается её декодировать и сохранить в файл: