Zeichnen Sie mit der Maus auf HTML5 Canvas


110

Ich möchte mit einer Maus auf eine HTML-Leinwand zeichnen (z. B. eine Signatur zeichnen, einen Namen zeichnen, ...)

Bitte helfen Sie mir, wie kann ich tun? Bitte geben Sie einen Quellcode an. Danke dir




Antworten:


223

Hier ist ein Arbeitsbeispiel.

 <html>
    <script type="text/javascript">
    var canvas, ctx, flag = false,
        prevX = 0,
        currX = 0,
        prevY = 0,
        currY = 0,
        dot_flag = false;

    var x = "black",
        y = 2;
    
    function init() {
        canvas = document.getElementById('can');
        ctx = canvas.getContext("2d");
        w = canvas.width;
        h = canvas.height;
    
        canvas.addEventListener("mousemove", function (e) {
            findxy('move', e)
        }, false);
        canvas.addEventListener("mousedown", function (e) {
            findxy('down', e)
        }, false);
        canvas.addEventListener("mouseup", function (e) {
            findxy('up', e)
        }, false);
        canvas.addEventListener("mouseout", function (e) {
            findxy('out', e)
        }, false);
    }
    
    function color(obj) {
        switch (obj.id) {
            case "green":
                x = "green";
                break;
            case "blue":
                x = "blue";
                break;
            case "red":
                x = "red";
                break;
            case "yellow":
                x = "yellow";
                break;
            case "orange":
                x = "orange";
                break;
            case "black":
                x = "black";
                break;
            case "white":
                x = "white";
                break;
        }
        if (x == "white") y = 14;
        else y = 2;
    
    }
    
    function draw() {
        ctx.beginPath();
        ctx.moveTo(prevX, prevY);
        ctx.lineTo(currX, currY);
        ctx.strokeStyle = x;
        ctx.lineWidth = y;
        ctx.stroke();
        ctx.closePath();
    }
    
    function erase() {
        var m = confirm("Want to clear");
        if (m) {
            ctx.clearRect(0, 0, w, h);
            document.getElementById("canvasimg").style.display = "none";
        }
    }
    
    function save() {
        document.getElementById("canvasimg").style.border = "2px solid";
        var dataURL = canvas.toDataURL();
        document.getElementById("canvasimg").src = dataURL;
        document.getElementById("canvasimg").style.display = "inline";
    }
    
    function findxy(res, e) {
        if (res == 'down') {
            prevX = currX;
            prevY = currY;
            currX = e.clientX - canvas.offsetLeft;
            currY = e.clientY - canvas.offsetTop;
    
            flag = true;
            dot_flag = true;
            if (dot_flag) {
                ctx.beginPath();
                ctx.fillStyle = x;
                ctx.fillRect(currX, currY, 2, 2);
                ctx.closePath();
                dot_flag = false;
            }
        }
        if (res == 'up' || res == "out") {
            flag = false;
        }
        if (res == 'move') {
            if (flag) {
                prevX = currX;
                prevY = currY;
                currX = e.clientX - canvas.offsetLeft;
                currY = e.clientY - canvas.offsetTop;
                draw();
            }
        }
    }
    </script>
    <body onload="init()">
        <canvas id="can" width="400" height="400" style="position:absolute;top:10%;left:10%;border:2px solid;"></canvas>
        <div style="position:absolute;top:12%;left:43%;">Choose Color</div>
        <div style="position:absolute;top:15%;left:45%;width:10px;height:10px;background:green;" id="green" onclick="color(this)"></div>
        <div style="position:absolute;top:15%;left:46%;width:10px;height:10px;background:blue;" id="blue" onclick="color(this)"></div>
        <div style="position:absolute;top:15%;left:47%;width:10px;height:10px;background:red;" id="red" onclick="color(this)"></div>
        <div style="position:absolute;top:17%;left:45%;width:10px;height:10px;background:yellow;" id="yellow" onclick="color(this)"></div>
        <div style="position:absolute;top:17%;left:46%;width:10px;height:10px;background:orange;" id="orange" onclick="color(this)"></div>
        <div style="position:absolute;top:17%;left:47%;width:10px;height:10px;background:black;" id="black" onclick="color(this)"></div>
        <div style="position:absolute;top:20%;left:43%;">Eraser</div>
        <div style="position:absolute;top:22%;left:45%;width:15px;height:15px;background:white;border:2px solid;" id="white" onclick="color(this)"></div>
        <img id="canvasimg" style="position:absolute;top:10%;left:52%;" style="display:none;">
        <input type="button" value="save" id="btn" size="30" onclick="save()" style="position:absolute;top:55%;left:10%;">
        <input type="button" value="clear" id="clr" size="23" onclick="erase()" style="position:absolute;top:55%;left:15%;">
    </body>
    </html>


7
Warum wechselst du? Sie können auch x = obj.id ausführen. Getan.
MarijnS95

1
Ich versuche, diesen Code zu verwenden, habe jedoch Probleme damit, dass die Zeichnung vertikal deaktiviert ist, wenn ich nicht ganz nach unten auf der Seite gescrollt bin. Was soll ich an diesem Code ändern?
Cameron Darlington

8
Ich änderte canvas.offsetLeft;und canvas.offsetTop;mit canvas.getBoundingClientRect().left;und canvas.getBoundingClientRect().top;jeweils das Scrollen Problem zu beheben.
KWILLIAMS

1
Funktioniert nicht auf einem Touchscreen. Bezieht sich nicht auf Tabletten. Ich meine einen Windows 10-Laptop mit einer Maus und einem Touchscreen.
Paul

2
Damit dies mit einem Zeichenstift (wie einem Grafiktablett) funktioniert, müssen die Mausereignisse durch Berührungsereignisse ersetzt werden, z. touchmove, touchstart, touchendUnd dann das clientXkommt von e.touches["0"].clientXim findxy()Code, nicht von einer einfachen Art und Weise gedacht zu erkennen , was allerdings verwendet werden ist, da Sie nicht auf beiden Ereignisse zur gleichen Zeit von dem, was ich habe getestet hören. Ich ging mouseoutwie es ist. Es ist nicht perfekt, aber es funktioniert
Jacob David C. Cunningham

38

Hier ist der einfachste Weg, eine Zeichenanwendung mit Leinwand zu erstellen:

  1. Bringen Sie ein mousedown, mousemoveundmouseup Ereignis - Listener auf die Leinwand DOM
  2. auf mousedown, bekommen Sie die Mauskoordinaten und die Verwendung moveTo()Methode Zeichnung Cursor und die Positionierung beginPath()Methode eine neue Ziehweg zu beginnen.
  3. auf mousemove, kontinuierlich einen neuen Punkt zu dem Pfad mit ADD lineTo()und die Farbe das letzte Segment mit stroke().
  4. auf mouseup, einen Flag gesetzt um die Zeichnung zu deaktivieren.

Von dort aus können Sie alle Arten anderer Funktionen hinzufügen, z. B. dem Benutzer die Möglichkeit geben, eine Strichstärke, Farbe, Pinselstriche und sogar Ebenen auszuwählen.


28

Ich denke, andere Beispiele hier sind zu kompliziert. Dieser ist einfacher und nur JS ...

// create canvas element and append it to document body
var canvas = document.createElement('canvas');
document.body.appendChild(canvas);

// some hotfixes... ( ≖_≖)
document.body.style.margin = 0;
canvas.style.position = 'fixed';

// get canvas 2D context and set him correct size
var ctx = canvas.getContext('2d');
resize();

// last known position
var pos = { x: 0, y: 0 };

window.addEventListener('resize', resize);
document.addEventListener('mousemove', draw);
document.addEventListener('mousedown', setPosition);
document.addEventListener('mouseenter', setPosition);

// new position from mouse event
function setPosition(e) {
  pos.x = e.clientX;
  pos.y = e.clientY;
}

// resize canvas
function resize() {
  ctx.canvas.width = window.innerWidth;
  ctx.canvas.height = window.innerHeight;
}

function draw(e) {
  // mouse left button must be pressed
  if (e.buttons !== 1) return;

  ctx.beginPath(); // begin

  ctx.lineWidth = 5;
  ctx.lineCap = 'round';
  ctx.strokeStyle = '#c0392b';

  ctx.moveTo(pos.x, pos.y); // from
  setPosition(e);
  ctx.lineTo(pos.x, pos.y); // to

  ctx.stroke(); // draw it!
}


1
@ RyanCameron.Me nur Kommentarzeile if (e.buttons !== 1) return;;-).
Matěj Pokorný

1
@ RyanCameron.Me Ich habe gerade die neuesten Versionen von Chrome, Firefox und Edge ausprobiert und alles funktioniert ... Welchen Browser verwenden Sie?
Matěj Pokorný

1
@ RyanCameron.Me Es ist wahrscheinlicher, weil meine resizeFunktion. Ich stelle die Breite und Höhe der Leinwand basierend auf der Fenstergröße ein. Sie sollten diese basierend auf Ihrem festlegen <div class="container-fluid">.
Matěj Pokorný

1
Dies half auch dabei, etwa 250 von der y-Koordinate der eingestellten Positionsfunktion zu subtrahieren. Vielen Dank für deine Hilfe!
RyanCameron.Me

1
@ TaylorA.Leach yep, wenn Leinwand nicht in der oberen rechten Ecke platziert ist, müssen Sie einige offsetin setPositionFunktion hinzufügen ...
Matěj Pokorný


17

Überprüfen Sie diese http://jsfiddle.net/ArtBIT/kneDX/ . Dies sollte Sie in die richtige Richtung lenken


1
perfekt. sollte chk erhalten. Ich brauchte eine Möglichkeit, einfach gefüllte Rechtecke über einem vorhandenen Bild zu erstellen. Ihr Code ist genau das, was ich für eine Vorlage brauchte. tyvm!

11

Ich wollte diese Methode auch für Signaturen verwenden. Ich fand ein Beispiel auf http://codetheory.in/. .

Ich habe den folgenden Code zu einer jsfiddle hinzugefügt

Html:

<div id="sketch">
    <canvas id="paint"></canvas>
</div>

Javascript:

 (function() {
    var canvas = document.querySelector('#paint');
    var ctx = canvas.getContext('2d');

    var sketch = document.querySelector('#sketch');
    var sketch_style = getComputedStyle(sketch);
    canvas.width = parseInt(sketch_style.getPropertyValue('width'));
    canvas.height = parseInt(sketch_style.getPropertyValue('height'));

    var mouse = {x: 0, y: 0};
    var last_mouse = {x: 0, y: 0};

    /* Mouse Capturing Work */
    canvas.addEventListener('mousemove', function(e) {
        last_mouse.x = mouse.x;
        last_mouse.y = mouse.y;

        mouse.x = e.pageX - this.offsetLeft;
        mouse.y = e.pageY - this.offsetTop;
    }, false);


    /* Drawing on Paint App */
    ctx.lineWidth = 5;
    ctx.lineJoin = 'round';
    ctx.lineCap = 'round';
    ctx.strokeStyle = 'blue';

    canvas.addEventListener('mousedown', function(e) {
        canvas.addEventListener('mousemove', onPaint, false);
    }, false);

    canvas.addEventListener('mouseup', function() {
        canvas.removeEventListener('mousemove', onPaint, false);
    }, false);

    var onPaint = function() {
        ctx.beginPath();
        ctx.moveTo(last_mouse.x, last_mouse.y);
        ctx.lineTo(mouse.x, mouse.y);
        ctx.closePath();
        ctx.stroke();
    };

}());

Das Beste daran ist, dass Sie gerade verbundene Linien zeichnen können, indem Sie mit der rechten Maustaste auf verschiedene Stellen klicken. :)
Aidiakapi

Funktioniert nicht auf einem Touchscreen. Bezieht sich nicht auf Tabletten. Ich meine einen Windows 10-Laptop mit Maus und Touchscreen.
Paul

5

Hier ist meine sehr einfache Arbeitsfläche zeichnen und löschen.

https://jsfiddle.net/richardcwc/d2gxjdva/

//Canvas
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
//Variables
var canvasx = $(canvas).offset().left;
var canvasy = $(canvas).offset().top;
var last_mousex = last_mousey = 0;
var mousex = mousey = 0;
var mousedown = false;
var tooltype = 'draw';

//Mousedown
$(canvas).on('mousedown', function(e) {
    last_mousex = mousex = parseInt(e.clientX-canvasx);
	last_mousey = mousey = parseInt(e.clientY-canvasy);
    mousedown = true;
});

//Mouseup
$(canvas).on('mouseup', function(e) {
    mousedown = false;
});

//Mousemove
$(canvas).on('mousemove', function(e) {
    mousex = parseInt(e.clientX-canvasx);
    mousey = parseInt(e.clientY-canvasy);
    if(mousedown) {
        ctx.beginPath();
        if(tooltype=='draw') {
            ctx.globalCompositeOperation = 'source-over';
            ctx.strokeStyle = 'black';
            ctx.lineWidth = 3;
        } else {
            ctx.globalCompositeOperation = 'destination-out';
            ctx.lineWidth = 10;
        }
        ctx.moveTo(last_mousex,last_mousey);
        ctx.lineTo(mousex,mousey);
        ctx.lineJoin = ctx.lineCap = 'round';
        ctx.stroke();
    }
    last_mousex = mousex;
    last_mousey = mousey;
    //Output
    $('#output').html('current: '+mousex+', '+mousey+'<br/>last: '+last_mousex+', '+last_mousey+'<br/>mousedown: '+mousedown);
});

//Use draw|erase
use_tool = function(tool) {
    tooltype = tool; //update
}
canvas {
    cursor: crosshair;
    border: 1px solid #000000;
}
<canvas id="canvas" width="800" height="500"></canvas>
<input type="button" value="draw" onclick="use_tool('draw');" />
<input type="button" value="erase" onclick="use_tool('erase');" />
<div id="output"></div>


4

Alco prüfe dies:
Beispiel:
https://github.com/williammalone/Simple-HTML5-Drawing-App

Dokumentation:
http://www.williammalone.com/articles/create-html5-canvas-javascript-drawing-app/

Dieses Dokument enthält folgende Codes: -

HTML:

<canvas id="canvas" width="490" height="220"></canvas>

JS:

context = document.getElementById('canvas').getContext("2d");

$('#canvas').mousedown(function(e){
  var mouseX = e.pageX - this.offsetLeft;
  var mouseY = e.pageY - this.offsetTop;

  paint = true;
  addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop);
  redraw();
});

$('#canvas').mouseup(function(e){
  paint = false;
});

$('#canvas').mouseleave(function(e){
  paint = false;
});

var clickX = new Array();
var clickY = new Array();
var clickDrag = new Array();
var paint;

function addClick(x, y, dragging)
{
  clickX.push(x);
  clickY.push(y);
  clickDrag.push(dragging);
}

//Also redraw
function redraw(){
  context.clearRect(0, 0, context.canvas.width, context.canvas.height); // Clears the canvas

  context.strokeStyle = "#df4b26";
  context.lineJoin = "round";
  context.lineWidth = 5;

  for(var i=0; i < clickX.length; i++) {        
    context.beginPath();
    if(clickDrag[i] && i){
      context.moveTo(clickX[i-1], clickY[i-1]);
     }else{
       context.moveTo(clickX[i]-1, clickY[i]);
     }
     context.lineTo(clickX[i], clickY[i]);
     context.closePath();
     context.stroke();
  }
}

Und noch ein tolles Beispiel:
http://perfectionkills.com/exploring-canvas-drawing-techniques/


4

Ich musste ein einfaches Beispiel für dieses Thema liefern, damit ich es hier teilen kann:

http://jsfiddle.net/Haelle/v6tfp2e1

class SignTool {
  constructor() {
    this.initVars()
    this.initEvents()
  }

  initVars() {
    this.canvas = $('#canvas')[0]
    this.ctx = this.canvas.getContext("2d")
    this.isMouseClicked = false
    this.isMouseInCanvas = false
    this.prevX = 0
    this.currX = 0
    this.prevY = 0
    this.currY = 0
  }

  initEvents() {
    $('#canvas').on("mousemove", (e) => this.onMouseMove(e))
    $('#canvas').on("mousedown", (e) => this.onMouseDown(e))
    $('#canvas').on("mouseup", () => this.onMouseUp())
    $('#canvas').on("mouseout", () => this.onMouseOut())
    $('#canvas').on("mouseenter", (e) => this.onMouseEnter(e))
  }
  
  onMouseDown(e) {
  	this.isMouseClicked = true
    this.updateCurrentPosition(e)
  }
  
  onMouseUp() {
  	this.isMouseClicked = false
  }
  
  onMouseEnter(e) {
  	this.isMouseInCanvas = true
    this.updateCurrentPosition(e)
  }
  
  onMouseOut() {
  	this.isMouseInCanvas = false
  }

  onMouseMove(e) {
    if (this.isMouseClicked && this.isMouseInCanvas) {
    	this.updateCurrentPosition(e)
      this.draw()
    }
  }
  
  updateCurrentPosition(e) {
      this.prevX = this.currX
      this.prevY = this.currY
      this.currX = e.clientX - this.canvas.offsetLeft
      this.currY = e.clientY - this.canvas.offsetTop
  }
  
  draw() {
    this.ctx.beginPath()
    this.ctx.moveTo(this.prevX, this.prevY)
    this.ctx.lineTo(this.currX, this.currY)
    this.ctx.strokeStyle = "black"
    this.ctx.lineWidth = 2
    this.ctx.stroke()
    this.ctx.closePath()
  }
}

var canvas = new SignTool()
canvas {
  position: absolute;
  border: 2px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvas" width="500" height="300"></canvas>


2

Es ist Jahre her, seit die Frage gestellt und beantwortet wurde.

Für alle, die nach einer einfachen Zeichenfläche suchen (z. B. um die Unterschrift des Benutzers / Kunden zu erhalten), veröffentliche ich hier eine vereinfachte jquery-Version der aktuell akzeptierten Antwort

$(document).ready(function() {
  var flag, dot_flag = false,
	prevX, prevY, currX, currY = 0,
	color = 'black', thickness = 2;
  var $canvas = $('#canvas');
  var ctx = $canvas[0].getContext('2d');

  $canvas.on('mousemove mousedown mouseup mouseout', function(e) {
    prevX = currX;
    prevY = currY;
    currX = e.clientX - $canvas.offset().left;
    currY = e.clientY - $canvas.offset().top;
    if (e.type == 'mousedown') {
      flag = true;
    }
    if (e.type == 'mouseup' || e.type == 'mouseout') {
      flag = false;
    }
    if (e.type == 'mousemove') {
      if (flag) {
        ctx.beginPath();
        ctx.moveTo(prevX, prevY);
        ctx.lineTo(currX, currY);
        ctx.strokeStyle = color;
        ctx.lineWidth = thickness;
        ctx.stroke();
        ctx.closePath();
      }
    }
  });

  $('.canvas-clear').on('click', function(e) {
    c_width = $canvas.width();
    c_height = $canvas.height();
    ctx.clearRect(0, 0, c_width, c_height);
    $('#canvasimg').hide();
  });
});
<html>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
  <body>
    <canvas id="canvas" width="400" height="400" style="position:absolute;top:10%;left:10%;border:2px solid;"></canvas>
    <input type="button" value="Clear" class="canvas-clear" />
  </body>
</html>


1

Lassen Sie mich wissen, wenn Sie Probleme bei der Implementierung haben. Es verwendet process.js und verfügt über Funktionen zum Ändern von Farben und zum Vergrößern und Verkleinern des Zeichenpunkts.

<html>
<head>
<!--script librarires-->
<script type="text/javascript" src="processing.js"></script>
<script type="text/javascript" src="init.js"></script>

<!--styles -->
<style type="text/css" src="stylesheet.css">
</style> 
</head>
<body>
<!--toolbox -->
<div id="draggable toolbox"></div>
<script type="application/processing">
// new script
int prevx, prevy;
int newx, newy;
boolean cliked;
color c1 = #000000;
int largeur=2;
int ps = 20;
int px = 50;
int py = 50;

void setup() {
size(500,500);
frameRate(25);
background(50);

 prevx = mouseX;
 prevy = mouseY;
 cliked = false;
 }

void draw() {
 //couleur
 noStroke(0);
 fill(#FFFFFF);//blanc
rect(px, py, ps, ps);
 fill(#000000);
 rect(px, py+(ps), ps, ps);
 fill(#FF0000);
 rect(px, py+(ps*2), ps, ps);
 fill(#00FF00);
 rect(px, py+(ps*3), ps, ps);
 fill(#FFFF00);
 rect(px, py+(ps*4), ps, ps);
 fill(#0000FF);
 rect(px, py+(ps*5), ps, ps);
 //largeur
 fill(#FFFFFF);
 rect(px, py+(ps*7), ps, ps);
  fill(#FFFFFF);
 rect(px, py+(ps*8), ps, ps);
 stroke(#000000);
 line(px+2, py+(ps*7)+(ps/2), px+(ps-2), py+(ps*7)+(ps/2));
 line(px+(ps/2), py+(ps*7)+1, px+(ps/2), py+(ps*8)-1);
 line(px+2, py+(ps*8)+(ps/2), px+(ps-2), py+(ps*8)+(ps/2));

 if(cliked==false){
  prevx = mouseX;
 prevy = mouseY;  
 }
 if(mousePressed) { 
  cliked = true;
 newx = mouseX;
  newy = mouseY;
  strokeWeight(largeur);
  stroke(c1);
  line(prevx, prevy, newx, newy);
  prevx = newx;
 prevy = newy;
 }else{
  cliked= false;
  }
}
void mouseClicked() {
 if (mouseX>=px && mouseX<=(px+ps)){
  //couleur
  if (mouseY>=py && mouseY<=py+(ps*6)){ 
   c1 = get(mouseX, mouseY);
  }
   //largeur
  if (mouseY>=py+(ps*7) && mouseY<=py+(ps*8)){ 
   largeur += 2;
  }
 if (mouseY>=py+(ps*8) && mouseY<=py+(ps*9)){ 
   if (largeur>2){
    largeur -= 2;
   }
  }
 }
}
</script><canvas></canvas>
</body>
</html>

Was ist drin init.js?
Majid Fouladpour

Ich verstehe es nicht, aber es beginnt zu verarbeiten.
Expiredninja

0

Wenn Sie ein Hintergrundbild für Ihre Leinwand haben, müssen Sie einige Anpassungen vornehmen, damit es ordnungsgemäß funktioniert, da der weiße Löschtrick den Hintergrund verdeckt.

Hier ist ein Kern mit dem Code.

<html>
    <script type="text/javascript">
    var canvas, canvasimg, backgroundImage, finalImg;
    var mouseClicked = false;
    var prevX = 0;
    var currX = 0;
    var prevY = 0;
    var currY = 0;
    var fillStyle = "black";
    var globalCompositeOperation = "source-over";
    var lineWidth = 2;

    function init() {
      var imageSrc = '/abstract-geometric-pattern_23-2147508597.jpg'
      backgroundImage = new Image();
      backgroundImage.src = imageSrc;
      canvas = document.getElementById('can');
      finalImg = document.getElementById('finalImg');
      canvasimg = document.getElementById('canvasimg');
      canvas.style.backgroundImage = "url('" + imageSrc + "')";
      canvas.addEventListener("mousemove", handleMouseEvent);
      canvas.addEventListener("mousedown", handleMouseEvent);
      canvas.addEventListener("mouseup", handleMouseEvent);
      canvas.addEventListener("mouseout", handleMouseEvent);
    }

    function getColor(btn) {
      globalCompositeOperation = 'source-over';
      lineWidth = 2;
      switch (btn.getAttribute('data-color')) {
        case "green":
        fillStyle = "green";
        break;
        case "blue":
        fillStyle = "blue";
        break;
        case "red":
        fillStyle = "red";
        break;
        case "yellow":
        fillStyle = "yellow";
        break;
        case "orange":
        fillStyle = "orange";
        break;
        case "black":
        fillStyle = "black";
        break;
        case "eraser":
        globalCompositeOperation = 'destination-out';
        fillStyle = "rgba(0,0,0,1)";
        lineWidth = 14;
        break;
      }

    }

    function draw(dot) {
      var ctx = canvas.getContext("2d");
      ctx.beginPath();
      ctx.globalCompositeOperation = globalCompositeOperation;
      if(dot){
        ctx.fillStyle = fillStyle;
        ctx.fillRect(currX, currY, 2, 2);
      } else {
        ctx.beginPath();
        ctx.moveTo(prevX, prevY);
        ctx.lineTo(currX, currY);
        ctx.strokeStyle = fillStyle;
        ctx.lineWidth = lineWidth;
        ctx.stroke();
      }
      ctx.closePath();
    }

    function erase() {
      if (confirm("Want to clear")) {
        var ctx = canvas.getContext("2d");
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        document.getElementById("canvasimg").style.display = "none";
      }
    }

    function save() {
      canvas.style.border = "2px solid";
      canvasimg.width = canvas.width;
      canvasimg.height = canvas.height;
      var ctx2 = canvasimg.getContext("2d");
      // comment next line to save the draw only
      ctx2.drawImage(backgroundImage, 0, 0);
      ctx2.drawImage(canvas, 0, 0);
      finalImg.src = canvasimg.toDataURL();
      finalImg.style.display = "inline";
    }

    function handleMouseEvent(e) {
      if (e.type === 'mousedown') {
        prevX = currX;
        prevY = currY;
        currX = e.offsetX;
        currY = e.offsetY;
        mouseClicked = true;
        draw(true);
      }
      if (e.type === 'mouseup' || e.type === "mouseout") {
        mouseClicked = false;
      }
      if (e.type === 'mousemove') {
        if (mouseClicked) {
          prevX = currX;
          prevY = currY;
          currX = e.offsetX;
          currY = e.offsetY;
          draw();
        }
      }
    }
    </script>
    <body onload="init()">
      <canvas id="can" width="400" height="400" style="position:absolute;top:10%;left:10%;border:2px solid;">
      </canvas>
      <div style="position:absolute;top:12%;left:43%;">Choose Color</div>
      <div style="position:absolute;top:15%;left:45%;width:10px;height:10px;background:green;" data-color="green" onclick="getColor(this)"></div>
      <div style="position:absolute;top:15%;left:46%;width:10px;height:10px;background:blue;" data-color="blue" onclick="getColor(this)"></div>
      <div style="position:absolute;top:15%;left:47%;width:10px;height:10px;background:red;" data-color="red" onclick="getColor(this)"></div>
      <div style="position:absolute;top:17%;left:45%;width:10px;height:10px;background:yellow;" data-color="yellow" onclick="getColor(this)"></div>
      <div style="position:absolute;top:17%;left:46%;width:10px;height:10px;background:orange;" data-color="orange" onclick="getColor(this)"></div>
      <div style="position:absolute;top:17%;left:47%;width:10px;height:10px;background:black;" data-color="black" onclick="getColor(this)"></div>
      <div style="position:absolute;top:20%;left:43%;">Eraser</div>
      <div style="position:absolute;top:22%;left:45%;width:15px;height:15px;background:white;border:2px solid;" data-color="eraser" onclick="getColor(this)"></div>
      <canvas id="canvasimg" style="display:none;" ></canvas>
      <img id="finalImg" style="position:absolute;top:10%;left:52%;display:none;" >
      <input type="button" value="save" id="btn" size="30" onclick="save()" style="position:absolute;top:55%;left:10%;">
      <input type="button" value="clear" id="clr" size="23" onclick="erase()" style="position:absolute;top:55%;left:15%;">
    </body>
    </html>

0

Eine super kurze Version hier ohne position:absoluteVanille-JavaScript. Die Hauptidee besteht darin, den Kontext der Leinwand an die richtigen Koordinaten zu verschieben und eine Linie zu zeichnen. Kommentieren Sie den clickHandler und die Kommentar- mousedownund mousemoveHandler unten aus, um ein Gefühl dafür zu bekommen, wie es funktioniert.

<!DOCTYPE html>
<html>
<body>

<p style="margin: 50px">Just some padding in y direction</p>

<canvas id="myCanvas" width="300" height="300" style="background: #000; margin-left: 100px;">Your browser does not support the HTML5 canvas tag.</canvas>

<script>
    const c = document.getElementById("myCanvas");
    // c.addEventListener("click", penTool); // fires after mouse left btn is released
    c.addEventListener("mousedown", setLastCoords); // fires before mouse left btn is released
    c.addEventListener("mousemove", freeForm);


    const ctx = c.getContext("2d");

    function setLastCoords(e) {
        const {x, y} = c.getBoundingClientRect();
        lastX = e.clientX - x;
        lastY = e.clientY - y;
    }

    function freeForm(e) {
        if (e.buttons !== 1) return; // left button is not pushed yet
        penTool(e);
    }

    function penTool(e) {
        const {x, y} = c.getBoundingClientRect();
        const newX = e.clientX - x;
        const newY = e.clientY - y;

        ctx.beginPath();
        ctx.lineWidth = 5;
        ctx.moveTo(lastX, lastY);
        ctx.lineTo(newX, newY);
        ctx.strokeStyle = 'white';
        ctx.stroke();
        ctx.closePath();

        lastX = newX;
        lastY = newY;
    }

    let lastX = 0;
    let lastY = 0;  
</script>

</body>
</html>

Es ist wichtig, die Breite und Höhe nicht in CSS festzulegen,
Nitin
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.