简体   繁体   English

在Chrome中调整绘图画布的大小

[英]Resizing drawing canvas in chrome

I am trying to make an drawing canvas that is can be resized. 我正在尝试制作可以调整大小的绘图画布。 I have found a way but the drawing is erased every time you update the canvas, unfortunately it has a weird "bug". 我找到了一种方法,但是每次您更新画布时都会删除该图形,但是不幸的是它有一个怪异的“ bug”。 In Firefox everything works as expected but when I try it out in Chrome I am unable to resize the canvas. 在Firefox中,一切正常,但是在Chrome中尝试时,无法调整画布的大小。

My apologies if it isn't the prettiest or most efficient code. 如果不是最漂亮或最有效的代码,我深表歉意。

 $(document).ready(function() { $("#canvaSizer").mouseup(function() { canvaWidthNew = document.getElementById('canvaSizer').clientWidth; if (canvaWidthNew != canvaWidth) { initialize(); } canvaWidth = canvaWidthNew; }); canvaWidth = document.getElementById('canvaSizer').clientWidth; var myscreen = document.getElementById("screen"); var ctx = myscreen.getContext("2d"); initialize(); function initialize() { // Fill Window Width and Height myscreen.width = document.getElementById('canvaSizer').clientWidth; myscreen.height = document.getElementById('canvaSizer').clientHeight; // Set Background Color ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, myscreen.width, myscreen.height); // Mouse Event Handlers if (myscreen) { var isDown = false; var canvasX, canvasY; ctx.lineWidth = 5; $(myscreen) .mousedown(function(e) { isDown = true; ctx.beginPath(); canvasX = e.pageX - myscreen.offsetLeft; canvasY = e.pageY - myscreen.offsetTop; ctx.moveTo(canvasX, canvasY); }) .mousemove(function(e) { if (isDown !== false) { canvasX = e.pageX - myscreen.offsetLeft; canvasY = e.pageY - myscreen.offsetTop; ctx.lineTo(canvasX, canvasY); ctx.strokeStyle = "#000"; ctx.stroke(); } }) .mouseup(function(e) { isDown = false; ctx.closePath(); }); } // Touch Events Handlers draw = { started: false, start: function(evt) { ctx.beginPath(); ctx.moveTo( evt.touches[0].pageX, evt.touches[0].pageY ); this.started = true; }, move: function(evt) { if (this.started) { ctx.lineTo( evt.touches[0].pageX, evt.touches[0].pageY ); ctx.strokeStyle = "#000"; ctx.lineWidth = 5; ctx.stroke(); } }, end: function(evt) { this.started = false; } }; // Touch Events myscreen.addEventListener('touchstart', draw.start, false); myscreen.addEventListener('touchend', draw.end, false); myscreen.addEventListener('touchmove', draw.move, false); // Disable Page Move document.body.addEventListener('touchmove', function(evt) { evt.preventDefault(); }, false); } }); 
 * { margin: 0; padding: 0; } html, body { width: 100%; height: 100%; overflow: hidden; } #canvasWrapper { width: 95.6%; height: 100%; position: absolute; z-index: 1; overflow: hidden; } #canvaSizer { padding: 0; display: block; width: 35%; border-style: solid; height: 35%; position: absolute; resize: both; max-width: 95%; min-width: 35%; max-height: 95%; min-height: 35%; overflow: hidden; resize: both; } canvas {} #screen { cursor: crosshair; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <!DOCTYPE html> <html lang="en"> <body> <div id="canvasWrapper"> <div id="canvaSizer"> <canvas id="screen"></canvas> </div> </div> </body> </html> 

Chrome is buggy regarding resize CSS elements. Chrome在resize CSS元素resize方面存在问题。 ( Filed a bug here ) 在此处提交了错误

If you put a child img the resize handler will not be visible, but it will resize! 如果您将子img放入,则调整大小处理程序将不可见,但会调整大小!
The same does not works for canvas (or input ). canvas (或input )不能使用相同的方法。 The handler is shadowed and irresponsive. 处理程序是阴影化的,没有响应。

A solution would be to add a custom "corner" handler element (with the adequate JS and event listeners)... 一种解决方案是添加一个自定义的“ corner”处理程序元素(具有足够的JS和事件侦听器)...


Meanwhile here's some improvements to your code: 同时,这是对代码的一些改进:

 // (i) PS: i filed a bug here: https://bugs.webkit.org/show_bug.cgi?id=181818 jQuery(function($) { // (i) Better DOM ready var canvaSizer = document.getElementById("canvaSizer"); var $canvaSizer = $(canvaSizer); var canvaWidth = $canvaSizer.width(); var canvas = document.getElementById("screen"); var ctx = canvas.getContext("2d"); var $canvas = $(canvas); var lineWidth = 5; // (i) var color = "#000"; // (i) // Events Handlers // (i) this object is all you need. Don't make other handlers var draw = { started: false, // (i) you need this function because you want to paint also on mousedown paint: function(e) { // (i) instead of wrapping large chunks of code, use return if (!draw.started) return; // (i) Don't duplicate event handlers, rather figure if a certain event exists e = e.touches ? e.touches[0] : e; ctx.lineTo( e.pageX - canvas.offsetLeft - (lineWidth / 2), // (i) forgot about lineWidth? e.pageY - canvas.offsetTop - (lineWidth / 2) ); ctx.strokeStyle = color; ctx.lineWidth = lineWidth; ctx.lineCap = 'round'; // (i) why not, will paint a mousedown shape ctx.stroke(); }, start: function(e) { ctx.beginPath(); // (i) No need to ctx.moveTo // (i) `this` is now `$canvas` so use `draw` draw.started = true; draw.paint(e); }, move: function(e) { draw.paint(e); }, end: function() { draw.started = false; ctx.closePath(); // (i) You forgot this one } }; function initialize() { // Fill Window Width and Height canvas.width = canvaSizer.clientWidth; canvas.height = canvaSizer.clientHeight; // Set Background Color ctx.fillStyle = "#fff"; // (i) This causes your canvas to clear on eveery initialize() // and you're calling initialize() on wrapper resize! ctx.fillRect(0, 0, canvas.width, canvas.height); // (i) No need to define ctx styles, you already have them in draw.move // Attach events // (i) Use a `.draw` namespace, so you can clear easily all events using .off() // (i) On init - off all events in the ".draw" namespace (if any) // (i) Use jQuery and pass the needed events // (i) You want to attach event handlers only once, not on every initialize() $canvas.off('.draw').on({ 'touchstart.draw mousedown.draw': draw.start, 'touchmove.draw mousemove.draw': draw.move, }); // (i) end should be delegated to body // you could mouseup over body, not necessarily over the paint area // Disable Page Move (i) if we're operating over $canvaSizer!! $('body').off('.draw').on({ 'touchmove.draw': function(evt) { if (draw.started) evt.preventDefault(); }, 'mouseup.draw': function() { draw.end(); } }); } // Wrapper resize event // (i) comment what does this - it helps. // (i) Don't use mouseup! Mouseup happens even if you're painting. Use "resize" $canvaSizer.on('resize', function() { var canvaWidthNew = $(this).width(); if (canvaWidthNew != canvaWidth) { canvaWidth = canvaWidthNew; // (i) move this inside, before init initialize(); } }); // INIT! initialize(); }); 
 * { margin: 0; } html, body { height: 100%; font: 14px/1.4 sans-serif; } #canvaSizer { padding: 0; display: inline-block; width: 35%; border-style: solid; height: 35%; position: absolute; resize: both; max-width: 95%; min-width: 35%; max-height: 95%; min-height: 35%; overflow: hidden; /*resize: both; so... don't... or figure out a JS way to do it. */ } #screen { display: inline-block; cursor: crosshair; position: relative; } 
 <div id="canvaSizer"> <canvas id="screen"></canvas> </div> <script src="https://code.jquery.com/jquery-3.1.0.js"></script> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM