-
[Javascript] canvas에서 S펜, Stylus pen 으로 선 그릴 때 끊어짐 해결Javascript & TypeScript 2023. 9. 28. 09:42반응형
마우스로는 클릭 이벤트가 떨어질때까지 정상동작하지만, 펜이나 터치에선 선이 지속적으로 그려지지 않고 중단되는 현상이 있다면 canvas 에 touch-action: none 으로 적용하면 된다.
<canvas id="drawing" width="500" height="500" style="touch-action: none;"> </canvas>
아래는 선그리기 예제소스
<!DOCTYPE html> <html> <!-- https://stackoverflow.com/questions/21930514/speeding-up-html5-canvas-brush-drawing-onmousemove --> <!-- https://jsfiddle.net/m1erickson/wAGcL/ --> <!-- s-pen 선끊김 현상 해결 방법(touch-action: none) : https://stackoverflow.com/questions/49299496/html5-pointermove-touchmove-not-working-in-microsoft-edge --> <head> <meta charset='utf-8'> <meta http-equiv='X-UA-Compatible' content='IE=edge'> <title>Page Title</title> <meta name='viewport' content='width=device-width, initial-scale=1'> </head> <body style="background-color: black;"> <div id="log" style="background:wheat;width:500px;height:100%;position:absolute;right:0;top:0;overflow: auto;"> <p>Pressure: <span id="pressure"></span></p> </div> <canvas id="drawing" width="500" height="500" style="touch-action: none;"> </canvas> </body> <script> // get reference to canvas and save canvas offsets var canvas = document.getElementById('drawing'); var offsetX = canvas.offsetLeft; var offsetY = canvas.offsetTop; var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; /** * @param {CanvasRenderingContext2D} context */ function PrimitiveBrush(context, pressure) { if (!(context instanceof CanvasRenderingContext2D)) { throw new Error('No 2D rendering context given!'); } this.ctx = context; this.strokes = []; this.strokeIndex = 0; this.workingStrokes; this.lastLength = 0; this.isTouching = false; // init context this.ctx.strokeStyle = '#f00'; this.ctx.lineCap = this.ctx.lineJoin = 'round'; } /** * Begins a new stroke * @param {MouseEvent} event */ PrimitiveBrush.prototype.start = function (event) { event.preventDefault(); var x = event.clientX - offsetX; var y = event.clientY - offsetY; this.workingStrokes = [{ x: x, y: y }]; this.strokes.push(this.workingStrokes); this.lastLength = 1; this.isTouching = true; requestAnimationFrame(this._draw.bind(this)); }; /** * Moves the current position of our brush * @param {MouseEvent} event */ PrimitiveBrush.prototype.move = function (event) { event.preventDefault(); document.getElementById('pressure').innerHTML = `${new Date()} ${event.pressure}` ; if (!this.isTouching || !event.pressure || event.pressure === 0) { return; } var x = event.clientX - offsetX; var y = event.clientY - offsetY; this.ctx.lineWidth = event.pressure * 10; this.workingStrokes.push({ x: x, y: y }); requestAnimationFrame(this._draw.bind(this)); }; /** * Stops a stroke * @param {MouseEvent} event */ PrimitiveBrush.prototype.end = function (event) { event.preventDefault(); this.move(event); this.isTouching = false; }; PrimitiveBrush.prototype._draw = function () { // save the current length quickly (it's dynamic) var length = this.workingStrokes.length; // return if there's no work to do if (length <= this.lastLength) { return; } var startIndex = this.lastLength - 1; this.lastLength = length; var pt0 = this.workingStrokes[startIndex]; this.ctx.beginPath(); this.ctx.moveTo(pt0.x, pt0.y); for (var j = startIndex; j < this.lastLength; j++) { var pt = this.workingStrokes[j]; this.ctx.lineTo(pt.x, pt.y); } this.ctx.stroke(); }; // Set up brush to listen to events var brush = new PrimitiveBrush(canvas.getContext('2d')); canvas.addEventListener('pointerdown', brush.start.bind(brush)); canvas.addEventListener('pointermove', brush.move.bind(brush)); canvas.addEventListener('pointerup', brush.end.bind(brush)); </script> </html>
반응형'Javascript & TypeScript' 카테고리의 다른 글