在响应式 canvas 上绘图时光标和绘图之间的间隙

Gap between cursor and drawing WHEN drawing on responsive canvas

我已经搜索了几个小时的解决方案,但找不到适合我的解决方案。我希望你能帮助我。

我有一个 canvas 可以用来画画(铅笔、线条、矩形、圆圈)。 当我缩小window时,canvas变小,在我画画的时候鼠标光标和canvas上的画之间有间隙。结果是对的,画出来的结果就是我鼠标光标所在的位置,但是画的时候显示的位置和大小不对,好像全屏一样。

由于结果是正确的,但过程显示错误,我真的不知道代码的哪一部分可能会受到影响,并且负责在您释放鼠标按钮之前显示绘图。也许鼠标移动?如果您需要更多代码,请告诉我,感谢您的帮助!

/* Grundstruktur: © 2009 ROBO Design
 * http://www.robodesign.ro
 */

// Funktion wird bei Laden des Fensters aufgerufen
if(window.addEventListener) {
window.addEventListener('load', function () {
  var canvas, context, canvaso, contexto;

  // Aktive Werkzeug-Instanz
  var tool;
  var tool_default = 'line';

  function init () {
    // Canvas Element aus HTML-Dokument abrufen
    canvaso = document.getElementById('imageView');
    if (!canvaso) {
      alert('Error: I cannot find the canvas element!');
      return;
    }

    if (!canvaso.getContext) {
      alert('Error: no canvas.getContext!');
      return;
    }

    // 2D Canvas Kontext abrufen
    contexto = canvaso.getContext('2d');
    if (!contexto) {
      alert('Error: failed to getContext!');
      return;
    }

    // Temporäres Canvas hinzufügen
    var container = canvaso.parentNode;
    canvas = document.createElement('canvas');
    if (!canvas) {
      alert('Error: I cannot create a new canvas element!');
      return;
    }

    canvas.id     = 'imageTemp';
    canvas.width  = canvaso.width;
    canvas.height = canvaso.height;
    container.appendChild(canvas);

    context = canvas.getContext('2d');

    // Eingabe für Werkzeugauswahl abrufen
    var tool_select = document.getElementById('dtool');
    if (!tool_select) {
      alert('Error: failed to get the dtool element!');
      return;
    }
    tool_select.addEventListener('change', ev_tool_change, false);

    // Standardwerkzeug aktivieren
    if (tools[tool_default]) {
      tool = new tools[tool_default]();
      tool_select.value = tool_default;
    }

    // EventListeners für mousedown, mousemove und mouseup
    canvas.addEventListener('mousedown', ev_canvas, false);
    canvas.addEventListener('mousemove', ev_canvas, false);
    canvas.addEventListener('mouseup',   ev_canvas, false);
  }

  // Allgemeiner Ereignishandler. Funktion bestimmt die Mausposition im Verhältnis zum Canvas Element.
  


  function ev_canvas (ev) {
    if (ev.layerX || ev.layerX == 0) { 
      
   
 var rect = document.getElementById('imageView').getBoundingClientRect();
 
    var X = (ev.clientX - rect.left) / (document.getElementById('imageView').clientWidth / document.getElementById('imageView').width);
    var Y = (ev.clientY - rect.top) / (document.getElementById('imageView').clientHeight / document.getElementById('imageView').height);
    ev._x = Math.ceil(X);
    ev._y = Math.ceil(Y);
 
    } 

    // Ereignishandler des Werkzeugs aufrufen.
    var func = tool[ev.type];
    if (func) {
      func(ev);
    }
  }

  // Ereignishandler für Änderungen an der Werkzeugauswahl.
  function ev_tool_change (ev) {
    if (tools[this.value]) {
      tool = new tools[this.value]();
    }
  }

  // Funktion malt #imageTemp Canvas auf dem #imageView Canvas, danach wird #imageTemp
  // geleert. Funktion wird immer aufgerufen, wenn der Nutzer eine Zeichenoperation vervollständigt.
  function img_update () {
  contexto.drawImage(canvas, 0, 0);
  context.clearRect(0, 0, canvas.width, canvas.height);
  }

  // Objekt für die Implementierung jedes Zeichenwerkzeugs
  var tools = {};

  // Stift
  tools.pencil = function () {
    var tool = this;
    this.started = false;

    // Maustaste anfangen zu drücken
    // Stift fängt an zu malen
    this.mousedown = function (ev) {
        context.beginPath();
        context.moveTo(ev._x, ev._y);
        tool.started = true;
    };

    // Mausbewegung (tool.started muss true sein, also Maustaste gedrückt)
    this.mousemove = function (ev) {
  var color=document.getElementById ("color").value;
  context.strokeStyle = color;
  var stärke=document.getElementById ("stärke").value;
  context.lineWidth = stärke;
  context.lineCap = 'round';
      if (tool.started) {
        context.lineTo(ev._x, ev._y);
        
  
  context.stroke();
      }
    };

    // Maustaste wieder loslassen
    this.mouseup = function (ev) {
      if (tool.started) {
        tool.mousemove(ev);
        tool.started = false;
        img_update();
      }
    };
  };

  // Rechteck
  tools.rect = function () {
    var tool = this;
    this.started = false;

    this.mousedown = function (ev) {
      tool.started = true;
      tool.x0 = ev._x;
      tool.y0 = ev._y;
    };

    this.mousemove = function (ev) {
      if (!tool.started) {
        return;
      }
 
 // Variablen, um die Breite und Höhe zu ermitteln
      var x = Math.min(ev._x,  tool.x0),
          y = Math.min(ev._y,  tool.y0),
          w = Math.abs(ev._x - tool.x0),
          h = Math.abs(ev._y - tool.y0);

      context.clearRect(0, 0, canvas.width, canvas.height);

      if (!w || !h) {
        return;
      }

      
   // Farbe, Ausgefüllt und Linienstärke werden abgerufen
   var color=document.getElementById ("color").value;
   var ausgefüllt=document.getElementById ("ausgefüllt").checked;
   var stärke=document.getElementById ("stärke").value;
   
   // Wenn Häkchen bei ausgefüllt, dann fill, ansonsten stroke (also nur Umrandung)
   if (ausgefüllt) {
  context.fillStyle = color;
  context.fillRect(x, y, w, h);
   }
   else {
  context.strokeStyle = color;
  context.lineWidth = stärke;
  context.strokeRect(x, y, w, h);
   }
  
  
  
  
    };

    this.mouseup = function (ev) {
      if (tool.started) {
        tool.mousemove(ev);
        tool.started = false;
        img_update();
      }
    };
 
 

  
  };
  
  
  // Das Kreiswerkzeug
  
  tools.arc = function () {
    var tool = this;
    this.started = false;

    this.mousedown = function (ev) {
      tool.started = true;
      tool.x0 = ev._x;
      tool.y0 = ev._y;
    };

    this.mousemove = function (ev) {
      if (!tool.started) {
        return;
      }

   //Hinzufügen von r als Radius, Satz des Pythagoras
   //ev._x und ev._y : Mausposition nach Bewegung
   //tool.x0 und tool.y0 : Mausposition, wenn man anfängt zu klicken (vor der Bewegung)
   //sqrt : Wurzel --> Wurzel aus a² + b²
      var x = Math.min(ev._x, tool.x0),
          y = Math.min(ev._y, tool.y0),
    r = Math.sqrt((ev._x - tool.x0)*(ev._x - tool.x0) + (ev._y - tool.y0)*(ev._y - tool.y0))

      context.clearRect(0, 0, canvas.width, canvas.height);

    var color=document.getElementById ("color").value;
 var ausgefüllt=document.getElementById ("ausgefüllt").checked;
 var stärke=document.getElementById ("stärke").value;
 
 //arc zeichnet Bogen, 2*Math.PI ergibt dann einen vollständigen Kreis
 if (ausgefüllt) {
  context.beginPath();
  context.fillStyle = color;
  context.arc(x, y, r, 0, 2 * Math.PI, false);
  context.fill();
    
 }
 
 else {
  context.beginPath();
  context.strokeStyle = color;
  context.lineWidth = stärke;
  context.arc(x, y, r, 0, 2 * Math.PI, false);
  context.stroke();
   }
  
    };

    this.mouseup = function (ev) {
      if (tool.started) {
        tool.mousemove(ev);
        tool.started = false;
        img_update();
      }
    };
 
 

  
  };
   
   

  // Das Linien-Werkzeug
  tools.line = function () {
    var tool = this;
    this.started = false;

    this.mousedown = function (ev) {
      tool.started = true;
      tool.x0 = ev._x;
      tool.y0 = ev._y;
    };

    this.mousemove = function (ev) {
      if (!tool.started) {
        return;
      }

      context.clearRect(0, 0, canvas.width, canvas.height);

   // Mausposition wird nach tool.x0 und tool.y0 (x- und y-Wert des Mauszeigers) versetzt 
   //(dort beginnt die Linie), Linie wird dann nach ev._x und ev._y gezogen (x- und y-Wert
   //wenn Bewegung der Maus vollzogen)
      context.beginPath();
      context.moveTo(tool.x0, tool.y0);
      context.lineTo(ev._x,   ev._y);
      
   context.stroke();
   var color=document.getElementById ("color").value;
  context.strokeStyle = color;
   var stärke=document.getElementById ("stärke").value;
  context.lineWidth = stärke;
      context.closePath();
    };

 
    this.mouseup = function (ev) {
      if (tool.started) {
        tool.mousemove(ev);
        tool.started = false;
        img_update();
      }
    };
  };

  init();

}, false); }

// 


//X- und Y-Werte der Maus anzeigen (nur für Canvas-Bereich)

var info = document.getElementById('mouse-position');

this.tellPos = function (ev) {
 pageX = ev._x;
 pageY = ev._y;
  info.innerHTML = 'Position X : ' + pageX + '<br />Position Y : ' + pageY;
}
addEventListener('mousemove', tellPos, false);
   
   
   
//Buttons-Funktionen

//"Speichern"
function putImage()
{
  var canvas = document.getElementById("imageView");        
  if (canvas.getContext) {
     var context = canvas.getContext("2d");                
     var image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");    
  }
  var imageElement = document.getElementById("MyPix");  
  window.location.href=image;                          

}  

//Zeichenfläche leeren "Neu"
var canvas = document.getElementById('imageView');
var context = canvas.getContext('2d');
var clearCanvas = document.getElementById("clear");
clearCanvas.addEventListener("click", eraseCanvas, false);

function eraseCanvas() {
 context.clearRect(0, 0, canvas.width, canvas.height);
}

//Canvas responsiv machen
body {
    margin: 0;
}
 h1 {
         
  color: #000000;
 }
 
 .nav-tabs {
 background-color:#FFFFFF;
}

 
.form-inline {
    display: flex;
    flex-direction: row;
    position: block;
    width: 100%;
 
}
 
.kriterien, .farbe, .linienstärke, .ausfüllen{
 margin-right: 10px;
 margin-bottom: 5px;
 font-size: 12pt;
 line-height: 10px;
 vertical-align: middle;
 background-color:#F0FFFF;
 border-color: black;
 border-width: 1px;
 border-style: solid;
 border-radius: 5px;
 padding-top: 15px;
 padding-right: 10px;
 padding-left: 10px;
 padding-bottom: 15px;
}


.mouse-position {
 position: right;
 margin-left:40px;
 margin-right: 40px;
 
}

.controls {
 margin-top: 10px;
}

#imageView {
 position: center;
 padding-left: 0;
 padding-right: 0;
 margin-left: auto;
 margin-right: auto;
 width: 100%;
}

#unterereihe {
 margin-top: 30px;
}

.form-control {
 font-size: 95%;
}
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
    <link rel="stylesheet" href="style.css">
 



<style>
#container { position: relative; }
#imageView { border: 1px solid #000; }
#imageTemp { position: absolute; top: 1px; left: 1px; }

</style>

</head>

<body>


<div class="container">

 <div class="page-header">
  <h1 class="display-3 text-center">Paint-Tool</h1>
 </div>

 <div class="container">

  

  <div>

   
  </div>
 </div>



 <form class="form-inline">
  <div class="form-group">


   <div class="kriterien">
    <label>Zeichenwerkzeug &nbsp;<select id="dtool">
     <option value="pencil">Stift</option>
     <option value="rect">Rechteck</option>      
     <option value="arc">Kreis</option>
     <option value="line">Linie</option>
    </select></label>
   </div>
 

   <div class="farbe">
    <label>Farbe &nbsp;
     <form action="#">
      <input id="color" type="color" name="color" value="#000000">
     </form> 
    </label>
   </div>


   <div class="linienstärke">
    <label>Linienstärke &nbsp; 
     <form action="#">
      <input id="stärke" type="range" name="range" value="1"min="1" max="50" value="1">
     </form>
    </label>
   </div>
 
   <div class="ausfüllen">
    <input id="ausgefüllt" name="ausgefüllt" type="checkbox" checked> Ausfüllen
   </div>
  
  
   <div id="mouse-position">
   </div>
  </div>
    </form>
 
 
 <div id="container">
  <canvas id="imageView" width="1108" height="400">
  </canvas>
 </div>
 
 <div class="controls">
  <button type="button" class="btn btn-dark" onclick="putImage()" id="save">Speichern</button>
  <button type="button" class="btn btn-dark" onclick"clear()" id="clear">Neu</button>
 </div>




<script type="text/javascript" src="paint-tool.js"></script>
  
  </body>
</html>
      



</div>










<!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
 <script src="http://hongru.github.io/proj/canvas2image/canvas2image.js"></script>
 
 
</body>
</html>

imageTemp和imageView不一样CSS(宽度:100%)

imageTemp canvas 已创建并附加到您的容器,但没有考虑到您的 imageView 已应用特定的 CSS 属性。因此,当您调整 window 大小时,只有 imageView 会调整大小而 imageTemp 不会(因为您从未指定 100% 宽度)

临时修复: 我复制并粘贴了您的 imageView css 并将其应用于您的 imageTemp,以模仿相同的大小。

#imageView {
    position: center;
    padding-left: 0;
    padding-right: 0;
    margin-left: auto;
    margin-right: auto;
    width: 100%;
}

#imageTemp {
    position: center;
    padding-left: 0;
    padding-right: 0;
    margin-left: auto;
    margin-right: auto;
    width: 100%;
}

不过

这并不能完全解决您的问题,因为尺寸并非 100% 相同(误差范围非常小,可能不会引起注意)。我建议您使用 imageTemp css 或使用

 window.addEventListener("resize", ()=>{
   const canvas = document.getElementById("imageTemp");
   const canvaso = document.getElementById("imageView");
   canvas.width = canvaso.width;
   canvas.height = canvaso.height;
 }, false);

更新了代码,增加了 css

/* Grundstruktur: © 2009 ROBO Design
 * http://www.robodesign.ro
 */

// Funktion wird bei Laden des Fensters aufgerufen
if(window.addEventListener) {

window.addEventListener('load', function () {
  var canvas, context, canvaso, contexto;

  // Aktive Werkzeug-Instanz
  var tool;
  var tool_default = 'line';

  function init () {
    // Canvas Element aus HTML-Dokument abrufen
    canvaso = document.getElementById('imageView');
    if (!canvaso) {
      alert('Error: I cannot find the canvas element!');
      return;
    }

    if (!canvaso.getContext) {
      alert('Error: no canvas.getContext!');
      return;
    }

    // 2D Canvas Kontext abrufen
    contexto = canvaso.getContext('2d');
    if (!contexto) {
      alert('Error: failed to getContext!');
      return;
    }

    // Temporäres Canvas hinzufügen
    var container = canvaso.parentNode;
    canvas = document.createElement('canvas');
    if (!canvas) {
      alert('Error: I cannot create a new canvas element!');
      return;
    }

    canvas.id     = 'imageTemp';
    canvas.width  = canvaso.width;
    canvas.height = canvaso.height;
    container.appendChild(canvas);

    context = canvas.getContext('2d');

    // Eingabe für Werkzeugauswahl abrufen
    var tool_select = document.getElementById('dtool');
    if (!tool_select) {
      alert('Error: failed to get the dtool element!');
      return;
    }
    tool_select.addEventListener('change', ev_tool_change, false);

    // Standardwerkzeug aktivieren
    if (tools[tool_default]) {
      tool = new tools[tool_default]();
      tool_select.value = tool_default;
    }

    // EventListeners für mousedown, mousemove und mouseup
    canvas.addEventListener('mousedown', ev_canvas, false);
    canvas.addEventListener('mousemove', ev_canvas, false);
    canvas.addEventListener('mouseup',   ev_canvas, false);
  }

  // Allgemeiner Ereignishandler. Funktion bestimmt die Mausposition im Verhältnis zum Canvas Element.
  


  function ev_canvas (ev) {
    if (ev.layerX || ev.layerX == 0) { 
      
   
 var rect = document.getElementById('imageView').getBoundingClientRect();
 
    var X = (ev.clientX - rect.left) / (document.getElementById('imageView').clientWidth / document.getElementById('imageView').width);
    var Y = (ev.clientY - rect.top) / (document.getElementById('imageView').clientHeight / document.getElementById('imageView').height);
    ev._x = Math.ceil(X);
    ev._y = Math.ceil(Y);
 
    } 

    // Ereignishandler des Werkzeugs aufrufen.
    var func = tool[ev.type];
    if (func) {
      func(ev);
    }
  }

  // Ereignishandler für Änderungen an der Werkzeugauswahl.
  function ev_tool_change (ev) {
    if (tools[this.value]) {
      tool = new tools[this.value]();
    }
  }

  // Funktion malt #imageTemp Canvas auf dem #imageView Canvas, danach wird #imageTemp
  // geleert. Funktion wird immer aufgerufen, wenn der Nutzer eine Zeichenoperation vervollständigt.
  function img_update () {
  contexto.drawImage(canvas, 0, 0);
  context.clearRect(0, 0, canvas.width, canvas.height);
  }

  // Objekt für die Implementierung jedes Zeichenwerkzeugs
  var tools = {};

  // Stift
  tools.pencil = function () {
    var tool = this;
    this.started = false;

    // Maustaste anfangen zu drücken
    // Stift fängt an zu malen
    this.mousedown = function (ev) {
        context.beginPath();
        context.moveTo(ev._x, ev._y);
        tool.started = true;
    };

    // Mausbewegung (tool.started muss true sein, also Maustaste gedrückt)
    this.mousemove = function (ev) {
  var color=document.getElementById ("color").value;
  context.strokeStyle = color;
  var stärke=document.getElementById ("stärke").value;
  context.lineWidth = stärke;
  context.lineCap = 'round';
      if (tool.started) {
        context.lineTo(ev._x, ev._y);
        
  
  context.stroke();
      }
    };

    // Maustaste wieder loslassen
    this.mouseup = function (ev) {
      if (tool.started) {
        tool.mousemove(ev);
        tool.started = false;
        img_update();
      }
    };
  };

  // Rechteck
  tools.rect = function () {
    var tool = this;
    this.started = false;

    this.mousedown = function (ev) {
      tool.started = true;
      tool.x0 = ev._x;
      tool.y0 = ev._y;
    };

    this.mousemove = function (ev) {
      if (!tool.started) {
        return;
      }
 
 // Variablen, um die Breite und Höhe zu ermitteln
      var x = Math.min(ev._x,  tool.x0),
          y = Math.min(ev._y,  tool.y0),
          w = Math.abs(ev._x - tool.x0),
          h = Math.abs(ev._y - tool.y0);

      context.clearRect(0, 0, canvas.width, canvas.height);

      if (!w || !h) {
        return;
      }

      
   // Farbe, Ausgefüllt und Linienstärke werden abgerufen
   var color=document.getElementById ("color").value;
   var ausgefüllt=document.getElementById ("ausgefüllt").checked;
   var stärke=document.getElementById ("stärke").value;
   
   // Wenn Häkchen bei ausgefüllt, dann fill, ansonsten stroke (also nur Umrandung)
   if (ausgefüllt) {
  context.fillStyle = color;
  context.fillRect(x, y, w, h);
   }
   else {
  context.strokeStyle = color;
  context.lineWidth = stärke;
  context.strokeRect(x, y, w, h);
   }
  
  
  
  
    };

    this.mouseup = function (ev) {
      if (tool.started) {
        tool.mousemove(ev);
        tool.started = false;
        img_update();
      }
    };
 
 

  
  };
  
  
  // Das Kreiswerkzeug
  
  tools.arc = function () {
    var tool = this;
    this.started = false;

    this.mousedown = function (ev) {
      tool.started = true;
      tool.x0 = ev._x;
      tool.y0 = ev._y;
    };

    this.mousemove = function (ev) {
      if (!tool.started) {
        return;
      }

   //Hinzufügen von r als Radius, Satz des Pythagoras
   //ev._x und ev._y : Mausposition nach Bewegung
   //tool.x0 und tool.y0 : Mausposition, wenn man anfängt zu klicken (vor der Bewegung)
   //sqrt : Wurzel --> Wurzel aus a² + b²
      var x = Math.min(ev._x, tool.x0),
          y = Math.min(ev._y, tool.y0),
    r = Math.sqrt((ev._x - tool.x0)*(ev._x - tool.x0) + (ev._y - tool.y0)*(ev._y - tool.y0))

      context.clearRect(0, 0, canvas.width, canvas.height);

    var color=document.getElementById ("color").value;
 var ausgefüllt=document.getElementById ("ausgefüllt").checked;
 var stärke=document.getElementById ("stärke").value;
 
 //arc zeichnet Bogen, 2*Math.PI ergibt dann einen vollständigen Kreis
 if (ausgefüllt) {
  context.beginPath();
  context.fillStyle = color;
  context.arc(x, y, r, 0, 2 * Math.PI, false);
  context.fill();
    
 }
 
 else {
  context.beginPath();
  context.strokeStyle = color;
  context.lineWidth = stärke;
  context.arc(x, y, r, 0, 2 * Math.PI, false);
  context.stroke();
   }
  
    };

    this.mouseup = function (ev) {
      if (tool.started) {
        tool.mousemove(ev);
        tool.started = false;
        img_update();
      }
    };
 
 

  
  };
   
   

  // Das Linien-Werkzeug
  tools.line = function () {
    var tool = this;
    this.started = false;

    this.mousedown = function (ev) {
      tool.started = true;
      tool.x0 = ev._x;
      tool.y0 = ev._y;
    };

    this.mousemove = function (ev) {
      if (!tool.started) {
        return;
      }

      context.clearRect(0, 0, canvas.width, canvas.height);

   // Mausposition wird nach tool.x0 und tool.y0 (x- und y-Wert des Mauszeigers) versetzt 
   //(dort beginnt die Linie), Linie wird dann nach ev._x und ev._y gezogen (x- und y-Wert
   //wenn Bewegung der Maus vollzogen)
      context.beginPath();
      context.moveTo(tool.x0, tool.y0);
      context.lineTo(ev._x,   ev._y);
      
   context.stroke();
   var color=document.getElementById ("color").value;
  context.strokeStyle = color;
   var stärke=document.getElementById ("stärke").value;
  context.lineWidth = stärke;
      context.closePath();
    };

 
    this.mouseup = function (ev) {
      if (tool.started) {
        tool.mousemove(ev);
        tool.started = false;
        img_update();
      }
    };
  };

  init();

}, false); }

// 


//X- und Y-Werte der Maus anzeigen (nur für Canvas-Bereich)

var info = document.getElementById('mouse-position');

this.tellPos = function (ev) {
 pageX = ev._x;
 pageY = ev._y;
  info.innerHTML = 'Position X : ' + pageX + '<br />Position Y : ' + pageY;
}
addEventListener('mousemove', tellPos, false);
   
   
   
//Buttons-Funktionen

//"Speichern"
function putImage()
{
  var canvas = document.getElementById("imageView");        
  if (canvas.getContext) {
     var context = canvas.getContext("2d");                
     var image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");    
  }
  var imageElement = document.getElementById("MyPix");  
  window.location.href=image;                          

}  

//Zeichenfläche leeren "Neu"
var canvas = document.getElementById('imageView');
var context = canvas.getContext('2d');
var clearCanvas = document.getElementById("clear");
clearCanvas.addEventListener("click", eraseCanvas, false);

function eraseCanvas() {
 context.clearRect(0, 0, canvas.width, canvas.height);
}

//Canvas responsiv machen
body {
    margin: 0;
}
 h1 {
         
  color: #000000;
 }
 
 .nav-tabs {
 background-color:#FFFFFF;
}

 
.form-inline {
    display: flex;
    flex-direction: row;
    position: block;
    width: 100%;
 
}
 
.kriterien, .farbe, .linienstärke, .ausfüllen{
 margin-right: 10px;
 margin-bottom: 5px;
 font-size: 12pt;
 line-height: 10px;
 vertical-align: middle;
 background-color:#F0FFFF;
 border-color: black;
 border-width: 1px;
 border-style: solid;
 border-radius: 5px;
 padding-top: 15px;
 padding-right: 10px;
 padding-left: 10px;
 padding-bottom: 15px;
}


.mouse-position {
 position: right;
 margin-left:40px;
 margin-right: 40px;
 
}

.controls {
 margin-top: 10px;
}

#imageView {
 position: center;
 padding-left: 0;
 padding-right: 0;
 margin-left: auto;
 margin-right: auto;
 width: 100%;
}

#imageTemp {
 position: center;
 padding-left: 0;
 padding-right: 0;
 margin-left: auto;
 margin-right: auto;
 width: 100%;
}

#unterereihe {
 margin-top: 30px;
}

.form-control {
 font-size: 95%;
}
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
    <link rel="stylesheet" href="style.css">
 



<style>
#container { position: relative; }
#imageView { border: 1px solid #000; }
#imageTemp { position: absolute; top: 1px; left: 1px; }

</style>

</head>

<body>


<div class="container">

 <div class="page-header">
  <h1 class="display-3 text-center">Paint-Tool</h1>
 </div>

 <div class="container">

  

  <div>

   
  </div>
 </div>



 <form class="form-inline">
  <div class="form-group">


   <div class="kriterien">
    <label>Zeichenwerkzeug &nbsp;<select id="dtool">
     <option value="pencil">Stift</option>
     <option value="rect">Rechteck</option>      
     <option value="arc">Kreis</option>
     <option value="line">Linie</option>
    </select></label>
   </div>
 

   <div class="farbe">
    <label>Farbe &nbsp;
     <form action="#">
      <input id="color" type="color" name="color" value="#000000">
     </form> 
    </label>
   </div>


   <div class="linienstärke">
    <label>Linienstärke &nbsp; 
     <form action="#">
      <input id="stärke" type="range" name="range" value="1"min="1" max="50" value="1">
     </form>
    </label>
   </div>
 
   <div class="ausfüllen">
    <input id="ausgefüllt" name="ausgefüllt" type="checkbox" checked> Ausfüllen
   </div>
  
  
   <div id="mouse-position">
   </div>
  </div>
    </form>
 
 
 <div id="container">
  <canvas id="imageView" width="1108" height="400">
  </canvas>
 </div>
 
 <div class="controls">
  <button type="button" class="btn btn-dark" onclick="putImage()" id="save">Speichern</button>
  <button type="button" class="btn btn-dark" onclick"clear()" id="clear">Neu</button>
 </div>




<script type="text/javascript" src="paint-tool.js"></script>
  
  </body>
</html>
      



</div>










<!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
 <script src="http://hongru.github.io/proj/canvas2image/canvas2image.js"></script>
 
 
</body>
</html>