Форум программистов, компьютерный форум, киберфорум
JavaScript: HTML5 Canvas
Войти
Регистрация
Восстановить пароль
 
1 / 0 / 0
Регистрация: 26.10.2010
Сообщений: 5
1

Как отменить последнее действие при рисовании в canvas карандашом (pencil)?

24.04.2020, 00:39. Показов 537. Ответов 0

Задача:
  • создать холст canvas с возможностью свободного рисования на нем "карандашом",
  • с возможностью полной отмены нарисованного (очисткой холста)
  • с возможностью отмены последнего действия (последней линии, нарисованной "карандашом").

Статус выполнения: выполнено частично. Создан холст, работает "карандаш", работает полная очистка холста. Не получается написать механизм отмены последнего действия ''карандаша", последней проведенной кривой.

Причина сбоя: не хватает данных из-за недостаточного личного опыта работы с canvas. Гугление ТОП-30 к явному ответу также не привело.

Запрос: помощь и/или совет по решению задачи отмены последнего действия "карандаша".

Плюс, ответ на этот вопрос заполнит в Сети информационный пробел для будущих разработчиков.

Текущий код JS:

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
if(window.addEventListener) {
    window.addEventListener('load', function () {
    
    var canvas, context, tool;
 
    function init () {
        // Находим canvas элемент
        canvas = document.getElementById('tablet');
        
        if (!canvas) {
            alert('Ошибка! Canvas элемент не найден!');
            return;
        }
 
        if (!canvas.getContext) {
            alert('Ошибка: canvas.getContext не существует!');
            return;
        }
 
        // Получаем 2D canvas context.
        context = canvas.getContext('2d');
        if (!context) {
            alert('Ошибка: getContext! не существует');
            return;
        }
        
        tool = new tool_pencil();
        canvas.addEventListener('mousedown', ev_canvas, false);
        canvas.addEventListener('mousemove', ev_canvas, false);
        canvas.addEventListener('mouseup',   ev_canvas, false);
    }
    
        // Очистка всего нарисованного на поле
        document.getElementById('clear').addEventListener('click', function() {
        context.clearRect(0, 0, tablet.width, tablet.height);
        }, false);
 
    // Здесь мы будем ловить движения мыши
    function tool_pencil () {
        var tool = this;
        this.started = false;
 
    
        this.mousedown = function (ev) {
            context.beginPath();
            context.moveTo(ev._x, ev._y);
            tool.started = true;
        };
 
        // Эта функция вызывается каждый раз, когда вы перемещаете мышь.
        // Но рисование происходит только когда вы удерживаете кнопку мыши
        // нажатой.
        this.mousemove = function (ev) {
            if (tool.started) {
                context.lineTo(ev._x, ev._y);
                context.stroke();
            }
        };
 
        // Событие при отпускании мыши
        this.mouseup = function (ev) {
            if (tool.started) {
                tool.mousemove(ev);
                tool.started = false;
            }
        };
    }
 
    // Эта функция определяет позицию курсора относительно холста
    function ev_canvas (ev) {
        if (ev.layerX || ev.layerX == 0) { // Firefox
            ev._x = ev.layerX;
            ev._y = ev.layerY;
        } else if (ev.offsetX || ev.offsetX == 0) { // Opera
            ev._x = ev.offsetX;
            ev._y = ev.offsetY;
        }
 
        // Вызываем обработчик события tool
        var func = tool[ev.type];
        if (func) {
            func(ev);
        }
    }
 
    init();
 
}, false); }
И очевидный тег в HTML:

HTML5
1
2
<canvas id = "tablet" width="1050" height="900"></canvas>
<button id="clear">Очистка всего холста</button>
Благодарю сообщество за помощь в решении!

Добавлено через 26 минут
Вопрос снят. Для меня подходит ответ тут: https://stackoverflow.com/ques... ing-canvas

Пуст код останется для будущих искателей, не знакомых с английским:

HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<!--[if lt IE 9]><script type="text/javascript" src="../excanvas.js"></script><![endif]-->
 
<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>
 
<script>
$(function(){
 
    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var lastX;
    var lastY;
    var mouseX;
    var mouseY;
    var canvasOffset=$("#canvas").offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;
    var isMouseDown=false;
    var brushSize=20;
    var brushColor="#ff0000";
    var points=[];
 
 
    function handleMouseDown(e){
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
 
      // Put your mousedown stuff here
      ctx.beginPath();
      if(ctx.lineWidth!=brushSize){ctx.lineWidth=brushSize;}
      if(ctx.strokeStyle!=brushColor){ctx.strokeStyle=brushColor;}
      ctx.moveTo(mouseX,mouseY);
      points.push({x:mouseX,y:mouseY,size:brushSize,color:brushColor,mode:"begin"});
      lastX=mouseX;
      lastY=mouseY;
      isMouseDown=true;
    }
 
    function handleMouseUp(e){
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
 
      // Put your mouseup stuff here
      isMouseDown=false;
      points.push({x:mouseX,y:mouseY,size:brushSize,color:brushColor,mode:"end"});
    }
 
 
    function handleMouseMove(e){
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
 
      // Put your mousemove stuff here
      if(isMouseDown){
          ctx.lineTo(mouseX,mouseY);
          ctx.stroke();     
          lastX=mouseX;
          lastY=mouseY;
          // command pattern stuff
          points.push({x:mouseX,y:mouseY,size:brushSize,color:brushColor,mode:"draw"});
      }
    }
 
 
    function redrawAll(){
 
        if(points.length==0){return;}
 
        ctx.clearRect(0,0,canvas.width,canvas.height);
 
        for(var i=0;i<points.length;i++){
 
          var pt=points[i];
 
          var begin=false;
 
          if(ctx.lineWidth!=pt.size){
              ctx.lineWidth=pt.size;
              begin=true;
          }
          if(ctx.strokeStyle!=pt.color){
              ctx.strokeStyle=pt.color;
              begin=true;
          }
          if(pt.mode=="begin" || 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();
    }
 
    ctx.lineJoin = "round";
    ctx.fillStyle=brushColor;
    ctx.lineWidth=brushSize;
 
    $("#brush5").click(function(){ brushSize=5; });
    $("#brush10").click(function(){ brushSize=10; });
    // Important!  Brush colors must be defined in 6-digit hex format only
    $("#brushRed").click(function(){ brushColor="#ff0000"; });
    $("#brushBlue").click(function(){ brushColor="#0000ff"; });
 
    $("#canvas").mousedown(function(e){handleMouseDown(e);});
    $("#canvas").mousemove(function(e){handleMouseMove(e);});
    $("#canvas").mouseup(function(e){handleMouseUp(e);});
 
    // hold down the undo button to erase the last line segment
    var interval;
    $("#undo").mousedown(function() {
      interval = setInterval(undoLast, 100);
    }).mouseup(function() {
      clearInterval(interval);
    });
 
 
}); // end $(function(){});
</script>
 
</head>
 
<body>
    <p>Drag to draw. Use buttons to change lineWidth/color</p>
    <canvas id="canvas" width=300 height=300></canvas><br>
    <button id="undo">Hold this button down to Undo</button><br><br>
    <button id="brush5">5px Brush</button>
    <button id="brush10">10px Brush</button>
    <button id="brushRed">Red Brush</button>
    <button id="brushBlue">Blue Brush</button>
</body>
</html>
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.04.2020, 00:39
Ответы с готовыми решениями:

Как отменить последнее действие в DataGridView1
Как прописать возможность отмены последнего действия в DataGridView1 средствами visual basic net

Как отменить действие при щелчке в любом месте страницы
Всем привет ,у меня такой вопрос .написал код ,который увеличивает изображение по щелчке по нему...

Как убрать последнее действие при обновлении страницы?!!
Здравствуйте уважаемые! Есть TextBox в который я ввожу текст и по нажатии на кнопку значение...

Пропуск пикселей при рисовании на canvas
Здравствуйте. Проблема такая: есть изображение - и такой код в xe7 - Graphics::TBitmap...

0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.04.2020, 00:39

Заказываю контрольные, курсовые, дипломные работы и диссертации здесь.

При рисовании на Bitmap.Canvas исчезает основное изображение
Procedure TDynamicObjects.Drawsquare(xmax, ymax, ymin, xmin: integer); begin ...

Ошибка при рисовании на форме через Canvas->FloodFill
Рисую на форме с CANVAS-&gt;FloodFill. Есть 2 формы. Хочу по нажатию клавиши на одной форме рисовать в...

Игра на Canvas как реализовать гравитацию и действие(событие) при соприкосновении с объектом
Как реализовать гравитацию и действие(событие) при соприкосновении с объектом. Хочу реализовать...

Как отменить действие стиля?
В главном html таблица красится через tbody tr:nth-child(odd) Присоединяю по событию другой html и...

Отменить действие как в блокноте
как мне отменить действие как в блокноте??

Как отменить действие обработчика?
Добрый вечер. Возник такой вопрос, можно ли по клику на кнопку отменить предыдущую обработку...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.