Skip to content

Instantly share code, notes, and snippets.

@riffrain
Created December 15, 2019 01:36
Show Gist options
  • Save riffrain/80181bf3611a50acebdf7cffaee18089 to your computer and use it in GitHub Desktop.
Save riffrain/80181bf3611a50acebdf7cffaee18089 to your computer and use it in GitHub Desktop.
class DrawCanvas {
/**
* @param {String} id id of <canvas>
*/
constructor(id) {
this.lastPos = { x: 0, y: 0 };
this.paths = [];
this.drawing = false;
this.canvas = document.getElementById(id);
this.init();
this.setEvents();
this.reg = new RegExp('^touch');
this.run();
}
init() {
// clear canvas
this.canvas.width = this.canvas.width;
// set context options
this.ctx = this.canvas.getContext('2d');
this.ctx.strokeStyle = "#000";
this.ctx.lineWidth = 5;
this.ctx.lineJoin = "round";
this.ctx.lineCap = "round";
}
run() {
const animateFrame = ((callback) => {
return window.requestAnimationFrame
|| window.webkitRequestAnimationFrame
|| window.mozRequestAnimationFrame
|| window.oRequestAnimationFrame
|| window.msRequestAnimaitonFrame
|| function (cb) {
window.setTimeout(cb, 1000/60);
};
})();
const loop = () => {
animateFrame(loop);
this.strokePaths();
};
loop();
}
setEvents() {
[
{ eventName: 'touchstart', handle: 'drawStart' },
{ eventName: 'touchmove', handle: 'draw' },
{ eventName: 'touchend', handle: 'drawEnd' },
{ eventName: 'mousedown', handle: 'drawStart' },
{ eventName: 'mousemove', handle: 'draw' },
{ eventName: 'mouseup', handle: 'drawEnd' },
].forEach(({ eventName, handle }) => {
/** @var {Event} e */
this.canvas.addEventListener(eventName, (e) => {
e.stopPropagation();
e.preventDefault();
this[handle](e);
}, false);
});
}
/**
* @param {Event} event
*/
drawStart(event) {
this.drawing = true;
this.lastPos = this.getCurrentPos(event);
}
/**
* @param {Event} event
*/
draw(event) {
if (!this.drawing) return;
this.paths.push(this.getCurrentPos(event));
}
drawEnd() {
this.drawing = false;
}
/**
* @param {Event} event
*/
getCurrentPos(event) {
const { left, top } = this.canvas.getBoundingClientRect();
const { clientX, clientY } = this.getClientPos(event);
return { x: clientX - left, y: clientY - top };
}
/**
* @param {Event} event
*/
getClientPos(event) {
return this.reg.test(event.type)
? {
clientX: event.touches[0].clientX,
clientY: event.touches[0].clientY,
}
: {
clientX: event.clientX,
clientY: event.clientY,
};
}
strokePaths() {
if (!this.paths.length && !this.drawing) {
return;
}
let path = this.paths.shift();
while(path) {
this.ctx.beginPath();
this.ctx.moveTo(this.lastPos.x, this.lastPos.y);
this.ctx.lineTo(path.x, path.y);
this.ctx.stroke();
this.lastPos = path;
path = this.paths.shift();
}
}
getData() {
return this.canvas.toDataURL();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment