diff --git a/dist/index.es.js b/dist/index.es.js index 7bab69d..0aa4647 100644 --- a/dist/index.es.js +++ b/dist/index.es.js @@ -1,19 +1,19 @@ -function g(e, t) { - return Math.sqrt(Math.pow(e.x - t.x, 2) + Math.pow(e.y - t.y, 2)); +function c(i, t) { + return Math.sqrt(Math.pow(i.x - t.x, 2) + Math.pow(i.y - t.y, 2)); } -function y(e, t) { - const i = g(e, t), o = { - x: t.x - e.x, - y: t.y - e.y +function k(i, t) { + const e = c(i, t), s = { + x: t.x - i.x, + y: t.y - i.y }; return { - x: o.x / i, - y: o.y / i + x: s.x / e, + y: s.y / e }; } -class k { +class w { constructor(t) { - this.canvas = t, this.lastTouch = null, this.sensitivity = 20, this.lastStrokeParts = [], this.onStrokePartHandlers = [], this.onTouchStart = this.onTouchStart.bind(this), this.onTouchEnd = this.onTouchEnd.bind(this), this.onTouchCancel = this.onTouchCancel.bind(this), this.onTouchMove = this.onTouchMove.bind(this), this.destroy = this.destroy.bind(this), this.getRelativePosition = this.getRelativePosition.bind(this), this.canvas.addEventListener("touchstart", this.onTouchStart, { + this.canvas = t, this.lastTouch = null, this.lastMouse = null, this.sensitivity = 20, this.lastStrokeParts = [], this.onStrokePartHandlers = [], this.onTouchStart = this.onTouchStart.bind(this), this.onTouchEnd = this.onTouchEnd.bind(this), this.onTouchCancel = this.onTouchCancel.bind(this), this.onTouchMove = this.onTouchMove.bind(this), this.destroy = this.destroy.bind(this), this.getRelativePosition = this.getRelativePosition.bind(this), this.onMouseDown = this.onMouseDown.bind(this), this.onMouseUp = this.onMouseUp.bind(this), this.onMouseMove = this.onMouseMove.bind(this), this.canvas.addEventListener("touchstart", this.onTouchStart, { passive: !1 }), this.canvas.addEventListener("touchend", this.onTouchEnd, { passive: !1 @@ -21,6 +21,12 @@ class k { passive: !1 }), this.canvas.addEventListener("touchmove", this.onTouchMove, { passive: !1 + }), this.canvas.addEventListener("mousedown", this.onMouseDown, { + passive: !1 + }), document.addEventListener("mouseup", this.onMouseUp, { + passive: !1 + }), this.canvas.addEventListener("mousemove", this.onMouseMove, { + passive: !1 }); } /** @@ -34,7 +40,7 @@ class k { * Removes all active listeners */ destroy() { - this.onStrokePartHandlers = [], this.lastStrokeParts = [], this.canvas.removeEventListener("touchstart", this.onTouchStart), this.canvas.removeEventListener("touchend", this.onTouchEnd), this.canvas.removeEventListener("touchcancel", this.onTouchCancel), this.canvas.removeEventListener("touchmove", this.onTouchMove); + this.onStrokePartHandlers = [], this.lastStrokeParts = [], this.canvas.removeEventListener("touchstart", this.onTouchStart), this.canvas.removeEventListener("touchend", this.onTouchEnd), this.canvas.removeEventListener("touchcancel", this.onTouchCancel), this.canvas.removeEventListener("touchmove", this.onTouchMove), this.canvas.removeEventListener("mousedown", this.onMouseDown), document.removeEventListener("mouseup", this.onMouseUp), this.canvas.removeEventListener("mousemove", this.onMouseMove); } /** * Get relative position to canvas @@ -42,11 +48,11 @@ class k { * @param clientY * @returns IPoint */ - getRelativePosition(t, i) { - const o = this.canvas.getBoundingClientRect(); + getRelativePosition(t, e) { + const s = this.canvas.getBoundingClientRect(); return { - x: t - o.left, - y: i - o.top + x: (t - s.left) / s.width, + y: (e - s.top) / s.height }; } /** @@ -57,10 +63,10 @@ class k { onTouchStart(t) { if (t.preventDefault(), this.lastTouch) return; - const o = t.changedTouches.item(0); + const s = t.changedTouches.item(0); this.lastTouch = { - id: o.identifier, - position: this.getRelativePosition(o.clientX, o.clientY) + id: s.identifier, + position: this.getRelativePosition(s.clientX, s.clientY) }; } /** @@ -71,24 +77,24 @@ class k { onTouchMove(t) { if (t.preventDefault(), !this.lastTouch) return; - const i = t.changedTouches, o = Array.from(i).find((a) => a.identifier === this.lastTouch.id); - if (!o) + const e = t.changedTouches, s = Array.from(e).find((a) => a.identifier === this.lastTouch.id); + if (!s) return; const n = { - id: o.identifier, - position: this.getRelativePosition(o.clientX, o.clientY) + id: s.identifier, + position: this.getRelativePosition(s.clientX, s.clientY) }; - if (this.sensitivity && g(n.position, this.lastTouch.position) < 10 / this.sensitivity) + if (this.sensitivity && c(n.position, this.lastTouch.position) < 10 / this.sensitivity) return; - const s = { + const o = { endPoint: n.position, startPoint: this.lastTouch.position, isStart: this.lastStrokeParts.length === 0, isEnd: !1 }; this.onStrokePartHandlers.forEach((a) => { - a(s); - }), this.lastTouch = n, this.lastStrokeParts.push(s); + a(o); + }), this.lastTouch = n, this.lastStrokeParts.push(o); } /** * Draws a line from last point to final point. Removes @@ -98,17 +104,17 @@ class k { onTouchEnd(t) { if (t.preventDefault(), !this.lastTouch) return; - const i = t.changedTouches, o = Array.from(i).find((a) => a.identifier === this.lastTouch.id); - if (!o) + const e = t.changedTouches, s = Array.from(e).find((a) => a.identifier === this.lastTouch.id); + if (!s) return; - const n = this.getRelativePosition(o.clientX, o.clientY), s = { + const n = this.getRelativePosition(s.clientX, s.clientY), o = { startPoint: this.lastTouch.position, endPoint: n, isStart: !1, isEnd: !0 }; this.onStrokePartHandlers.forEach((a) => { - a(s); + a(o); }), this.lastTouch = null, this.lastStrokeParts = []; } /** @@ -118,12 +124,49 @@ class k { onTouchCancel(t) { t.preventDefault(), this.lastTouch = null, this.lastStrokeParts = []; } + onMouseDown(t) { + this.lastMouse || (this.lastMouse = this.getRelativePosition(t.clientX, t.clientY)); + } + onMouseUp(t) { + if (!this.lastMouse) + return; + let e = this.getRelativePosition(t.clientX, t.clientY); + c(this.lastMouse, e) < 1 && (e = { + x: this.lastMouse.x + 8e-4, + y: this.lastMouse.y + 8e-4 + }); + const n = { + startPoint: this.lastMouse, + endPoint: e, + isStart: !1, + isEnd: !0 + }; + this.onStrokePartHandlers.forEach((o) => { + o(n); + }), this.lastMouse = null, this.lastStrokeParts = []; + } + onMouseMove(t) { + if (!this.lastMouse) + return; + const e = this.getRelativePosition(t.clientX, t.clientY); + if (this.sensitivity && c(e, this.lastMouse) < 0.05 / this.sensitivity) + return; + const s = { + endPoint: e, + startPoint: this.lastMouse, + isStart: this.lastStrokeParts.length === 0, + isEnd: !1 + }; + this.onStrokePartHandlers.forEach((n) => { + n(s); + }), this.lastMouse = e, this.lastStrokeParts.push(s); + } } -class P { - constructor(t, i, o) { - this.canvas = t, this.canvasWidth = i, this.canvasHeight = o, this.currentTool = null, this.currentStroke = [], this.strokeManager = new k(t), this.canvasState = null, this.shouldDraw = !1, this.shouldCommit = !1; - const n = t.getContext("2d").backingStorePixelRatio || 1, s = window.devicePixelRatio || 1; - this.pixelRatio = s / n, this.setCanvasSize = this.setCanvasSize.bind(this), this.setTool = this.setTool.bind(this), this.destroy = this.destroy.bind(this), this.clear = this.clear.bind(this), this.draw = this.draw.bind(this), this.onStrokePart = this.onStrokePart.bind(this), this.nextAnimationFrame = window.requestAnimationFrame(this.draw), this.strokeManager.onStrokePart(this.onStrokePart), this.setCanvasSize(i, o); +class M { + constructor(t, e, s) { + this.canvas = t, this.ctx = t.getContext("2d", { willReadFrequently: !0 }), this.canvasWidth = e, this.canvasHeight = s, this.currentTool = null, this.currentStroke = [], this.strokeManager = new w(t), this.canvasState = null, this.shouldDraw = !1, this.shouldCommit = !1; + const n = this.ctx.backingStorePixelRatio || 1, o = window.devicePixelRatio || 1; + this.pixelRatio = o / n, this.setCanvasSize = this.setCanvasSize.bind(this), this.setTool = this.setTool.bind(this), this.destroy = this.destroy.bind(this), this.clear = this.clear.bind(this), this.draw = this.draw.bind(this), this.onStrokePart = this.onStrokePart.bind(this), this.nextAnimationFrame = window.requestAnimationFrame(this.draw), this.strokeManager.onStrokePart(this.onStrokePart), this.setCanvasSize(e, s); } /** * Sets the canvas desired width and height and sets transform @@ -131,10 +174,10 @@ class P { * @param width * @param height */ - setCanvasSize(t, i) { - this.canvasWidth = t, this.canvasHeight = i; - const { canvas: o, canvasWidth: n, canvasHeight: s, pixelRatio: a } = this, h = o.getContext("2d"); - o.width = n * a, o.height = s * a, o.style.width = n + "px", o.style.height = s + "px", h.setTransform(a, 0, 0, a, 0, 0); + setCanvasSize(t, e) { + this.canvasWidth = t, this.canvasHeight = e; + const { ctx: s, canvas: n, canvasWidth: o, canvasHeight: a, pixelRatio: r } = this; + s && (n.width = o * r, n.height = a * r, n.style.width = o + "px", n.style.height = a + "px", s.scale(r, r)); } /** * Sets the current tool for the manager @@ -168,39 +211,42 @@ class P { */ draw() { this.nextAnimationFrame = window.requestAnimationFrame(this.draw); - const t = this.canvas.getContext("2d"); - this.shouldDraw && (t.clearRect(0, 0, this.canvasWidth, this.canvasHeight), this.canvasState && t.putImageData(this.canvasState, 0, 0), this.currentTool && this.currentStroke.length && (t.save(), this.currentTool.draw(t, this.currentStroke), t.restore()), this.shouldCommit && (this.canvasState = t.getImageData( + const { ctx: t, canvasWidth: e, canvasHeight: s } = this; + !this.shouldDraw || !t || (t.clearRect(0, 0, this.canvasWidth, this.canvasHeight), this.canvasState && t.putImageData(this.canvasState, 0, 0), this.currentTool && this.currentStroke.length && (t.save(), this.currentTool.draw(t, this.currentStroke, e, s), t.restore()), this.shouldCommit && (this.canvasState = t.getImageData( 0, 0, - this.canvasWidth * this.pixelRatio, - this.canvasHeight * this.pixelRatio + e * this.pixelRatio, + s * this.pixelRatio ), this.currentStroke = [], this.shouldCommit = !1), this.shouldDraw = !1); } } -class C { - constructor(t = "red", i = 3) { - this.color = t, this.width = i; +class E { + constructor(t = "red", e = 3) { + this.color = t, this.width = e; } /** * Draws a "pen stroke" for all line segments * @param ctx * @param strokeParts */ - draw(t, i) { - const o = i[0]; - t.beginPath(), t.lineWidth = this.width, t.strokeStyle = this.color, t.lineCap = "round", t.lineJoin = "round", t.moveTo(o.startPoint.x, o.startPoint.y), i.forEach((n) => { - const { endPoint: s } = n; - t.lineTo(s.x, s.y); + draw(t, e, s, n) { + const o = e[0]; + t.beginPath(), t.lineWidth = this.width, t.strokeStyle = this.color, t.lineCap = "round", t.lineJoin = "round", t.moveTo( + o.startPoint.x * s, + o.startPoint.y * n + ), e.forEach((a) => { + const { endPoint: r } = a; + t.lineTo(r.x * s, r.y * n); }), t.stroke(); } } -class E { - constructor(t = 10, i) { - this.width = t, i = i || {}, this.handleOpts = { - hide: i.hide || !1, - strokeWidth: i.strokeWidth || 2, - fillColor: i.fillColor || "white", - strokeColor: i.strokeColor || "black" +class C { + constructor(t = 10, e) { + this.width = t, e = e || {}, this.handleOpts = { + hide: e.hide || !1, + strokeWidth: e.strokeWidth || 2, + fillColor: e.fillColor || "white", + strokeColor: e.strokeColor || "black" }; } /** @@ -208,42 +254,49 @@ class E { * @param ctx * @param strokeParts */ - draw(t, i) { - const { handleOpts: o } = this, n = this.width / 2; - i.forEach((a) => { - const { startPoint: h, endPoint: l, isEnd: f } = a, d = g(h, l), v = y(h, l); - let r = h, u = 0; - for (; u < d; ) { - const c = { - x: r.x + v.x, - y: r.y + v.y + draw(t, e, s, n) { + const { handleOpts: o } = this, a = this.width / 2; + e.forEach((l) => { + const { startPoint: d, endPoint: g } = l, y = c(d, g), h = k(d, g); + let u = d, f = 0; + for (; f < y; ) { + const v = { + x: u.x * s + h.x, + y: u.y * n + h.y }; t.clearRect( - c.x - n, - c.y - n, + v.x - a, + v.y - a, this.width, this.width - ), u++, r = c; + ), f++, u = v; } }); - const s = i[i.length - 1]; - !s.isEnd && !o.hide && (t.strokeStyle = o.strokeColor, t.fillStyle = o.fillColor, t.fillRect( - s.endPoint.x - n, - s.endPoint.y - n, - this.width, - this.width - ), t.strokeRect( - s.endPoint.x - n + 0.5, - s.endPoint.y - n + 0.5, - this.width - 1, - this.width - 1 - )); + const r = e[e.length - 1]; + if (!r.isEnd && !o.hide) { + t.strokeStyle = o.strokeColor, t.fillStyle = o.fillColor; + const l = { + x: r.endPoint.x * s, + y: r.endPoint.y * n + }; + t.fillRect( + l.x - a, + l.y - a, + this.width, + this.width + ), t.strokeRect( + l.x - a + 0.5, + l.y - a + 0.5, + this.width - 1, + this.width - 1 + ); + } } } -function w(e) { - return e && e.__esModule && Object.prototype.hasOwnProperty.call(e, "default") ? e.default : e; +function b(i) { + return i && i.__esModule && Object.prototype.hasOwnProperty.call(i, "default") ? i.default : i; } -var b = { +var P = { aliceblue: [240, 248, 255], antiquewhite: [250, 235, 215], aqua: [0, 255, 255], @@ -393,7 +446,7 @@ var b = { yellow: [255, 255, 0], yellowgreen: [154, 205, 50] }; -const p = /* @__PURE__ */ w(b); +const p = /* @__PURE__ */ b(P); var m = { red: 0, orange: 60, @@ -402,84 +455,87 @@ var m = { blue: 240, purple: 300 }; -function T(e) { - var t, i = [], o = 1, n; - if (typeof e == "string") - if (e = e.toLowerCase(), p[e]) - i = p[e].slice(), n = "rgb"; - else if (e === "transparent") - o = 0, n = "rgb", i = [0, 0, 0]; - else if (/^#[A-Fa-f0-9]+$/.test(e)) { - var s = e.slice(1), a = s.length, h = a <= 4; - o = 1, h ? (i = [ - parseInt(s[0] + s[0], 16), - parseInt(s[1] + s[1], 16), - parseInt(s[2] + s[2], 16) - ], a === 4 && (o = parseInt(s[3] + s[3], 16) / 255)) : (i = [ - parseInt(s[0] + s[1], 16), - parseInt(s[2] + s[3], 16), - parseInt(s[4] + s[5], 16) - ], a === 8 && (o = parseInt(s[6] + s[7], 16) / 255)), i[0] || (i[0] = 0), i[1] || (i[1] = 0), i[2] || (i[2] = 0), n = "rgb"; - } else if (t = /^((?:rgb|hs[lvb]|hwb|cmyk?|xy[zy]|gray|lab|lchu?v?|[ly]uv|lms)a?)\s*\(([^\)]*)\)/.exec(e)) { - var l = t[1], f = l === "rgb", s = l.replace(/a$/, ""); - n = s; - var a = s === "cmyk" ? 4 : s === "gray" ? 1 : 3; - i = t[2].trim().split(/\s*[,\/]\s*|\s+/).map(function(r, u) { - if (/%$/.test(r)) - return u === a ? parseFloat(r) / 100 : s === "rgb" ? parseFloat(r) * 255 / 100 : parseFloat(r); - if (s[u] === "h") { - if (/deg$/.test(r)) - return parseFloat(r); - if (m[r] !== void 0) - return m[r]; +function S(i) { + var t, e = [], s = 1, n; + if (typeof i == "string") + if (i = i.toLowerCase(), p[i]) + e = p[i].slice(), n = "rgb"; + else if (i === "transparent") + s = 0, n = "rgb", e = [0, 0, 0]; + else if (/^#[A-Fa-f0-9]+$/.test(i)) { + var o = i.slice(1), a = o.length, r = a <= 4; + s = 1, r ? (e = [ + parseInt(o[0] + o[0], 16), + parseInt(o[1] + o[1], 16), + parseInt(o[2] + o[2], 16) + ], a === 4 && (s = parseInt(o[3] + o[3], 16) / 255)) : (e = [ + parseInt(o[0] + o[1], 16), + parseInt(o[2] + o[3], 16), + parseInt(o[4] + o[5], 16) + ], a === 8 && (s = parseInt(o[6] + o[7], 16) / 255)), e[0] || (e[0] = 0), e[1] || (e[1] = 0), e[2] || (e[2] = 0), n = "rgb"; + } else if (t = /^((?:rgb|hs[lvb]|hwb|cmyk?|xy[zy]|gray|lab|lchu?v?|[ly]uv|lms)a?)\s*\(([^\)]*)\)/.exec(i)) { + var l = t[1], d = l === "rgb", o = l.replace(/a$/, ""); + n = o; + var a = o === "cmyk" ? 4 : o === "gray" ? 1 : 3; + e = t[2].trim().split(/\s*[,\/]\s*|\s+/).map(function(h, u) { + if (/%$/.test(h)) + return u === a ? parseFloat(h) / 100 : o === "rgb" ? parseFloat(h) * 255 / 100 : parseFloat(h); + if (o[u] === "h") { + if (/deg$/.test(h)) + return parseFloat(h); + if (m[h] !== void 0) + return m[h]; } - return parseFloat(r); - }), l === s && i.push(1), o = f || i[a] === void 0 ? 1 : i[a], i = i.slice(0, a); + return parseFloat(h); + }), l === o && e.push(1), s = d || e[a] === void 0 ? 1 : e[a], e = e.slice(0, a); } else - e.length > 10 && /[0-9](?:\s|\/)/.test(e) && (i = e.match(/([0-9]+)/g).map(function(d) { - return parseFloat(d); - }), n = e.match(/([a-z])/ig).join("").toLowerCase()); + i.length > 10 && /[0-9](?:\s|\/)/.test(i) && (e = i.match(/([0-9]+)/g).map(function(g) { + return parseFloat(g); + }), n = i.match(/([a-z])/ig).join("").toLowerCase()); else - isNaN(e) ? Array.isArray(e) || e.length ? (i = [e[0], e[1], e[2]], n = "rgb", o = e.length === 4 ? e[3] : 1) : e instanceof Object && (e.r != null || e.red != null || e.R != null ? (n = "rgb", i = [ - e.r || e.red || e.R || 0, - e.g || e.green || e.G || 0, - e.b || e.blue || e.B || 0 - ]) : (n = "hsl", i = [ - e.h || e.hue || e.H || 0, - e.s || e.saturation || e.S || 0, - e.l || e.lightness || e.L || e.b || e.brightness - ]), o = e.a || e.alpha || e.opacity || 1, e.opacity != null && (o /= 100)) : (n = "rgb", i = [e >>> 16, (e & 65280) >>> 8, e & 255]); + isNaN(i) ? Array.isArray(i) || i.length ? (e = [i[0], i[1], i[2]], n = "rgb", s = i.length === 4 ? i[3] : 1) : i instanceof Object && (i.r != null || i.red != null || i.R != null ? (n = "rgb", e = [ + i.r || i.red || i.R || 0, + i.g || i.green || i.G || 0, + i.b || i.blue || i.B || 0 + ]) : (n = "hsl", e = [ + i.h || i.hue || i.H || 0, + i.s || i.saturation || i.S || 0, + i.l || i.lightness || i.L || i.b || i.brightness + ]), s = i.a || i.alpha || i.opacity || 1, i.opacity != null && (s /= 100)) : (n = "rgb", e = [i >>> 16, (i & 65280) >>> 8, i & 255]); return { space: n, - values: i, - alpha: o + values: e, + alpha: s }; } -function S(e, t) { - var i = T(e); - return t == null && (t = i.alpha), i.space[0] === "h" ? i.space + ["a(", i.values[0], ",", i.values[1], "%,", i.values[2], "%,", t, ")"].join("") : i.space + ["a(", i.values, ",", t, ")"].join(""); +function T(i, t) { + var e = S(i); + return t == null && (t = e.alpha), e.space[0] === "h" ? e.space + ["a(", e.values[0], ",", e.values[1], "%,", e.values[2], "%,", t, ")"].join("") : e.space + ["a(", e.values, ",", t, ")"].join(""); } class R { - constructor(t = "yellow", i = 8, o = 0.3) { - this.width = i, this.color = S(t, 0.4); + constructor(t = "yellow", e = 8, s = 0.3) { + this.width = e, this.color = T(t, 0.4); } /** * Draws a "highlighter stroke" for all line segments * @param ctx * @param strokeParts */ - draw(t, i) { - const o = i[0]; - t.beginPath(), t.lineWidth = this.width, t.strokeStyle = this.color, t.lineCap = "butt", t.miterLimit = 1, t.moveTo(o.startPoint.x, o.startPoint.y), i.forEach((n) => { - const { endPoint: s } = n; - t.lineTo(s.x, s.y); + draw(t, e, s, n) { + const o = e[0]; + t.beginPath(), t.lineWidth = this.width, t.strokeStyle = this.color, t.lineCap = "butt", t.miterLimit = 1, t.moveTo( + o.startPoint.x * s, + o.startPoint.y * n + ), e.forEach((a) => { + const { endPoint: r } = a; + t.lineTo(r.x * s, r.y * n); }), t.stroke(); } } export { - E as EraserTool, + C as EraserTool, R as HighlighterTool, - P as Manager, - C as PenTool + M as Manager, + E as PenTool }; //# sourceMappingURL=index.es.js.map diff --git a/dist/index.es.js.map b/dist/index.es.js.map index 74ac204..c4796be 100644 --- a/dist/index.es.js.map +++ b/dist/index.es.js.map @@ -1 +1 @@ -{"version":3,"file":"index.es.js","sources":["../src/util.ts","../src/StrokeManager.ts","../src/Manager.ts","../src/tools/PenTool.ts","../src/tools/EraserTool.ts","../node_modules/color-name/index.js","../node_modules/color-parse/index.mjs","../node_modules/color-alpha/index.mjs","../src/tools/HighlighterTool.ts"],"sourcesContent":["import { IPoint } from \"./types\";\n\n/**\n * Get the distance between two points\n * @param p1\n * @param p2\n * @returns number\n */\nexport function getEuclidean(p1: IPoint, p2: IPoint): number {\n return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));\n}\n\n/**\n * Gets the unit vector representing the vector from start\n * point to end point with a length of 1.\n * @param startPoint\n * @param endPoint\n * @returns IPoint\n */\nexport function getUnitVector(startPoint: IPoint, endPoint: IPoint): IPoint {\n const length = getEuclidean(startPoint, endPoint);\n\n const dirVect = {\n x: endPoint.x - startPoint.x,\n y: endPoint.y - startPoint.y,\n };\n\n const unitVect: IPoint = {\n x: dirVect.x / length,\n y: dirVect.y / length,\n };\n\n return unitVect;\n}\n","import { IPoint, IStrokePart } from \"./types\";\nimport { getEuclidean } from \"./util\";\n\nexport interface IOnStrokePartHandler {\n (strokePart: IStrokePart): void;\n}\n\nexport interface ITouch {\n id: number;\n position: IPoint;\n}\n\nexport class StrokeManager {\n // reference to canvas element\n private canvas: HTMLCanvasElement;\n // holds last touch point in a drag\n private lastTouch: ITouch | null;\n // value indicates how sensitive the stroke detection is higher is better\n private sensitivity: number;\n // holds all of the last emitted stroke parts in a drag\n private lastStrokeParts: IStrokePart[];\n // the handlers listening for new strokes\n private onStrokePartHandlers: IOnStrokePartHandler[];\n\n constructor(canvas: HTMLCanvasElement) {\n this.canvas = canvas;\n this.lastTouch = null;\n this.sensitivity = 20.0;\n this.lastStrokeParts = [];\n this.onStrokePartHandlers = [];\n\n this.onTouchStart = this.onTouchStart.bind(this);\n this.onTouchEnd = this.onTouchEnd.bind(this);\n this.onTouchCancel = this.onTouchCancel.bind(this);\n this.onTouchMove = this.onTouchMove.bind(this);\n this.destroy = this.destroy.bind(this);\n this.getRelativePosition = this.getRelativePosition.bind(this);\n\n this.canvas.addEventListener(\"touchstart\", this.onTouchStart, {\n passive: false,\n });\n this.canvas.addEventListener(\"touchend\", this.onTouchEnd, {\n passive: false,\n });\n this.canvas.addEventListener(\"touchcancel\", this.onTouchCancel, {\n passive: false,\n });\n this.canvas.addEventListener(\"touchmove\", this.onTouchMove, {\n passive: false,\n });\n }\n\n /**\n * Registers a handler to be fired on a new stroke part\n * @param handler\n */\n public onStrokePart(handler: IOnStrokePartHandler): void {\n this.onStrokePartHandlers.push(handler);\n }\n\n /**\n * Removes all active listeners\n */\n public destroy(): void {\n this.onStrokePartHandlers = [];\n this.lastStrokeParts = [];\n this.canvas.removeEventListener(\"touchstart\", this.onTouchStart);\n this.canvas.removeEventListener(\"touchend\", this.onTouchEnd);\n this.canvas.removeEventListener(\"touchcancel\", this.onTouchCancel);\n this.canvas.removeEventListener(\"touchmove\", this.onTouchMove);\n }\n\n /**\n * Get relative position to canvas\n * @param clientX\n * @param clientY\n * @returns IPoint\n */\n private getRelativePosition(clientX: number, clientY: number): IPoint {\n const rect = this.canvas.getBoundingClientRect();\n\n return {\n x: clientX - rect.left,\n y: clientY - rect.top,\n };\n }\n\n /**\n * Creates a new touch if one does not\n * already exist\n * @param e\n */\n private onTouchStart(e: TouchEvent): void {\n e.preventDefault();\n\n // if there is an ongoing touch, ignore this event\n if (this.lastTouch) {\n return;\n }\n\n const touches: TouchList = e.changedTouches;\n\n // only get the first touch\n const touch = touches.item(0);\n\n // save the touch\n this.lastTouch = {\n id: touch.identifier,\n position: this.getRelativePosition(touch.clientX, touch.clientY),\n };\n }\n\n /**\n * Creates a line from last touch to current touch\n * point and emits event. Does no-op if no existing touch\n * @param e\n */\n private onTouchMove(e: TouchEvent): void {\n e.preventDefault();\n\n // if no last touch... something is wrong\n if (!this.lastTouch) {\n return;\n }\n\n const touches: TouchList = e.changedTouches;\n\n // find the current touch we are tracking\n const touch: Touch = Array.from(touches).find((touch) => {\n return touch.identifier === this.lastTouch.id;\n });\n\n // if the touch was not one we were tracking,\n // ignore and no-op\n if (!touch) {\n return;\n }\n\n const nextTouch: ITouch = {\n id: touch.identifier,\n position: this.getRelativePosition(touch.clientX, touch.clientY),\n };\n\n // If sensitivity setting has been set,\n // check if this point is far enough from last\n // touch to be drawn\n if (\n this.sensitivity &&\n getEuclidean(nextTouch.position, this.lastTouch.position) <\n 10.0 / this.sensitivity\n ) {\n return;\n }\n\n const strokePart: IStrokePart = {\n endPoint: nextTouch.position,\n startPoint: this.lastTouch.position,\n isStart: this.lastStrokeParts.length === 0,\n isEnd: false,\n };\n\n this.onStrokePartHandlers.forEach((handler) => {\n handler(strokePart);\n });\n\n // save this touch as last touch\n this.lastTouch = nextTouch;\n this.lastStrokeParts.push(strokePart);\n }\n\n /**\n * Draws a line from last point to final point. Removes\n * the reference to last touch point.\n * @param e\n */\n private onTouchEnd(e: TouchEvent): void {\n e.preventDefault();\n\n // if no last touch... something is wrong\n if (!this.lastTouch) {\n return;\n }\n\n const touches: TouchList = e.changedTouches;\n\n // find the current touch we are tracking\n const touch: Touch = Array.from(touches).find((touch) => {\n return touch.identifier === this.lastTouch.id;\n });\n\n // if the touch was not one we were tracking,\n // ignore and no-op\n if (!touch) {\n return;\n }\n\n const endPoint = this.getRelativePosition(touch.clientX, touch.clientY);\n\n const strokePart: IStrokePart = {\n startPoint: this.lastTouch.position,\n endPoint,\n isStart: false,\n isEnd: true,\n };\n\n this.onStrokePartHandlers.forEach((handler) => {\n handler(strokePart);\n });\n\n this.lastTouch = null;\n this.lastStrokeParts = [];\n }\n\n /**\n * Removes the current last touch point\n * @param e\n */\n private onTouchCancel(e: TouchEvent): void {\n e.preventDefault();\n this.lastTouch = null;\n this.lastStrokeParts = [];\n }\n}\n","import { IStrokePart, ITool } from \"./types\";\nimport { StrokeManager } from \"./StrokeManager\";\n\nexport class Manager {\n // reference to the canvas\n private canvas: HTMLCanvasElement;\n // reference to stroke manager\n private strokeManager: StrokeManager;\n // holds the pixel ratio between canvas backing\n // store and device ratio (used for hi fi displays)\n private pixelRatio: number;\n // the width of the canvas\n private canvasWidth: number;\n // the height of the canvas\n private canvasHeight: number;\n // holds a reference to next animation frame\n private nextAnimationFrame: number;\n // the currently selected tool\n private currentTool: ITool | null;\n // holds stroke parts for ongoing stroke\n private currentStroke: IStrokePart[];\n // the state of the canvas (not including ongoing stroke)\n private canvasState: ImageData | null;\n // indicates whether changes have occured that require redraw\n private shouldDraw: boolean;\n // indicates whether canvas should commit its next draw state to current state\n private shouldCommit: boolean;\n\n constructor(\n canvas: HTMLCanvasElement,\n canvasWidth: number,\n canvasHeight: number,\n ) {\n this.canvas = canvas;\n this.canvasWidth = canvasWidth;\n this.canvasHeight = canvasHeight;\n this.currentTool = null;\n this.currentStroke = [];\n this.strokeManager = new StrokeManager(canvas);\n this.canvasState = null;\n this.shouldDraw = false;\n this.shouldCommit = false;\n\n // find pixel ratio relative to backing store and device ratio\n const bsr = (canvas.getContext(\"2d\") as any).backingStorePixelRatio || 1;\n const dpr = window.devicePixelRatio || 1;\n this.pixelRatio = dpr / bsr;\n\n this.setCanvasSize = this.setCanvasSize.bind(this);\n this.setTool = this.setTool.bind(this);\n this.destroy = this.destroy.bind(this);\n this.clear = this.clear.bind(this);\n this.draw = this.draw.bind(this);\n this.onStrokePart = this.onStrokePart.bind(this);\n\n // schedule animation frame loop\n this.nextAnimationFrame = window.requestAnimationFrame(this.draw);\n // set up listener for new stroke part\n this.strokeManager.onStrokePart(this.onStrokePart);\n\n this.setCanvasSize(canvasWidth, canvasHeight);\n }\n\n /**\n * Sets the canvas desired width and height and sets transform\n * for hifi displays\n * @param width\n * @param height\n */\n public setCanvasSize(width: number, height: number): void {\n this.canvasWidth = width;\n this.canvasHeight = height;\n\n const { canvas, canvasWidth, canvasHeight, pixelRatio } = this;\n\n const ctx = canvas.getContext(\"2d\");\n\n // appropriately scale canvas to map to device ratio\n canvas.width = canvasWidth * pixelRatio;\n canvas.height = canvasHeight * pixelRatio;\n canvas.style.width = canvasWidth + \"px\";\n canvas.style.height = canvasHeight + \"px\";\n ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);\n }\n\n /**\n * Sets the current tool for the manager\n * @param tool\n */\n public setTool(tool: ITool): void {\n this.currentTool = tool;\n }\n\n /**\n * Remove all event listeners\n */\n public destroy(): void {\n // cancel animation loop\n window.cancelAnimationFrame(this.nextAnimationFrame);\n // remove all listeners on stroke manager\n this.strokeManager.destroy();\n }\n\n /**\n * Clears the canvas\n */\n public clear(): void {\n this.canvasState = null;\n this.currentStroke = [];\n this.shouldDraw = true;\n this.shouldCommit = true;\n }\n\n /**\n * Adds a new stroke part to the nextStrokes\n * array\n * @param strokePart\n */\n private onStrokePart(strokePart: IStrokePart): void {\n this.currentStroke.push(strokePart);\n\n this.shouldDraw = true;\n\n if (strokePart.isEnd) {\n this.shouldCommit = true;\n }\n }\n\n /**\n * Draws a frame\n */\n private draw(): void {\n // schedule next draw\n this.nextAnimationFrame = window.requestAnimationFrame(this.draw);\n\n const ctx = this.canvas.getContext(\"2d\");\n\n if (!this.shouldDraw) {\n return;\n }\n\n // clear canvas\n ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);\n\n // draw current state\n if (this.canvasState) {\n ctx.putImageData(this.canvasState, 0, 0);\n }\n\n // if a tool has been selected and there are\n // pending strokes, draw them\n if (this.currentTool && this.currentStroke.length) {\n ctx.save();\n this.currentTool.draw(ctx, this.currentStroke);\n ctx.restore();\n }\n\n // if all changes have been made for current stroke,\n // save it as the new canvas state\n if (this.shouldCommit) {\n this.canvasState = ctx.getImageData(\n 0,\n 0,\n this.canvasWidth * this.pixelRatio,\n this.canvasHeight * this.pixelRatio,\n );\n this.currentStroke = [];\n this.shouldCommit = false;\n }\n\n this.shouldDraw = false;\n }\n}\n","import { IStrokePart } from \"../types\";\n\nexport class PenTool {\n readonly color: string;\n readonly width: number;\n\n constructor(color: string = \"red\", width: number = 3) {\n this.color = color;\n this.width = width;\n }\n\n /**\n * Draws a \"pen stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n public draw(ctx: CanvasRenderingContext2D, strokeParts: IStrokePart[]): void {\n const firstPart = strokeParts[0];\n\n ctx.beginPath();\n\n ctx.lineWidth = this.width;\n ctx.strokeStyle = this.color;\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n\n ctx.moveTo(firstPart.startPoint.x, firstPart.startPoint.y);\n\n strokeParts.forEach((strokePart) => {\n const { endPoint } = strokePart;\n ctx.lineTo(endPoint.x, endPoint.y);\n });\n\n ctx.stroke();\n }\n}\n","import { IStrokePart, IPoint } from \"../types\";\nimport { getUnitVector, getEuclidean } from \"../util\";\n\nexport interface IHandleOptions {\n hide: boolean;\n strokeWidth: number;\n fillColor: string;\n strokeColor: string;\n}\n\nexport class EraserTool {\n readonly width: number;\n readonly handleOpts: IHandleOptions;\n\n constructor(width: number = 10, handleOpts?: Partial) {\n this.width = width;\n\n handleOpts = handleOpts || {};\n\n this.handleOpts = {\n hide: handleOpts.hide || false,\n strokeWidth: handleOpts.strokeWidth || 2,\n fillColor: handleOpts.fillColor || \"white\",\n strokeColor: handleOpts.strokeColor || \"black\",\n };\n }\n\n /**\n * Draws an \"eraser stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n public draw(ctx: CanvasRenderingContext2D, strokeParts: IStrokePart[]): void {\n const { handleOpts } = this;\n const halfWidth = this.width / 2.0;\n\n strokeParts.forEach((strokePart) => {\n const { startPoint, endPoint, isEnd } = strokePart;\n\n const length = getEuclidean(startPoint, endPoint);\n const unitVect: IPoint = getUnitVector(startPoint, endPoint);\n let currentPoint: IPoint = startPoint;\n let i = 0;\n\n // clear all the way along the drag\n while (i < length) {\n const nextPoint: IPoint = {\n x: currentPoint.x + unitVect.x,\n y: currentPoint.y + unitVect.y,\n };\n\n ctx.clearRect(\n nextPoint.x - halfWidth,\n nextPoint.y - halfWidth,\n this.width,\n this.width,\n );\n\n i++;\n currentPoint = nextPoint;\n }\n });\n\n const lastPart = strokeParts[strokeParts.length - 1];\n\n // if the end is not the last part, then draw\n // the tool indicator at the endpoint\n if (!lastPart.isEnd && !handleOpts.hide) {\n ctx.strokeStyle = handleOpts.strokeColor;\n ctx.fillStyle = handleOpts.fillColor;\n\n ctx.fillRect(\n lastPart.endPoint.x - halfWidth,\n lastPart.endPoint.y - halfWidth,\n this.width,\n this.width,\n );\n\n ctx.strokeRect(\n lastPart.endPoint.x - halfWidth + 0.5,\n lastPart.endPoint.y - halfWidth + 0.5,\n this.width - 1,\n this.width - 1,\n );\n }\n }\n}\n","'use strict'\r\n\r\nmodule.exports = {\r\n\t\"aliceblue\": [240, 248, 255],\r\n\t\"antiquewhite\": [250, 235, 215],\r\n\t\"aqua\": [0, 255, 255],\r\n\t\"aquamarine\": [127, 255, 212],\r\n\t\"azure\": [240, 255, 255],\r\n\t\"beige\": [245, 245, 220],\r\n\t\"bisque\": [255, 228, 196],\r\n\t\"black\": [0, 0, 0],\r\n\t\"blanchedalmond\": [255, 235, 205],\r\n\t\"blue\": [0, 0, 255],\r\n\t\"blueviolet\": [138, 43, 226],\r\n\t\"brown\": [165, 42, 42],\r\n\t\"burlywood\": [222, 184, 135],\r\n\t\"cadetblue\": [95, 158, 160],\r\n\t\"chartreuse\": [127, 255, 0],\r\n\t\"chocolate\": [210, 105, 30],\r\n\t\"coral\": [255, 127, 80],\r\n\t\"cornflowerblue\": [100, 149, 237],\r\n\t\"cornsilk\": [255, 248, 220],\r\n\t\"crimson\": [220, 20, 60],\r\n\t\"cyan\": [0, 255, 255],\r\n\t\"darkblue\": [0, 0, 139],\r\n\t\"darkcyan\": [0, 139, 139],\r\n\t\"darkgoldenrod\": [184, 134, 11],\r\n\t\"darkgray\": [169, 169, 169],\r\n\t\"darkgreen\": [0, 100, 0],\r\n\t\"darkgrey\": [169, 169, 169],\r\n\t\"darkkhaki\": [189, 183, 107],\r\n\t\"darkmagenta\": [139, 0, 139],\r\n\t\"darkolivegreen\": [85, 107, 47],\r\n\t\"darkorange\": [255, 140, 0],\r\n\t\"darkorchid\": [153, 50, 204],\r\n\t\"darkred\": [139, 0, 0],\r\n\t\"darksalmon\": [233, 150, 122],\r\n\t\"darkseagreen\": [143, 188, 143],\r\n\t\"darkslateblue\": [72, 61, 139],\r\n\t\"darkslategray\": [47, 79, 79],\r\n\t\"darkslategrey\": [47, 79, 79],\r\n\t\"darkturquoise\": [0, 206, 209],\r\n\t\"darkviolet\": [148, 0, 211],\r\n\t\"deeppink\": [255, 20, 147],\r\n\t\"deepskyblue\": [0, 191, 255],\r\n\t\"dimgray\": [105, 105, 105],\r\n\t\"dimgrey\": [105, 105, 105],\r\n\t\"dodgerblue\": [30, 144, 255],\r\n\t\"firebrick\": [178, 34, 34],\r\n\t\"floralwhite\": [255, 250, 240],\r\n\t\"forestgreen\": [34, 139, 34],\r\n\t\"fuchsia\": [255, 0, 255],\r\n\t\"gainsboro\": [220, 220, 220],\r\n\t\"ghostwhite\": [248, 248, 255],\r\n\t\"gold\": [255, 215, 0],\r\n\t\"goldenrod\": [218, 165, 32],\r\n\t\"gray\": [128, 128, 128],\r\n\t\"green\": [0, 128, 0],\r\n\t\"greenyellow\": [173, 255, 47],\r\n\t\"grey\": [128, 128, 128],\r\n\t\"honeydew\": [240, 255, 240],\r\n\t\"hotpink\": [255, 105, 180],\r\n\t\"indianred\": [205, 92, 92],\r\n\t\"indigo\": [75, 0, 130],\r\n\t\"ivory\": [255, 255, 240],\r\n\t\"khaki\": [240, 230, 140],\r\n\t\"lavender\": [230, 230, 250],\r\n\t\"lavenderblush\": [255, 240, 245],\r\n\t\"lawngreen\": [124, 252, 0],\r\n\t\"lemonchiffon\": [255, 250, 205],\r\n\t\"lightblue\": [173, 216, 230],\r\n\t\"lightcoral\": [240, 128, 128],\r\n\t\"lightcyan\": [224, 255, 255],\r\n\t\"lightgoldenrodyellow\": [250, 250, 210],\r\n\t\"lightgray\": [211, 211, 211],\r\n\t\"lightgreen\": [144, 238, 144],\r\n\t\"lightgrey\": [211, 211, 211],\r\n\t\"lightpink\": [255, 182, 193],\r\n\t\"lightsalmon\": [255, 160, 122],\r\n\t\"lightseagreen\": [32, 178, 170],\r\n\t\"lightskyblue\": [135, 206, 250],\r\n\t\"lightslategray\": [119, 136, 153],\r\n\t\"lightslategrey\": [119, 136, 153],\r\n\t\"lightsteelblue\": [176, 196, 222],\r\n\t\"lightyellow\": [255, 255, 224],\r\n\t\"lime\": [0, 255, 0],\r\n\t\"limegreen\": [50, 205, 50],\r\n\t\"linen\": [250, 240, 230],\r\n\t\"magenta\": [255, 0, 255],\r\n\t\"maroon\": [128, 0, 0],\r\n\t\"mediumaquamarine\": [102, 205, 170],\r\n\t\"mediumblue\": [0, 0, 205],\r\n\t\"mediumorchid\": [186, 85, 211],\r\n\t\"mediumpurple\": [147, 112, 219],\r\n\t\"mediumseagreen\": [60, 179, 113],\r\n\t\"mediumslateblue\": [123, 104, 238],\r\n\t\"mediumspringgreen\": [0, 250, 154],\r\n\t\"mediumturquoise\": [72, 209, 204],\r\n\t\"mediumvioletred\": [199, 21, 133],\r\n\t\"midnightblue\": [25, 25, 112],\r\n\t\"mintcream\": [245, 255, 250],\r\n\t\"mistyrose\": [255, 228, 225],\r\n\t\"moccasin\": [255, 228, 181],\r\n\t\"navajowhite\": [255, 222, 173],\r\n\t\"navy\": [0, 0, 128],\r\n\t\"oldlace\": [253, 245, 230],\r\n\t\"olive\": [128, 128, 0],\r\n\t\"olivedrab\": [107, 142, 35],\r\n\t\"orange\": [255, 165, 0],\r\n\t\"orangered\": [255, 69, 0],\r\n\t\"orchid\": [218, 112, 214],\r\n\t\"palegoldenrod\": [238, 232, 170],\r\n\t\"palegreen\": [152, 251, 152],\r\n\t\"paleturquoise\": [175, 238, 238],\r\n\t\"palevioletred\": [219, 112, 147],\r\n\t\"papayawhip\": [255, 239, 213],\r\n\t\"peachpuff\": [255, 218, 185],\r\n\t\"peru\": [205, 133, 63],\r\n\t\"pink\": [255, 192, 203],\r\n\t\"plum\": [221, 160, 221],\r\n\t\"powderblue\": [176, 224, 230],\r\n\t\"purple\": [128, 0, 128],\r\n\t\"rebeccapurple\": [102, 51, 153],\r\n\t\"red\": [255, 0, 0],\r\n\t\"rosybrown\": [188, 143, 143],\r\n\t\"royalblue\": [65, 105, 225],\r\n\t\"saddlebrown\": [139, 69, 19],\r\n\t\"salmon\": [250, 128, 114],\r\n\t\"sandybrown\": [244, 164, 96],\r\n\t\"seagreen\": [46, 139, 87],\r\n\t\"seashell\": [255, 245, 238],\r\n\t\"sienna\": [160, 82, 45],\r\n\t\"silver\": [192, 192, 192],\r\n\t\"skyblue\": [135, 206, 235],\r\n\t\"slateblue\": [106, 90, 205],\r\n\t\"slategray\": [112, 128, 144],\r\n\t\"slategrey\": [112, 128, 144],\r\n\t\"snow\": [255, 250, 250],\r\n\t\"springgreen\": [0, 255, 127],\r\n\t\"steelblue\": [70, 130, 180],\r\n\t\"tan\": [210, 180, 140],\r\n\t\"teal\": [0, 128, 128],\r\n\t\"thistle\": [216, 191, 216],\r\n\t\"tomato\": [255, 99, 71],\r\n\t\"turquoise\": [64, 224, 208],\r\n\t\"violet\": [238, 130, 238],\r\n\t\"wheat\": [245, 222, 179],\r\n\t\"white\": [255, 255, 255],\r\n\t\"whitesmoke\": [245, 245, 245],\r\n\t\"yellow\": [255, 255, 0],\r\n\t\"yellowgreen\": [154, 205, 50]\r\n};\r\n","/**\n * @module color-parse\n */\nimport names from 'color-name'\n\nexport default parse\n\n/**\n * Base hues\n * http://dev.w3.org/csswg/css-color/#typedef-named-hue\n */\n//FIXME: use external hue detector\nvar baseHues = {\n\tred: 0,\n\torange: 60,\n\tyellow: 120,\n\tgreen: 180,\n\tblue: 240,\n\tpurple: 300\n}\n\n/**\n * Parse color from the string passed\n *\n * @return {Object} A space indicator `space`, an array `values` and `alpha`\n */\nfunction parse(cstr) {\n\tvar m, parts = [], alpha = 1, space\n\n\tif (typeof cstr === 'string') {\n\t\tcstr = cstr.toLowerCase();\n\n\t\t//keyword\n\t\tif (names[cstr]) {\n\t\t\tparts = names[cstr].slice()\n\t\t\tspace = 'rgb'\n\t\t}\n\n\t\t//reserved words\n\t\telse if (cstr === 'transparent') {\n\t\t\talpha = 0\n\t\t\tspace = 'rgb'\n\t\t\tparts = [0, 0, 0]\n\t\t}\n\n\t\t//hex\n\t\telse if (/^#[A-Fa-f0-9]+$/.test(cstr)) {\n\t\t\tvar base = cstr.slice(1)\n\t\t\tvar size = base.length\n\t\t\tvar isShort = size <= 4\n\t\t\talpha = 1\n\n\t\t\tif (isShort) {\n\t\t\t\tparts = [\n\t\t\t\t\tparseInt(base[0] + base[0], 16),\n\t\t\t\t\tparseInt(base[1] + base[1], 16),\n\t\t\t\t\tparseInt(base[2] + base[2], 16)\n\t\t\t\t]\n\t\t\t\tif (size === 4) {\n\t\t\t\t\talpha = parseInt(base[3] + base[3], 16) / 255\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tparts = [\n\t\t\t\t\tparseInt(base[0] + base[1], 16),\n\t\t\t\t\tparseInt(base[2] + base[3], 16),\n\t\t\t\t\tparseInt(base[4] + base[5], 16)\n\t\t\t\t]\n\t\t\t\tif (size === 8) {\n\t\t\t\t\talpha = parseInt(base[6] + base[7], 16) / 255\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!parts[0]) parts[0] = 0\n\t\t\tif (!parts[1]) parts[1] = 0\n\t\t\tif (!parts[2]) parts[2] = 0\n\n\t\t\tspace = 'rgb'\n\t\t}\n\n\t\t//color space\n\t\telse if (m = /^((?:rgb|hs[lvb]|hwb|cmyk?|xy[zy]|gray|lab|lchu?v?|[ly]uv|lms)a?)\\s*\\(([^\\)]*)\\)/.exec(cstr)) {\n\t\t\tvar name = m[1]\n\t\t\tvar isRGB = name === 'rgb'\n\t\t\tvar base = name.replace(/a$/, '')\n\t\t\tspace = base\n\t\t\tvar size = base === 'cmyk' ? 4 : base === 'gray' ? 1 : 3\n\t\t\tparts = m[2].trim()\n\t\t\t\t.split(/\\s*[,\\/]\\s*|\\s+/)\n\t\t\t\t.map(function (x, i) {\n\t\t\t\t\t//\n\t\t\t\t\tif (/%$/.test(x)) {\n\t\t\t\t\t\t//alpha\n\t\t\t\t\t\tif (i === size) return parseFloat(x) / 100\n\t\t\t\t\t\t//rgb\n\t\t\t\t\t\tif (base === 'rgb') return parseFloat(x) * 255 / 100\n\t\t\t\t\t\treturn parseFloat(x)\n\t\t\t\t\t}\n\t\t\t\t\t//hue\n\t\t\t\t\telse if (base[i] === 'h') {\n\t\t\t\t\t\t//\n\t\t\t\t\t\tif (/deg$/.test(x)) {\n\t\t\t\t\t\t\treturn parseFloat(x)\n\t\t\t\t\t\t}\n\t\t\t\t\t\t//\n\t\t\t\t\t\telse if (baseHues[x] !== undefined) {\n\t\t\t\t\t\t\treturn baseHues[x]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn parseFloat(x)\n\t\t\t\t})\n\n\t\t\tif (name === base) parts.push(1)\n\t\t\talpha = (isRGB) ? 1 : (parts[size] === undefined) ? 1 : parts[size]\n\t\t\tparts = parts.slice(0, size)\n\t\t}\n\n\t\t//named channels case\n\t\telse if (cstr.length > 10 && /[0-9](?:\\s|\\/)/.test(cstr)) {\n\t\t\tparts = cstr.match(/([0-9]+)/g).map(function (value) {\n\t\t\t\treturn parseFloat(value)\n\t\t\t})\n\n\t\t\tspace = cstr.match(/([a-z])/ig).join('').toLowerCase()\n\t\t}\n\t}\n\n\t//numeric case\n\telse if (!isNaN(cstr)) {\n\t\tspace = 'rgb'\n\t\tparts = [cstr >>> 16, (cstr & 0x00ff00) >>> 8, cstr & 0x0000ff]\n\t}\n\n\t//array-like\n\telse if (Array.isArray(cstr) || cstr.length) {\n\t\tparts = [cstr[0], cstr[1], cstr[2]]\n\t\tspace = 'rgb'\n\t\talpha = cstr.length === 4 ? cstr[3] : 1\n\t}\n\n\t//object case - detects css cases of rgb and hsl\n\telse if (cstr instanceof Object) {\n\t\tif (cstr.r != null || cstr.red != null || cstr.R != null) {\n\t\t\tspace = 'rgb'\n\t\t\tparts = [\n\t\t\t\tcstr.r || cstr.red || cstr.R || 0,\n\t\t\t\tcstr.g || cstr.green || cstr.G || 0,\n\t\t\t\tcstr.b || cstr.blue || cstr.B || 0\n\t\t\t]\n\t\t}\n\t\telse {\n\t\t\tspace = 'hsl'\n\t\t\tparts = [\n\t\t\t\tcstr.h || cstr.hue || cstr.H || 0,\n\t\t\t\tcstr.s || cstr.saturation || cstr.S || 0,\n\t\t\t\tcstr.l || cstr.lightness || cstr.L || cstr.b || cstr.brightness\n\t\t\t]\n\t\t}\n\n\t\talpha = cstr.a || cstr.alpha || cstr.opacity || 1\n\n\t\tif (cstr.opacity != null) alpha /= 100\n\t}\n\n\treturn {\n\t\tspace: space,\n\t\tvalues: parts,\n\t\talpha: alpha\n\t}\n}\n","/**\r\n * @module color-alpha\r\n */\r\nimport parse from 'color-parse';\r\n\r\nexport default function alpha (color, value) {\r\n\tvar obj = parse(color);\r\n\r\n\tif (value == null) value = obj.alpha;\r\n\r\n\t//catch percent\r\n\tif (obj.space[0] === 'h') {\r\n\t\treturn obj.space + ['a(', obj.values[0], ',', obj.values[1], '%,', obj.values[2], '%,', value, ')'].join('');\r\n\t}\r\n\r\n\treturn obj.space + ['a(', obj.values, ',', value, ')'].join('');\r\n}\r\n","import alpha from \"color-alpha\";\n\nimport { IStrokePart } from \"../types\";\n\nexport class HighlighterTool {\n readonly color: string;\n readonly width: number;\n\n constructor(\n color: string = \"yellow\",\n width: number = 8,\n opacity: Number = 0.3,\n ) {\n this.width = width;\n\n // calculate color w/ opacity\n this.color = alpha(color, 0.4);\n }\n\n /**\n * Draws a \"highlighter stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n public draw(ctx: CanvasRenderingContext2D, strokeParts: IStrokePart[]): void {\n const firstPart = strokeParts[0];\n\n ctx.beginPath();\n\n ctx.lineWidth = this.width;\n ctx.strokeStyle = this.color;\n ctx.lineCap = \"butt\";\n ctx.miterLimit = 1;\n\n ctx.moveTo(firstPart.startPoint.x, firstPart.startPoint.y);\n\n strokeParts.forEach((strokePart) => {\n const { endPoint } = strokePart;\n ctx.lineTo(endPoint.x, endPoint.y);\n });\n\n ctx.stroke();\n }\n}\n"],"names":["getEuclidean","p1","p2","getUnitVector","startPoint","endPoint","length","dirVect","StrokeManager","canvas","handler","clientX","clientY","rect","e","touch","touches","nextTouch","strokePart","Manager","canvasWidth","canvasHeight","bsr","dpr","width","height","pixelRatio","ctx","tool","PenTool","color","strokeParts","firstPart","EraserTool","handleOpts","halfWidth","isEnd","unitVect","currentPoint","i","nextPoint","lastPart","colorName","baseHues","parse","cstr","m","parts","alpha","space","names","base","size","isShort","name","isRGB","x","value","obj","HighlighterTool","opacity"],"mappings":"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","x_google_ignoreList":[5,6,7]} \ No newline at end of file +{"version":3,"file":"index.es.js","sources":["../src/util.ts","../src/StrokeManager.ts","../src/Manager.ts","../src/tools/PenTool.ts","../src/tools/EraserTool.ts","../node_modules/color-name/index.js","../node_modules/color-parse/index.mjs","../node_modules/color-alpha/index.mjs","../src/tools/HighlighterTool.ts"],"sourcesContent":["import { IPoint } from \"./types\";\n\n/**\n * Get the distance between two points\n * @param p1\n * @param p2\n * @returns number\n */\nexport function getEuclidean(p1: IPoint, p2: IPoint): number {\n return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));\n}\n\n/**\n * Gets the unit vector representing the vector from start\n * point to end point with a length of 1.\n * @param startPoint\n * @param endPoint\n * @returns IPoint\n */\nexport function getUnitVector(startPoint: IPoint, endPoint: IPoint): IPoint {\n const length = getEuclidean(startPoint, endPoint);\n\n const dirVect = {\n x: endPoint.x - startPoint.x,\n y: endPoint.y - startPoint.y,\n };\n\n const unitVect: IPoint = {\n x: dirVect.x / length,\n y: dirVect.y / length,\n };\n\n return unitVect;\n}\n","import { IPoint, IStrokePart } from \"./types\";\nimport { getEuclidean } from \"./util\";\n\nexport interface IOnStrokePartHandler {\n (strokePart: IStrokePart): void;\n}\n\nexport interface ITouch {\n id: number;\n position: IPoint;\n}\n\nexport class StrokeManager {\n // reference to canvas element\n private canvas: HTMLCanvasElement;\n // holds last touch point in a drag\n private lastTouch: ITouch | null;\n // holds last mouse point in drag\n private lastMouse: IPoint | null;\n // value indicates how sensitive the stroke detection is higher is better\n private sensitivity: number;\n // holds all of the last emitted stroke parts in a drag\n private lastStrokeParts: IStrokePart[];\n // the handlers listening for new strokes\n private onStrokePartHandlers: IOnStrokePartHandler[];\n\n constructor(canvas: HTMLCanvasElement) {\n this.canvas = canvas;\n this.lastTouch = null;\n this.lastMouse = null;\n this.sensitivity = 20.0;\n this.lastStrokeParts = [];\n this.onStrokePartHandlers = [];\n\n this.onTouchStart = this.onTouchStart.bind(this);\n this.onTouchEnd = this.onTouchEnd.bind(this);\n this.onTouchCancel = this.onTouchCancel.bind(this);\n this.onTouchMove = this.onTouchMove.bind(this);\n this.destroy = this.destroy.bind(this);\n this.getRelativePosition = this.getRelativePosition.bind(this);\n this.onMouseDown = this.onMouseDown.bind(this);\n this.onMouseUp = this.onMouseUp.bind(this);\n this.onMouseMove = this.onMouseMove.bind(this);\n\n this.canvas.addEventListener(\"touchstart\", this.onTouchStart, {\n passive: false,\n });\n this.canvas.addEventListener(\"touchend\", this.onTouchEnd, {\n passive: false,\n });\n this.canvas.addEventListener(\"touchcancel\", this.onTouchCancel, {\n passive: false,\n });\n this.canvas.addEventListener(\"touchmove\", this.onTouchMove, {\n passive: false,\n });\n this.canvas.addEventListener(\"mousedown\", this.onMouseDown, {\n passive: false,\n });\n document.addEventListener(\"mouseup\", this.onMouseUp, {\n passive: false,\n });\n this.canvas.addEventListener(\"mousemove\", this.onMouseMove, {\n passive: false,\n });\n }\n\n /**\n * Registers a handler to be fired on a new stroke part\n * @param handler\n */\n public onStrokePart(handler: IOnStrokePartHandler): void {\n this.onStrokePartHandlers.push(handler);\n }\n\n /**\n * Removes all active listeners\n */\n public destroy(): void {\n this.onStrokePartHandlers = [];\n this.lastStrokeParts = [];\n this.canvas.removeEventListener(\"touchstart\", this.onTouchStart);\n this.canvas.removeEventListener(\"touchend\", this.onTouchEnd);\n this.canvas.removeEventListener(\"touchcancel\", this.onTouchCancel);\n this.canvas.removeEventListener(\"touchmove\", this.onTouchMove);\n this.canvas.removeEventListener(\"mousedown\", this.onMouseDown);\n document.removeEventListener(\"mouseup\", this.onMouseUp);\n this.canvas.removeEventListener(\"mousemove\", this.onMouseMove);\n }\n\n /**\n * Get relative position to canvas\n * @param clientX\n * @param clientY\n * @returns IPoint\n */\n private getRelativePosition(clientX: number, clientY: number): IPoint {\n const rect = this.canvas.getBoundingClientRect();\n\n return {\n x: (clientX - rect.left) / rect.width,\n y: (clientY - rect.top) / rect.height,\n };\n }\n\n /**\n * Creates a new touch if one does not\n * already exist\n * @param e\n */\n private onTouchStart(e: TouchEvent): void {\n e.preventDefault();\n\n // if there is an ongoing touch, ignore this event\n if (this.lastTouch) {\n return;\n }\n\n const touches: TouchList = e.changedTouches;\n\n // only get the first touch\n const touch = touches.item(0);\n\n // save the touch\n this.lastTouch = {\n id: touch.identifier,\n position: this.getRelativePosition(touch.clientX, touch.clientY),\n };\n }\n\n /**\n * Creates a line from last touch to current touch\n * point and emits event. Does no-op if no existing touch\n * @param e\n */\n private onTouchMove(e: TouchEvent): void {\n e.preventDefault();\n\n // if no last touch... something is wrong\n if (!this.lastTouch) {\n return;\n }\n\n const touches: TouchList = e.changedTouches;\n\n // find the current touch we are tracking\n const touch: Touch = Array.from(touches).find((touch) => {\n return touch.identifier === this.lastTouch.id;\n });\n\n // if the touch was not one we were tracking,\n // ignore and no-op\n if (!touch) {\n return;\n }\n\n const nextTouch: ITouch = {\n id: touch.identifier,\n position: this.getRelativePosition(touch.clientX, touch.clientY),\n };\n\n // If sensitivity setting has been set,\n // check if this point is far enough from last\n // touch to be drawn\n if (\n this.sensitivity &&\n getEuclidean(nextTouch.position, this.lastTouch.position) <\n 10.0 / this.sensitivity\n ) {\n return;\n }\n\n const strokePart: IStrokePart = {\n endPoint: nextTouch.position,\n startPoint: this.lastTouch.position,\n isStart: this.lastStrokeParts.length === 0,\n isEnd: false,\n };\n\n this.onStrokePartHandlers.forEach((handler) => {\n handler(strokePart);\n });\n\n // save this touch as last touch\n this.lastTouch = nextTouch;\n this.lastStrokeParts.push(strokePart);\n }\n\n /**\n * Draws a line from last point to final point. Removes\n * the reference to last touch point.\n * @param e\n */\n private onTouchEnd(e: TouchEvent): void {\n e.preventDefault();\n\n // if no last touch... something is wrong\n if (!this.lastTouch) {\n return;\n }\n\n const touches: TouchList = e.changedTouches;\n\n // find the current touch we are tracking\n const touch: Touch = Array.from(touches).find((touch) => {\n return touch.identifier === this.lastTouch.id;\n });\n\n // if the touch was not one we were tracking,\n // ignore and no-op\n if (!touch) {\n return;\n }\n\n const endPoint = this.getRelativePosition(touch.clientX, touch.clientY);\n\n const strokePart: IStrokePart = {\n startPoint: this.lastTouch.position,\n endPoint,\n isStart: false,\n isEnd: true,\n };\n\n this.onStrokePartHandlers.forEach((handler) => {\n handler(strokePart);\n });\n\n this.lastTouch = null;\n this.lastStrokeParts = [];\n }\n\n /**\n * Removes the current last touch point\n * @param e\n */\n private onTouchCancel(e: TouchEvent): void {\n e.preventDefault();\n this.lastTouch = null;\n this.lastStrokeParts = [];\n }\n\n private onMouseDown(e: MouseEvent): void {\n // if there is an ongoing drag, ignore this event\n if (this.lastMouse) {\n return;\n }\n\n // save the drag\n this.lastMouse = this.getRelativePosition(e.clientX, e.clientY);\n }\n\n private onMouseUp(e: MouseEvent): void {\n // if no last mouse... something is wrong\n if (!this.lastMouse) {\n return;\n }\n\n let endPoint = this.getRelativePosition(e.clientX, e.clientY);\n\n const d = getEuclidean(this.lastMouse, endPoint);\n\n // if line is less than 1 pixel length, generate a fake line\n if (d < 1) {\n endPoint = {\n x: this.lastMouse.x + 0.0008,\n y: this.lastMouse.y + 0.0008,\n };\n }\n\n const strokePart: IStrokePart = {\n startPoint: this.lastMouse,\n endPoint: endPoint,\n isStart: false,\n isEnd: true,\n };\n\n this.onStrokePartHandlers.forEach((handler) => {\n handler(strokePart);\n });\n\n this.lastMouse = null;\n this.lastStrokeParts = [];\n }\n\n private onMouseMove(e: MouseEvent): void {\n // if no last drag... something is wrong\n if (!this.lastMouse) {\n return;\n }\n\n const nextMouse = this.getRelativePosition(e.clientX, e.clientY);\n\n // If sensitivity setting has been set,\n // check if this point is far enough from last\n // drag to be drawn\n if (\n this.sensitivity &&\n getEuclidean(nextMouse, this.lastMouse) < 0.05 / this.sensitivity\n ) {\n return;\n }\n\n const strokePart: IStrokePart = {\n endPoint: nextMouse,\n startPoint: this.lastMouse,\n isStart: this.lastStrokeParts.length === 0,\n isEnd: false,\n };\n\n this.onStrokePartHandlers.forEach((handler) => {\n handler(strokePart);\n });\n\n // save this drag as last drag\n this.lastMouse = nextMouse;\n this.lastStrokeParts.push(strokePart);\n }\n}\n","import { IStrokePart, ITool } from \"./types\";\nimport { StrokeManager } from \"./StrokeManager\";\n\nexport class Manager {\n // reference to the canvas\n private canvas: HTMLCanvasElement;\n // reference to canvas rendering context\n private ctx: CanvasRenderingContext2D | null;\n // reference to stroke manager\n private strokeManager: StrokeManager;\n // holds the pixel ratio between canvas backing\n // store and device ratio (used for hi fi displays)\n private pixelRatio: number;\n // the width of the canvas\n private canvasWidth: number;\n // the height of the canvas\n private canvasHeight: number;\n // holds a reference to next animation frame\n private nextAnimationFrame: number;\n // the currently selected tool\n private currentTool: ITool | null;\n // holds stroke parts for ongoing stroke\n private currentStroke: IStrokePart[];\n // the state of the canvas (not including ongoing stroke)\n private canvasState: ImageData | null;\n // indicates whether changes have occured that require redraw\n private shouldDraw: boolean;\n // indicates whether canvas should commit its next draw state to current state\n private shouldCommit: boolean;\n\n constructor(\n canvas: HTMLCanvasElement,\n canvasWidth: number,\n canvasHeight: number,\n ) {\n this.canvas = canvas;\n this.ctx = canvas.getContext(\"2d\", { willReadFrequently: true });\n this.canvasWidth = canvasWidth;\n this.canvasHeight = canvasHeight;\n this.currentTool = null;\n this.currentStroke = [];\n this.strokeManager = new StrokeManager(canvas);\n this.canvasState = null;\n this.shouldDraw = false;\n this.shouldCommit = false;\n\n // find pixel ratio relative to backing store and device ratio\n const bsr = (this.ctx as any).backingStorePixelRatio || 1;\n const dpr = window.devicePixelRatio || 1;\n this.pixelRatio = dpr / bsr;\n\n this.setCanvasSize = this.setCanvasSize.bind(this);\n this.setTool = this.setTool.bind(this);\n this.destroy = this.destroy.bind(this);\n this.clear = this.clear.bind(this);\n this.draw = this.draw.bind(this);\n this.onStrokePart = this.onStrokePart.bind(this);\n\n // schedule animation frame loop\n this.nextAnimationFrame = window.requestAnimationFrame(this.draw);\n // set up listener for new stroke part\n this.strokeManager.onStrokePart(this.onStrokePart);\n\n this.setCanvasSize(canvasWidth, canvasHeight);\n }\n\n /**\n * Sets the canvas desired width and height and sets transform\n * for hifi displays\n * @param width\n * @param height\n */\n public setCanvasSize(width: number, height: number): void {\n this.canvasWidth = width;\n this.canvasHeight = height;\n\n const { ctx, canvas, canvasWidth, canvasHeight, pixelRatio } = this;\n\n if (!ctx) return;\n\n // appropriately scale canvas to map to device ratio\n canvas.width = canvasWidth * pixelRatio;\n canvas.height = canvasHeight * pixelRatio;\n canvas.style.width = canvasWidth + \"px\";\n canvas.style.height = canvasHeight + \"px\";\n ctx.scale(pixelRatio, pixelRatio);\n }\n\n /**\n * Sets the current tool for the manager\n * @param tool\n */\n public setTool(tool: ITool): void {\n this.currentTool = tool;\n }\n\n /**\n * Remove all event listeners\n */\n public destroy(): void {\n // cancel animation loop\n window.cancelAnimationFrame(this.nextAnimationFrame);\n // remove all listeners on stroke manager\n this.strokeManager.destroy();\n }\n\n /**\n * Clears the canvas\n */\n public clear(): void {\n this.canvasState = null;\n this.currentStroke = [];\n this.shouldDraw = true;\n this.shouldCommit = true;\n }\n\n /**\n * Adds a new stroke part to the nextStrokes\n * array\n * @param strokePart\n */\n private onStrokePart(strokePart: IStrokePart): void {\n this.currentStroke.push(strokePart);\n\n this.shouldDraw = true;\n\n if (strokePart.isEnd) {\n this.shouldCommit = true;\n }\n }\n\n /**\n * Draws a frame\n */\n private draw(): void {\n // schedule next draw\n this.nextAnimationFrame = window.requestAnimationFrame(this.draw);\n\n const { ctx, canvasWidth, canvasHeight } = this;\n\n if (!this.shouldDraw || !ctx) {\n return;\n }\n\n // clear canvas\n ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);\n\n // draw current state\n if (this.canvasState) {\n ctx.putImageData(this.canvasState, 0, 0);\n }\n\n // if a tool has been selected and there are\n // pending strokes, draw them\n if (this.currentTool && this.currentStroke.length) {\n ctx.save();\n this.currentTool.draw(ctx, this.currentStroke, canvasWidth, canvasHeight);\n ctx.restore();\n }\n\n // if all changes have been made for current stroke,\n // save it as the new canvas state\n if (this.shouldCommit) {\n this.canvasState = ctx.getImageData(\n 0,\n 0,\n canvasWidth * this.pixelRatio,\n canvasHeight * this.pixelRatio,\n );\n this.currentStroke = [];\n this.shouldCommit = false;\n }\n\n this.shouldDraw = false;\n }\n}\n","import { IStrokePart } from \"../types\";\n\nexport class PenTool {\n readonly color: string;\n readonly width: number;\n\n constructor(color: string = \"red\", width: number = 3) {\n this.color = color;\n this.width = width;\n }\n\n /**\n * Draws a \"pen stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n public draw(\n ctx: CanvasRenderingContext2D,\n strokeParts: IStrokePart[],\n canvasWidth: number,\n canvasHeight: number,\n ): void {\n const firstPart = strokeParts[0];\n\n ctx.beginPath();\n\n ctx.lineWidth = this.width;\n ctx.strokeStyle = this.color;\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n\n ctx.moveTo(\n firstPart.startPoint.x * canvasWidth,\n firstPart.startPoint.y * canvasHeight,\n );\n\n strokeParts.forEach((strokePart) => {\n const { endPoint } = strokePart;\n ctx.lineTo(endPoint.x * canvasWidth, endPoint.y * canvasHeight);\n });\n\n ctx.stroke();\n }\n}\n","import { IStrokePart, IPoint } from \"../types\";\nimport { getUnitVector, getEuclidean } from \"../util\";\n\nexport interface IHandleOptions {\n hide: boolean;\n strokeWidth: number;\n fillColor: string;\n strokeColor: string;\n}\n\nexport class EraserTool {\n readonly width: number;\n readonly handleOpts: IHandleOptions;\n\n constructor(width: number = 10, handleOpts?: Partial) {\n this.width = width;\n\n handleOpts = handleOpts || {};\n\n this.handleOpts = {\n hide: handleOpts.hide || false,\n strokeWidth: handleOpts.strokeWidth || 2,\n fillColor: handleOpts.fillColor || \"white\",\n strokeColor: handleOpts.strokeColor || \"black\",\n };\n }\n\n /**\n * Draws an \"eraser stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n public draw(\n ctx: CanvasRenderingContext2D,\n strokeParts: IStrokePart[],\n canvasWidth: number,\n canvasHeight: number,\n ): void {\n const { handleOpts } = this;\n const halfWidth = this.width / 2.0;\n\n strokeParts.forEach((strokePart) => {\n const { startPoint, endPoint } = strokePart;\n\n const length = getEuclidean(startPoint, endPoint);\n const unitVect: IPoint = getUnitVector(startPoint, endPoint);\n let currentPoint: IPoint = startPoint;\n let i = 0;\n\n // clear all the way along the drag\n while (i < length) {\n const nextPoint: IPoint = {\n x: currentPoint.x * canvasWidth + unitVect.x,\n y: currentPoint.y * canvasHeight + unitVect.y,\n };\n\n ctx.clearRect(\n nextPoint.x - halfWidth,\n nextPoint.y - halfWidth,\n this.width,\n this.width,\n );\n\n i++;\n currentPoint = nextPoint;\n }\n });\n\n const lastPart = strokeParts[strokeParts.length - 1];\n\n // if the end is not the last part, then draw\n // the tool indicator at the endpoint\n if (!lastPart.isEnd && !handleOpts.hide) {\n ctx.strokeStyle = handleOpts.strokeColor;\n ctx.fillStyle = handleOpts.fillColor;\n\n const lastEndPoint = {\n x: lastPart.endPoint.x * canvasWidth,\n y: lastPart.endPoint.y * canvasHeight,\n };\n\n ctx.fillRect(\n lastEndPoint.x - halfWidth,\n lastEndPoint.y - halfWidth,\n this.width,\n this.width,\n );\n\n ctx.strokeRect(\n lastEndPoint.x - halfWidth + 0.5,\n lastEndPoint.y - halfWidth + 0.5,\n this.width - 1,\n this.width - 1,\n );\n }\n }\n}\n","'use strict'\r\n\r\nmodule.exports = {\r\n\t\"aliceblue\": [240, 248, 255],\r\n\t\"antiquewhite\": [250, 235, 215],\r\n\t\"aqua\": [0, 255, 255],\r\n\t\"aquamarine\": [127, 255, 212],\r\n\t\"azure\": [240, 255, 255],\r\n\t\"beige\": [245, 245, 220],\r\n\t\"bisque\": [255, 228, 196],\r\n\t\"black\": [0, 0, 0],\r\n\t\"blanchedalmond\": [255, 235, 205],\r\n\t\"blue\": [0, 0, 255],\r\n\t\"blueviolet\": [138, 43, 226],\r\n\t\"brown\": [165, 42, 42],\r\n\t\"burlywood\": [222, 184, 135],\r\n\t\"cadetblue\": [95, 158, 160],\r\n\t\"chartreuse\": [127, 255, 0],\r\n\t\"chocolate\": [210, 105, 30],\r\n\t\"coral\": [255, 127, 80],\r\n\t\"cornflowerblue\": [100, 149, 237],\r\n\t\"cornsilk\": [255, 248, 220],\r\n\t\"crimson\": [220, 20, 60],\r\n\t\"cyan\": [0, 255, 255],\r\n\t\"darkblue\": [0, 0, 139],\r\n\t\"darkcyan\": [0, 139, 139],\r\n\t\"darkgoldenrod\": [184, 134, 11],\r\n\t\"darkgray\": [169, 169, 169],\r\n\t\"darkgreen\": [0, 100, 0],\r\n\t\"darkgrey\": [169, 169, 169],\r\n\t\"darkkhaki\": [189, 183, 107],\r\n\t\"darkmagenta\": [139, 0, 139],\r\n\t\"darkolivegreen\": [85, 107, 47],\r\n\t\"darkorange\": [255, 140, 0],\r\n\t\"darkorchid\": [153, 50, 204],\r\n\t\"darkred\": [139, 0, 0],\r\n\t\"darksalmon\": [233, 150, 122],\r\n\t\"darkseagreen\": [143, 188, 143],\r\n\t\"darkslateblue\": [72, 61, 139],\r\n\t\"darkslategray\": [47, 79, 79],\r\n\t\"darkslategrey\": [47, 79, 79],\r\n\t\"darkturquoise\": [0, 206, 209],\r\n\t\"darkviolet\": [148, 0, 211],\r\n\t\"deeppink\": [255, 20, 147],\r\n\t\"deepskyblue\": [0, 191, 255],\r\n\t\"dimgray\": [105, 105, 105],\r\n\t\"dimgrey\": [105, 105, 105],\r\n\t\"dodgerblue\": [30, 144, 255],\r\n\t\"firebrick\": [178, 34, 34],\r\n\t\"floralwhite\": [255, 250, 240],\r\n\t\"forestgreen\": [34, 139, 34],\r\n\t\"fuchsia\": [255, 0, 255],\r\n\t\"gainsboro\": [220, 220, 220],\r\n\t\"ghostwhite\": [248, 248, 255],\r\n\t\"gold\": [255, 215, 0],\r\n\t\"goldenrod\": [218, 165, 32],\r\n\t\"gray\": [128, 128, 128],\r\n\t\"green\": [0, 128, 0],\r\n\t\"greenyellow\": [173, 255, 47],\r\n\t\"grey\": [128, 128, 128],\r\n\t\"honeydew\": [240, 255, 240],\r\n\t\"hotpink\": [255, 105, 180],\r\n\t\"indianred\": [205, 92, 92],\r\n\t\"indigo\": [75, 0, 130],\r\n\t\"ivory\": [255, 255, 240],\r\n\t\"khaki\": [240, 230, 140],\r\n\t\"lavender\": [230, 230, 250],\r\n\t\"lavenderblush\": [255, 240, 245],\r\n\t\"lawngreen\": [124, 252, 0],\r\n\t\"lemonchiffon\": [255, 250, 205],\r\n\t\"lightblue\": [173, 216, 230],\r\n\t\"lightcoral\": [240, 128, 128],\r\n\t\"lightcyan\": [224, 255, 255],\r\n\t\"lightgoldenrodyellow\": [250, 250, 210],\r\n\t\"lightgray\": [211, 211, 211],\r\n\t\"lightgreen\": [144, 238, 144],\r\n\t\"lightgrey\": [211, 211, 211],\r\n\t\"lightpink\": [255, 182, 193],\r\n\t\"lightsalmon\": [255, 160, 122],\r\n\t\"lightseagreen\": [32, 178, 170],\r\n\t\"lightskyblue\": [135, 206, 250],\r\n\t\"lightslategray\": [119, 136, 153],\r\n\t\"lightslategrey\": [119, 136, 153],\r\n\t\"lightsteelblue\": [176, 196, 222],\r\n\t\"lightyellow\": [255, 255, 224],\r\n\t\"lime\": [0, 255, 0],\r\n\t\"limegreen\": [50, 205, 50],\r\n\t\"linen\": [250, 240, 230],\r\n\t\"magenta\": [255, 0, 255],\r\n\t\"maroon\": [128, 0, 0],\r\n\t\"mediumaquamarine\": [102, 205, 170],\r\n\t\"mediumblue\": [0, 0, 205],\r\n\t\"mediumorchid\": [186, 85, 211],\r\n\t\"mediumpurple\": [147, 112, 219],\r\n\t\"mediumseagreen\": [60, 179, 113],\r\n\t\"mediumslateblue\": [123, 104, 238],\r\n\t\"mediumspringgreen\": [0, 250, 154],\r\n\t\"mediumturquoise\": [72, 209, 204],\r\n\t\"mediumvioletred\": [199, 21, 133],\r\n\t\"midnightblue\": [25, 25, 112],\r\n\t\"mintcream\": [245, 255, 250],\r\n\t\"mistyrose\": [255, 228, 225],\r\n\t\"moccasin\": [255, 228, 181],\r\n\t\"navajowhite\": [255, 222, 173],\r\n\t\"navy\": [0, 0, 128],\r\n\t\"oldlace\": [253, 245, 230],\r\n\t\"olive\": [128, 128, 0],\r\n\t\"olivedrab\": [107, 142, 35],\r\n\t\"orange\": [255, 165, 0],\r\n\t\"orangered\": [255, 69, 0],\r\n\t\"orchid\": [218, 112, 214],\r\n\t\"palegoldenrod\": [238, 232, 170],\r\n\t\"palegreen\": [152, 251, 152],\r\n\t\"paleturquoise\": [175, 238, 238],\r\n\t\"palevioletred\": [219, 112, 147],\r\n\t\"papayawhip\": [255, 239, 213],\r\n\t\"peachpuff\": [255, 218, 185],\r\n\t\"peru\": [205, 133, 63],\r\n\t\"pink\": [255, 192, 203],\r\n\t\"plum\": [221, 160, 221],\r\n\t\"powderblue\": [176, 224, 230],\r\n\t\"purple\": [128, 0, 128],\r\n\t\"rebeccapurple\": [102, 51, 153],\r\n\t\"red\": [255, 0, 0],\r\n\t\"rosybrown\": [188, 143, 143],\r\n\t\"royalblue\": [65, 105, 225],\r\n\t\"saddlebrown\": [139, 69, 19],\r\n\t\"salmon\": [250, 128, 114],\r\n\t\"sandybrown\": [244, 164, 96],\r\n\t\"seagreen\": [46, 139, 87],\r\n\t\"seashell\": [255, 245, 238],\r\n\t\"sienna\": [160, 82, 45],\r\n\t\"silver\": [192, 192, 192],\r\n\t\"skyblue\": [135, 206, 235],\r\n\t\"slateblue\": [106, 90, 205],\r\n\t\"slategray\": [112, 128, 144],\r\n\t\"slategrey\": [112, 128, 144],\r\n\t\"snow\": [255, 250, 250],\r\n\t\"springgreen\": [0, 255, 127],\r\n\t\"steelblue\": [70, 130, 180],\r\n\t\"tan\": [210, 180, 140],\r\n\t\"teal\": [0, 128, 128],\r\n\t\"thistle\": [216, 191, 216],\r\n\t\"tomato\": [255, 99, 71],\r\n\t\"turquoise\": [64, 224, 208],\r\n\t\"violet\": [238, 130, 238],\r\n\t\"wheat\": [245, 222, 179],\r\n\t\"white\": [255, 255, 255],\r\n\t\"whitesmoke\": [245, 245, 245],\r\n\t\"yellow\": [255, 255, 0],\r\n\t\"yellowgreen\": [154, 205, 50]\r\n};\r\n","/**\n * @module color-parse\n */\nimport names from 'color-name'\n\nexport default parse\n\n/**\n * Base hues\n * http://dev.w3.org/csswg/css-color/#typedef-named-hue\n */\n//FIXME: use external hue detector\nvar baseHues = {\n\tred: 0,\n\torange: 60,\n\tyellow: 120,\n\tgreen: 180,\n\tblue: 240,\n\tpurple: 300\n}\n\n/**\n * Parse color from the string passed\n *\n * @return {Object} A space indicator `space`, an array `values` and `alpha`\n */\nfunction parse(cstr) {\n\tvar m, parts = [], alpha = 1, space\n\n\tif (typeof cstr === 'string') {\n\t\tcstr = cstr.toLowerCase();\n\n\t\t//keyword\n\t\tif (names[cstr]) {\n\t\t\tparts = names[cstr].slice()\n\t\t\tspace = 'rgb'\n\t\t}\n\n\t\t//reserved words\n\t\telse if (cstr === 'transparent') {\n\t\t\talpha = 0\n\t\t\tspace = 'rgb'\n\t\t\tparts = [0, 0, 0]\n\t\t}\n\n\t\t//hex\n\t\telse if (/^#[A-Fa-f0-9]+$/.test(cstr)) {\n\t\t\tvar base = cstr.slice(1)\n\t\t\tvar size = base.length\n\t\t\tvar isShort = size <= 4\n\t\t\talpha = 1\n\n\t\t\tif (isShort) {\n\t\t\t\tparts = [\n\t\t\t\t\tparseInt(base[0] + base[0], 16),\n\t\t\t\t\tparseInt(base[1] + base[1], 16),\n\t\t\t\t\tparseInt(base[2] + base[2], 16)\n\t\t\t\t]\n\t\t\t\tif (size === 4) {\n\t\t\t\t\talpha = parseInt(base[3] + base[3], 16) / 255\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tparts = [\n\t\t\t\t\tparseInt(base[0] + base[1], 16),\n\t\t\t\t\tparseInt(base[2] + base[3], 16),\n\t\t\t\t\tparseInt(base[4] + base[5], 16)\n\t\t\t\t]\n\t\t\t\tif (size === 8) {\n\t\t\t\t\talpha = parseInt(base[6] + base[7], 16) / 255\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!parts[0]) parts[0] = 0\n\t\t\tif (!parts[1]) parts[1] = 0\n\t\t\tif (!parts[2]) parts[2] = 0\n\n\t\t\tspace = 'rgb'\n\t\t}\n\n\t\t//color space\n\t\telse if (m = /^((?:rgb|hs[lvb]|hwb|cmyk?|xy[zy]|gray|lab|lchu?v?|[ly]uv|lms)a?)\\s*\\(([^\\)]*)\\)/.exec(cstr)) {\n\t\t\tvar name = m[1]\n\t\t\tvar isRGB = name === 'rgb'\n\t\t\tvar base = name.replace(/a$/, '')\n\t\t\tspace = base\n\t\t\tvar size = base === 'cmyk' ? 4 : base === 'gray' ? 1 : 3\n\t\t\tparts = m[2].trim()\n\t\t\t\t.split(/\\s*[,\\/]\\s*|\\s+/)\n\t\t\t\t.map(function (x, i) {\n\t\t\t\t\t//\n\t\t\t\t\tif (/%$/.test(x)) {\n\t\t\t\t\t\t//alpha\n\t\t\t\t\t\tif (i === size) return parseFloat(x) / 100\n\t\t\t\t\t\t//rgb\n\t\t\t\t\t\tif (base === 'rgb') return parseFloat(x) * 255 / 100\n\t\t\t\t\t\treturn parseFloat(x)\n\t\t\t\t\t}\n\t\t\t\t\t//hue\n\t\t\t\t\telse if (base[i] === 'h') {\n\t\t\t\t\t\t//\n\t\t\t\t\t\tif (/deg$/.test(x)) {\n\t\t\t\t\t\t\treturn parseFloat(x)\n\t\t\t\t\t\t}\n\t\t\t\t\t\t//\n\t\t\t\t\t\telse if (baseHues[x] !== undefined) {\n\t\t\t\t\t\t\treturn baseHues[x]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn parseFloat(x)\n\t\t\t\t})\n\n\t\t\tif (name === base) parts.push(1)\n\t\t\talpha = (isRGB) ? 1 : (parts[size] === undefined) ? 1 : parts[size]\n\t\t\tparts = parts.slice(0, size)\n\t\t}\n\n\t\t//named channels case\n\t\telse if (cstr.length > 10 && /[0-9](?:\\s|\\/)/.test(cstr)) {\n\t\t\tparts = cstr.match(/([0-9]+)/g).map(function (value) {\n\t\t\t\treturn parseFloat(value)\n\t\t\t})\n\n\t\t\tspace = cstr.match(/([a-z])/ig).join('').toLowerCase()\n\t\t}\n\t}\n\n\t//numeric case\n\telse if (!isNaN(cstr)) {\n\t\tspace = 'rgb'\n\t\tparts = [cstr >>> 16, (cstr & 0x00ff00) >>> 8, cstr & 0x0000ff]\n\t}\n\n\t//array-like\n\telse if (Array.isArray(cstr) || cstr.length) {\n\t\tparts = [cstr[0], cstr[1], cstr[2]]\n\t\tspace = 'rgb'\n\t\talpha = cstr.length === 4 ? cstr[3] : 1\n\t}\n\n\t//object case - detects css cases of rgb and hsl\n\telse if (cstr instanceof Object) {\n\t\tif (cstr.r != null || cstr.red != null || cstr.R != null) {\n\t\t\tspace = 'rgb'\n\t\t\tparts = [\n\t\t\t\tcstr.r || cstr.red || cstr.R || 0,\n\t\t\t\tcstr.g || cstr.green || cstr.G || 0,\n\t\t\t\tcstr.b || cstr.blue || cstr.B || 0\n\t\t\t]\n\t\t}\n\t\telse {\n\t\t\tspace = 'hsl'\n\t\t\tparts = [\n\t\t\t\tcstr.h || cstr.hue || cstr.H || 0,\n\t\t\t\tcstr.s || cstr.saturation || cstr.S || 0,\n\t\t\t\tcstr.l || cstr.lightness || cstr.L || cstr.b || cstr.brightness\n\t\t\t]\n\t\t}\n\n\t\talpha = cstr.a || cstr.alpha || cstr.opacity || 1\n\n\t\tif (cstr.opacity != null) alpha /= 100\n\t}\n\n\treturn {\n\t\tspace: space,\n\t\tvalues: parts,\n\t\talpha: alpha\n\t}\n}\n","/**\r\n * @module color-alpha\r\n */\r\nimport parse from 'color-parse';\r\n\r\nexport default function alpha (color, value) {\r\n\tvar obj = parse(color);\r\n\r\n\tif (value == null) value = obj.alpha;\r\n\r\n\t//catch percent\r\n\tif (obj.space[0] === 'h') {\r\n\t\treturn obj.space + ['a(', obj.values[0], ',', obj.values[1], '%,', obj.values[2], '%,', value, ')'].join('');\r\n\t}\r\n\r\n\treturn obj.space + ['a(', obj.values, ',', value, ')'].join('');\r\n}\r\n","import alpha from \"color-alpha\";\n\nimport { IStrokePart } from \"../types\";\n\nexport class HighlighterTool {\n readonly color: string;\n readonly width: number;\n\n constructor(\n color: string = \"yellow\",\n width: number = 8,\n opacity: Number = 0.3,\n ) {\n this.width = width;\n\n // calculate color w/ opacity\n this.color = alpha(color, 0.4);\n }\n\n /**\n * Draws a \"highlighter stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n public draw(\n ctx: CanvasRenderingContext2D,\n strokeParts: IStrokePart[],\n canvasWidth: number,\n canvasHeight: number,\n ): void {\n const firstPart = strokeParts[0];\n\n ctx.beginPath();\n\n ctx.lineWidth = this.width;\n ctx.strokeStyle = this.color;\n ctx.lineCap = \"butt\";\n ctx.miterLimit = 1;\n\n ctx.moveTo(\n firstPart.startPoint.x * canvasWidth,\n firstPart.startPoint.y * canvasHeight,\n );\n\n strokeParts.forEach((strokePart) => {\n const { endPoint } = strokePart;\n ctx.lineTo(endPoint.x * canvasWidth, endPoint.y * canvasHeight);\n });\n\n ctx.stroke();\n }\n}\n"],"names":["getEuclidean","p1","p2","getUnitVector","startPoint","endPoint","length","dirVect","StrokeManager","canvas","handler","clientX","clientY","rect","e","touch","touches","nextTouch","strokePart","nextMouse","Manager","canvasWidth","canvasHeight","bsr","dpr","width","height","ctx","pixelRatio","tool","PenTool","color","strokeParts","firstPart","EraserTool","handleOpts","halfWidth","unitVect","currentPoint","i","nextPoint","lastPart","lastEndPoint","colorName","baseHues","parse","cstr","m","parts","alpha","space","names","base","size","isShort","name","isRGB","x","value","obj","HighlighterTool","opacity"],"mappings":"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","x_google_ignoreList":[5,6,7]} \ No newline at end of file diff --git a/dist/index.umd.js b/dist/index.umd.js index 51cbc58..e9601d4 100644 --- a/dist/index.umd.js +++ b/dist/index.umd.js @@ -1,2 +1,2 @@ -(function(h,l){typeof exports=="object"&&typeof module<"u"?l(exports):typeof define=="function"&&define.amd?define(["exports"],l):(h=typeof globalThis<"u"?globalThis:h||self,l(h.Paintbricks={}))})(this,function(h){"use strict";function l(e,t){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}function k(e,t){const i=l(e,t),o={x:t.x-e.x,y:t.y-e.y};return{x:o.x/i,y:o.y/i}}class w{constructor(t){this.canvas=t,this.lastTouch=null,this.sensitivity=20,this.lastStrokeParts=[],this.onStrokePartHandlers=[],this.onTouchStart=this.onTouchStart.bind(this),this.onTouchEnd=this.onTouchEnd.bind(this),this.onTouchCancel=this.onTouchCancel.bind(this),this.onTouchMove=this.onTouchMove.bind(this),this.destroy=this.destroy.bind(this),this.getRelativePosition=this.getRelativePosition.bind(this),this.canvas.addEventListener("touchstart",this.onTouchStart,{passive:!1}),this.canvas.addEventListener("touchend",this.onTouchEnd,{passive:!1}),this.canvas.addEventListener("touchcancel",this.onTouchCancel,{passive:!1}),this.canvas.addEventListener("touchmove",this.onTouchMove,{passive:!1})}onStrokePart(t){this.onStrokePartHandlers.push(t)}destroy(){this.onStrokePartHandlers=[],this.lastStrokeParts=[],this.canvas.removeEventListener("touchstart",this.onTouchStart),this.canvas.removeEventListener("touchend",this.onTouchEnd),this.canvas.removeEventListener("touchcancel",this.onTouchCancel),this.canvas.removeEventListener("touchmove",this.onTouchMove)}getRelativePosition(t,i){const o=this.canvas.getBoundingClientRect();return{x:t-o.left,y:i-o.top}}onTouchStart(t){if(t.preventDefault(),this.lastTouch)return;const o=t.changedTouches.item(0);this.lastTouch={id:o.identifier,position:this.getRelativePosition(o.clientX,o.clientY)}}onTouchMove(t){if(t.preventDefault(),!this.lastTouch)return;const i=t.changedTouches,o=Array.from(i).find(a=>a.identifier===this.lastTouch.id);if(!o)return;const s={id:o.identifier,position:this.getRelativePosition(o.clientX,o.clientY)};if(this.sensitivity&&l(s.position,this.lastTouch.position)<10/this.sensitivity)return;const n={endPoint:s.position,startPoint:this.lastTouch.position,isStart:this.lastStrokeParts.length===0,isEnd:!1};this.onStrokePartHandlers.forEach(a=>{a(n)}),this.lastTouch=s,this.lastStrokeParts.push(n)}onTouchEnd(t){if(t.preventDefault(),!this.lastTouch)return;const i=t.changedTouches,o=Array.from(i).find(a=>a.identifier===this.lastTouch.id);if(!o)return;const s=this.getRelativePosition(o.clientX,o.clientY),n={startPoint:this.lastTouch.position,endPoint:s,isStart:!1,isEnd:!0};this.onStrokePartHandlers.forEach(a=>{a(n)}),this.lastTouch=null,this.lastStrokeParts=[]}onTouchCancel(t){t.preventDefault(),this.lastTouch=null,this.lastStrokeParts=[]}}class b{constructor(t,i,o){this.canvas=t,this.canvasWidth=i,this.canvasHeight=o,this.currentTool=null,this.currentStroke=[],this.strokeManager=new w(t),this.canvasState=null,this.shouldDraw=!1,this.shouldCommit=!1;const s=t.getContext("2d").backingStorePixelRatio||1,n=window.devicePixelRatio||1;this.pixelRatio=n/s,this.setCanvasSize=this.setCanvasSize.bind(this),this.setTool=this.setTool.bind(this),this.destroy=this.destroy.bind(this),this.clear=this.clear.bind(this),this.draw=this.draw.bind(this),this.onStrokePart=this.onStrokePart.bind(this),this.nextAnimationFrame=window.requestAnimationFrame(this.draw),this.strokeManager.onStrokePart(this.onStrokePart),this.setCanvasSize(i,o)}setCanvasSize(t,i){this.canvasWidth=t,this.canvasHeight=i;const{canvas:o,canvasWidth:s,canvasHeight:n,pixelRatio:a}=this,u=o.getContext("2d");o.width=s*a,o.height=n*a,o.style.width=s+"px",o.style.height=n+"px",u.setTransform(a,0,0,a,0,0)}setTool(t){this.currentTool=t}destroy(){window.cancelAnimationFrame(this.nextAnimationFrame),this.strokeManager.destroy()}clear(){this.canvasState=null,this.currentStroke=[],this.shouldDraw=!0,this.shouldCommit=!0}onStrokePart(t){this.currentStroke.push(t),this.shouldDraw=!0,t.isEnd&&(this.shouldCommit=!0)}draw(){this.nextAnimationFrame=window.requestAnimationFrame(this.draw);const t=this.canvas.getContext("2d");this.shouldDraw&&(t.clearRect(0,0,this.canvasWidth,this.canvasHeight),this.canvasState&&t.putImageData(this.canvasState,0,0),this.currentTool&&this.currentStroke.length&&(t.save(),this.currentTool.draw(t,this.currentStroke),t.restore()),this.shouldCommit&&(this.canvasState=t.getImageData(0,0,this.canvasWidth*this.pixelRatio,this.canvasHeight*this.pixelRatio),this.currentStroke=[],this.shouldCommit=!1),this.shouldDraw=!1)}}class T{constructor(t="red",i=3){this.color=t,this.width=i}draw(t,i){const o=i[0];t.beginPath(),t.lineWidth=this.width,t.strokeStyle=this.color,t.lineCap="round",t.lineJoin="round",t.moveTo(o.startPoint.x,o.startPoint.y),i.forEach(s=>{const{endPoint:n}=s;t.lineTo(n.x,n.y)}),t.stroke()}}class S{constructor(t=10,i){this.width=t,i=i||{},this.handleOpts={hide:i.hide||!1,strokeWidth:i.strokeWidth||2,fillColor:i.fillColor||"white",strokeColor:i.strokeColor||"black"}}draw(t,i){const{handleOpts:o}=this,s=this.width/2;i.forEach(a=>{const{startPoint:u,endPoint:d,isEnd:m}=a,g=l(u,d),y=k(u,d);let r=u,c=0;for(;c10&&/[0-9](?:\s|\/)/.test(e)&&(i=e.match(/([0-9]+)/g).map(function(g){return parseFloat(g)}),s=e.match(/([a-z])/ig).join("").toLowerCase());else isNaN(e)?Array.isArray(e)||e.length?(i=[e[0],e[1],e[2]],s="rgb",o=e.length===4?e[3]:1):e instanceof Object&&(e.r!=null||e.red!=null||e.R!=null?(s="rgb",i=[e.r||e.red||e.R||0,e.g||e.green||e.G||0,e.b||e.blue||e.B||0]):(s="hsl",i=[e.h||e.hue||e.H||0,e.s||e.saturation||e.S||0,e.l||e.lightness||e.L||e.b||e.brightness]),o=e.a||e.alpha||e.opacity||1,e.opacity!=null&&(o/=100)):(s="rgb",i=[e>>>16,(e&65280)>>>8,e&255]);return{space:s,values:i,alpha:o}}function R(e,t){var i=E(e);return t==null&&(t=i.alpha),i.space[0]==="h"?i.space+["a(",i.values[0],",",i.values[1],"%,",i.values[2],"%,",t,")"].join(""):i.space+["a(",i.values,",",t,")"].join("")}class M{constructor(t="yellow",i=8,o=.3){this.width=i,this.color=R(t,.4)}draw(t,i){const o=i[0];t.beginPath(),t.lineWidth=this.width,t.strokeStyle=this.color,t.lineCap="butt",t.miterLimit=1,t.moveTo(o.startPoint.x,o.startPoint.y),i.forEach(s=>{const{endPoint:n}=s;t.lineTo(n.x,n.y)}),t.stroke()}}h.EraserTool=S,h.HighlighterTool=M,h.Manager=b,h.PenTool=T,Object.defineProperty(h,Symbol.toStringTag,{value:"Module"})}); +(function(u,d){typeof exports=="object"&&typeof module<"u"?d(exports):typeof define=="function"&&define.amd?define(["exports"],d):(u=typeof globalThis<"u"?globalThis:u||self,d(u.Paintbricks={}))})(this,function(u){"use strict";function d(i,t){return Math.sqrt(Math.pow(i.x-t.x,2)+Math.pow(i.y-t.y,2))}function k(i,t){const e=d(i,t),s={x:t.x-i.x,y:t.y-i.y};return{x:s.x/e,y:s.y/e}}class w{constructor(t){this.canvas=t,this.lastTouch=null,this.lastMouse=null,this.sensitivity=20,this.lastStrokeParts=[],this.onStrokePartHandlers=[],this.onTouchStart=this.onTouchStart.bind(this),this.onTouchEnd=this.onTouchEnd.bind(this),this.onTouchCancel=this.onTouchCancel.bind(this),this.onTouchMove=this.onTouchMove.bind(this),this.destroy=this.destroy.bind(this),this.getRelativePosition=this.getRelativePosition.bind(this),this.onMouseDown=this.onMouseDown.bind(this),this.onMouseUp=this.onMouseUp.bind(this),this.onMouseMove=this.onMouseMove.bind(this),this.canvas.addEventListener("touchstart",this.onTouchStart,{passive:!1}),this.canvas.addEventListener("touchend",this.onTouchEnd,{passive:!1}),this.canvas.addEventListener("touchcancel",this.onTouchCancel,{passive:!1}),this.canvas.addEventListener("touchmove",this.onTouchMove,{passive:!1}),this.canvas.addEventListener("mousedown",this.onMouseDown,{passive:!1}),document.addEventListener("mouseup",this.onMouseUp,{passive:!1}),this.canvas.addEventListener("mousemove",this.onMouseMove,{passive:!1})}onStrokePart(t){this.onStrokePartHandlers.push(t)}destroy(){this.onStrokePartHandlers=[],this.lastStrokeParts=[],this.canvas.removeEventListener("touchstart",this.onTouchStart),this.canvas.removeEventListener("touchend",this.onTouchEnd),this.canvas.removeEventListener("touchcancel",this.onTouchCancel),this.canvas.removeEventListener("touchmove",this.onTouchMove),this.canvas.removeEventListener("mousedown",this.onMouseDown),document.removeEventListener("mouseup",this.onMouseUp),this.canvas.removeEventListener("mousemove",this.onMouseMove)}getRelativePosition(t,e){const s=this.canvas.getBoundingClientRect();return{x:(t-s.left)/s.width,y:(e-s.top)/s.height}}onTouchStart(t){if(t.preventDefault(),this.lastTouch)return;const s=t.changedTouches.item(0);this.lastTouch={id:s.identifier,position:this.getRelativePosition(s.clientX,s.clientY)}}onTouchMove(t){if(t.preventDefault(),!this.lastTouch)return;const e=t.changedTouches,s=Array.from(e).find(a=>a.identifier===this.lastTouch.id);if(!s)return;const n={id:s.identifier,position:this.getRelativePosition(s.clientX,s.clientY)};if(this.sensitivity&&d(n.position,this.lastTouch.position)<10/this.sensitivity)return;const o={endPoint:n.position,startPoint:this.lastTouch.position,isStart:this.lastStrokeParts.length===0,isEnd:!1};this.onStrokePartHandlers.forEach(a=>{a(o)}),this.lastTouch=n,this.lastStrokeParts.push(o)}onTouchEnd(t){if(t.preventDefault(),!this.lastTouch)return;const e=t.changedTouches,s=Array.from(e).find(a=>a.identifier===this.lastTouch.id);if(!s)return;const n=this.getRelativePosition(s.clientX,s.clientY),o={startPoint:this.lastTouch.position,endPoint:n,isStart:!1,isEnd:!0};this.onStrokePartHandlers.forEach(a=>{a(o)}),this.lastTouch=null,this.lastStrokeParts=[]}onTouchCancel(t){t.preventDefault(),this.lastTouch=null,this.lastStrokeParts=[]}onMouseDown(t){this.lastMouse||(this.lastMouse=this.getRelativePosition(t.clientX,t.clientY))}onMouseUp(t){if(!this.lastMouse)return;let e=this.getRelativePosition(t.clientX,t.clientY);d(this.lastMouse,e)<1&&(e={x:this.lastMouse.x+8e-4,y:this.lastMouse.y+8e-4});const n={startPoint:this.lastMouse,endPoint:e,isStart:!1,isEnd:!0};this.onStrokePartHandlers.forEach(o=>{o(n)}),this.lastMouse=null,this.lastStrokeParts=[]}onMouseMove(t){if(!this.lastMouse)return;const e=this.getRelativePosition(t.clientX,t.clientY);if(this.sensitivity&&d(e,this.lastMouse)<.05/this.sensitivity)return;const s={endPoint:e,startPoint:this.lastMouse,isStart:this.lastStrokeParts.length===0,isEnd:!1};this.onStrokePartHandlers.forEach(n=>{n(s)}),this.lastMouse=e,this.lastStrokeParts.push(s)}}class b{constructor(t,e,s){this.canvas=t,this.ctx=t.getContext("2d",{willReadFrequently:!0}),this.canvasWidth=e,this.canvasHeight=s,this.currentTool=null,this.currentStroke=[],this.strokeManager=new w(t),this.canvasState=null,this.shouldDraw=!1,this.shouldCommit=!1;const n=this.ctx.backingStorePixelRatio||1,o=window.devicePixelRatio||1;this.pixelRatio=o/n,this.setCanvasSize=this.setCanvasSize.bind(this),this.setTool=this.setTool.bind(this),this.destroy=this.destroy.bind(this),this.clear=this.clear.bind(this),this.draw=this.draw.bind(this),this.onStrokePart=this.onStrokePart.bind(this),this.nextAnimationFrame=window.requestAnimationFrame(this.draw),this.strokeManager.onStrokePart(this.onStrokePart),this.setCanvasSize(e,s)}setCanvasSize(t,e){this.canvasWidth=t,this.canvasHeight=e;const{ctx:s,canvas:n,canvasWidth:o,canvasHeight:a,pixelRatio:r}=this;s&&(n.width=o*r,n.height=a*r,n.style.width=o+"px",n.style.height=a+"px",s.scale(r,r))}setTool(t){this.currentTool=t}destroy(){window.cancelAnimationFrame(this.nextAnimationFrame),this.strokeManager.destroy()}clear(){this.canvasState=null,this.currentStroke=[],this.shouldDraw=!0,this.shouldCommit=!0}onStrokePart(t){this.currentStroke.push(t),this.shouldDraw=!0,t.isEnd&&(this.shouldCommit=!0)}draw(){this.nextAnimationFrame=window.requestAnimationFrame(this.draw);const{ctx:t,canvasWidth:e,canvasHeight:s}=this;!this.shouldDraw||!t||(t.clearRect(0,0,this.canvasWidth,this.canvasHeight),this.canvasState&&t.putImageData(this.canvasState,0,0),this.currentTool&&this.currentStroke.length&&(t.save(),this.currentTool.draw(t,this.currentStroke,e,s),t.restore()),this.shouldCommit&&(this.canvasState=t.getImageData(0,0,e*this.pixelRatio,s*this.pixelRatio),this.currentStroke=[],this.shouldCommit=!1),this.shouldDraw=!1)}}class P{constructor(t="red",e=3){this.color=t,this.width=e}draw(t,e,s,n){const o=e[0];t.beginPath(),t.lineWidth=this.width,t.strokeStyle=this.color,t.lineCap="round",t.lineJoin="round",t.moveTo(o.startPoint.x*s,o.startPoint.y*n),e.forEach(a=>{const{endPoint:r}=a;t.lineTo(r.x*s,r.y*n)}),t.stroke()}}class T{constructor(t=10,e){this.width=t,e=e||{},this.handleOpts={hide:e.hide||!1,strokeWidth:e.strokeWidth||2,fillColor:e.fillColor||"white",strokeColor:e.strokeColor||"black"}}draw(t,e,s,n){const{handleOpts:o}=this,a=this.width/2;e.forEach(l=>{const{startPoint:g,endPoint:f}=l,L=d(g,f),h=k(g,f);let c=g,y=0;for(;y10&&/[0-9](?:\s|\/)/.test(i)&&(e=i.match(/([0-9]+)/g).map(function(f){return parseFloat(f)}),n=i.match(/([a-z])/ig).join("").toLowerCase());else isNaN(i)?Array.isArray(i)||i.length?(e=[i[0],i[1],i[2]],n="rgb",s=i.length===4?i[3]:1):i instanceof Object&&(i.r!=null||i.red!=null||i.R!=null?(n="rgb",e=[i.r||i.red||i.R||0,i.g||i.green||i.G||0,i.b||i.blue||i.B||0]):(n="hsl",e=[i.h||i.hue||i.H||0,i.s||i.saturation||i.S||0,i.l||i.lightness||i.L||i.b||i.brightness]),s=i.a||i.alpha||i.opacity||1,i.opacity!=null&&(s/=100)):(n="rgb",e=[i>>>16,(i&65280)>>>8,i&255]);return{space:n,values:e,alpha:s}}function C(i,t){var e=E(i);return t==null&&(t=e.alpha),e.space[0]==="h"?e.space+["a(",e.values[0],",",e.values[1],"%,",e.values[2],"%,",t,")"].join(""):e.space+["a(",e.values,",",t,")"].join("")}class R{constructor(t="yellow",e=8,s=.3){this.width=e,this.color=C(t,.4)}draw(t,e,s,n){const o=e[0];t.beginPath(),t.lineWidth=this.width,t.strokeStyle=this.color,t.lineCap="butt",t.miterLimit=1,t.moveTo(o.startPoint.x*s,o.startPoint.y*n),e.forEach(a=>{const{endPoint:r}=a;t.lineTo(r.x*s,r.y*n)}),t.stroke()}}u.EraserTool=T,u.HighlighterTool=R,u.Manager=b,u.PenTool=P,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})}); //# sourceMappingURL=index.umd.js.map diff --git a/dist/index.umd.js.map b/dist/index.umd.js.map index 3cfe016..f303907 100644 --- a/dist/index.umd.js.map +++ b/dist/index.umd.js.map @@ -1 +1 @@ -{"version":3,"file":"index.umd.js","sources":["../src/util.ts","../src/StrokeManager.ts","../src/Manager.ts","../src/tools/PenTool.ts","../src/tools/EraserTool.ts","../node_modules/color-name/index.js","../node_modules/color-parse/index.mjs","../node_modules/color-alpha/index.mjs","../src/tools/HighlighterTool.ts"],"sourcesContent":["import { IPoint } from \"./types\";\n\n/**\n * Get the distance between two points\n * @param p1\n * @param p2\n * @returns number\n */\nexport function getEuclidean(p1: IPoint, p2: IPoint): number {\n return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));\n}\n\n/**\n * Gets the unit vector representing the vector from start\n * point to end point with a length of 1.\n * @param startPoint\n * @param endPoint\n * @returns IPoint\n */\nexport function getUnitVector(startPoint: IPoint, endPoint: IPoint): IPoint {\n const length = getEuclidean(startPoint, endPoint);\n\n const dirVect = {\n x: endPoint.x - startPoint.x,\n y: endPoint.y - startPoint.y,\n };\n\n const unitVect: IPoint = {\n x: dirVect.x / length,\n y: dirVect.y / length,\n };\n\n return unitVect;\n}\n","import { IPoint, IStrokePart } from \"./types\";\nimport { getEuclidean } from \"./util\";\n\nexport interface IOnStrokePartHandler {\n (strokePart: IStrokePart): void;\n}\n\nexport interface ITouch {\n id: number;\n position: IPoint;\n}\n\nexport class StrokeManager {\n // reference to canvas element\n private canvas: HTMLCanvasElement;\n // holds last touch point in a drag\n private lastTouch: ITouch | null;\n // value indicates how sensitive the stroke detection is higher is better\n private sensitivity: number;\n // holds all of the last emitted stroke parts in a drag\n private lastStrokeParts: IStrokePart[];\n // the handlers listening for new strokes\n private onStrokePartHandlers: IOnStrokePartHandler[];\n\n constructor(canvas: HTMLCanvasElement) {\n this.canvas = canvas;\n this.lastTouch = null;\n this.sensitivity = 20.0;\n this.lastStrokeParts = [];\n this.onStrokePartHandlers = [];\n\n this.onTouchStart = this.onTouchStart.bind(this);\n this.onTouchEnd = this.onTouchEnd.bind(this);\n this.onTouchCancel = this.onTouchCancel.bind(this);\n this.onTouchMove = this.onTouchMove.bind(this);\n this.destroy = this.destroy.bind(this);\n this.getRelativePosition = this.getRelativePosition.bind(this);\n\n this.canvas.addEventListener(\"touchstart\", this.onTouchStart, {\n passive: false,\n });\n this.canvas.addEventListener(\"touchend\", this.onTouchEnd, {\n passive: false,\n });\n this.canvas.addEventListener(\"touchcancel\", this.onTouchCancel, {\n passive: false,\n });\n this.canvas.addEventListener(\"touchmove\", this.onTouchMove, {\n passive: false,\n });\n }\n\n /**\n * Registers a handler to be fired on a new stroke part\n * @param handler\n */\n public onStrokePart(handler: IOnStrokePartHandler): void {\n this.onStrokePartHandlers.push(handler);\n }\n\n /**\n * Removes all active listeners\n */\n public destroy(): void {\n this.onStrokePartHandlers = [];\n this.lastStrokeParts = [];\n this.canvas.removeEventListener(\"touchstart\", this.onTouchStart);\n this.canvas.removeEventListener(\"touchend\", this.onTouchEnd);\n this.canvas.removeEventListener(\"touchcancel\", this.onTouchCancel);\n this.canvas.removeEventListener(\"touchmove\", this.onTouchMove);\n }\n\n /**\n * Get relative position to canvas\n * @param clientX\n * @param clientY\n * @returns IPoint\n */\n private getRelativePosition(clientX: number, clientY: number): IPoint {\n const rect = this.canvas.getBoundingClientRect();\n\n return {\n x: clientX - rect.left,\n y: clientY - rect.top,\n };\n }\n\n /**\n * Creates a new touch if one does not\n * already exist\n * @param e\n */\n private onTouchStart(e: TouchEvent): void {\n e.preventDefault();\n\n // if there is an ongoing touch, ignore this event\n if (this.lastTouch) {\n return;\n }\n\n const touches: TouchList = e.changedTouches;\n\n // only get the first touch\n const touch = touches.item(0);\n\n // save the touch\n this.lastTouch = {\n id: touch.identifier,\n position: this.getRelativePosition(touch.clientX, touch.clientY),\n };\n }\n\n /**\n * Creates a line from last touch to current touch\n * point and emits event. Does no-op if no existing touch\n * @param e\n */\n private onTouchMove(e: TouchEvent): void {\n e.preventDefault();\n\n // if no last touch... something is wrong\n if (!this.lastTouch) {\n return;\n }\n\n const touches: TouchList = e.changedTouches;\n\n // find the current touch we are tracking\n const touch: Touch = Array.from(touches).find((touch) => {\n return touch.identifier === this.lastTouch.id;\n });\n\n // if the touch was not one we were tracking,\n // ignore and no-op\n if (!touch) {\n return;\n }\n\n const nextTouch: ITouch = {\n id: touch.identifier,\n position: this.getRelativePosition(touch.clientX, touch.clientY),\n };\n\n // If sensitivity setting has been set,\n // check if this point is far enough from last\n // touch to be drawn\n if (\n this.sensitivity &&\n getEuclidean(nextTouch.position, this.lastTouch.position) <\n 10.0 / this.sensitivity\n ) {\n return;\n }\n\n const strokePart: IStrokePart = {\n endPoint: nextTouch.position,\n startPoint: this.lastTouch.position,\n isStart: this.lastStrokeParts.length === 0,\n isEnd: false,\n };\n\n this.onStrokePartHandlers.forEach((handler) => {\n handler(strokePart);\n });\n\n // save this touch as last touch\n this.lastTouch = nextTouch;\n this.lastStrokeParts.push(strokePart);\n }\n\n /**\n * Draws a line from last point to final point. Removes\n * the reference to last touch point.\n * @param e\n */\n private onTouchEnd(e: TouchEvent): void {\n e.preventDefault();\n\n // if no last touch... something is wrong\n if (!this.lastTouch) {\n return;\n }\n\n const touches: TouchList = e.changedTouches;\n\n // find the current touch we are tracking\n const touch: Touch = Array.from(touches).find((touch) => {\n return touch.identifier === this.lastTouch.id;\n });\n\n // if the touch was not one we were tracking,\n // ignore and no-op\n if (!touch) {\n return;\n }\n\n const endPoint = this.getRelativePosition(touch.clientX, touch.clientY);\n\n const strokePart: IStrokePart = {\n startPoint: this.lastTouch.position,\n endPoint,\n isStart: false,\n isEnd: true,\n };\n\n this.onStrokePartHandlers.forEach((handler) => {\n handler(strokePart);\n });\n\n this.lastTouch = null;\n this.lastStrokeParts = [];\n }\n\n /**\n * Removes the current last touch point\n * @param e\n */\n private onTouchCancel(e: TouchEvent): void {\n e.preventDefault();\n this.lastTouch = null;\n this.lastStrokeParts = [];\n }\n}\n","import { IStrokePart, ITool } from \"./types\";\nimport { StrokeManager } from \"./StrokeManager\";\n\nexport class Manager {\n // reference to the canvas\n private canvas: HTMLCanvasElement;\n // reference to stroke manager\n private strokeManager: StrokeManager;\n // holds the pixel ratio between canvas backing\n // store and device ratio (used for hi fi displays)\n private pixelRatio: number;\n // the width of the canvas\n private canvasWidth: number;\n // the height of the canvas\n private canvasHeight: number;\n // holds a reference to next animation frame\n private nextAnimationFrame: number;\n // the currently selected tool\n private currentTool: ITool | null;\n // holds stroke parts for ongoing stroke\n private currentStroke: IStrokePart[];\n // the state of the canvas (not including ongoing stroke)\n private canvasState: ImageData | null;\n // indicates whether changes have occured that require redraw\n private shouldDraw: boolean;\n // indicates whether canvas should commit its next draw state to current state\n private shouldCommit: boolean;\n\n constructor(\n canvas: HTMLCanvasElement,\n canvasWidth: number,\n canvasHeight: number,\n ) {\n this.canvas = canvas;\n this.canvasWidth = canvasWidth;\n this.canvasHeight = canvasHeight;\n this.currentTool = null;\n this.currentStroke = [];\n this.strokeManager = new StrokeManager(canvas);\n this.canvasState = null;\n this.shouldDraw = false;\n this.shouldCommit = false;\n\n // find pixel ratio relative to backing store and device ratio\n const bsr = (canvas.getContext(\"2d\") as any).backingStorePixelRatio || 1;\n const dpr = window.devicePixelRatio || 1;\n this.pixelRatio = dpr / bsr;\n\n this.setCanvasSize = this.setCanvasSize.bind(this);\n this.setTool = this.setTool.bind(this);\n this.destroy = this.destroy.bind(this);\n this.clear = this.clear.bind(this);\n this.draw = this.draw.bind(this);\n this.onStrokePart = this.onStrokePart.bind(this);\n\n // schedule animation frame loop\n this.nextAnimationFrame = window.requestAnimationFrame(this.draw);\n // set up listener for new stroke part\n this.strokeManager.onStrokePart(this.onStrokePart);\n\n this.setCanvasSize(canvasWidth, canvasHeight);\n }\n\n /**\n * Sets the canvas desired width and height and sets transform\n * for hifi displays\n * @param width\n * @param height\n */\n public setCanvasSize(width: number, height: number): void {\n this.canvasWidth = width;\n this.canvasHeight = height;\n\n const { canvas, canvasWidth, canvasHeight, pixelRatio } = this;\n\n const ctx = canvas.getContext(\"2d\");\n\n // appropriately scale canvas to map to device ratio\n canvas.width = canvasWidth * pixelRatio;\n canvas.height = canvasHeight * pixelRatio;\n canvas.style.width = canvasWidth + \"px\";\n canvas.style.height = canvasHeight + \"px\";\n ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);\n }\n\n /**\n * Sets the current tool for the manager\n * @param tool\n */\n public setTool(tool: ITool): void {\n this.currentTool = tool;\n }\n\n /**\n * Remove all event listeners\n */\n public destroy(): void {\n // cancel animation loop\n window.cancelAnimationFrame(this.nextAnimationFrame);\n // remove all listeners on stroke manager\n this.strokeManager.destroy();\n }\n\n /**\n * Clears the canvas\n */\n public clear(): void {\n this.canvasState = null;\n this.currentStroke = [];\n this.shouldDraw = true;\n this.shouldCommit = true;\n }\n\n /**\n * Adds a new stroke part to the nextStrokes\n * array\n * @param strokePart\n */\n private onStrokePart(strokePart: IStrokePart): void {\n this.currentStroke.push(strokePart);\n\n this.shouldDraw = true;\n\n if (strokePart.isEnd) {\n this.shouldCommit = true;\n }\n }\n\n /**\n * Draws a frame\n */\n private draw(): void {\n // schedule next draw\n this.nextAnimationFrame = window.requestAnimationFrame(this.draw);\n\n const ctx = this.canvas.getContext(\"2d\");\n\n if (!this.shouldDraw) {\n return;\n }\n\n // clear canvas\n ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);\n\n // draw current state\n if (this.canvasState) {\n ctx.putImageData(this.canvasState, 0, 0);\n }\n\n // if a tool has been selected and there are\n // pending strokes, draw them\n if (this.currentTool && this.currentStroke.length) {\n ctx.save();\n this.currentTool.draw(ctx, this.currentStroke);\n ctx.restore();\n }\n\n // if all changes have been made for current stroke,\n // save it as the new canvas state\n if (this.shouldCommit) {\n this.canvasState = ctx.getImageData(\n 0,\n 0,\n this.canvasWidth * this.pixelRatio,\n this.canvasHeight * this.pixelRatio,\n );\n this.currentStroke = [];\n this.shouldCommit = false;\n }\n\n this.shouldDraw = false;\n }\n}\n","import { IStrokePart } from \"../types\";\n\nexport class PenTool {\n readonly color: string;\n readonly width: number;\n\n constructor(color: string = \"red\", width: number = 3) {\n this.color = color;\n this.width = width;\n }\n\n /**\n * Draws a \"pen stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n public draw(ctx: CanvasRenderingContext2D, strokeParts: IStrokePart[]): void {\n const firstPart = strokeParts[0];\n\n ctx.beginPath();\n\n ctx.lineWidth = this.width;\n ctx.strokeStyle = this.color;\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n\n ctx.moveTo(firstPart.startPoint.x, firstPart.startPoint.y);\n\n strokeParts.forEach((strokePart) => {\n const { endPoint } = strokePart;\n ctx.lineTo(endPoint.x, endPoint.y);\n });\n\n ctx.stroke();\n }\n}\n","import { IStrokePart, IPoint } from \"../types\";\nimport { getUnitVector, getEuclidean } from \"../util\";\n\nexport interface IHandleOptions {\n hide: boolean;\n strokeWidth: number;\n fillColor: string;\n strokeColor: string;\n}\n\nexport class EraserTool {\n readonly width: number;\n readonly handleOpts: IHandleOptions;\n\n constructor(width: number = 10, handleOpts?: Partial) {\n this.width = width;\n\n handleOpts = handleOpts || {};\n\n this.handleOpts = {\n hide: handleOpts.hide || false,\n strokeWidth: handleOpts.strokeWidth || 2,\n fillColor: handleOpts.fillColor || \"white\",\n strokeColor: handleOpts.strokeColor || \"black\",\n };\n }\n\n /**\n * Draws an \"eraser stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n public draw(ctx: CanvasRenderingContext2D, strokeParts: IStrokePart[]): void {\n const { handleOpts } = this;\n const halfWidth = this.width / 2.0;\n\n strokeParts.forEach((strokePart) => {\n const { startPoint, endPoint, isEnd } = strokePart;\n\n const length = getEuclidean(startPoint, endPoint);\n const unitVect: IPoint = getUnitVector(startPoint, endPoint);\n let currentPoint: IPoint = startPoint;\n let i = 0;\n\n // clear all the way along the drag\n while (i < length) {\n const nextPoint: IPoint = {\n x: currentPoint.x + unitVect.x,\n y: currentPoint.y + unitVect.y,\n };\n\n ctx.clearRect(\n nextPoint.x - halfWidth,\n nextPoint.y - halfWidth,\n this.width,\n this.width,\n );\n\n i++;\n currentPoint = nextPoint;\n }\n });\n\n const lastPart = strokeParts[strokeParts.length - 1];\n\n // if the end is not the last part, then draw\n // the tool indicator at the endpoint\n if (!lastPart.isEnd && !handleOpts.hide) {\n ctx.strokeStyle = handleOpts.strokeColor;\n ctx.fillStyle = handleOpts.fillColor;\n\n ctx.fillRect(\n lastPart.endPoint.x - halfWidth,\n lastPart.endPoint.y - halfWidth,\n this.width,\n this.width,\n );\n\n ctx.strokeRect(\n lastPart.endPoint.x - halfWidth + 0.5,\n lastPart.endPoint.y - halfWidth + 0.5,\n this.width - 1,\n this.width - 1,\n );\n }\n }\n}\n","'use strict'\r\n\r\nmodule.exports = {\r\n\t\"aliceblue\": [240, 248, 255],\r\n\t\"antiquewhite\": [250, 235, 215],\r\n\t\"aqua\": [0, 255, 255],\r\n\t\"aquamarine\": [127, 255, 212],\r\n\t\"azure\": [240, 255, 255],\r\n\t\"beige\": [245, 245, 220],\r\n\t\"bisque\": [255, 228, 196],\r\n\t\"black\": [0, 0, 0],\r\n\t\"blanchedalmond\": [255, 235, 205],\r\n\t\"blue\": [0, 0, 255],\r\n\t\"blueviolet\": [138, 43, 226],\r\n\t\"brown\": [165, 42, 42],\r\n\t\"burlywood\": [222, 184, 135],\r\n\t\"cadetblue\": [95, 158, 160],\r\n\t\"chartreuse\": [127, 255, 0],\r\n\t\"chocolate\": [210, 105, 30],\r\n\t\"coral\": [255, 127, 80],\r\n\t\"cornflowerblue\": [100, 149, 237],\r\n\t\"cornsilk\": [255, 248, 220],\r\n\t\"crimson\": [220, 20, 60],\r\n\t\"cyan\": [0, 255, 255],\r\n\t\"darkblue\": [0, 0, 139],\r\n\t\"darkcyan\": [0, 139, 139],\r\n\t\"darkgoldenrod\": [184, 134, 11],\r\n\t\"darkgray\": [169, 169, 169],\r\n\t\"darkgreen\": [0, 100, 0],\r\n\t\"darkgrey\": [169, 169, 169],\r\n\t\"darkkhaki\": [189, 183, 107],\r\n\t\"darkmagenta\": [139, 0, 139],\r\n\t\"darkolivegreen\": [85, 107, 47],\r\n\t\"darkorange\": [255, 140, 0],\r\n\t\"darkorchid\": [153, 50, 204],\r\n\t\"darkred\": [139, 0, 0],\r\n\t\"darksalmon\": [233, 150, 122],\r\n\t\"darkseagreen\": [143, 188, 143],\r\n\t\"darkslateblue\": [72, 61, 139],\r\n\t\"darkslategray\": [47, 79, 79],\r\n\t\"darkslategrey\": [47, 79, 79],\r\n\t\"darkturquoise\": [0, 206, 209],\r\n\t\"darkviolet\": [148, 0, 211],\r\n\t\"deeppink\": [255, 20, 147],\r\n\t\"deepskyblue\": [0, 191, 255],\r\n\t\"dimgray\": [105, 105, 105],\r\n\t\"dimgrey\": [105, 105, 105],\r\n\t\"dodgerblue\": [30, 144, 255],\r\n\t\"firebrick\": [178, 34, 34],\r\n\t\"floralwhite\": [255, 250, 240],\r\n\t\"forestgreen\": [34, 139, 34],\r\n\t\"fuchsia\": [255, 0, 255],\r\n\t\"gainsboro\": [220, 220, 220],\r\n\t\"ghostwhite\": [248, 248, 255],\r\n\t\"gold\": [255, 215, 0],\r\n\t\"goldenrod\": [218, 165, 32],\r\n\t\"gray\": [128, 128, 128],\r\n\t\"green\": [0, 128, 0],\r\n\t\"greenyellow\": [173, 255, 47],\r\n\t\"grey\": [128, 128, 128],\r\n\t\"honeydew\": [240, 255, 240],\r\n\t\"hotpink\": [255, 105, 180],\r\n\t\"indianred\": [205, 92, 92],\r\n\t\"indigo\": [75, 0, 130],\r\n\t\"ivory\": [255, 255, 240],\r\n\t\"khaki\": [240, 230, 140],\r\n\t\"lavender\": [230, 230, 250],\r\n\t\"lavenderblush\": [255, 240, 245],\r\n\t\"lawngreen\": [124, 252, 0],\r\n\t\"lemonchiffon\": [255, 250, 205],\r\n\t\"lightblue\": [173, 216, 230],\r\n\t\"lightcoral\": [240, 128, 128],\r\n\t\"lightcyan\": [224, 255, 255],\r\n\t\"lightgoldenrodyellow\": [250, 250, 210],\r\n\t\"lightgray\": [211, 211, 211],\r\n\t\"lightgreen\": [144, 238, 144],\r\n\t\"lightgrey\": [211, 211, 211],\r\n\t\"lightpink\": [255, 182, 193],\r\n\t\"lightsalmon\": [255, 160, 122],\r\n\t\"lightseagreen\": [32, 178, 170],\r\n\t\"lightskyblue\": [135, 206, 250],\r\n\t\"lightslategray\": [119, 136, 153],\r\n\t\"lightslategrey\": [119, 136, 153],\r\n\t\"lightsteelblue\": [176, 196, 222],\r\n\t\"lightyellow\": [255, 255, 224],\r\n\t\"lime\": [0, 255, 0],\r\n\t\"limegreen\": [50, 205, 50],\r\n\t\"linen\": [250, 240, 230],\r\n\t\"magenta\": [255, 0, 255],\r\n\t\"maroon\": [128, 0, 0],\r\n\t\"mediumaquamarine\": [102, 205, 170],\r\n\t\"mediumblue\": [0, 0, 205],\r\n\t\"mediumorchid\": [186, 85, 211],\r\n\t\"mediumpurple\": [147, 112, 219],\r\n\t\"mediumseagreen\": [60, 179, 113],\r\n\t\"mediumslateblue\": [123, 104, 238],\r\n\t\"mediumspringgreen\": [0, 250, 154],\r\n\t\"mediumturquoise\": [72, 209, 204],\r\n\t\"mediumvioletred\": [199, 21, 133],\r\n\t\"midnightblue\": [25, 25, 112],\r\n\t\"mintcream\": [245, 255, 250],\r\n\t\"mistyrose\": [255, 228, 225],\r\n\t\"moccasin\": [255, 228, 181],\r\n\t\"navajowhite\": [255, 222, 173],\r\n\t\"navy\": [0, 0, 128],\r\n\t\"oldlace\": [253, 245, 230],\r\n\t\"olive\": [128, 128, 0],\r\n\t\"olivedrab\": [107, 142, 35],\r\n\t\"orange\": [255, 165, 0],\r\n\t\"orangered\": [255, 69, 0],\r\n\t\"orchid\": [218, 112, 214],\r\n\t\"palegoldenrod\": [238, 232, 170],\r\n\t\"palegreen\": [152, 251, 152],\r\n\t\"paleturquoise\": [175, 238, 238],\r\n\t\"palevioletred\": [219, 112, 147],\r\n\t\"papayawhip\": [255, 239, 213],\r\n\t\"peachpuff\": [255, 218, 185],\r\n\t\"peru\": [205, 133, 63],\r\n\t\"pink\": [255, 192, 203],\r\n\t\"plum\": [221, 160, 221],\r\n\t\"powderblue\": [176, 224, 230],\r\n\t\"purple\": [128, 0, 128],\r\n\t\"rebeccapurple\": [102, 51, 153],\r\n\t\"red\": [255, 0, 0],\r\n\t\"rosybrown\": [188, 143, 143],\r\n\t\"royalblue\": [65, 105, 225],\r\n\t\"saddlebrown\": [139, 69, 19],\r\n\t\"salmon\": [250, 128, 114],\r\n\t\"sandybrown\": [244, 164, 96],\r\n\t\"seagreen\": [46, 139, 87],\r\n\t\"seashell\": [255, 245, 238],\r\n\t\"sienna\": [160, 82, 45],\r\n\t\"silver\": [192, 192, 192],\r\n\t\"skyblue\": [135, 206, 235],\r\n\t\"slateblue\": [106, 90, 205],\r\n\t\"slategray\": [112, 128, 144],\r\n\t\"slategrey\": [112, 128, 144],\r\n\t\"snow\": [255, 250, 250],\r\n\t\"springgreen\": [0, 255, 127],\r\n\t\"steelblue\": [70, 130, 180],\r\n\t\"tan\": [210, 180, 140],\r\n\t\"teal\": [0, 128, 128],\r\n\t\"thistle\": [216, 191, 216],\r\n\t\"tomato\": [255, 99, 71],\r\n\t\"turquoise\": [64, 224, 208],\r\n\t\"violet\": [238, 130, 238],\r\n\t\"wheat\": [245, 222, 179],\r\n\t\"white\": [255, 255, 255],\r\n\t\"whitesmoke\": [245, 245, 245],\r\n\t\"yellow\": [255, 255, 0],\r\n\t\"yellowgreen\": [154, 205, 50]\r\n};\r\n","/**\n * @module color-parse\n */\nimport names from 'color-name'\n\nexport default parse\n\n/**\n * Base hues\n * http://dev.w3.org/csswg/css-color/#typedef-named-hue\n */\n//FIXME: use external hue detector\nvar baseHues = {\n\tred: 0,\n\torange: 60,\n\tyellow: 120,\n\tgreen: 180,\n\tblue: 240,\n\tpurple: 300\n}\n\n/**\n * Parse color from the string passed\n *\n * @return {Object} A space indicator `space`, an array `values` and `alpha`\n */\nfunction parse(cstr) {\n\tvar m, parts = [], alpha = 1, space\n\n\tif (typeof cstr === 'string') {\n\t\tcstr = cstr.toLowerCase();\n\n\t\t//keyword\n\t\tif (names[cstr]) {\n\t\t\tparts = names[cstr].slice()\n\t\t\tspace = 'rgb'\n\t\t}\n\n\t\t//reserved words\n\t\telse if (cstr === 'transparent') {\n\t\t\talpha = 0\n\t\t\tspace = 'rgb'\n\t\t\tparts = [0, 0, 0]\n\t\t}\n\n\t\t//hex\n\t\telse if (/^#[A-Fa-f0-9]+$/.test(cstr)) {\n\t\t\tvar base = cstr.slice(1)\n\t\t\tvar size = base.length\n\t\t\tvar isShort = size <= 4\n\t\t\talpha = 1\n\n\t\t\tif (isShort) {\n\t\t\t\tparts = [\n\t\t\t\t\tparseInt(base[0] + base[0], 16),\n\t\t\t\t\tparseInt(base[1] + base[1], 16),\n\t\t\t\t\tparseInt(base[2] + base[2], 16)\n\t\t\t\t]\n\t\t\t\tif (size === 4) {\n\t\t\t\t\talpha = parseInt(base[3] + base[3], 16) / 255\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tparts = [\n\t\t\t\t\tparseInt(base[0] + base[1], 16),\n\t\t\t\t\tparseInt(base[2] + base[3], 16),\n\t\t\t\t\tparseInt(base[4] + base[5], 16)\n\t\t\t\t]\n\t\t\t\tif (size === 8) {\n\t\t\t\t\talpha = parseInt(base[6] + base[7], 16) / 255\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!parts[0]) parts[0] = 0\n\t\t\tif (!parts[1]) parts[1] = 0\n\t\t\tif (!parts[2]) parts[2] = 0\n\n\t\t\tspace = 'rgb'\n\t\t}\n\n\t\t//color space\n\t\telse if (m = /^((?:rgb|hs[lvb]|hwb|cmyk?|xy[zy]|gray|lab|lchu?v?|[ly]uv|lms)a?)\\s*\\(([^\\)]*)\\)/.exec(cstr)) {\n\t\t\tvar name = m[1]\n\t\t\tvar isRGB = name === 'rgb'\n\t\t\tvar base = name.replace(/a$/, '')\n\t\t\tspace = base\n\t\t\tvar size = base === 'cmyk' ? 4 : base === 'gray' ? 1 : 3\n\t\t\tparts = m[2].trim()\n\t\t\t\t.split(/\\s*[,\\/]\\s*|\\s+/)\n\t\t\t\t.map(function (x, i) {\n\t\t\t\t\t//\n\t\t\t\t\tif (/%$/.test(x)) {\n\t\t\t\t\t\t//alpha\n\t\t\t\t\t\tif (i === size) return parseFloat(x) / 100\n\t\t\t\t\t\t//rgb\n\t\t\t\t\t\tif (base === 'rgb') return parseFloat(x) * 255 / 100\n\t\t\t\t\t\treturn parseFloat(x)\n\t\t\t\t\t}\n\t\t\t\t\t//hue\n\t\t\t\t\telse if (base[i] === 'h') {\n\t\t\t\t\t\t//\n\t\t\t\t\t\tif (/deg$/.test(x)) {\n\t\t\t\t\t\t\treturn parseFloat(x)\n\t\t\t\t\t\t}\n\t\t\t\t\t\t//\n\t\t\t\t\t\telse if (baseHues[x] !== undefined) {\n\t\t\t\t\t\t\treturn baseHues[x]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn parseFloat(x)\n\t\t\t\t})\n\n\t\t\tif (name === base) parts.push(1)\n\t\t\talpha = (isRGB) ? 1 : (parts[size] === undefined) ? 1 : parts[size]\n\t\t\tparts = parts.slice(0, size)\n\t\t}\n\n\t\t//named channels case\n\t\telse if (cstr.length > 10 && /[0-9](?:\\s|\\/)/.test(cstr)) {\n\t\t\tparts = cstr.match(/([0-9]+)/g).map(function (value) {\n\t\t\t\treturn parseFloat(value)\n\t\t\t})\n\n\t\t\tspace = cstr.match(/([a-z])/ig).join('').toLowerCase()\n\t\t}\n\t}\n\n\t//numeric case\n\telse if (!isNaN(cstr)) {\n\t\tspace = 'rgb'\n\t\tparts = [cstr >>> 16, (cstr & 0x00ff00) >>> 8, cstr & 0x0000ff]\n\t}\n\n\t//array-like\n\telse if (Array.isArray(cstr) || cstr.length) {\n\t\tparts = [cstr[0], cstr[1], cstr[2]]\n\t\tspace = 'rgb'\n\t\talpha = cstr.length === 4 ? cstr[3] : 1\n\t}\n\n\t//object case - detects css cases of rgb and hsl\n\telse if (cstr instanceof Object) {\n\t\tif (cstr.r != null || cstr.red != null || cstr.R != null) {\n\t\t\tspace = 'rgb'\n\t\t\tparts = [\n\t\t\t\tcstr.r || cstr.red || cstr.R || 0,\n\t\t\t\tcstr.g || cstr.green || cstr.G || 0,\n\t\t\t\tcstr.b || cstr.blue || cstr.B || 0\n\t\t\t]\n\t\t}\n\t\telse {\n\t\t\tspace = 'hsl'\n\t\t\tparts = [\n\t\t\t\tcstr.h || cstr.hue || cstr.H || 0,\n\t\t\t\tcstr.s || cstr.saturation || cstr.S || 0,\n\t\t\t\tcstr.l || cstr.lightness || cstr.L || cstr.b || cstr.brightness\n\t\t\t]\n\t\t}\n\n\t\talpha = cstr.a || cstr.alpha || cstr.opacity || 1\n\n\t\tif (cstr.opacity != null) alpha /= 100\n\t}\n\n\treturn {\n\t\tspace: space,\n\t\tvalues: parts,\n\t\talpha: alpha\n\t}\n}\n","/**\r\n * @module color-alpha\r\n */\r\nimport parse from 'color-parse';\r\n\r\nexport default function alpha (color, value) {\r\n\tvar obj = parse(color);\r\n\r\n\tif (value == null) value = obj.alpha;\r\n\r\n\t//catch percent\r\n\tif (obj.space[0] === 'h') {\r\n\t\treturn obj.space + ['a(', obj.values[0], ',', obj.values[1], '%,', obj.values[2], '%,', value, ')'].join('');\r\n\t}\r\n\r\n\treturn obj.space + ['a(', obj.values, ',', value, ')'].join('');\r\n}\r\n","import alpha from \"color-alpha\";\n\nimport { IStrokePart } from \"../types\";\n\nexport class HighlighterTool {\n readonly color: string;\n readonly width: number;\n\n constructor(\n color: string = \"yellow\",\n width: number = 8,\n opacity: Number = 0.3,\n ) {\n this.width = width;\n\n // calculate color w/ opacity\n this.color = alpha(color, 0.4);\n }\n\n /**\n * Draws a \"highlighter stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n public draw(ctx: CanvasRenderingContext2D, strokeParts: IStrokePart[]): void {\n const firstPart = strokeParts[0];\n\n ctx.beginPath();\n\n ctx.lineWidth = this.width;\n ctx.strokeStyle = this.color;\n ctx.lineCap = \"butt\";\n ctx.miterLimit = 1;\n\n ctx.moveTo(firstPart.startPoint.x, firstPart.startPoint.y);\n\n strokeParts.forEach((strokePart) => {\n const { endPoint } = strokePart;\n ctx.lineTo(endPoint.x, endPoint.y);\n });\n\n ctx.stroke();\n }\n}\n"],"names":["getEuclidean","p1","p2","getUnitVector","startPoint","endPoint","length","dirVect","StrokeManager","canvas","handler","clientX","clientY","rect","e","touch","touches","nextTouch","strokePart","Manager","canvasWidth","canvasHeight","bsr","dpr","width","height","pixelRatio","ctx","tool","PenTool","color","strokeParts","firstPart","EraserTool","handleOpts","halfWidth","isEnd","unitVect","currentPoint","i","nextPoint","lastPart","colorName","baseHues","parse","cstr","m","parts","alpha","space","names","base","size","isShort","name","isRGB","x","value","obj","HighlighterTool","opacity"],"mappings":"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","x_google_ignoreList":[5,6,7]} \ No newline at end of file +{"version":3,"file":"index.umd.js","sources":["../src/util.ts","../src/StrokeManager.ts","../src/Manager.ts","../src/tools/PenTool.ts","../src/tools/EraserTool.ts","../node_modules/color-name/index.js","../node_modules/color-parse/index.mjs","../node_modules/color-alpha/index.mjs","../src/tools/HighlighterTool.ts"],"sourcesContent":["import { IPoint } from \"./types\";\n\n/**\n * Get the distance between two points\n * @param p1\n * @param p2\n * @returns number\n */\nexport function getEuclidean(p1: IPoint, p2: IPoint): number {\n return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));\n}\n\n/**\n * Gets the unit vector representing the vector from start\n * point to end point with a length of 1.\n * @param startPoint\n * @param endPoint\n * @returns IPoint\n */\nexport function getUnitVector(startPoint: IPoint, endPoint: IPoint): IPoint {\n const length = getEuclidean(startPoint, endPoint);\n\n const dirVect = {\n x: endPoint.x - startPoint.x,\n y: endPoint.y - startPoint.y,\n };\n\n const unitVect: IPoint = {\n x: dirVect.x / length,\n y: dirVect.y / length,\n };\n\n return unitVect;\n}\n","import { IPoint, IStrokePart } from \"./types\";\nimport { getEuclidean } from \"./util\";\n\nexport interface IOnStrokePartHandler {\n (strokePart: IStrokePart): void;\n}\n\nexport interface ITouch {\n id: number;\n position: IPoint;\n}\n\nexport class StrokeManager {\n // reference to canvas element\n private canvas: HTMLCanvasElement;\n // holds last touch point in a drag\n private lastTouch: ITouch | null;\n // holds last mouse point in drag\n private lastMouse: IPoint | null;\n // value indicates how sensitive the stroke detection is higher is better\n private sensitivity: number;\n // holds all of the last emitted stroke parts in a drag\n private lastStrokeParts: IStrokePart[];\n // the handlers listening for new strokes\n private onStrokePartHandlers: IOnStrokePartHandler[];\n\n constructor(canvas: HTMLCanvasElement) {\n this.canvas = canvas;\n this.lastTouch = null;\n this.lastMouse = null;\n this.sensitivity = 20.0;\n this.lastStrokeParts = [];\n this.onStrokePartHandlers = [];\n\n this.onTouchStart = this.onTouchStart.bind(this);\n this.onTouchEnd = this.onTouchEnd.bind(this);\n this.onTouchCancel = this.onTouchCancel.bind(this);\n this.onTouchMove = this.onTouchMove.bind(this);\n this.destroy = this.destroy.bind(this);\n this.getRelativePosition = this.getRelativePosition.bind(this);\n this.onMouseDown = this.onMouseDown.bind(this);\n this.onMouseUp = this.onMouseUp.bind(this);\n this.onMouseMove = this.onMouseMove.bind(this);\n\n this.canvas.addEventListener(\"touchstart\", this.onTouchStart, {\n passive: false,\n });\n this.canvas.addEventListener(\"touchend\", this.onTouchEnd, {\n passive: false,\n });\n this.canvas.addEventListener(\"touchcancel\", this.onTouchCancel, {\n passive: false,\n });\n this.canvas.addEventListener(\"touchmove\", this.onTouchMove, {\n passive: false,\n });\n this.canvas.addEventListener(\"mousedown\", this.onMouseDown, {\n passive: false,\n });\n document.addEventListener(\"mouseup\", this.onMouseUp, {\n passive: false,\n });\n this.canvas.addEventListener(\"mousemove\", this.onMouseMove, {\n passive: false,\n });\n }\n\n /**\n * Registers a handler to be fired on a new stroke part\n * @param handler\n */\n public onStrokePart(handler: IOnStrokePartHandler): void {\n this.onStrokePartHandlers.push(handler);\n }\n\n /**\n * Removes all active listeners\n */\n public destroy(): void {\n this.onStrokePartHandlers = [];\n this.lastStrokeParts = [];\n this.canvas.removeEventListener(\"touchstart\", this.onTouchStart);\n this.canvas.removeEventListener(\"touchend\", this.onTouchEnd);\n this.canvas.removeEventListener(\"touchcancel\", this.onTouchCancel);\n this.canvas.removeEventListener(\"touchmove\", this.onTouchMove);\n this.canvas.removeEventListener(\"mousedown\", this.onMouseDown);\n document.removeEventListener(\"mouseup\", this.onMouseUp);\n this.canvas.removeEventListener(\"mousemove\", this.onMouseMove);\n }\n\n /**\n * Get relative position to canvas\n * @param clientX\n * @param clientY\n * @returns IPoint\n */\n private getRelativePosition(clientX: number, clientY: number): IPoint {\n const rect = this.canvas.getBoundingClientRect();\n\n return {\n x: (clientX - rect.left) / rect.width,\n y: (clientY - rect.top) / rect.height,\n };\n }\n\n /**\n * Creates a new touch if one does not\n * already exist\n * @param e\n */\n private onTouchStart(e: TouchEvent): void {\n e.preventDefault();\n\n // if there is an ongoing touch, ignore this event\n if (this.lastTouch) {\n return;\n }\n\n const touches: TouchList = e.changedTouches;\n\n // only get the first touch\n const touch = touches.item(0);\n\n // save the touch\n this.lastTouch = {\n id: touch.identifier,\n position: this.getRelativePosition(touch.clientX, touch.clientY),\n };\n }\n\n /**\n * Creates a line from last touch to current touch\n * point and emits event. Does no-op if no existing touch\n * @param e\n */\n private onTouchMove(e: TouchEvent): void {\n e.preventDefault();\n\n // if no last touch... something is wrong\n if (!this.lastTouch) {\n return;\n }\n\n const touches: TouchList = e.changedTouches;\n\n // find the current touch we are tracking\n const touch: Touch = Array.from(touches).find((touch) => {\n return touch.identifier === this.lastTouch.id;\n });\n\n // if the touch was not one we were tracking,\n // ignore and no-op\n if (!touch) {\n return;\n }\n\n const nextTouch: ITouch = {\n id: touch.identifier,\n position: this.getRelativePosition(touch.clientX, touch.clientY),\n };\n\n // If sensitivity setting has been set,\n // check if this point is far enough from last\n // touch to be drawn\n if (\n this.sensitivity &&\n getEuclidean(nextTouch.position, this.lastTouch.position) <\n 10.0 / this.sensitivity\n ) {\n return;\n }\n\n const strokePart: IStrokePart = {\n endPoint: nextTouch.position,\n startPoint: this.lastTouch.position,\n isStart: this.lastStrokeParts.length === 0,\n isEnd: false,\n };\n\n this.onStrokePartHandlers.forEach((handler) => {\n handler(strokePart);\n });\n\n // save this touch as last touch\n this.lastTouch = nextTouch;\n this.lastStrokeParts.push(strokePart);\n }\n\n /**\n * Draws a line from last point to final point. Removes\n * the reference to last touch point.\n * @param e\n */\n private onTouchEnd(e: TouchEvent): void {\n e.preventDefault();\n\n // if no last touch... something is wrong\n if (!this.lastTouch) {\n return;\n }\n\n const touches: TouchList = e.changedTouches;\n\n // find the current touch we are tracking\n const touch: Touch = Array.from(touches).find((touch) => {\n return touch.identifier === this.lastTouch.id;\n });\n\n // if the touch was not one we were tracking,\n // ignore and no-op\n if (!touch) {\n return;\n }\n\n const endPoint = this.getRelativePosition(touch.clientX, touch.clientY);\n\n const strokePart: IStrokePart = {\n startPoint: this.lastTouch.position,\n endPoint,\n isStart: false,\n isEnd: true,\n };\n\n this.onStrokePartHandlers.forEach((handler) => {\n handler(strokePart);\n });\n\n this.lastTouch = null;\n this.lastStrokeParts = [];\n }\n\n /**\n * Removes the current last touch point\n * @param e\n */\n private onTouchCancel(e: TouchEvent): void {\n e.preventDefault();\n this.lastTouch = null;\n this.lastStrokeParts = [];\n }\n\n private onMouseDown(e: MouseEvent): void {\n // if there is an ongoing drag, ignore this event\n if (this.lastMouse) {\n return;\n }\n\n // save the drag\n this.lastMouse = this.getRelativePosition(e.clientX, e.clientY);\n }\n\n private onMouseUp(e: MouseEvent): void {\n // if no last mouse... something is wrong\n if (!this.lastMouse) {\n return;\n }\n\n let endPoint = this.getRelativePosition(e.clientX, e.clientY);\n\n const d = getEuclidean(this.lastMouse, endPoint);\n\n // if line is less than 1 pixel length, generate a fake line\n if (d < 1) {\n endPoint = {\n x: this.lastMouse.x + 0.0008,\n y: this.lastMouse.y + 0.0008,\n };\n }\n\n const strokePart: IStrokePart = {\n startPoint: this.lastMouse,\n endPoint: endPoint,\n isStart: false,\n isEnd: true,\n };\n\n this.onStrokePartHandlers.forEach((handler) => {\n handler(strokePart);\n });\n\n this.lastMouse = null;\n this.lastStrokeParts = [];\n }\n\n private onMouseMove(e: MouseEvent): void {\n // if no last drag... something is wrong\n if (!this.lastMouse) {\n return;\n }\n\n const nextMouse = this.getRelativePosition(e.clientX, e.clientY);\n\n // If sensitivity setting has been set,\n // check if this point is far enough from last\n // drag to be drawn\n if (\n this.sensitivity &&\n getEuclidean(nextMouse, this.lastMouse) < 0.05 / this.sensitivity\n ) {\n return;\n }\n\n const strokePart: IStrokePart = {\n endPoint: nextMouse,\n startPoint: this.lastMouse,\n isStart: this.lastStrokeParts.length === 0,\n isEnd: false,\n };\n\n this.onStrokePartHandlers.forEach((handler) => {\n handler(strokePart);\n });\n\n // save this drag as last drag\n this.lastMouse = nextMouse;\n this.lastStrokeParts.push(strokePart);\n }\n}\n","import { IStrokePart, ITool } from \"./types\";\nimport { StrokeManager } from \"./StrokeManager\";\n\nexport class Manager {\n // reference to the canvas\n private canvas: HTMLCanvasElement;\n // reference to canvas rendering context\n private ctx: CanvasRenderingContext2D | null;\n // reference to stroke manager\n private strokeManager: StrokeManager;\n // holds the pixel ratio between canvas backing\n // store and device ratio (used for hi fi displays)\n private pixelRatio: number;\n // the width of the canvas\n private canvasWidth: number;\n // the height of the canvas\n private canvasHeight: number;\n // holds a reference to next animation frame\n private nextAnimationFrame: number;\n // the currently selected tool\n private currentTool: ITool | null;\n // holds stroke parts for ongoing stroke\n private currentStroke: IStrokePart[];\n // the state of the canvas (not including ongoing stroke)\n private canvasState: ImageData | null;\n // indicates whether changes have occured that require redraw\n private shouldDraw: boolean;\n // indicates whether canvas should commit its next draw state to current state\n private shouldCommit: boolean;\n\n constructor(\n canvas: HTMLCanvasElement,\n canvasWidth: number,\n canvasHeight: number,\n ) {\n this.canvas = canvas;\n this.ctx = canvas.getContext(\"2d\", { willReadFrequently: true });\n this.canvasWidth = canvasWidth;\n this.canvasHeight = canvasHeight;\n this.currentTool = null;\n this.currentStroke = [];\n this.strokeManager = new StrokeManager(canvas);\n this.canvasState = null;\n this.shouldDraw = false;\n this.shouldCommit = false;\n\n // find pixel ratio relative to backing store and device ratio\n const bsr = (this.ctx as any).backingStorePixelRatio || 1;\n const dpr = window.devicePixelRatio || 1;\n this.pixelRatio = dpr / bsr;\n\n this.setCanvasSize = this.setCanvasSize.bind(this);\n this.setTool = this.setTool.bind(this);\n this.destroy = this.destroy.bind(this);\n this.clear = this.clear.bind(this);\n this.draw = this.draw.bind(this);\n this.onStrokePart = this.onStrokePart.bind(this);\n\n // schedule animation frame loop\n this.nextAnimationFrame = window.requestAnimationFrame(this.draw);\n // set up listener for new stroke part\n this.strokeManager.onStrokePart(this.onStrokePart);\n\n this.setCanvasSize(canvasWidth, canvasHeight);\n }\n\n /**\n * Sets the canvas desired width and height and sets transform\n * for hifi displays\n * @param width\n * @param height\n */\n public setCanvasSize(width: number, height: number): void {\n this.canvasWidth = width;\n this.canvasHeight = height;\n\n const { ctx, canvas, canvasWidth, canvasHeight, pixelRatio } = this;\n\n if (!ctx) return;\n\n // appropriately scale canvas to map to device ratio\n canvas.width = canvasWidth * pixelRatio;\n canvas.height = canvasHeight * pixelRatio;\n canvas.style.width = canvasWidth + \"px\";\n canvas.style.height = canvasHeight + \"px\";\n ctx.scale(pixelRatio, pixelRatio);\n }\n\n /**\n * Sets the current tool for the manager\n * @param tool\n */\n public setTool(tool: ITool): void {\n this.currentTool = tool;\n }\n\n /**\n * Remove all event listeners\n */\n public destroy(): void {\n // cancel animation loop\n window.cancelAnimationFrame(this.nextAnimationFrame);\n // remove all listeners on stroke manager\n this.strokeManager.destroy();\n }\n\n /**\n * Clears the canvas\n */\n public clear(): void {\n this.canvasState = null;\n this.currentStroke = [];\n this.shouldDraw = true;\n this.shouldCommit = true;\n }\n\n /**\n * Adds a new stroke part to the nextStrokes\n * array\n * @param strokePart\n */\n private onStrokePart(strokePart: IStrokePart): void {\n this.currentStroke.push(strokePart);\n\n this.shouldDraw = true;\n\n if (strokePart.isEnd) {\n this.shouldCommit = true;\n }\n }\n\n /**\n * Draws a frame\n */\n private draw(): void {\n // schedule next draw\n this.nextAnimationFrame = window.requestAnimationFrame(this.draw);\n\n const { ctx, canvasWidth, canvasHeight } = this;\n\n if (!this.shouldDraw || !ctx) {\n return;\n }\n\n // clear canvas\n ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);\n\n // draw current state\n if (this.canvasState) {\n ctx.putImageData(this.canvasState, 0, 0);\n }\n\n // if a tool has been selected and there are\n // pending strokes, draw them\n if (this.currentTool && this.currentStroke.length) {\n ctx.save();\n this.currentTool.draw(ctx, this.currentStroke, canvasWidth, canvasHeight);\n ctx.restore();\n }\n\n // if all changes have been made for current stroke,\n // save it as the new canvas state\n if (this.shouldCommit) {\n this.canvasState = ctx.getImageData(\n 0,\n 0,\n canvasWidth * this.pixelRatio,\n canvasHeight * this.pixelRatio,\n );\n this.currentStroke = [];\n this.shouldCommit = false;\n }\n\n this.shouldDraw = false;\n }\n}\n","import { IStrokePart } from \"../types\";\n\nexport class PenTool {\n readonly color: string;\n readonly width: number;\n\n constructor(color: string = \"red\", width: number = 3) {\n this.color = color;\n this.width = width;\n }\n\n /**\n * Draws a \"pen stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n public draw(\n ctx: CanvasRenderingContext2D,\n strokeParts: IStrokePart[],\n canvasWidth: number,\n canvasHeight: number,\n ): void {\n const firstPart = strokeParts[0];\n\n ctx.beginPath();\n\n ctx.lineWidth = this.width;\n ctx.strokeStyle = this.color;\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n\n ctx.moveTo(\n firstPart.startPoint.x * canvasWidth,\n firstPart.startPoint.y * canvasHeight,\n );\n\n strokeParts.forEach((strokePart) => {\n const { endPoint } = strokePart;\n ctx.lineTo(endPoint.x * canvasWidth, endPoint.y * canvasHeight);\n });\n\n ctx.stroke();\n }\n}\n","import { IStrokePart, IPoint } from \"../types\";\nimport { getUnitVector, getEuclidean } from \"../util\";\n\nexport interface IHandleOptions {\n hide: boolean;\n strokeWidth: number;\n fillColor: string;\n strokeColor: string;\n}\n\nexport class EraserTool {\n readonly width: number;\n readonly handleOpts: IHandleOptions;\n\n constructor(width: number = 10, handleOpts?: Partial) {\n this.width = width;\n\n handleOpts = handleOpts || {};\n\n this.handleOpts = {\n hide: handleOpts.hide || false,\n strokeWidth: handleOpts.strokeWidth || 2,\n fillColor: handleOpts.fillColor || \"white\",\n strokeColor: handleOpts.strokeColor || \"black\",\n };\n }\n\n /**\n * Draws an \"eraser stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n public draw(\n ctx: CanvasRenderingContext2D,\n strokeParts: IStrokePart[],\n canvasWidth: number,\n canvasHeight: number,\n ): void {\n const { handleOpts } = this;\n const halfWidth = this.width / 2.0;\n\n strokeParts.forEach((strokePart) => {\n const { startPoint, endPoint } = strokePart;\n\n const length = getEuclidean(startPoint, endPoint);\n const unitVect: IPoint = getUnitVector(startPoint, endPoint);\n let currentPoint: IPoint = startPoint;\n let i = 0;\n\n // clear all the way along the drag\n while (i < length) {\n const nextPoint: IPoint = {\n x: currentPoint.x * canvasWidth + unitVect.x,\n y: currentPoint.y * canvasHeight + unitVect.y,\n };\n\n ctx.clearRect(\n nextPoint.x - halfWidth,\n nextPoint.y - halfWidth,\n this.width,\n this.width,\n );\n\n i++;\n currentPoint = nextPoint;\n }\n });\n\n const lastPart = strokeParts[strokeParts.length - 1];\n\n // if the end is not the last part, then draw\n // the tool indicator at the endpoint\n if (!lastPart.isEnd && !handleOpts.hide) {\n ctx.strokeStyle = handleOpts.strokeColor;\n ctx.fillStyle = handleOpts.fillColor;\n\n const lastEndPoint = {\n x: lastPart.endPoint.x * canvasWidth,\n y: lastPart.endPoint.y * canvasHeight,\n };\n\n ctx.fillRect(\n lastEndPoint.x - halfWidth,\n lastEndPoint.y - halfWidth,\n this.width,\n this.width,\n );\n\n ctx.strokeRect(\n lastEndPoint.x - halfWidth + 0.5,\n lastEndPoint.y - halfWidth + 0.5,\n this.width - 1,\n this.width - 1,\n );\n }\n }\n}\n","'use strict'\r\n\r\nmodule.exports = {\r\n\t\"aliceblue\": [240, 248, 255],\r\n\t\"antiquewhite\": [250, 235, 215],\r\n\t\"aqua\": [0, 255, 255],\r\n\t\"aquamarine\": [127, 255, 212],\r\n\t\"azure\": [240, 255, 255],\r\n\t\"beige\": [245, 245, 220],\r\n\t\"bisque\": [255, 228, 196],\r\n\t\"black\": [0, 0, 0],\r\n\t\"blanchedalmond\": [255, 235, 205],\r\n\t\"blue\": [0, 0, 255],\r\n\t\"blueviolet\": [138, 43, 226],\r\n\t\"brown\": [165, 42, 42],\r\n\t\"burlywood\": [222, 184, 135],\r\n\t\"cadetblue\": [95, 158, 160],\r\n\t\"chartreuse\": [127, 255, 0],\r\n\t\"chocolate\": [210, 105, 30],\r\n\t\"coral\": [255, 127, 80],\r\n\t\"cornflowerblue\": [100, 149, 237],\r\n\t\"cornsilk\": [255, 248, 220],\r\n\t\"crimson\": [220, 20, 60],\r\n\t\"cyan\": [0, 255, 255],\r\n\t\"darkblue\": [0, 0, 139],\r\n\t\"darkcyan\": [0, 139, 139],\r\n\t\"darkgoldenrod\": [184, 134, 11],\r\n\t\"darkgray\": [169, 169, 169],\r\n\t\"darkgreen\": [0, 100, 0],\r\n\t\"darkgrey\": [169, 169, 169],\r\n\t\"darkkhaki\": [189, 183, 107],\r\n\t\"darkmagenta\": [139, 0, 139],\r\n\t\"darkolivegreen\": [85, 107, 47],\r\n\t\"darkorange\": [255, 140, 0],\r\n\t\"darkorchid\": [153, 50, 204],\r\n\t\"darkred\": [139, 0, 0],\r\n\t\"darksalmon\": [233, 150, 122],\r\n\t\"darkseagreen\": [143, 188, 143],\r\n\t\"darkslateblue\": [72, 61, 139],\r\n\t\"darkslategray\": [47, 79, 79],\r\n\t\"darkslategrey\": [47, 79, 79],\r\n\t\"darkturquoise\": [0, 206, 209],\r\n\t\"darkviolet\": [148, 0, 211],\r\n\t\"deeppink\": [255, 20, 147],\r\n\t\"deepskyblue\": [0, 191, 255],\r\n\t\"dimgray\": [105, 105, 105],\r\n\t\"dimgrey\": [105, 105, 105],\r\n\t\"dodgerblue\": [30, 144, 255],\r\n\t\"firebrick\": [178, 34, 34],\r\n\t\"floralwhite\": [255, 250, 240],\r\n\t\"forestgreen\": [34, 139, 34],\r\n\t\"fuchsia\": [255, 0, 255],\r\n\t\"gainsboro\": [220, 220, 220],\r\n\t\"ghostwhite\": [248, 248, 255],\r\n\t\"gold\": [255, 215, 0],\r\n\t\"goldenrod\": [218, 165, 32],\r\n\t\"gray\": [128, 128, 128],\r\n\t\"green\": [0, 128, 0],\r\n\t\"greenyellow\": [173, 255, 47],\r\n\t\"grey\": [128, 128, 128],\r\n\t\"honeydew\": [240, 255, 240],\r\n\t\"hotpink\": [255, 105, 180],\r\n\t\"indianred\": [205, 92, 92],\r\n\t\"indigo\": [75, 0, 130],\r\n\t\"ivory\": [255, 255, 240],\r\n\t\"khaki\": [240, 230, 140],\r\n\t\"lavender\": [230, 230, 250],\r\n\t\"lavenderblush\": [255, 240, 245],\r\n\t\"lawngreen\": [124, 252, 0],\r\n\t\"lemonchiffon\": [255, 250, 205],\r\n\t\"lightblue\": [173, 216, 230],\r\n\t\"lightcoral\": [240, 128, 128],\r\n\t\"lightcyan\": [224, 255, 255],\r\n\t\"lightgoldenrodyellow\": [250, 250, 210],\r\n\t\"lightgray\": [211, 211, 211],\r\n\t\"lightgreen\": [144, 238, 144],\r\n\t\"lightgrey\": [211, 211, 211],\r\n\t\"lightpink\": [255, 182, 193],\r\n\t\"lightsalmon\": [255, 160, 122],\r\n\t\"lightseagreen\": [32, 178, 170],\r\n\t\"lightskyblue\": [135, 206, 250],\r\n\t\"lightslategray\": [119, 136, 153],\r\n\t\"lightslategrey\": [119, 136, 153],\r\n\t\"lightsteelblue\": [176, 196, 222],\r\n\t\"lightyellow\": [255, 255, 224],\r\n\t\"lime\": [0, 255, 0],\r\n\t\"limegreen\": [50, 205, 50],\r\n\t\"linen\": [250, 240, 230],\r\n\t\"magenta\": [255, 0, 255],\r\n\t\"maroon\": [128, 0, 0],\r\n\t\"mediumaquamarine\": [102, 205, 170],\r\n\t\"mediumblue\": [0, 0, 205],\r\n\t\"mediumorchid\": [186, 85, 211],\r\n\t\"mediumpurple\": [147, 112, 219],\r\n\t\"mediumseagreen\": [60, 179, 113],\r\n\t\"mediumslateblue\": [123, 104, 238],\r\n\t\"mediumspringgreen\": [0, 250, 154],\r\n\t\"mediumturquoise\": [72, 209, 204],\r\n\t\"mediumvioletred\": [199, 21, 133],\r\n\t\"midnightblue\": [25, 25, 112],\r\n\t\"mintcream\": [245, 255, 250],\r\n\t\"mistyrose\": [255, 228, 225],\r\n\t\"moccasin\": [255, 228, 181],\r\n\t\"navajowhite\": [255, 222, 173],\r\n\t\"navy\": [0, 0, 128],\r\n\t\"oldlace\": [253, 245, 230],\r\n\t\"olive\": [128, 128, 0],\r\n\t\"olivedrab\": [107, 142, 35],\r\n\t\"orange\": [255, 165, 0],\r\n\t\"orangered\": [255, 69, 0],\r\n\t\"orchid\": [218, 112, 214],\r\n\t\"palegoldenrod\": [238, 232, 170],\r\n\t\"palegreen\": [152, 251, 152],\r\n\t\"paleturquoise\": [175, 238, 238],\r\n\t\"palevioletred\": [219, 112, 147],\r\n\t\"papayawhip\": [255, 239, 213],\r\n\t\"peachpuff\": [255, 218, 185],\r\n\t\"peru\": [205, 133, 63],\r\n\t\"pink\": [255, 192, 203],\r\n\t\"plum\": [221, 160, 221],\r\n\t\"powderblue\": [176, 224, 230],\r\n\t\"purple\": [128, 0, 128],\r\n\t\"rebeccapurple\": [102, 51, 153],\r\n\t\"red\": [255, 0, 0],\r\n\t\"rosybrown\": [188, 143, 143],\r\n\t\"royalblue\": [65, 105, 225],\r\n\t\"saddlebrown\": [139, 69, 19],\r\n\t\"salmon\": [250, 128, 114],\r\n\t\"sandybrown\": [244, 164, 96],\r\n\t\"seagreen\": [46, 139, 87],\r\n\t\"seashell\": [255, 245, 238],\r\n\t\"sienna\": [160, 82, 45],\r\n\t\"silver\": [192, 192, 192],\r\n\t\"skyblue\": [135, 206, 235],\r\n\t\"slateblue\": [106, 90, 205],\r\n\t\"slategray\": [112, 128, 144],\r\n\t\"slategrey\": [112, 128, 144],\r\n\t\"snow\": [255, 250, 250],\r\n\t\"springgreen\": [0, 255, 127],\r\n\t\"steelblue\": [70, 130, 180],\r\n\t\"tan\": [210, 180, 140],\r\n\t\"teal\": [0, 128, 128],\r\n\t\"thistle\": [216, 191, 216],\r\n\t\"tomato\": [255, 99, 71],\r\n\t\"turquoise\": [64, 224, 208],\r\n\t\"violet\": [238, 130, 238],\r\n\t\"wheat\": [245, 222, 179],\r\n\t\"white\": [255, 255, 255],\r\n\t\"whitesmoke\": [245, 245, 245],\r\n\t\"yellow\": [255, 255, 0],\r\n\t\"yellowgreen\": [154, 205, 50]\r\n};\r\n","/**\n * @module color-parse\n */\nimport names from 'color-name'\n\nexport default parse\n\n/**\n * Base hues\n * http://dev.w3.org/csswg/css-color/#typedef-named-hue\n */\n//FIXME: use external hue detector\nvar baseHues = {\n\tred: 0,\n\torange: 60,\n\tyellow: 120,\n\tgreen: 180,\n\tblue: 240,\n\tpurple: 300\n}\n\n/**\n * Parse color from the string passed\n *\n * @return {Object} A space indicator `space`, an array `values` and `alpha`\n */\nfunction parse(cstr) {\n\tvar m, parts = [], alpha = 1, space\n\n\tif (typeof cstr === 'string') {\n\t\tcstr = cstr.toLowerCase();\n\n\t\t//keyword\n\t\tif (names[cstr]) {\n\t\t\tparts = names[cstr].slice()\n\t\t\tspace = 'rgb'\n\t\t}\n\n\t\t//reserved words\n\t\telse if (cstr === 'transparent') {\n\t\t\talpha = 0\n\t\t\tspace = 'rgb'\n\t\t\tparts = [0, 0, 0]\n\t\t}\n\n\t\t//hex\n\t\telse if (/^#[A-Fa-f0-9]+$/.test(cstr)) {\n\t\t\tvar base = cstr.slice(1)\n\t\t\tvar size = base.length\n\t\t\tvar isShort = size <= 4\n\t\t\talpha = 1\n\n\t\t\tif (isShort) {\n\t\t\t\tparts = [\n\t\t\t\t\tparseInt(base[0] + base[0], 16),\n\t\t\t\t\tparseInt(base[1] + base[1], 16),\n\t\t\t\t\tparseInt(base[2] + base[2], 16)\n\t\t\t\t]\n\t\t\t\tif (size === 4) {\n\t\t\t\t\talpha = parseInt(base[3] + base[3], 16) / 255\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tparts = [\n\t\t\t\t\tparseInt(base[0] + base[1], 16),\n\t\t\t\t\tparseInt(base[2] + base[3], 16),\n\t\t\t\t\tparseInt(base[4] + base[5], 16)\n\t\t\t\t]\n\t\t\t\tif (size === 8) {\n\t\t\t\t\talpha = parseInt(base[6] + base[7], 16) / 255\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!parts[0]) parts[0] = 0\n\t\t\tif (!parts[1]) parts[1] = 0\n\t\t\tif (!parts[2]) parts[2] = 0\n\n\t\t\tspace = 'rgb'\n\t\t}\n\n\t\t//color space\n\t\telse if (m = /^((?:rgb|hs[lvb]|hwb|cmyk?|xy[zy]|gray|lab|lchu?v?|[ly]uv|lms)a?)\\s*\\(([^\\)]*)\\)/.exec(cstr)) {\n\t\t\tvar name = m[1]\n\t\t\tvar isRGB = name === 'rgb'\n\t\t\tvar base = name.replace(/a$/, '')\n\t\t\tspace = base\n\t\t\tvar size = base === 'cmyk' ? 4 : base === 'gray' ? 1 : 3\n\t\t\tparts = m[2].trim()\n\t\t\t\t.split(/\\s*[,\\/]\\s*|\\s+/)\n\t\t\t\t.map(function (x, i) {\n\t\t\t\t\t//\n\t\t\t\t\tif (/%$/.test(x)) {\n\t\t\t\t\t\t//alpha\n\t\t\t\t\t\tif (i === size) return parseFloat(x) / 100\n\t\t\t\t\t\t//rgb\n\t\t\t\t\t\tif (base === 'rgb') return parseFloat(x) * 255 / 100\n\t\t\t\t\t\treturn parseFloat(x)\n\t\t\t\t\t}\n\t\t\t\t\t//hue\n\t\t\t\t\telse if (base[i] === 'h') {\n\t\t\t\t\t\t//\n\t\t\t\t\t\tif (/deg$/.test(x)) {\n\t\t\t\t\t\t\treturn parseFloat(x)\n\t\t\t\t\t\t}\n\t\t\t\t\t\t//\n\t\t\t\t\t\telse if (baseHues[x] !== undefined) {\n\t\t\t\t\t\t\treturn baseHues[x]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn parseFloat(x)\n\t\t\t\t})\n\n\t\t\tif (name === base) parts.push(1)\n\t\t\talpha = (isRGB) ? 1 : (parts[size] === undefined) ? 1 : parts[size]\n\t\t\tparts = parts.slice(0, size)\n\t\t}\n\n\t\t//named channels case\n\t\telse if (cstr.length > 10 && /[0-9](?:\\s|\\/)/.test(cstr)) {\n\t\t\tparts = cstr.match(/([0-9]+)/g).map(function (value) {\n\t\t\t\treturn parseFloat(value)\n\t\t\t})\n\n\t\t\tspace = cstr.match(/([a-z])/ig).join('').toLowerCase()\n\t\t}\n\t}\n\n\t//numeric case\n\telse if (!isNaN(cstr)) {\n\t\tspace = 'rgb'\n\t\tparts = [cstr >>> 16, (cstr & 0x00ff00) >>> 8, cstr & 0x0000ff]\n\t}\n\n\t//array-like\n\telse if (Array.isArray(cstr) || cstr.length) {\n\t\tparts = [cstr[0], cstr[1], cstr[2]]\n\t\tspace = 'rgb'\n\t\talpha = cstr.length === 4 ? cstr[3] : 1\n\t}\n\n\t//object case - detects css cases of rgb and hsl\n\telse if (cstr instanceof Object) {\n\t\tif (cstr.r != null || cstr.red != null || cstr.R != null) {\n\t\t\tspace = 'rgb'\n\t\t\tparts = [\n\t\t\t\tcstr.r || cstr.red || cstr.R || 0,\n\t\t\t\tcstr.g || cstr.green || cstr.G || 0,\n\t\t\t\tcstr.b || cstr.blue || cstr.B || 0\n\t\t\t]\n\t\t}\n\t\telse {\n\t\t\tspace = 'hsl'\n\t\t\tparts = [\n\t\t\t\tcstr.h || cstr.hue || cstr.H || 0,\n\t\t\t\tcstr.s || cstr.saturation || cstr.S || 0,\n\t\t\t\tcstr.l || cstr.lightness || cstr.L || cstr.b || cstr.brightness\n\t\t\t]\n\t\t}\n\n\t\talpha = cstr.a || cstr.alpha || cstr.opacity || 1\n\n\t\tif (cstr.opacity != null) alpha /= 100\n\t}\n\n\treturn {\n\t\tspace: space,\n\t\tvalues: parts,\n\t\talpha: alpha\n\t}\n}\n","/**\r\n * @module color-alpha\r\n */\r\nimport parse from 'color-parse';\r\n\r\nexport default function alpha (color, value) {\r\n\tvar obj = parse(color);\r\n\r\n\tif (value == null) value = obj.alpha;\r\n\r\n\t//catch percent\r\n\tif (obj.space[0] === 'h') {\r\n\t\treturn obj.space + ['a(', obj.values[0], ',', obj.values[1], '%,', obj.values[2], '%,', value, ')'].join('');\r\n\t}\r\n\r\n\treturn obj.space + ['a(', obj.values, ',', value, ')'].join('');\r\n}\r\n","import alpha from \"color-alpha\";\n\nimport { IStrokePart } from \"../types\";\n\nexport class HighlighterTool {\n readonly color: string;\n readonly width: number;\n\n constructor(\n color: string = \"yellow\",\n width: number = 8,\n opacity: Number = 0.3,\n ) {\n this.width = width;\n\n // calculate color w/ opacity\n this.color = alpha(color, 0.4);\n }\n\n /**\n * Draws a \"highlighter stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n public draw(\n ctx: CanvasRenderingContext2D,\n strokeParts: IStrokePart[],\n canvasWidth: number,\n canvasHeight: number,\n ): void {\n const firstPart = strokeParts[0];\n\n ctx.beginPath();\n\n ctx.lineWidth = this.width;\n ctx.strokeStyle = this.color;\n ctx.lineCap = \"butt\";\n ctx.miterLimit = 1;\n\n ctx.moveTo(\n firstPart.startPoint.x * canvasWidth,\n firstPart.startPoint.y * canvasHeight,\n );\n\n strokeParts.forEach((strokePart) => {\n const { endPoint } = strokePart;\n ctx.lineTo(endPoint.x * canvasWidth, endPoint.y * canvasHeight);\n });\n\n ctx.stroke();\n }\n}\n"],"names":["getEuclidean","p1","p2","getUnitVector","startPoint","endPoint","length","dirVect","StrokeManager","canvas","handler","clientX","clientY","rect","e","touch","touches","nextTouch","strokePart","nextMouse","Manager","canvasWidth","canvasHeight","bsr","dpr","width","height","ctx","pixelRatio","tool","PenTool","color","strokeParts","firstPart","EraserTool","handleOpts","halfWidth","unitVect","currentPoint","i","nextPoint","lastPart","lastEndPoint","colorName","baseHues","parse","cstr","m","parts","alpha","space","names","base","size","isShort","name","isRGB","x","value","obj","HighlighterTool","opacity"],"mappings":"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","x_google_ignoreList":[5,6,7]} \ No newline at end of file diff --git a/example/build/example.es.js b/example/build/example.es.js index 00ff68c..ada0ce8 100644 --- a/example/build/example.es.js +++ b/example/build/example.es.js @@ -1,19 +1,19 @@ -function v(e, t) { - return Math.sqrt(Math.pow(e.x - t.x, 2) + Math.pow(e.y - t.y, 2)); +function g(s, t) { + return Math.sqrt(Math.pow(s.x - t.x, 2) + Math.pow(s.y - t.y, 2)); } -function w(e, t) { - const i = v(e, t), n = { - x: t.x - e.x, - y: t.y - e.y +function b(s, t) { + const e = g(s, t), i = { + x: t.x - s.x, + y: t.y - s.y }; return { - x: n.x / i, - y: n.y / i + x: i.x / e, + y: i.y / e }; } -class b { +class f { constructor(t) { - this.canvas = t, this.lastTouch = null, this.sensitivity = 20, this.lastStrokeParts = [], this.onStrokePartHandlers = [], this.onTouchStart = this.onTouchStart.bind(this), this.onTouchEnd = this.onTouchEnd.bind(this), this.onTouchCancel = this.onTouchCancel.bind(this), this.onTouchMove = this.onTouchMove.bind(this), this.destroy = this.destroy.bind(this), this.getRelativePosition = this.getRelativePosition.bind(this), this.canvas.addEventListener("touchstart", this.onTouchStart, { + this.canvas = t, this.lastTouch = null, this.lastMouse = null, this.sensitivity = 20, this.lastStrokeParts = [], this.onStrokePartHandlers = [], this.onTouchStart = this.onTouchStart.bind(this), this.onTouchEnd = this.onTouchEnd.bind(this), this.onTouchCancel = this.onTouchCancel.bind(this), this.onTouchMove = this.onTouchMove.bind(this), this.destroy = this.destroy.bind(this), this.getRelativePosition = this.getRelativePosition.bind(this), this.onMouseDown = this.onMouseDown.bind(this), this.onMouseUp = this.onMouseUp.bind(this), this.onMouseMove = this.onMouseMove.bind(this), this.canvas.addEventListener("touchstart", this.onTouchStart, { passive: !1 }), this.canvas.addEventListener("touchend", this.onTouchEnd, { passive: !1 @@ -21,6 +21,12 @@ class b { passive: !1 }), this.canvas.addEventListener("touchmove", this.onTouchMove, { passive: !1 + }), this.canvas.addEventListener("mousedown", this.onMouseDown, { + passive: !1 + }), document.addEventListener("mouseup", this.onMouseUp, { + passive: !1 + }), this.canvas.addEventListener("mousemove", this.onMouseMove, { + passive: !1 }); } /** @@ -34,7 +40,7 @@ class b { * Removes all active listeners */ destroy() { - this.onStrokePartHandlers = [], this.lastStrokeParts = [], this.canvas.removeEventListener("touchstart", this.onTouchStart), this.canvas.removeEventListener("touchend", this.onTouchEnd), this.canvas.removeEventListener("touchcancel", this.onTouchCancel), this.canvas.removeEventListener("touchmove", this.onTouchMove); + this.onStrokePartHandlers = [], this.lastStrokeParts = [], this.canvas.removeEventListener("touchstart", this.onTouchStart), this.canvas.removeEventListener("touchend", this.onTouchEnd), this.canvas.removeEventListener("touchcancel", this.onTouchCancel), this.canvas.removeEventListener("touchmove", this.onTouchMove), this.canvas.removeEventListener("mousedown", this.onMouseDown), document.removeEventListener("mouseup", this.onMouseUp), this.canvas.removeEventListener("mousemove", this.onMouseMove); } /** * Get relative position to canvas @@ -42,11 +48,11 @@ class b { * @param clientY * @returns IPoint */ - getRelativePosition(t, i) { - const n = this.canvas.getBoundingClientRect(); + getRelativePosition(t, e) { + const i = this.canvas.getBoundingClientRect(); return { - x: t - n.left, - y: i - n.top + x: (t - i.left) / i.width, + y: (e - i.top) / i.height }; } /** @@ -57,10 +63,10 @@ class b { onTouchStart(t) { if (t.preventDefault(), this.lastTouch) return; - const i = t.changedTouches.item(0); + const e = t.changedTouches.item(0); this.lastTouch = { - id: i.identifier, - position: this.getRelativePosition(i.clientX, i.clientY) + id: e.identifier, + position: this.getRelativePosition(e.clientX, e.clientY) }; } /** @@ -71,24 +77,24 @@ class b { onTouchMove(t) { if (t.preventDefault(), !this.lastTouch) return; - const i = t.changedTouches, n = Array.from(i).find((a) => a.identifier === this.lastTouch.id); - if (!n) + const e = t.changedTouches, i = Array.from(e).find((a) => a.identifier === this.lastTouch.id); + if (!i) return; const o = { - id: n.identifier, - position: this.getRelativePosition(n.clientX, n.clientY) + id: i.identifier, + position: this.getRelativePosition(i.clientX, i.clientY) }; - if (this.sensitivity && v(o.position, this.lastTouch.position) < 10 / this.sensitivity) + if (this.sensitivity && g(o.position, this.lastTouch.position) < 10 / this.sensitivity) return; - const s = { + const n = { endPoint: o.position, startPoint: this.lastTouch.position, isStart: this.lastStrokeParts.length === 0, isEnd: !1 }; this.onStrokePartHandlers.forEach((a) => { - a(s); - }), this.lastTouch = o, this.lastStrokeParts.push(s); + a(n); + }), this.lastTouch = o, this.lastStrokeParts.push(n); } /** * Draws a line from last point to final point. Removes @@ -98,17 +104,17 @@ class b { onTouchEnd(t) { if (t.preventDefault(), !this.lastTouch) return; - const i = t.changedTouches, n = Array.from(i).find((a) => a.identifier === this.lastTouch.id); - if (!n) + const e = t.changedTouches, i = Array.from(e).find((a) => a.identifier === this.lastTouch.id); + if (!i) return; - const o = this.getRelativePosition(n.clientX, n.clientY), s = { + const o = this.getRelativePosition(i.clientX, i.clientY), n = { startPoint: this.lastTouch.position, endPoint: o, isStart: !1, isEnd: !0 }; this.onStrokePartHandlers.forEach((a) => { - a(s); + a(n); }), this.lastTouch = null, this.lastStrokeParts = []; } /** @@ -118,12 +124,49 @@ class b { onTouchCancel(t) { t.preventDefault(), this.lastTouch = null, this.lastStrokeParts = []; } + onMouseDown(t) { + this.lastMouse || (this.lastMouse = this.getRelativePosition(t.clientX, t.clientY)); + } + onMouseUp(t) { + if (!this.lastMouse) + return; + let e = this.getRelativePosition(t.clientX, t.clientY); + g(this.lastMouse, e) < 1 && (e = { + x: this.lastMouse.x + 8e-4, + y: this.lastMouse.y + 8e-4 + }); + const i = { + startPoint: this.lastMouse, + endPoint: e, + isStart: !1, + isEnd: !0 + }; + this.onStrokePartHandlers.forEach((o) => { + o(i); + }), this.lastMouse = null, this.lastStrokeParts = []; + } + onMouseMove(t) { + if (!this.lastMouse) + return; + const e = this.getRelativePosition(t.clientX, t.clientY); + if (this.sensitivity && g(e, this.lastMouse) < 0.05 / this.sensitivity) + return; + const i = { + endPoint: e, + startPoint: this.lastMouse, + isStart: this.lastStrokeParts.length === 0, + isEnd: !1 + }; + this.onStrokePartHandlers.forEach((o) => { + o(i); + }), this.lastMouse = e, this.lastStrokeParts.push(i); + } } -class f { - constructor(t, i, n) { - this.canvas = t, this.canvasWidth = i, this.canvasHeight = n, this.currentTool = null, this.currentStroke = [], this.strokeManager = new b(t), this.canvasState = null, this.shouldDraw = !1, this.shouldCommit = !1; - const o = t.getContext("2d").backingStorePixelRatio || 1, s = window.devicePixelRatio || 1; - this.pixelRatio = s / o, this.setCanvasSize = this.setCanvasSize.bind(this), this.setTool = this.setTool.bind(this), this.destroy = this.destroy.bind(this), this.clear = this.clear.bind(this), this.draw = this.draw.bind(this), this.onStrokePart = this.onStrokePart.bind(this), this.nextAnimationFrame = window.requestAnimationFrame(this.draw), this.strokeManager.onStrokePart(this.onStrokePart), this.setCanvasSize(i, n); +class P { + constructor(t, e, i) { + this.canvas = t, this.ctx = t.getContext("2d", { willReadFrequently: !0 }), this.canvasWidth = e, this.canvasHeight = i, this.currentTool = null, this.currentStroke = [], this.strokeManager = new f(t), this.canvasState = null, this.shouldDraw = !1, this.shouldCommit = !1; + const o = this.ctx.backingStorePixelRatio || 1, n = window.devicePixelRatio || 1; + this.pixelRatio = n / o, this.setCanvasSize = this.setCanvasSize.bind(this), this.setTool = this.setTool.bind(this), this.destroy = this.destroy.bind(this), this.clear = this.clear.bind(this), this.draw = this.draw.bind(this), this.onStrokePart = this.onStrokePart.bind(this), this.nextAnimationFrame = window.requestAnimationFrame(this.draw), this.strokeManager.onStrokePart(this.onStrokePart), this.setCanvasSize(e, i); } /** * Sets the canvas desired width and height and sets transform @@ -131,10 +174,10 @@ class f { * @param width * @param height */ - setCanvasSize(t, i) { - this.canvasWidth = t, this.canvasHeight = i; - const { canvas: n, canvasWidth: o, canvasHeight: s, pixelRatio: a } = this, l = n.getContext("2d"); - n.width = o * a, n.height = s * a, n.style.width = o + "px", n.style.height = s + "px", l.setTransform(a, 0, 0, a, 0, 0); + setCanvasSize(t, e) { + this.canvasWidth = t, this.canvasHeight = e; + const { ctx: i, canvas: o, canvasWidth: n, canvasHeight: a, pixelRatio: r } = this; + i && (o.width = n * r, o.height = a * r, o.style.width = n + "px", o.style.height = a + "px", i.scale(r, r)); } /** * Sets the current tool for the manager @@ -168,39 +211,42 @@ class f { */ draw() { this.nextAnimationFrame = window.requestAnimationFrame(this.draw); - const t = this.canvas.getContext("2d"); - this.shouldDraw && (t.clearRect(0, 0, this.canvasWidth, this.canvasHeight), this.canvasState && t.putImageData(this.canvasState, 0, 0), this.currentTool && this.currentStroke.length && (t.save(), this.currentTool.draw(t, this.currentStroke), t.restore()), this.shouldCommit && (this.canvasState = t.getImageData( + const { ctx: t, canvasWidth: e, canvasHeight: i } = this; + !this.shouldDraw || !t || (t.clearRect(0, 0, this.canvasWidth, this.canvasHeight), this.canvasState && t.putImageData(this.canvasState, 0, 0), this.currentTool && this.currentStroke.length && (t.save(), this.currentTool.draw(t, this.currentStroke, e, i), t.restore()), this.shouldCommit && (this.canvasState = t.getImageData( 0, 0, - this.canvasWidth * this.pixelRatio, - this.canvasHeight * this.pixelRatio + e * this.pixelRatio, + i * this.pixelRatio ), this.currentStroke = [], this.shouldCommit = !1), this.shouldDraw = !1); } } -class p { - constructor(t = "red", i = 3) { - this.color = t, this.width = i; +class y { + constructor(t = "red", e = 3) { + this.color = t, this.width = e; } /** * Draws a "pen stroke" for all line segments * @param ctx * @param strokeParts */ - draw(t, i) { - const n = i[0]; - t.beginPath(), t.lineWidth = this.width, t.strokeStyle = this.color, t.lineCap = "round", t.lineJoin = "round", t.moveTo(n.startPoint.x, n.startPoint.y), i.forEach((o) => { - const { endPoint: s } = o; - t.lineTo(s.x, s.y); + draw(t, e, i, o) { + const n = e[0]; + t.beginPath(), t.lineWidth = this.width, t.strokeStyle = this.color, t.lineCap = "round", t.lineJoin = "round", t.moveTo( + n.startPoint.x * i, + n.startPoint.y * o + ), e.forEach((a) => { + const { endPoint: r } = a; + t.lineTo(r.x * i, r.y * o); }), t.stroke(); } } class T { - constructor(t = 10, i) { - this.width = t, i = i || {}, this.handleOpts = { - hide: i.hide || !1, - strokeWidth: i.strokeWidth || 2, - fillColor: i.fillColor || "white", - strokeColor: i.strokeColor || "black" + constructor(t = 10, e) { + this.width = t, e = e || {}, this.handleOpts = { + hide: e.hide || !1, + strokeWidth: e.strokeWidth || 2, + fillColor: e.fillColor || "white", + strokeColor: e.strokeColor || "black" }; } /** @@ -208,42 +254,49 @@ class T { * @param ctx * @param strokeParts */ - draw(t, i) { - const { handleOpts: n } = this, o = this.width / 2; - i.forEach((a) => { - const { startPoint: l, endPoint: h, isEnd: c } = a, d = v(l, h), g = w(l, h); - let r = l, u = 0; - for (; u < d; ) { + draw(t, e, i, o) { + const { handleOpts: n } = this, a = this.width / 2; + e.forEach((h) => { + const { startPoint: c, endPoint: u } = h, v = g(c, u), l = b(c, u); + let d = c, p = 0; + for (; p < v; ) { const m = { - x: r.x + g.x, - y: r.y + g.y + x: d.x * i + l.x, + y: d.y * o + l.y }; t.clearRect( - m.x - o, - m.y - o, + m.x - a, + m.y - a, this.width, this.width - ), u++, r = m; + ), p++, d = m; } }); - const s = i[i.length - 1]; - !s.isEnd && !n.hide && (t.strokeStyle = n.strokeColor, t.fillStyle = n.fillColor, t.fillRect( - s.endPoint.x - o, - s.endPoint.y - o, - this.width, - this.width - ), t.strokeRect( - s.endPoint.x - o + 0.5, - s.endPoint.y - o + 0.5, - this.width - 1, - this.width - 1 - )); + const r = e[e.length - 1]; + if (!r.isEnd && !n.hide) { + t.strokeStyle = n.strokeColor, t.fillStyle = n.fillColor; + const h = { + x: r.endPoint.x * i, + y: r.endPoint.y * o + }; + t.fillRect( + h.x - a, + h.y - a, + this.width, + this.width + ), t.strokeRect( + h.x - a + 0.5, + h.y - a + 0.5, + this.width - 1, + this.width - 1 + ); + } } } -function P(e) { - return e && e.__esModule && Object.prototype.hasOwnProperty.call(e, "default") ? e.default : e; +function S(s) { + return s && s.__esModule && Object.prototype.hasOwnProperty.call(s, "default") ? s.default : s; } -var S = { +var M = { aliceblue: [240, 248, 255], antiquewhite: [250, 235, 215], aqua: [0, 255, 255], @@ -393,7 +446,7 @@ var S = { yellow: [255, 255, 0], yellowgreen: [154, 205, 50] }; -const y = /* @__PURE__ */ P(S); +const w = /* @__PURE__ */ S(M); var k = { red: 0, orange: 60, @@ -402,94 +455,97 @@ var k = { blue: 240, purple: 300 }; -function E(e) { - var t, i = [], n = 1, o; - if (typeof e == "string") - if (e = e.toLowerCase(), y[e]) - i = y[e].slice(), o = "rgb"; - else if (e === "transparent") - n = 0, o = "rgb", i = [0, 0, 0]; - else if (/^#[A-Fa-f0-9]+$/.test(e)) { - var s = e.slice(1), a = s.length, l = a <= 4; - n = 1, l ? (i = [ - parseInt(s[0] + s[0], 16), - parseInt(s[1] + s[1], 16), - parseInt(s[2] + s[2], 16) - ], a === 4 && (n = parseInt(s[3] + s[3], 16) / 255)) : (i = [ - parseInt(s[0] + s[1], 16), - parseInt(s[2] + s[3], 16), - parseInt(s[4] + s[5], 16) - ], a === 8 && (n = parseInt(s[6] + s[7], 16) / 255)), i[0] || (i[0] = 0), i[1] || (i[1] = 0), i[2] || (i[2] = 0), o = "rgb"; - } else if (t = /^((?:rgb|hs[lvb]|hwb|cmyk?|xy[zy]|gray|lab|lchu?v?|[ly]uv|lms)a?)\s*\(([^\)]*)\)/.exec(e)) { - var h = t[1], c = h === "rgb", s = h.replace(/a$/, ""); - o = s; - var a = s === "cmyk" ? 4 : s === "gray" ? 1 : 3; - i = t[2].trim().split(/\s*[,\/]\s*|\s+/).map(function(r, u) { - if (/%$/.test(r)) - return u === a ? parseFloat(r) / 100 : s === "rgb" ? parseFloat(r) * 255 / 100 : parseFloat(r); - if (s[u] === "h") { - if (/deg$/.test(r)) - return parseFloat(r); - if (k[r] !== void 0) - return k[r]; +function E(s) { + var t, e = [], i = 1, o; + if (typeof s == "string") + if (s = s.toLowerCase(), w[s]) + e = w[s].slice(), o = "rgb"; + else if (s === "transparent") + i = 0, o = "rgb", e = [0, 0, 0]; + else if (/^#[A-Fa-f0-9]+$/.test(s)) { + var n = s.slice(1), a = n.length, r = a <= 4; + i = 1, r ? (e = [ + parseInt(n[0] + n[0], 16), + parseInt(n[1] + n[1], 16), + parseInt(n[2] + n[2], 16) + ], a === 4 && (i = parseInt(n[3] + n[3], 16) / 255)) : (e = [ + parseInt(n[0] + n[1], 16), + parseInt(n[2] + n[3], 16), + parseInt(n[4] + n[5], 16) + ], a === 8 && (i = parseInt(n[6] + n[7], 16) / 255)), e[0] || (e[0] = 0), e[1] || (e[1] = 0), e[2] || (e[2] = 0), o = "rgb"; + } else if (t = /^((?:rgb|hs[lvb]|hwb|cmyk?|xy[zy]|gray|lab|lchu?v?|[ly]uv|lms)a?)\s*\(([^\)]*)\)/.exec(s)) { + var h = t[1], c = h === "rgb", n = h.replace(/a$/, ""); + o = n; + var a = n === "cmyk" ? 4 : n === "gray" ? 1 : 3; + e = t[2].trim().split(/\s*[,\/]\s*|\s+/).map(function(l, d) { + if (/%$/.test(l)) + return d === a ? parseFloat(l) / 100 : n === "rgb" ? parseFloat(l) * 255 / 100 : parseFloat(l); + if (n[d] === "h") { + if (/deg$/.test(l)) + return parseFloat(l); + if (k[l] !== void 0) + return k[l]; } - return parseFloat(r); - }), h === s && i.push(1), n = c || i[a] === void 0 ? 1 : i[a], i = i.slice(0, a); + return parseFloat(l); + }), h === n && e.push(1), i = c || e[a] === void 0 ? 1 : e[a], e = e.slice(0, a); } else - e.length > 10 && /[0-9](?:\s|\/)/.test(e) && (i = e.match(/([0-9]+)/g).map(function(d) { - return parseFloat(d); - }), o = e.match(/([a-z])/ig).join("").toLowerCase()); + s.length > 10 && /[0-9](?:\s|\/)/.test(s) && (e = s.match(/([0-9]+)/g).map(function(u) { + return parseFloat(u); + }), o = s.match(/([a-z])/ig).join("").toLowerCase()); else - isNaN(e) ? Array.isArray(e) || e.length ? (i = [e[0], e[1], e[2]], o = "rgb", n = e.length === 4 ? e[3] : 1) : e instanceof Object && (e.r != null || e.red != null || e.R != null ? (o = "rgb", i = [ - e.r || e.red || e.R || 0, - e.g || e.green || e.G || 0, - e.b || e.blue || e.B || 0 - ]) : (o = "hsl", i = [ - e.h || e.hue || e.H || 0, - e.s || e.saturation || e.S || 0, - e.l || e.lightness || e.L || e.b || e.brightness - ]), n = e.a || e.alpha || e.opacity || 1, e.opacity != null && (n /= 100)) : (o = "rgb", i = [e >>> 16, (e & 65280) >>> 8, e & 255]); + isNaN(s) ? Array.isArray(s) || s.length ? (e = [s[0], s[1], s[2]], o = "rgb", i = s.length === 4 ? s[3] : 1) : s instanceof Object && (s.r != null || s.red != null || s.R != null ? (o = "rgb", e = [ + s.r || s.red || s.R || 0, + s.g || s.green || s.G || 0, + s.b || s.blue || s.B || 0 + ]) : (o = "hsl", e = [ + s.h || s.hue || s.H || 0, + s.s || s.saturation || s.S || 0, + s.l || s.lightness || s.L || s.b || s.brightness + ]), i = s.a || s.alpha || s.opacity || 1, s.opacity != null && (i /= 100)) : (o = "rgb", e = [s >>> 16, (s & 65280) >>> 8, s & 255]); return { space: o, - values: i, - alpha: n + values: e, + alpha: i }; } -function x(e, t) { - var i = E(e); - return t == null && (t = i.alpha), i.space[0] === "h" ? i.space + ["a(", i.values[0], ",", i.values[1], "%,", i.values[2], "%,", t, ")"].join("") : i.space + ["a(", i.values, ",", t, ")"].join(""); +function x(s, t) { + var e = E(s); + return t == null && (t = e.alpha), e.space[0] === "h" ? e.space + ["a(", e.values[0], ",", e.values[1], "%,", e.values[2], "%,", t, ")"].join("") : e.space + ["a(", e.values, ",", t, ")"].join(""); } class C { - constructor(t = "yellow", i = 8, n = 0.3) { - this.width = i, this.color = x(t, 0.4); + constructor(t = "yellow", e = 8, i = 0.3) { + this.width = e, this.color = x(t, 0.4); } /** * Draws a "highlighter stroke" for all line segments * @param ctx * @param strokeParts */ - draw(t, i) { - const n = i[0]; - t.beginPath(), t.lineWidth = this.width, t.strokeStyle = this.color, t.lineCap = "butt", t.miterLimit = 1, t.moveTo(n.startPoint.x, n.startPoint.y), i.forEach((o) => { - const { endPoint: s } = o; - t.lineTo(s.x, s.y); + draw(t, e, i, o) { + const n = e[0]; + t.beginPath(), t.lineWidth = this.width, t.strokeStyle = this.color, t.lineCap = "butt", t.miterLimit = 1, t.moveTo( + n.startPoint.x * i, + n.startPoint.y * o + ), e.forEach((a) => { + const { endPoint: r } = a; + t.lineTo(r.x * i, r.y * o); }), t.stroke(); } } window.onload = function() { - const e = document.getElementById("canvas"), t = document.getElementById("red-pen"), i = document.getElementById("blue-pen"), n = document.getElementById("eraser"), o = document.getElementById("highlighter"), s = document.getElementById("clear"); - if (!t || !i || !n || !o || !s) + const s = document.getElementById("canvas"), t = document.getElementById("red-pen"), e = document.getElementById("blue-pen"), i = document.getElementById("eraser"), o = document.getElementById("highlighter"), n = document.getElementById("clear"); + if (!t || !e || !i || !o || !n) throw new Error("Invalid elements"); - const a = 400, l = 400, h = new f(e, a, l), c = new p("red", 3), d = new p("blue", 8), g = new T(20), r = new C("yellow", 30); + const a = 400, r = 400, h = new P(s, a, r), c = new y("red", 3), u = new y("blue", 8), v = new T(20), l = new C("yellow", 30); h.setTool(c), t.onclick = function() { h.setTool(c); + }, e.onclick = function() { + h.setTool(u); }, i.onclick = function() { - h.setTool(d); - }, n.onclick = function() { - h.setTool(g); + h.setTool(v); }, o.onclick = function() { - h.setTool(r); - }, s.onclick = function() { + h.setTool(l); + }, n.onclick = function() { h.clear(); }; }; diff --git a/example/build/example.es.js.map b/example/build/example.es.js.map index 5f7a6df..a6aa642 100644 --- a/example/build/example.es.js.map +++ b/example/build/example.es.js.map @@ -1 +1 @@ -{"version":3,"file":"example.es.js","sources":["../../dist/index.es.js","../src/example.ts"],"sourcesContent":["function g(e, t) {\n return Math.sqrt(Math.pow(e.x - t.x, 2) + Math.pow(e.y - t.y, 2));\n}\nfunction y(e, t) {\n const i = g(e, t), o = {\n x: t.x - e.x,\n y: t.y - e.y\n };\n return {\n x: o.x / i,\n y: o.y / i\n };\n}\nclass k {\n constructor(t) {\n this.canvas = t, this.lastTouch = null, this.sensitivity = 20, this.lastStrokeParts = [], this.onStrokePartHandlers = [], this.onTouchStart = this.onTouchStart.bind(this), this.onTouchEnd = this.onTouchEnd.bind(this), this.onTouchCancel = this.onTouchCancel.bind(this), this.onTouchMove = this.onTouchMove.bind(this), this.destroy = this.destroy.bind(this), this.getRelativePosition = this.getRelativePosition.bind(this), this.canvas.addEventListener(\"touchstart\", this.onTouchStart, {\n passive: !1\n }), this.canvas.addEventListener(\"touchend\", this.onTouchEnd, {\n passive: !1\n }), this.canvas.addEventListener(\"touchcancel\", this.onTouchCancel, {\n passive: !1\n }), this.canvas.addEventListener(\"touchmove\", this.onTouchMove, {\n passive: !1\n });\n }\n /**\n * Registers a handler to be fired on a new stroke part\n * @param handler\n */\n onStrokePart(t) {\n this.onStrokePartHandlers.push(t);\n }\n /**\n * Removes all active listeners\n */\n destroy() {\n this.onStrokePartHandlers = [], this.lastStrokeParts = [], this.canvas.removeEventListener(\"touchstart\", this.onTouchStart), this.canvas.removeEventListener(\"touchend\", this.onTouchEnd), this.canvas.removeEventListener(\"touchcancel\", this.onTouchCancel), this.canvas.removeEventListener(\"touchmove\", this.onTouchMove);\n }\n /**\n * Get relative position to canvas\n * @param clientX\n * @param clientY\n * @returns IPoint\n */\n getRelativePosition(t, i) {\n const o = this.canvas.getBoundingClientRect();\n return {\n x: t - o.left,\n y: i - o.top\n };\n }\n /**\n * Creates a new touch if one does not\n * already exist\n * @param e\n */\n onTouchStart(t) {\n if (t.preventDefault(), this.lastTouch)\n return;\n const o = t.changedTouches.item(0);\n this.lastTouch = {\n id: o.identifier,\n position: this.getRelativePosition(o.clientX, o.clientY)\n };\n }\n /**\n * Creates a line from last touch to current touch\n * point and emits event. Does no-op if no existing touch\n * @param e\n */\n onTouchMove(t) {\n if (t.preventDefault(), !this.lastTouch)\n return;\n const i = t.changedTouches, o = Array.from(i).find((a) => a.identifier === this.lastTouch.id);\n if (!o)\n return;\n const n = {\n id: o.identifier,\n position: this.getRelativePosition(o.clientX, o.clientY)\n };\n if (this.sensitivity && g(n.position, this.lastTouch.position) < 10 / this.sensitivity)\n return;\n const s = {\n endPoint: n.position,\n startPoint: this.lastTouch.position,\n isStart: this.lastStrokeParts.length === 0,\n isEnd: !1\n };\n this.onStrokePartHandlers.forEach((a) => {\n a(s);\n }), this.lastTouch = n, this.lastStrokeParts.push(s);\n }\n /**\n * Draws a line from last point to final point. Removes\n * the reference to last touch point.\n * @param e\n */\n onTouchEnd(t) {\n if (t.preventDefault(), !this.lastTouch)\n return;\n const i = t.changedTouches, o = Array.from(i).find((a) => a.identifier === this.lastTouch.id);\n if (!o)\n return;\n const n = this.getRelativePosition(o.clientX, o.clientY), s = {\n startPoint: this.lastTouch.position,\n endPoint: n,\n isStart: !1,\n isEnd: !0\n };\n this.onStrokePartHandlers.forEach((a) => {\n a(s);\n }), this.lastTouch = null, this.lastStrokeParts = [];\n }\n /**\n * Removes the current last touch point\n * @param e\n */\n onTouchCancel(t) {\n t.preventDefault(), this.lastTouch = null, this.lastStrokeParts = [];\n }\n}\nclass P {\n constructor(t, i, o) {\n this.canvas = t, this.canvasWidth = i, this.canvasHeight = o, this.currentTool = null, this.currentStroke = [], this.strokeManager = new k(t), this.canvasState = null, this.shouldDraw = !1, this.shouldCommit = !1;\n const n = t.getContext(\"2d\").backingStorePixelRatio || 1, s = window.devicePixelRatio || 1;\n this.pixelRatio = s / n, this.setCanvasSize = this.setCanvasSize.bind(this), this.setTool = this.setTool.bind(this), this.destroy = this.destroy.bind(this), this.clear = this.clear.bind(this), this.draw = this.draw.bind(this), this.onStrokePart = this.onStrokePart.bind(this), this.nextAnimationFrame = window.requestAnimationFrame(this.draw), this.strokeManager.onStrokePart(this.onStrokePart), this.setCanvasSize(i, o);\n }\n /**\n * Sets the canvas desired width and height and sets transform\n * for hifi displays\n * @param width\n * @param height\n */\n setCanvasSize(t, i) {\n this.canvasWidth = t, this.canvasHeight = i;\n const { canvas: o, canvasWidth: n, canvasHeight: s, pixelRatio: a } = this, h = o.getContext(\"2d\");\n o.width = n * a, o.height = s * a, o.style.width = n + \"px\", o.style.height = s + \"px\", h.setTransform(a, 0, 0, a, 0, 0);\n }\n /**\n * Sets the current tool for the manager\n * @param tool\n */\n setTool(t) {\n this.currentTool = t;\n }\n /**\n * Remove all event listeners\n */\n destroy() {\n window.cancelAnimationFrame(this.nextAnimationFrame), this.strokeManager.destroy();\n }\n /**\n * Clears the canvas\n */\n clear() {\n this.canvasState = null, this.currentStroke = [], this.shouldDraw = !0, this.shouldCommit = !0;\n }\n /**\n * Adds a new stroke part to the nextStrokes\n * array\n * @param strokePart\n */\n onStrokePart(t) {\n this.currentStroke.push(t), this.shouldDraw = !0, t.isEnd && (this.shouldCommit = !0);\n }\n /**\n * Draws a frame\n */\n draw() {\n this.nextAnimationFrame = window.requestAnimationFrame(this.draw);\n const t = this.canvas.getContext(\"2d\");\n this.shouldDraw && (t.clearRect(0, 0, this.canvasWidth, this.canvasHeight), this.canvasState && t.putImageData(this.canvasState, 0, 0), this.currentTool && this.currentStroke.length && (t.save(), this.currentTool.draw(t, this.currentStroke), t.restore()), this.shouldCommit && (this.canvasState = t.getImageData(\n 0,\n 0,\n this.canvasWidth * this.pixelRatio,\n this.canvasHeight * this.pixelRatio\n ), this.currentStroke = [], this.shouldCommit = !1), this.shouldDraw = !1);\n }\n}\nclass C {\n constructor(t = \"red\", i = 3) {\n this.color = t, this.width = i;\n }\n /**\n * Draws a \"pen stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n draw(t, i) {\n const o = i[0];\n t.beginPath(), t.lineWidth = this.width, t.strokeStyle = this.color, t.lineCap = \"round\", t.lineJoin = \"round\", t.moveTo(o.startPoint.x, o.startPoint.y), i.forEach((n) => {\n const { endPoint: s } = n;\n t.lineTo(s.x, s.y);\n }), t.stroke();\n }\n}\nclass E {\n constructor(t = 10, i) {\n this.width = t, i = i || {}, this.handleOpts = {\n hide: i.hide || !1,\n strokeWidth: i.strokeWidth || 2,\n fillColor: i.fillColor || \"white\",\n strokeColor: i.strokeColor || \"black\"\n };\n }\n /**\n * Draws an \"eraser stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n draw(t, i) {\n const { handleOpts: o } = this, n = this.width / 2;\n i.forEach((a) => {\n const { startPoint: h, endPoint: l, isEnd: f } = a, d = g(h, l), v = y(h, l);\n let r = h, u = 0;\n for (; u < d; ) {\n const c = {\n x: r.x + v.x,\n y: r.y + v.y\n };\n t.clearRect(\n c.x - n,\n c.y - n,\n this.width,\n this.width\n ), u++, r = c;\n }\n });\n const s = i[i.length - 1];\n !s.isEnd && !o.hide && (t.strokeStyle = o.strokeColor, t.fillStyle = o.fillColor, t.fillRect(\n s.endPoint.x - n,\n s.endPoint.y - n,\n this.width,\n this.width\n ), t.strokeRect(\n s.endPoint.x - n + 0.5,\n s.endPoint.y - n + 0.5,\n this.width - 1,\n this.width - 1\n ));\n }\n}\nfunction w(e) {\n return e && e.__esModule && Object.prototype.hasOwnProperty.call(e, \"default\") ? e.default : e;\n}\nvar b = {\n aliceblue: [240, 248, 255],\n antiquewhite: [250, 235, 215],\n aqua: [0, 255, 255],\n aquamarine: [127, 255, 212],\n azure: [240, 255, 255],\n beige: [245, 245, 220],\n bisque: [255, 228, 196],\n black: [0, 0, 0],\n blanchedalmond: [255, 235, 205],\n blue: [0, 0, 255],\n blueviolet: [138, 43, 226],\n brown: [165, 42, 42],\n burlywood: [222, 184, 135],\n cadetblue: [95, 158, 160],\n chartreuse: [127, 255, 0],\n chocolate: [210, 105, 30],\n coral: [255, 127, 80],\n cornflowerblue: [100, 149, 237],\n cornsilk: [255, 248, 220],\n crimson: [220, 20, 60],\n cyan: [0, 255, 255],\n darkblue: [0, 0, 139],\n darkcyan: [0, 139, 139],\n darkgoldenrod: [184, 134, 11],\n darkgray: [169, 169, 169],\n darkgreen: [0, 100, 0],\n darkgrey: [169, 169, 169],\n darkkhaki: [189, 183, 107],\n darkmagenta: [139, 0, 139],\n darkolivegreen: [85, 107, 47],\n darkorange: [255, 140, 0],\n darkorchid: [153, 50, 204],\n darkred: [139, 0, 0],\n darksalmon: [233, 150, 122],\n darkseagreen: [143, 188, 143],\n darkslateblue: [72, 61, 139],\n darkslategray: [47, 79, 79],\n darkslategrey: [47, 79, 79],\n darkturquoise: [0, 206, 209],\n darkviolet: [148, 0, 211],\n deeppink: [255, 20, 147],\n deepskyblue: [0, 191, 255],\n dimgray: [105, 105, 105],\n dimgrey: [105, 105, 105],\n dodgerblue: [30, 144, 255],\n firebrick: [178, 34, 34],\n floralwhite: [255, 250, 240],\n forestgreen: [34, 139, 34],\n fuchsia: [255, 0, 255],\n gainsboro: [220, 220, 220],\n ghostwhite: [248, 248, 255],\n gold: [255, 215, 0],\n goldenrod: [218, 165, 32],\n gray: [128, 128, 128],\n green: [0, 128, 0],\n greenyellow: [173, 255, 47],\n grey: [128, 128, 128],\n honeydew: [240, 255, 240],\n hotpink: [255, 105, 180],\n indianred: [205, 92, 92],\n indigo: [75, 0, 130],\n ivory: [255, 255, 240],\n khaki: [240, 230, 140],\n lavender: [230, 230, 250],\n lavenderblush: [255, 240, 245],\n lawngreen: [124, 252, 0],\n lemonchiffon: [255, 250, 205],\n lightblue: [173, 216, 230],\n lightcoral: [240, 128, 128],\n lightcyan: [224, 255, 255],\n lightgoldenrodyellow: [250, 250, 210],\n lightgray: [211, 211, 211],\n lightgreen: [144, 238, 144],\n lightgrey: [211, 211, 211],\n lightpink: [255, 182, 193],\n lightsalmon: [255, 160, 122],\n lightseagreen: [32, 178, 170],\n lightskyblue: [135, 206, 250],\n lightslategray: [119, 136, 153],\n lightslategrey: [119, 136, 153],\n lightsteelblue: [176, 196, 222],\n lightyellow: [255, 255, 224],\n lime: [0, 255, 0],\n limegreen: [50, 205, 50],\n linen: [250, 240, 230],\n magenta: [255, 0, 255],\n maroon: [128, 0, 0],\n mediumaquamarine: [102, 205, 170],\n mediumblue: [0, 0, 205],\n mediumorchid: [186, 85, 211],\n mediumpurple: [147, 112, 219],\n mediumseagreen: [60, 179, 113],\n mediumslateblue: [123, 104, 238],\n mediumspringgreen: [0, 250, 154],\n mediumturquoise: [72, 209, 204],\n mediumvioletred: [199, 21, 133],\n midnightblue: [25, 25, 112],\n mintcream: [245, 255, 250],\n mistyrose: [255, 228, 225],\n moccasin: [255, 228, 181],\n navajowhite: [255, 222, 173],\n navy: [0, 0, 128],\n oldlace: [253, 245, 230],\n olive: [128, 128, 0],\n olivedrab: [107, 142, 35],\n orange: [255, 165, 0],\n orangered: [255, 69, 0],\n orchid: [218, 112, 214],\n palegoldenrod: [238, 232, 170],\n palegreen: [152, 251, 152],\n paleturquoise: [175, 238, 238],\n palevioletred: [219, 112, 147],\n papayawhip: [255, 239, 213],\n peachpuff: [255, 218, 185],\n peru: [205, 133, 63],\n pink: [255, 192, 203],\n plum: [221, 160, 221],\n powderblue: [176, 224, 230],\n purple: [128, 0, 128],\n rebeccapurple: [102, 51, 153],\n red: [255, 0, 0],\n rosybrown: [188, 143, 143],\n royalblue: [65, 105, 225],\n saddlebrown: [139, 69, 19],\n salmon: [250, 128, 114],\n sandybrown: [244, 164, 96],\n seagreen: [46, 139, 87],\n seashell: [255, 245, 238],\n sienna: [160, 82, 45],\n silver: [192, 192, 192],\n skyblue: [135, 206, 235],\n slateblue: [106, 90, 205],\n slategray: [112, 128, 144],\n slategrey: [112, 128, 144],\n snow: [255, 250, 250],\n springgreen: [0, 255, 127],\n steelblue: [70, 130, 180],\n tan: [210, 180, 140],\n teal: [0, 128, 128],\n thistle: [216, 191, 216],\n tomato: [255, 99, 71],\n turquoise: [64, 224, 208],\n violet: [238, 130, 238],\n wheat: [245, 222, 179],\n white: [255, 255, 255],\n whitesmoke: [245, 245, 245],\n yellow: [255, 255, 0],\n yellowgreen: [154, 205, 50]\n};\nconst p = /* @__PURE__ */ w(b);\nvar m = {\n red: 0,\n orange: 60,\n yellow: 120,\n green: 180,\n blue: 240,\n purple: 300\n};\nfunction T(e) {\n var t, i = [], o = 1, n;\n if (typeof e == \"string\")\n if (e = e.toLowerCase(), p[e])\n i = p[e].slice(), n = \"rgb\";\n else if (e === \"transparent\")\n o = 0, n = \"rgb\", i = [0, 0, 0];\n else if (/^#[A-Fa-f0-9]+$/.test(e)) {\n var s = e.slice(1), a = s.length, h = a <= 4;\n o = 1, h ? (i = [\n parseInt(s[0] + s[0], 16),\n parseInt(s[1] + s[1], 16),\n parseInt(s[2] + s[2], 16)\n ], a === 4 && (o = parseInt(s[3] + s[3], 16) / 255)) : (i = [\n parseInt(s[0] + s[1], 16),\n parseInt(s[2] + s[3], 16),\n parseInt(s[4] + s[5], 16)\n ], a === 8 && (o = parseInt(s[6] + s[7], 16) / 255)), i[0] || (i[0] = 0), i[1] || (i[1] = 0), i[2] || (i[2] = 0), n = \"rgb\";\n } else if (t = /^((?:rgb|hs[lvb]|hwb|cmyk?|xy[zy]|gray|lab|lchu?v?|[ly]uv|lms)a?)\\s*\\(([^\\)]*)\\)/.exec(e)) {\n var l = t[1], f = l === \"rgb\", s = l.replace(/a$/, \"\");\n n = s;\n var a = s === \"cmyk\" ? 4 : s === \"gray\" ? 1 : 3;\n i = t[2].trim().split(/\\s*[,\\/]\\s*|\\s+/).map(function(r, u) {\n if (/%$/.test(r))\n return u === a ? parseFloat(r) / 100 : s === \"rgb\" ? parseFloat(r) * 255 / 100 : parseFloat(r);\n if (s[u] === \"h\") {\n if (/deg$/.test(r))\n return parseFloat(r);\n if (m[r] !== void 0)\n return m[r];\n }\n return parseFloat(r);\n }), l === s && i.push(1), o = f || i[a] === void 0 ? 1 : i[a], i = i.slice(0, a);\n } else\n e.length > 10 && /[0-9](?:\\s|\\/)/.test(e) && (i = e.match(/([0-9]+)/g).map(function(d) {\n return parseFloat(d);\n }), n = e.match(/([a-z])/ig).join(\"\").toLowerCase());\n else\n isNaN(e) ? Array.isArray(e) || e.length ? (i = [e[0], e[1], e[2]], n = \"rgb\", o = e.length === 4 ? e[3] : 1) : e instanceof Object && (e.r != null || e.red != null || e.R != null ? (n = \"rgb\", i = [\n e.r || e.red || e.R || 0,\n e.g || e.green || e.G || 0,\n e.b || e.blue || e.B || 0\n ]) : (n = \"hsl\", i = [\n e.h || e.hue || e.H || 0,\n e.s || e.saturation || e.S || 0,\n e.l || e.lightness || e.L || e.b || e.brightness\n ]), o = e.a || e.alpha || e.opacity || 1, e.opacity != null && (o /= 100)) : (n = \"rgb\", i = [e >>> 16, (e & 65280) >>> 8, e & 255]);\n return {\n space: n,\n values: i,\n alpha: o\n };\n}\nfunction S(e, t) {\n var i = T(e);\n return t == null && (t = i.alpha), i.space[0] === \"h\" ? i.space + [\"a(\", i.values[0], \",\", i.values[1], \"%,\", i.values[2], \"%,\", t, \")\"].join(\"\") : i.space + [\"a(\", i.values, \",\", t, \")\"].join(\"\");\n}\nclass R {\n constructor(t = \"yellow\", i = 8, o = 0.3) {\n this.width = i, this.color = S(t, 0.4);\n }\n /**\n * Draws a \"highlighter stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n draw(t, i) {\n const o = i[0];\n t.beginPath(), t.lineWidth = this.width, t.strokeStyle = this.color, t.lineCap = \"butt\", t.miterLimit = 1, t.moveTo(o.startPoint.x, o.startPoint.y), i.forEach((n) => {\n const { endPoint: s } = n;\n t.lineTo(s.x, s.y);\n }), t.stroke();\n }\n}\nexport {\n E as EraserTool,\n R as HighlighterTool,\n P as Manager,\n C as PenTool\n};\n//# sourceMappingURL=index.es.js.map\n","import {\r\n Manager,\r\n PenTool,\r\n EraserTool,\r\n HighlighterTool,\r\n} from \"../../dist/index.es\";\r\n\r\nwindow.onload = function () {\r\n const canvas = document.getElementById(\"canvas\");\r\n const redPenElem = document.getElementById(\"red-pen\");\r\n const bluePenElem = document.getElementById(\"blue-pen\");\r\n const eraserElem = document.getElementById(\"eraser\");\r\n const highlighterElem = document.getElementById(\"highlighter\");\r\n const clearElem = document.getElementById(\"clear\");\r\n\r\n if (\r\n !redPenElem ||\r\n !bluePenElem ||\r\n !eraserElem ||\r\n !highlighterElem ||\r\n !clearElem\r\n ) {\r\n throw new Error(\"Invalid elements\");\r\n }\r\n\r\n const width = 400;\r\n const height = 400;\r\n\r\n const manager = new Manager(canvas, width, height);\r\n\r\n const redPen = new PenTool(\"red\", 3);\r\n const bluePen = new PenTool(\"blue\", 8);\r\n const eraser = new EraserTool(20);\r\n const highlighterTool = new HighlighterTool(\"yellow\", 30);\r\n\r\n manager.setTool(redPen);\r\n\r\n redPenElem.onclick = function () {\r\n manager.setTool(redPen);\r\n };\r\n\r\n bluePenElem.onclick = function () {\r\n manager.setTool(bluePen);\r\n };\r\n\r\n eraserElem.onclick = function () {\r\n manager.setTool(eraser);\r\n };\r\n\r\n highlighterElem.onclick = function () {\r\n manager.setTool(highlighterTool);\r\n };\r\n\r\n clearElem.onclick = function () {\r\n manager.clear();\r\n };\r\n};\r\n"],"names":["g","y","o","k","n","P","h","C","E","l","f","v","c","w","b","p","m","T","S","R","canvas","redPenElem","bluePenElem","eraserElem","highlighterElem","clearElem","width","height","manager","Manager","redPen","PenTool","bluePen","eraser","EraserTool","highlighterTool","HighlighterTool"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"example.es.js","sources":["../../dist/index.es.js","../src/example.ts"],"sourcesContent":["function c(i, t) {\n return Math.sqrt(Math.pow(i.x - t.x, 2) + Math.pow(i.y - t.y, 2));\n}\nfunction k(i, t) {\n const e = c(i, t), s = {\n x: t.x - i.x,\n y: t.y - i.y\n };\n return {\n x: s.x / e,\n y: s.y / e\n };\n}\nclass w {\n constructor(t) {\n this.canvas = t, this.lastTouch = null, this.lastMouse = null, this.sensitivity = 20, this.lastStrokeParts = [], this.onStrokePartHandlers = [], this.onTouchStart = this.onTouchStart.bind(this), this.onTouchEnd = this.onTouchEnd.bind(this), this.onTouchCancel = this.onTouchCancel.bind(this), this.onTouchMove = this.onTouchMove.bind(this), this.destroy = this.destroy.bind(this), this.getRelativePosition = this.getRelativePosition.bind(this), this.onMouseDown = this.onMouseDown.bind(this), this.onMouseUp = this.onMouseUp.bind(this), this.onMouseMove = this.onMouseMove.bind(this), this.canvas.addEventListener(\"touchstart\", this.onTouchStart, {\n passive: !1\n }), this.canvas.addEventListener(\"touchend\", this.onTouchEnd, {\n passive: !1\n }), this.canvas.addEventListener(\"touchcancel\", this.onTouchCancel, {\n passive: !1\n }), this.canvas.addEventListener(\"touchmove\", this.onTouchMove, {\n passive: !1\n }), this.canvas.addEventListener(\"mousedown\", this.onMouseDown, {\n passive: !1\n }), document.addEventListener(\"mouseup\", this.onMouseUp, {\n passive: !1\n }), this.canvas.addEventListener(\"mousemove\", this.onMouseMove, {\n passive: !1\n });\n }\n /**\n * Registers a handler to be fired on a new stroke part\n * @param handler\n */\n onStrokePart(t) {\n this.onStrokePartHandlers.push(t);\n }\n /**\n * Removes all active listeners\n */\n destroy() {\n this.onStrokePartHandlers = [], this.lastStrokeParts = [], this.canvas.removeEventListener(\"touchstart\", this.onTouchStart), this.canvas.removeEventListener(\"touchend\", this.onTouchEnd), this.canvas.removeEventListener(\"touchcancel\", this.onTouchCancel), this.canvas.removeEventListener(\"touchmove\", this.onTouchMove), this.canvas.removeEventListener(\"mousedown\", this.onMouseDown), document.removeEventListener(\"mouseup\", this.onMouseUp), this.canvas.removeEventListener(\"mousemove\", this.onMouseMove);\n }\n /**\n * Get relative position to canvas\n * @param clientX\n * @param clientY\n * @returns IPoint\n */\n getRelativePosition(t, e) {\n const s = this.canvas.getBoundingClientRect();\n return {\n x: (t - s.left) / s.width,\n y: (e - s.top) / s.height\n };\n }\n /**\n * Creates a new touch if one does not\n * already exist\n * @param e\n */\n onTouchStart(t) {\n if (t.preventDefault(), this.lastTouch)\n return;\n const s = t.changedTouches.item(0);\n this.lastTouch = {\n id: s.identifier,\n position: this.getRelativePosition(s.clientX, s.clientY)\n };\n }\n /**\n * Creates a line from last touch to current touch\n * point and emits event. Does no-op if no existing touch\n * @param e\n */\n onTouchMove(t) {\n if (t.preventDefault(), !this.lastTouch)\n return;\n const e = t.changedTouches, s = Array.from(e).find((a) => a.identifier === this.lastTouch.id);\n if (!s)\n return;\n const n = {\n id: s.identifier,\n position: this.getRelativePosition(s.clientX, s.clientY)\n };\n if (this.sensitivity && c(n.position, this.lastTouch.position) < 10 / this.sensitivity)\n return;\n const o = {\n endPoint: n.position,\n startPoint: this.lastTouch.position,\n isStart: this.lastStrokeParts.length === 0,\n isEnd: !1\n };\n this.onStrokePartHandlers.forEach((a) => {\n a(o);\n }), this.lastTouch = n, this.lastStrokeParts.push(o);\n }\n /**\n * Draws a line from last point to final point. Removes\n * the reference to last touch point.\n * @param e\n */\n onTouchEnd(t) {\n if (t.preventDefault(), !this.lastTouch)\n return;\n const e = t.changedTouches, s = Array.from(e).find((a) => a.identifier === this.lastTouch.id);\n if (!s)\n return;\n const n = this.getRelativePosition(s.clientX, s.clientY), o = {\n startPoint: this.lastTouch.position,\n endPoint: n,\n isStart: !1,\n isEnd: !0\n };\n this.onStrokePartHandlers.forEach((a) => {\n a(o);\n }), this.lastTouch = null, this.lastStrokeParts = [];\n }\n /**\n * Removes the current last touch point\n * @param e\n */\n onTouchCancel(t) {\n t.preventDefault(), this.lastTouch = null, this.lastStrokeParts = [];\n }\n onMouseDown(t) {\n this.lastMouse || (this.lastMouse = this.getRelativePosition(t.clientX, t.clientY));\n }\n onMouseUp(t) {\n if (!this.lastMouse)\n return;\n let e = this.getRelativePosition(t.clientX, t.clientY);\n c(this.lastMouse, e) < 1 && (e = {\n x: this.lastMouse.x + 8e-4,\n y: this.lastMouse.y + 8e-4\n });\n const n = {\n startPoint: this.lastMouse,\n endPoint: e,\n isStart: !1,\n isEnd: !0\n };\n this.onStrokePartHandlers.forEach((o) => {\n o(n);\n }), this.lastMouse = null, this.lastStrokeParts = [];\n }\n onMouseMove(t) {\n if (!this.lastMouse)\n return;\n const e = this.getRelativePosition(t.clientX, t.clientY);\n if (this.sensitivity && c(e, this.lastMouse) < 0.05 / this.sensitivity)\n return;\n const s = {\n endPoint: e,\n startPoint: this.lastMouse,\n isStart: this.lastStrokeParts.length === 0,\n isEnd: !1\n };\n this.onStrokePartHandlers.forEach((n) => {\n n(s);\n }), this.lastMouse = e, this.lastStrokeParts.push(s);\n }\n}\nclass M {\n constructor(t, e, s) {\n this.canvas = t, this.ctx = t.getContext(\"2d\", { willReadFrequently: !0 }), this.canvasWidth = e, this.canvasHeight = s, this.currentTool = null, this.currentStroke = [], this.strokeManager = new w(t), this.canvasState = null, this.shouldDraw = !1, this.shouldCommit = !1;\n const n = this.ctx.backingStorePixelRatio || 1, o = window.devicePixelRatio || 1;\n this.pixelRatio = o / n, this.setCanvasSize = this.setCanvasSize.bind(this), this.setTool = this.setTool.bind(this), this.destroy = this.destroy.bind(this), this.clear = this.clear.bind(this), this.draw = this.draw.bind(this), this.onStrokePart = this.onStrokePart.bind(this), this.nextAnimationFrame = window.requestAnimationFrame(this.draw), this.strokeManager.onStrokePart(this.onStrokePart), this.setCanvasSize(e, s);\n }\n /**\n * Sets the canvas desired width and height and sets transform\n * for hifi displays\n * @param width\n * @param height\n */\n setCanvasSize(t, e) {\n this.canvasWidth = t, this.canvasHeight = e;\n const { ctx: s, canvas: n, canvasWidth: o, canvasHeight: a, pixelRatio: r } = this;\n s && (n.width = o * r, n.height = a * r, n.style.width = o + \"px\", n.style.height = a + \"px\", s.scale(r, r));\n }\n /**\n * Sets the current tool for the manager\n * @param tool\n */\n setTool(t) {\n this.currentTool = t;\n }\n /**\n * Remove all event listeners\n */\n destroy() {\n window.cancelAnimationFrame(this.nextAnimationFrame), this.strokeManager.destroy();\n }\n /**\n * Clears the canvas\n */\n clear() {\n this.canvasState = null, this.currentStroke = [], this.shouldDraw = !0, this.shouldCommit = !0;\n }\n /**\n * Adds a new stroke part to the nextStrokes\n * array\n * @param strokePart\n */\n onStrokePart(t) {\n this.currentStroke.push(t), this.shouldDraw = !0, t.isEnd && (this.shouldCommit = !0);\n }\n /**\n * Draws a frame\n */\n draw() {\n this.nextAnimationFrame = window.requestAnimationFrame(this.draw);\n const { ctx: t, canvasWidth: e, canvasHeight: s } = this;\n !this.shouldDraw || !t || (t.clearRect(0, 0, this.canvasWidth, this.canvasHeight), this.canvasState && t.putImageData(this.canvasState, 0, 0), this.currentTool && this.currentStroke.length && (t.save(), this.currentTool.draw(t, this.currentStroke, e, s), t.restore()), this.shouldCommit && (this.canvasState = t.getImageData(\n 0,\n 0,\n e * this.pixelRatio,\n s * this.pixelRatio\n ), this.currentStroke = [], this.shouldCommit = !1), this.shouldDraw = !1);\n }\n}\nclass E {\n constructor(t = \"red\", e = 3) {\n this.color = t, this.width = e;\n }\n /**\n * Draws a \"pen stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n draw(t, e, s, n) {\n const o = e[0];\n t.beginPath(), t.lineWidth = this.width, t.strokeStyle = this.color, t.lineCap = \"round\", t.lineJoin = \"round\", t.moveTo(\n o.startPoint.x * s,\n o.startPoint.y * n\n ), e.forEach((a) => {\n const { endPoint: r } = a;\n t.lineTo(r.x * s, r.y * n);\n }), t.stroke();\n }\n}\nclass C {\n constructor(t = 10, e) {\n this.width = t, e = e || {}, this.handleOpts = {\n hide: e.hide || !1,\n strokeWidth: e.strokeWidth || 2,\n fillColor: e.fillColor || \"white\",\n strokeColor: e.strokeColor || \"black\"\n };\n }\n /**\n * Draws an \"eraser stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n draw(t, e, s, n) {\n const { handleOpts: o } = this, a = this.width / 2;\n e.forEach((l) => {\n const { startPoint: d, endPoint: g } = l, y = c(d, g), h = k(d, g);\n let u = d, f = 0;\n for (; f < y; ) {\n const v = {\n x: u.x * s + h.x,\n y: u.y * n + h.y\n };\n t.clearRect(\n v.x - a,\n v.y - a,\n this.width,\n this.width\n ), f++, u = v;\n }\n });\n const r = e[e.length - 1];\n if (!r.isEnd && !o.hide) {\n t.strokeStyle = o.strokeColor, t.fillStyle = o.fillColor;\n const l = {\n x: r.endPoint.x * s,\n y: r.endPoint.y * n\n };\n t.fillRect(\n l.x - a,\n l.y - a,\n this.width,\n this.width\n ), t.strokeRect(\n l.x - a + 0.5,\n l.y - a + 0.5,\n this.width - 1,\n this.width - 1\n );\n }\n }\n}\nfunction b(i) {\n return i && i.__esModule && Object.prototype.hasOwnProperty.call(i, \"default\") ? i.default : i;\n}\nvar P = {\n aliceblue: [240, 248, 255],\n antiquewhite: [250, 235, 215],\n aqua: [0, 255, 255],\n aquamarine: [127, 255, 212],\n azure: [240, 255, 255],\n beige: [245, 245, 220],\n bisque: [255, 228, 196],\n black: [0, 0, 0],\n blanchedalmond: [255, 235, 205],\n blue: [0, 0, 255],\n blueviolet: [138, 43, 226],\n brown: [165, 42, 42],\n burlywood: [222, 184, 135],\n cadetblue: [95, 158, 160],\n chartreuse: [127, 255, 0],\n chocolate: [210, 105, 30],\n coral: [255, 127, 80],\n cornflowerblue: [100, 149, 237],\n cornsilk: [255, 248, 220],\n crimson: [220, 20, 60],\n cyan: [0, 255, 255],\n darkblue: [0, 0, 139],\n darkcyan: [0, 139, 139],\n darkgoldenrod: [184, 134, 11],\n darkgray: [169, 169, 169],\n darkgreen: [0, 100, 0],\n darkgrey: [169, 169, 169],\n darkkhaki: [189, 183, 107],\n darkmagenta: [139, 0, 139],\n darkolivegreen: [85, 107, 47],\n darkorange: [255, 140, 0],\n darkorchid: [153, 50, 204],\n darkred: [139, 0, 0],\n darksalmon: [233, 150, 122],\n darkseagreen: [143, 188, 143],\n darkslateblue: [72, 61, 139],\n darkslategray: [47, 79, 79],\n darkslategrey: [47, 79, 79],\n darkturquoise: [0, 206, 209],\n darkviolet: [148, 0, 211],\n deeppink: [255, 20, 147],\n deepskyblue: [0, 191, 255],\n dimgray: [105, 105, 105],\n dimgrey: [105, 105, 105],\n dodgerblue: [30, 144, 255],\n firebrick: [178, 34, 34],\n floralwhite: [255, 250, 240],\n forestgreen: [34, 139, 34],\n fuchsia: [255, 0, 255],\n gainsboro: [220, 220, 220],\n ghostwhite: [248, 248, 255],\n gold: [255, 215, 0],\n goldenrod: [218, 165, 32],\n gray: [128, 128, 128],\n green: [0, 128, 0],\n greenyellow: [173, 255, 47],\n grey: [128, 128, 128],\n honeydew: [240, 255, 240],\n hotpink: [255, 105, 180],\n indianred: [205, 92, 92],\n indigo: [75, 0, 130],\n ivory: [255, 255, 240],\n khaki: [240, 230, 140],\n lavender: [230, 230, 250],\n lavenderblush: [255, 240, 245],\n lawngreen: [124, 252, 0],\n lemonchiffon: [255, 250, 205],\n lightblue: [173, 216, 230],\n lightcoral: [240, 128, 128],\n lightcyan: [224, 255, 255],\n lightgoldenrodyellow: [250, 250, 210],\n lightgray: [211, 211, 211],\n lightgreen: [144, 238, 144],\n lightgrey: [211, 211, 211],\n lightpink: [255, 182, 193],\n lightsalmon: [255, 160, 122],\n lightseagreen: [32, 178, 170],\n lightskyblue: [135, 206, 250],\n lightslategray: [119, 136, 153],\n lightslategrey: [119, 136, 153],\n lightsteelblue: [176, 196, 222],\n lightyellow: [255, 255, 224],\n lime: [0, 255, 0],\n limegreen: [50, 205, 50],\n linen: [250, 240, 230],\n magenta: [255, 0, 255],\n maroon: [128, 0, 0],\n mediumaquamarine: [102, 205, 170],\n mediumblue: [0, 0, 205],\n mediumorchid: [186, 85, 211],\n mediumpurple: [147, 112, 219],\n mediumseagreen: [60, 179, 113],\n mediumslateblue: [123, 104, 238],\n mediumspringgreen: [0, 250, 154],\n mediumturquoise: [72, 209, 204],\n mediumvioletred: [199, 21, 133],\n midnightblue: [25, 25, 112],\n mintcream: [245, 255, 250],\n mistyrose: [255, 228, 225],\n moccasin: [255, 228, 181],\n navajowhite: [255, 222, 173],\n navy: [0, 0, 128],\n oldlace: [253, 245, 230],\n olive: [128, 128, 0],\n olivedrab: [107, 142, 35],\n orange: [255, 165, 0],\n orangered: [255, 69, 0],\n orchid: [218, 112, 214],\n palegoldenrod: [238, 232, 170],\n palegreen: [152, 251, 152],\n paleturquoise: [175, 238, 238],\n palevioletred: [219, 112, 147],\n papayawhip: [255, 239, 213],\n peachpuff: [255, 218, 185],\n peru: [205, 133, 63],\n pink: [255, 192, 203],\n plum: [221, 160, 221],\n powderblue: [176, 224, 230],\n purple: [128, 0, 128],\n rebeccapurple: [102, 51, 153],\n red: [255, 0, 0],\n rosybrown: [188, 143, 143],\n royalblue: [65, 105, 225],\n saddlebrown: [139, 69, 19],\n salmon: [250, 128, 114],\n sandybrown: [244, 164, 96],\n seagreen: [46, 139, 87],\n seashell: [255, 245, 238],\n sienna: [160, 82, 45],\n silver: [192, 192, 192],\n skyblue: [135, 206, 235],\n slateblue: [106, 90, 205],\n slategray: [112, 128, 144],\n slategrey: [112, 128, 144],\n snow: [255, 250, 250],\n springgreen: [0, 255, 127],\n steelblue: [70, 130, 180],\n tan: [210, 180, 140],\n teal: [0, 128, 128],\n thistle: [216, 191, 216],\n tomato: [255, 99, 71],\n turquoise: [64, 224, 208],\n violet: [238, 130, 238],\n wheat: [245, 222, 179],\n white: [255, 255, 255],\n whitesmoke: [245, 245, 245],\n yellow: [255, 255, 0],\n yellowgreen: [154, 205, 50]\n};\nconst p = /* @__PURE__ */ b(P);\nvar m = {\n red: 0,\n orange: 60,\n yellow: 120,\n green: 180,\n blue: 240,\n purple: 300\n};\nfunction S(i) {\n var t, e = [], s = 1, n;\n if (typeof i == \"string\")\n if (i = i.toLowerCase(), p[i])\n e = p[i].slice(), n = \"rgb\";\n else if (i === \"transparent\")\n s = 0, n = \"rgb\", e = [0, 0, 0];\n else if (/^#[A-Fa-f0-9]+$/.test(i)) {\n var o = i.slice(1), a = o.length, r = a <= 4;\n s = 1, r ? (e = [\n parseInt(o[0] + o[0], 16),\n parseInt(o[1] + o[1], 16),\n parseInt(o[2] + o[2], 16)\n ], a === 4 && (s = parseInt(o[3] + o[3], 16) / 255)) : (e = [\n parseInt(o[0] + o[1], 16),\n parseInt(o[2] + o[3], 16),\n parseInt(o[4] + o[5], 16)\n ], a === 8 && (s = parseInt(o[6] + o[7], 16) / 255)), e[0] || (e[0] = 0), e[1] || (e[1] = 0), e[2] || (e[2] = 0), n = \"rgb\";\n } else if (t = /^((?:rgb|hs[lvb]|hwb|cmyk?|xy[zy]|gray|lab|lchu?v?|[ly]uv|lms)a?)\\s*\\(([^\\)]*)\\)/.exec(i)) {\n var l = t[1], d = l === \"rgb\", o = l.replace(/a$/, \"\");\n n = o;\n var a = o === \"cmyk\" ? 4 : o === \"gray\" ? 1 : 3;\n e = t[2].trim().split(/\\s*[,\\/]\\s*|\\s+/).map(function(h, u) {\n if (/%$/.test(h))\n return u === a ? parseFloat(h) / 100 : o === \"rgb\" ? parseFloat(h) * 255 / 100 : parseFloat(h);\n if (o[u] === \"h\") {\n if (/deg$/.test(h))\n return parseFloat(h);\n if (m[h] !== void 0)\n return m[h];\n }\n return parseFloat(h);\n }), l === o && e.push(1), s = d || e[a] === void 0 ? 1 : e[a], e = e.slice(0, a);\n } else\n i.length > 10 && /[0-9](?:\\s|\\/)/.test(i) && (e = i.match(/([0-9]+)/g).map(function(g) {\n return parseFloat(g);\n }), n = i.match(/([a-z])/ig).join(\"\").toLowerCase());\n else\n isNaN(i) ? Array.isArray(i) || i.length ? (e = [i[0], i[1], i[2]], n = \"rgb\", s = i.length === 4 ? i[3] : 1) : i instanceof Object && (i.r != null || i.red != null || i.R != null ? (n = \"rgb\", e = [\n i.r || i.red || i.R || 0,\n i.g || i.green || i.G || 0,\n i.b || i.blue || i.B || 0\n ]) : (n = \"hsl\", e = [\n i.h || i.hue || i.H || 0,\n i.s || i.saturation || i.S || 0,\n i.l || i.lightness || i.L || i.b || i.brightness\n ]), s = i.a || i.alpha || i.opacity || 1, i.opacity != null && (s /= 100)) : (n = \"rgb\", e = [i >>> 16, (i & 65280) >>> 8, i & 255]);\n return {\n space: n,\n values: e,\n alpha: s\n };\n}\nfunction T(i, t) {\n var e = S(i);\n return t == null && (t = e.alpha), e.space[0] === \"h\" ? e.space + [\"a(\", e.values[0], \",\", e.values[1], \"%,\", e.values[2], \"%,\", t, \")\"].join(\"\") : e.space + [\"a(\", e.values, \",\", t, \")\"].join(\"\");\n}\nclass R {\n constructor(t = \"yellow\", e = 8, s = 0.3) {\n this.width = e, this.color = T(t, 0.4);\n }\n /**\n * Draws a \"highlighter stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n draw(t, e, s, n) {\n const o = e[0];\n t.beginPath(), t.lineWidth = this.width, t.strokeStyle = this.color, t.lineCap = \"butt\", t.miterLimit = 1, t.moveTo(\n o.startPoint.x * s,\n o.startPoint.y * n\n ), e.forEach((a) => {\n const { endPoint: r } = a;\n t.lineTo(r.x * s, r.y * n);\n }), t.stroke();\n }\n}\nexport {\n C as EraserTool,\n R as HighlighterTool,\n M as Manager,\n E as PenTool\n};\n//# sourceMappingURL=index.es.js.map\n","import {\n Manager,\n PenTool,\n EraserTool,\n HighlighterTool,\n} from \"../../dist/index.es\";\n\nwindow.onload = function () {\n const canvas = document.getElementById(\"canvas\");\n const redPenElem = document.getElementById(\"red-pen\");\n const bluePenElem = document.getElementById(\"blue-pen\");\n const eraserElem = document.getElementById(\"eraser\");\n const highlighterElem = document.getElementById(\"highlighter\");\n const clearElem = document.getElementById(\"clear\");\n\n if (\n !redPenElem ||\n !bluePenElem ||\n !eraserElem ||\n !highlighterElem ||\n !clearElem\n ) {\n throw new Error(\"Invalid elements\");\n }\n\n const width = 400;\n const height = 400;\n\n const manager = new Manager(canvas, width, height);\n\n const redPen = new PenTool(\"red\", 3);\n const bluePen = new PenTool(\"blue\", 8);\n const eraser = new EraserTool(20);\n const highlighterTool = new HighlighterTool(\"yellow\", 30);\n\n manager.setTool(redPen);\n\n redPenElem.onclick = function () {\n manager.setTool(redPen);\n };\n\n bluePenElem.onclick = function () {\n manager.setTool(bluePen);\n };\n\n eraserElem.onclick = function () {\n manager.setTool(eraser);\n };\n\n highlighterElem.onclick = function () {\n manager.setTool(highlighterTool);\n };\n\n clearElem.onclick = function () {\n manager.clear();\n };\n};\n"],"names":["c","i","k","s","w","n","o","M","E","C","l","d","g","y","h","u","f","v","b","P","p","m","S","T","R","canvas","redPenElem","bluePenElem","eraserElem","highlighterElem","clearElem","width","height","manager","Manager","redPen","PenTool","bluePen","eraser","EraserTool","highlighterTool","HighlighterTool"],"mappings":"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"} \ No newline at end of file diff --git a/example/build/example.umd.js b/example/build/example.umd.js index 33ba8c3..c822752 100644 --- a/example/build/example.umd.js +++ b/example/build/example.umd.js @@ -1,2 +1,2 @@ -(function(c){typeof define=="function"&&define.amd?define(c):c()})(function(){"use strict";function c(e,t){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}function w(e,t){const i=c(e,t),n={x:t.x-e.x,y:t.y-e.y};return{x:n.x/i,y:n.y/i}}class b{constructor(t){this.canvas=t,this.lastTouch=null,this.sensitivity=20,this.lastStrokeParts=[],this.onStrokePartHandlers=[],this.onTouchStart=this.onTouchStart.bind(this),this.onTouchEnd=this.onTouchEnd.bind(this),this.onTouchCancel=this.onTouchCancel.bind(this),this.onTouchMove=this.onTouchMove.bind(this),this.destroy=this.destroy.bind(this),this.getRelativePosition=this.getRelativePosition.bind(this),this.canvas.addEventListener("touchstart",this.onTouchStart,{passive:!1}),this.canvas.addEventListener("touchend",this.onTouchEnd,{passive:!1}),this.canvas.addEventListener("touchcancel",this.onTouchCancel,{passive:!1}),this.canvas.addEventListener("touchmove",this.onTouchMove,{passive:!1})}onStrokePart(t){this.onStrokePartHandlers.push(t)}destroy(){this.onStrokePartHandlers=[],this.lastStrokeParts=[],this.canvas.removeEventListener("touchstart",this.onTouchStart),this.canvas.removeEventListener("touchend",this.onTouchEnd),this.canvas.removeEventListener("touchcancel",this.onTouchCancel),this.canvas.removeEventListener("touchmove",this.onTouchMove)}getRelativePosition(t,i){const n=this.canvas.getBoundingClientRect();return{x:t-n.left,y:i-n.top}}onTouchStart(t){if(t.preventDefault(),this.lastTouch)return;const i=t.changedTouches.item(0);this.lastTouch={id:i.identifier,position:this.getRelativePosition(i.clientX,i.clientY)}}onTouchMove(t){if(t.preventDefault(),!this.lastTouch)return;const i=t.changedTouches,n=Array.from(i).find(a=>a.identifier===this.lastTouch.id);if(!n)return;const o={id:n.identifier,position:this.getRelativePosition(n.clientX,n.clientY)};if(this.sensitivity&&c(o.position,this.lastTouch.position)<10/this.sensitivity)return;const s={endPoint:o.position,startPoint:this.lastTouch.position,isStart:this.lastStrokeParts.length===0,isEnd:!1};this.onStrokePartHandlers.forEach(a=>{a(s)}),this.lastTouch=o,this.lastStrokeParts.push(s)}onTouchEnd(t){if(t.preventDefault(),!this.lastTouch)return;const i=t.changedTouches,n=Array.from(i).find(a=>a.identifier===this.lastTouch.id);if(!n)return;const o=this.getRelativePosition(n.clientX,n.clientY),s={startPoint:this.lastTouch.position,endPoint:o,isStart:!1,isEnd:!0};this.onStrokePartHandlers.forEach(a=>{a(s)}),this.lastTouch=null,this.lastStrokeParts=[]}onTouchCancel(t){t.preventDefault(),this.lastTouch=null,this.lastStrokeParts=[]}}class f{constructor(t,i,n){this.canvas=t,this.canvasWidth=i,this.canvasHeight=n,this.currentTool=null,this.currentStroke=[],this.strokeManager=new b(t),this.canvasState=null,this.shouldDraw=!1,this.shouldCommit=!1;const o=t.getContext("2d").backingStorePixelRatio||1,s=window.devicePixelRatio||1;this.pixelRatio=s/o,this.setCanvasSize=this.setCanvasSize.bind(this),this.setTool=this.setTool.bind(this),this.destroy=this.destroy.bind(this),this.clear=this.clear.bind(this),this.draw=this.draw.bind(this),this.onStrokePart=this.onStrokePart.bind(this),this.nextAnimationFrame=window.requestAnimationFrame(this.draw),this.strokeManager.onStrokePart(this.onStrokePart),this.setCanvasSize(i,n)}setCanvasSize(t,i){this.canvasWidth=t,this.canvasHeight=i;const{canvas:n,canvasWidth:o,canvasHeight:s,pixelRatio:a}=this,l=n.getContext("2d");n.width=o*a,n.height=s*a,n.style.width=o+"px",n.style.height=s+"px",l.setTransform(a,0,0,a,0,0)}setTool(t){this.currentTool=t}destroy(){window.cancelAnimationFrame(this.nextAnimationFrame),this.strokeManager.destroy()}clear(){this.canvasState=null,this.currentStroke=[],this.shouldDraw=!0,this.shouldCommit=!0}onStrokePart(t){this.currentStroke.push(t),this.shouldDraw=!0,t.isEnd&&(this.shouldCommit=!0)}draw(){this.nextAnimationFrame=window.requestAnimationFrame(this.draw);const t=this.canvas.getContext("2d");this.shouldDraw&&(t.clearRect(0,0,this.canvasWidth,this.canvasHeight),this.canvasState&&t.putImageData(this.canvasState,0,0),this.currentTool&&this.currentStroke.length&&(t.save(),this.currentTool.draw(t,this.currentStroke),t.restore()),this.shouldCommit&&(this.canvasState=t.getImageData(0,0,this.canvasWidth*this.pixelRatio,this.canvasHeight*this.pixelRatio),this.currentStroke=[],this.shouldCommit=!1),this.shouldDraw=!1)}}class p{constructor(t="red",i=3){this.color=t,this.width=i}draw(t,i){const n=i[0];t.beginPath(),t.lineWidth=this.width,t.strokeStyle=this.color,t.lineCap="round",t.lineJoin="round",t.moveTo(n.startPoint.x,n.startPoint.y),i.forEach(o=>{const{endPoint:s}=o;t.lineTo(s.x,s.y)}),t.stroke()}}class T{constructor(t=10,i){this.width=t,i=i||{},this.handleOpts={hide:i.hide||!1,strokeWidth:i.strokeWidth||2,fillColor:i.fillColor||"white",strokeColor:i.strokeColor||"black"}}draw(t,i){const{handleOpts:n}=this,o=this.width/2;i.forEach(a=>{const{startPoint:l,endPoint:h,isEnd:d}=a,u=c(l,h),m=w(l,h);let r=l,g=0;for(;g10&&/[0-9](?:\s|\/)/.test(e)&&(i=e.match(/([0-9]+)/g).map(function(u){return parseFloat(u)}),o=e.match(/([a-z])/ig).join("").toLowerCase());else isNaN(e)?Array.isArray(e)||e.length?(i=[e[0],e[1],e[2]],o="rgb",n=e.length===4?e[3]:1):e instanceof Object&&(e.r!=null||e.red!=null||e.R!=null?(o="rgb",i=[e.r||e.red||e.R||0,e.g||e.green||e.G||0,e.b||e.blue||e.B||0]):(o="hsl",i=[e.h||e.hue||e.H||0,e.s||e.saturation||e.S||0,e.l||e.lightness||e.L||e.b||e.brightness]),n=e.a||e.alpha||e.opacity||1,e.opacity!=null&&(n/=100)):(o="rgb",i=[e>>>16,(e&65280)>>>8,e&255]);return{space:o,values:i,alpha:n}}function x(e,t){var i=E(e);return t==null&&(t=i.alpha),i.space[0]==="h"?i.space+["a(",i.values[0],",",i.values[1],"%,",i.values[2],"%,",t,")"].join(""):i.space+["a(",i.values,",",t,")"].join("")}class C{constructor(t="yellow",i=8,n=.3){this.width=i,this.color=x(t,.4)}draw(t,i){const n=i[0];t.beginPath(),t.lineWidth=this.width,t.strokeStyle=this.color,t.lineCap="butt",t.miterLimit=1,t.moveTo(n.startPoint.x,n.startPoint.y),i.forEach(o=>{const{endPoint:s}=o;t.lineTo(s.x,s.y)}),t.stroke()}}window.onload=function(){const e=document.getElementById("canvas"),t=document.getElementById("red-pen"),i=document.getElementById("blue-pen"),n=document.getElementById("eraser"),o=document.getElementById("highlighter"),s=document.getElementById("clear");if(!t||!i||!n||!o||!s)throw new Error("Invalid elements");const a=400,l=400,h=new f(e,a,l),d=new p("red",3),u=new p("blue",8),m=new T(20),r=new C("yellow",30);h.setTool(d),t.onclick=function(){h.setTool(d)},i.onclick=function(){h.setTool(u)},n.onclick=function(){h.setTool(m)},o.onclick=function(){h.setTool(r)},s.onclick=function(){h.clear()}}}); +(function(c){typeof define=="function"&&define.amd?define(c):c()})(function(){"use strict";function c(s,t){return Math.sqrt(Math.pow(s.x-t.x,2)+Math.pow(s.y-t.y,2))}function f(s,t){const e=c(s,t),i={x:t.x-s.x,y:t.y-s.y};return{x:i.x/e,y:i.y/e}}class b{constructor(t){this.canvas=t,this.lastTouch=null,this.lastMouse=null,this.sensitivity=20,this.lastStrokeParts=[],this.onStrokePartHandlers=[],this.onTouchStart=this.onTouchStart.bind(this),this.onTouchEnd=this.onTouchEnd.bind(this),this.onTouchCancel=this.onTouchCancel.bind(this),this.onTouchMove=this.onTouchMove.bind(this),this.destroy=this.destroy.bind(this),this.getRelativePosition=this.getRelativePosition.bind(this),this.onMouseDown=this.onMouseDown.bind(this),this.onMouseUp=this.onMouseUp.bind(this),this.onMouseMove=this.onMouseMove.bind(this),this.canvas.addEventListener("touchstart",this.onTouchStart,{passive:!1}),this.canvas.addEventListener("touchend",this.onTouchEnd,{passive:!1}),this.canvas.addEventListener("touchcancel",this.onTouchCancel,{passive:!1}),this.canvas.addEventListener("touchmove",this.onTouchMove,{passive:!1}),this.canvas.addEventListener("mousedown",this.onMouseDown,{passive:!1}),document.addEventListener("mouseup",this.onMouseUp,{passive:!1}),this.canvas.addEventListener("mousemove",this.onMouseMove,{passive:!1})}onStrokePart(t){this.onStrokePartHandlers.push(t)}destroy(){this.onStrokePartHandlers=[],this.lastStrokeParts=[],this.canvas.removeEventListener("touchstart",this.onTouchStart),this.canvas.removeEventListener("touchend",this.onTouchEnd),this.canvas.removeEventListener("touchcancel",this.onTouchCancel),this.canvas.removeEventListener("touchmove",this.onTouchMove),this.canvas.removeEventListener("mousedown",this.onMouseDown),document.removeEventListener("mouseup",this.onMouseUp),this.canvas.removeEventListener("mousemove",this.onMouseMove)}getRelativePosition(t,e){const i=this.canvas.getBoundingClientRect();return{x:(t-i.left)/i.width,y:(e-i.top)/i.height}}onTouchStart(t){if(t.preventDefault(),this.lastTouch)return;const e=t.changedTouches.item(0);this.lastTouch={id:e.identifier,position:this.getRelativePosition(e.clientX,e.clientY)}}onTouchMove(t){if(t.preventDefault(),!this.lastTouch)return;const e=t.changedTouches,i=Array.from(e).find(a=>a.identifier===this.lastTouch.id);if(!i)return;const o={id:i.identifier,position:this.getRelativePosition(i.clientX,i.clientY)};if(this.sensitivity&&c(o.position,this.lastTouch.position)<10/this.sensitivity)return;const n={endPoint:o.position,startPoint:this.lastTouch.position,isStart:this.lastStrokeParts.length===0,isEnd:!1};this.onStrokePartHandlers.forEach(a=>{a(n)}),this.lastTouch=o,this.lastStrokeParts.push(n)}onTouchEnd(t){if(t.preventDefault(),!this.lastTouch)return;const e=t.changedTouches,i=Array.from(e).find(a=>a.identifier===this.lastTouch.id);if(!i)return;const o=this.getRelativePosition(i.clientX,i.clientY),n={startPoint:this.lastTouch.position,endPoint:o,isStart:!1,isEnd:!0};this.onStrokePartHandlers.forEach(a=>{a(n)}),this.lastTouch=null,this.lastStrokeParts=[]}onTouchCancel(t){t.preventDefault(),this.lastTouch=null,this.lastStrokeParts=[]}onMouseDown(t){this.lastMouse||(this.lastMouse=this.getRelativePosition(t.clientX,t.clientY))}onMouseUp(t){if(!this.lastMouse)return;let e=this.getRelativePosition(t.clientX,t.clientY);c(this.lastMouse,e)<1&&(e={x:this.lastMouse.x+8e-4,y:this.lastMouse.y+8e-4});const i={startPoint:this.lastMouse,endPoint:e,isStart:!1,isEnd:!0};this.onStrokePartHandlers.forEach(o=>{o(i)}),this.lastMouse=null,this.lastStrokeParts=[]}onMouseMove(t){if(!this.lastMouse)return;const e=this.getRelativePosition(t.clientX,t.clientY);if(this.sensitivity&&c(e,this.lastMouse)<.05/this.sensitivity)return;const i={endPoint:e,startPoint:this.lastMouse,isStart:this.lastStrokeParts.length===0,isEnd:!1};this.onStrokePartHandlers.forEach(o=>{o(i)}),this.lastMouse=e,this.lastStrokeParts.push(i)}}class P{constructor(t,e,i){this.canvas=t,this.ctx=t.getContext("2d",{willReadFrequently:!0}),this.canvasWidth=e,this.canvasHeight=i,this.currentTool=null,this.currentStroke=[],this.strokeManager=new b(t),this.canvasState=null,this.shouldDraw=!1,this.shouldCommit=!1;const o=this.ctx.backingStorePixelRatio||1,n=window.devicePixelRatio||1;this.pixelRatio=n/o,this.setCanvasSize=this.setCanvasSize.bind(this),this.setTool=this.setTool.bind(this),this.destroy=this.destroy.bind(this),this.clear=this.clear.bind(this),this.draw=this.draw.bind(this),this.onStrokePart=this.onStrokePart.bind(this),this.nextAnimationFrame=window.requestAnimationFrame(this.draw),this.strokeManager.onStrokePart(this.onStrokePart),this.setCanvasSize(e,i)}setCanvasSize(t,e){this.canvasWidth=t,this.canvasHeight=e;const{ctx:i,canvas:o,canvasWidth:n,canvasHeight:a,pixelRatio:r}=this;i&&(o.width=n*r,o.height=a*r,o.style.width=n+"px",o.style.height=a+"px",i.scale(r,r))}setTool(t){this.currentTool=t}destroy(){window.cancelAnimationFrame(this.nextAnimationFrame),this.strokeManager.destroy()}clear(){this.canvasState=null,this.currentStroke=[],this.shouldDraw=!0,this.shouldCommit=!0}onStrokePart(t){this.currentStroke.push(t),this.shouldDraw=!0,t.isEnd&&(this.shouldCommit=!0)}draw(){this.nextAnimationFrame=window.requestAnimationFrame(this.draw);const{ctx:t,canvasWidth:e,canvasHeight:i}=this;!this.shouldDraw||!t||(t.clearRect(0,0,this.canvasWidth,this.canvasHeight),this.canvasState&&t.putImageData(this.canvasState,0,0),this.currentTool&&this.currentStroke.length&&(t.save(),this.currentTool.draw(t,this.currentStroke,e,i),t.restore()),this.shouldCommit&&(this.canvasState=t.getImageData(0,0,e*this.pixelRatio,i*this.pixelRatio),this.currentStroke=[],this.shouldCommit=!1),this.shouldDraw=!1)}}class p{constructor(t="red",e=3){this.color=t,this.width=e}draw(t,e,i,o){const n=e[0];t.beginPath(),t.lineWidth=this.width,t.strokeStyle=this.color,t.lineCap="round",t.lineJoin="round",t.moveTo(n.startPoint.x*i,n.startPoint.y*o),e.forEach(a=>{const{endPoint:r}=a;t.lineTo(r.x*i,r.y*o)}),t.stroke()}}class T{constructor(t=10,e){this.width=t,e=e||{},this.handleOpts={hide:e.hide||!1,strokeWidth:e.strokeWidth||2,fillColor:e.fillColor||"white",strokeColor:e.strokeColor||"black"}}draw(t,e,i,o){const{handleOpts:n}=this,a=this.width/2;e.forEach(h=>{const{startPoint:u,endPoint:d}=h,v=c(u,d),l=f(u,d);let g=u,k=0;for(;k10&&/[0-9](?:\s|\/)/.test(s)&&(e=s.match(/([0-9]+)/g).map(function(d){return parseFloat(d)}),o=s.match(/([a-z])/ig).join("").toLowerCase());else isNaN(s)?Array.isArray(s)||s.length?(e=[s[0],s[1],s[2]],o="rgb",i=s.length===4?s[3]:1):s instanceof Object&&(s.r!=null||s.red!=null||s.R!=null?(o="rgb",e=[s.r||s.red||s.R||0,s.g||s.green||s.G||0,s.b||s.blue||s.B||0]):(o="hsl",e=[s.h||s.hue||s.H||0,s.s||s.saturation||s.S||0,s.l||s.lightness||s.L||s.b||s.brightness]),i=s.a||s.alpha||s.opacity||1,s.opacity!=null&&(i/=100)):(o="rgb",e=[s>>>16,(s&65280)>>>8,s&255]);return{space:o,values:e,alpha:i}}function x(s,t){var e=E(s);return t==null&&(t=e.alpha),e.space[0]==="h"?e.space+["a(",e.values[0],",",e.values[1],"%,",e.values[2],"%,",t,")"].join(""):e.space+["a(",e.values,",",t,")"].join("")}class C{constructor(t="yellow",e=8,i=.3){this.width=e,this.color=x(t,.4)}draw(t,e,i,o){const n=e[0];t.beginPath(),t.lineWidth=this.width,t.strokeStyle=this.color,t.lineCap="butt",t.miterLimit=1,t.moveTo(n.startPoint.x*i,n.startPoint.y*o),e.forEach(a=>{const{endPoint:r}=a;t.lineTo(r.x*i,r.y*o)}),t.stroke()}}window.onload=function(){const s=document.getElementById("canvas"),t=document.getElementById("red-pen"),e=document.getElementById("blue-pen"),i=document.getElementById("eraser"),o=document.getElementById("highlighter"),n=document.getElementById("clear");if(!t||!e||!i||!o||!n)throw new Error("Invalid elements");const a=400,r=400,h=new P(s,a,r),u=new p("red",3),d=new p("blue",8),v=new T(20),l=new C("yellow",30);h.setTool(u),t.onclick=function(){h.setTool(u)},e.onclick=function(){h.setTool(d)},i.onclick=function(){h.setTool(v)},o.onclick=function(){h.setTool(l)},n.onclick=function(){h.clear()}}}); //# sourceMappingURL=example.umd.js.map diff --git a/example/build/example.umd.js.map b/example/build/example.umd.js.map index ceecc89..cfa61c9 100644 --- a/example/build/example.umd.js.map +++ b/example/build/example.umd.js.map @@ -1 +1 @@ -{"version":3,"file":"example.umd.js","sources":["../../dist/index.es.js","../src/example.ts"],"sourcesContent":["function g(e, t) {\n return Math.sqrt(Math.pow(e.x - t.x, 2) + Math.pow(e.y - t.y, 2));\n}\nfunction y(e, t) {\n const i = g(e, t), o = {\n x: t.x - e.x,\n y: t.y - e.y\n };\n return {\n x: o.x / i,\n y: o.y / i\n };\n}\nclass k {\n constructor(t) {\n this.canvas = t, this.lastTouch = null, this.sensitivity = 20, this.lastStrokeParts = [], this.onStrokePartHandlers = [], this.onTouchStart = this.onTouchStart.bind(this), this.onTouchEnd = this.onTouchEnd.bind(this), this.onTouchCancel = this.onTouchCancel.bind(this), this.onTouchMove = this.onTouchMove.bind(this), this.destroy = this.destroy.bind(this), this.getRelativePosition = this.getRelativePosition.bind(this), this.canvas.addEventListener(\"touchstart\", this.onTouchStart, {\n passive: !1\n }), this.canvas.addEventListener(\"touchend\", this.onTouchEnd, {\n passive: !1\n }), this.canvas.addEventListener(\"touchcancel\", this.onTouchCancel, {\n passive: !1\n }), this.canvas.addEventListener(\"touchmove\", this.onTouchMove, {\n passive: !1\n });\n }\n /**\n * Registers a handler to be fired on a new stroke part\n * @param handler\n */\n onStrokePart(t) {\n this.onStrokePartHandlers.push(t);\n }\n /**\n * Removes all active listeners\n */\n destroy() {\n this.onStrokePartHandlers = [], this.lastStrokeParts = [], this.canvas.removeEventListener(\"touchstart\", this.onTouchStart), this.canvas.removeEventListener(\"touchend\", this.onTouchEnd), this.canvas.removeEventListener(\"touchcancel\", this.onTouchCancel), this.canvas.removeEventListener(\"touchmove\", this.onTouchMove);\n }\n /**\n * Get relative position to canvas\n * @param clientX\n * @param clientY\n * @returns IPoint\n */\n getRelativePosition(t, i) {\n const o = this.canvas.getBoundingClientRect();\n return {\n x: t - o.left,\n y: i - o.top\n };\n }\n /**\n * Creates a new touch if one does not\n * already exist\n * @param e\n */\n onTouchStart(t) {\n if (t.preventDefault(), this.lastTouch)\n return;\n const o = t.changedTouches.item(0);\n this.lastTouch = {\n id: o.identifier,\n position: this.getRelativePosition(o.clientX, o.clientY)\n };\n }\n /**\n * Creates a line from last touch to current touch\n * point and emits event. Does no-op if no existing touch\n * @param e\n */\n onTouchMove(t) {\n if (t.preventDefault(), !this.lastTouch)\n return;\n const i = t.changedTouches, o = Array.from(i).find((a) => a.identifier === this.lastTouch.id);\n if (!o)\n return;\n const n = {\n id: o.identifier,\n position: this.getRelativePosition(o.clientX, o.clientY)\n };\n if (this.sensitivity && g(n.position, this.lastTouch.position) < 10 / this.sensitivity)\n return;\n const s = {\n endPoint: n.position,\n startPoint: this.lastTouch.position,\n isStart: this.lastStrokeParts.length === 0,\n isEnd: !1\n };\n this.onStrokePartHandlers.forEach((a) => {\n a(s);\n }), this.lastTouch = n, this.lastStrokeParts.push(s);\n }\n /**\n * Draws a line from last point to final point. Removes\n * the reference to last touch point.\n * @param e\n */\n onTouchEnd(t) {\n if (t.preventDefault(), !this.lastTouch)\n return;\n const i = t.changedTouches, o = Array.from(i).find((a) => a.identifier === this.lastTouch.id);\n if (!o)\n return;\n const n = this.getRelativePosition(o.clientX, o.clientY), s = {\n startPoint: this.lastTouch.position,\n endPoint: n,\n isStart: !1,\n isEnd: !0\n };\n this.onStrokePartHandlers.forEach((a) => {\n a(s);\n }), this.lastTouch = null, this.lastStrokeParts = [];\n }\n /**\n * Removes the current last touch point\n * @param e\n */\n onTouchCancel(t) {\n t.preventDefault(), this.lastTouch = null, this.lastStrokeParts = [];\n }\n}\nclass P {\n constructor(t, i, o) {\n this.canvas = t, this.canvasWidth = i, this.canvasHeight = o, this.currentTool = null, this.currentStroke = [], this.strokeManager = new k(t), this.canvasState = null, this.shouldDraw = !1, this.shouldCommit = !1;\n const n = t.getContext(\"2d\").backingStorePixelRatio || 1, s = window.devicePixelRatio || 1;\n this.pixelRatio = s / n, this.setCanvasSize = this.setCanvasSize.bind(this), this.setTool = this.setTool.bind(this), this.destroy = this.destroy.bind(this), this.clear = this.clear.bind(this), this.draw = this.draw.bind(this), this.onStrokePart = this.onStrokePart.bind(this), this.nextAnimationFrame = window.requestAnimationFrame(this.draw), this.strokeManager.onStrokePart(this.onStrokePart), this.setCanvasSize(i, o);\n }\n /**\n * Sets the canvas desired width and height and sets transform\n * for hifi displays\n * @param width\n * @param height\n */\n setCanvasSize(t, i) {\n this.canvasWidth = t, this.canvasHeight = i;\n const { canvas: o, canvasWidth: n, canvasHeight: s, pixelRatio: a } = this, h = o.getContext(\"2d\");\n o.width = n * a, o.height = s * a, o.style.width = n + \"px\", o.style.height = s + \"px\", h.setTransform(a, 0, 0, a, 0, 0);\n }\n /**\n * Sets the current tool for the manager\n * @param tool\n */\n setTool(t) {\n this.currentTool = t;\n }\n /**\n * Remove all event listeners\n */\n destroy() {\n window.cancelAnimationFrame(this.nextAnimationFrame), this.strokeManager.destroy();\n }\n /**\n * Clears the canvas\n */\n clear() {\n this.canvasState = null, this.currentStroke = [], this.shouldDraw = !0, this.shouldCommit = !0;\n }\n /**\n * Adds a new stroke part to the nextStrokes\n * array\n * @param strokePart\n */\n onStrokePart(t) {\n this.currentStroke.push(t), this.shouldDraw = !0, t.isEnd && (this.shouldCommit = !0);\n }\n /**\n * Draws a frame\n */\n draw() {\n this.nextAnimationFrame = window.requestAnimationFrame(this.draw);\n const t = this.canvas.getContext(\"2d\");\n this.shouldDraw && (t.clearRect(0, 0, this.canvasWidth, this.canvasHeight), this.canvasState && t.putImageData(this.canvasState, 0, 0), this.currentTool && this.currentStroke.length && (t.save(), this.currentTool.draw(t, this.currentStroke), t.restore()), this.shouldCommit && (this.canvasState = t.getImageData(\n 0,\n 0,\n this.canvasWidth * this.pixelRatio,\n this.canvasHeight * this.pixelRatio\n ), this.currentStroke = [], this.shouldCommit = !1), this.shouldDraw = !1);\n }\n}\nclass C {\n constructor(t = \"red\", i = 3) {\n this.color = t, this.width = i;\n }\n /**\n * Draws a \"pen stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n draw(t, i) {\n const o = i[0];\n t.beginPath(), t.lineWidth = this.width, t.strokeStyle = this.color, t.lineCap = \"round\", t.lineJoin = \"round\", t.moveTo(o.startPoint.x, o.startPoint.y), i.forEach((n) => {\n const { endPoint: s } = n;\n t.lineTo(s.x, s.y);\n }), t.stroke();\n }\n}\nclass E {\n constructor(t = 10, i) {\n this.width = t, i = i || {}, this.handleOpts = {\n hide: i.hide || !1,\n strokeWidth: i.strokeWidth || 2,\n fillColor: i.fillColor || \"white\",\n strokeColor: i.strokeColor || \"black\"\n };\n }\n /**\n * Draws an \"eraser stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n draw(t, i) {\n const { handleOpts: o } = this, n = this.width / 2;\n i.forEach((a) => {\n const { startPoint: h, endPoint: l, isEnd: f } = a, d = g(h, l), v = y(h, l);\n let r = h, u = 0;\n for (; u < d; ) {\n const c = {\n x: r.x + v.x,\n y: r.y + v.y\n };\n t.clearRect(\n c.x - n,\n c.y - n,\n this.width,\n this.width\n ), u++, r = c;\n }\n });\n const s = i[i.length - 1];\n !s.isEnd && !o.hide && (t.strokeStyle = o.strokeColor, t.fillStyle = o.fillColor, t.fillRect(\n s.endPoint.x - n,\n s.endPoint.y - n,\n this.width,\n this.width\n ), t.strokeRect(\n s.endPoint.x - n + 0.5,\n s.endPoint.y - n + 0.5,\n this.width - 1,\n this.width - 1\n ));\n }\n}\nfunction w(e) {\n return e && e.__esModule && Object.prototype.hasOwnProperty.call(e, \"default\") ? e.default : e;\n}\nvar b = {\n aliceblue: [240, 248, 255],\n antiquewhite: [250, 235, 215],\n aqua: [0, 255, 255],\n aquamarine: [127, 255, 212],\n azure: [240, 255, 255],\n beige: [245, 245, 220],\n bisque: [255, 228, 196],\n black: [0, 0, 0],\n blanchedalmond: [255, 235, 205],\n blue: [0, 0, 255],\n blueviolet: [138, 43, 226],\n brown: [165, 42, 42],\n burlywood: [222, 184, 135],\n cadetblue: [95, 158, 160],\n chartreuse: [127, 255, 0],\n chocolate: [210, 105, 30],\n coral: [255, 127, 80],\n cornflowerblue: [100, 149, 237],\n cornsilk: [255, 248, 220],\n crimson: [220, 20, 60],\n cyan: [0, 255, 255],\n darkblue: [0, 0, 139],\n darkcyan: [0, 139, 139],\n darkgoldenrod: [184, 134, 11],\n darkgray: [169, 169, 169],\n darkgreen: [0, 100, 0],\n darkgrey: [169, 169, 169],\n darkkhaki: [189, 183, 107],\n darkmagenta: [139, 0, 139],\n darkolivegreen: [85, 107, 47],\n darkorange: [255, 140, 0],\n darkorchid: [153, 50, 204],\n darkred: [139, 0, 0],\n darksalmon: [233, 150, 122],\n darkseagreen: [143, 188, 143],\n darkslateblue: [72, 61, 139],\n darkslategray: [47, 79, 79],\n darkslategrey: [47, 79, 79],\n darkturquoise: [0, 206, 209],\n darkviolet: [148, 0, 211],\n deeppink: [255, 20, 147],\n deepskyblue: [0, 191, 255],\n dimgray: [105, 105, 105],\n dimgrey: [105, 105, 105],\n dodgerblue: [30, 144, 255],\n firebrick: [178, 34, 34],\n floralwhite: [255, 250, 240],\n forestgreen: [34, 139, 34],\n fuchsia: [255, 0, 255],\n gainsboro: [220, 220, 220],\n ghostwhite: [248, 248, 255],\n gold: [255, 215, 0],\n goldenrod: [218, 165, 32],\n gray: [128, 128, 128],\n green: [0, 128, 0],\n greenyellow: [173, 255, 47],\n grey: [128, 128, 128],\n honeydew: [240, 255, 240],\n hotpink: [255, 105, 180],\n indianred: [205, 92, 92],\n indigo: [75, 0, 130],\n ivory: [255, 255, 240],\n khaki: [240, 230, 140],\n lavender: [230, 230, 250],\n lavenderblush: [255, 240, 245],\n lawngreen: [124, 252, 0],\n lemonchiffon: [255, 250, 205],\n lightblue: [173, 216, 230],\n lightcoral: [240, 128, 128],\n lightcyan: [224, 255, 255],\n lightgoldenrodyellow: [250, 250, 210],\n lightgray: [211, 211, 211],\n lightgreen: [144, 238, 144],\n lightgrey: [211, 211, 211],\n lightpink: [255, 182, 193],\n lightsalmon: [255, 160, 122],\n lightseagreen: [32, 178, 170],\n lightskyblue: [135, 206, 250],\n lightslategray: [119, 136, 153],\n lightslategrey: [119, 136, 153],\n lightsteelblue: [176, 196, 222],\n lightyellow: [255, 255, 224],\n lime: [0, 255, 0],\n limegreen: [50, 205, 50],\n linen: [250, 240, 230],\n magenta: [255, 0, 255],\n maroon: [128, 0, 0],\n mediumaquamarine: [102, 205, 170],\n mediumblue: [0, 0, 205],\n mediumorchid: [186, 85, 211],\n mediumpurple: [147, 112, 219],\n mediumseagreen: [60, 179, 113],\n mediumslateblue: [123, 104, 238],\n mediumspringgreen: [0, 250, 154],\n mediumturquoise: [72, 209, 204],\n mediumvioletred: [199, 21, 133],\n midnightblue: [25, 25, 112],\n mintcream: [245, 255, 250],\n mistyrose: [255, 228, 225],\n moccasin: [255, 228, 181],\n navajowhite: [255, 222, 173],\n navy: [0, 0, 128],\n oldlace: [253, 245, 230],\n olive: [128, 128, 0],\n olivedrab: [107, 142, 35],\n orange: [255, 165, 0],\n orangered: [255, 69, 0],\n orchid: [218, 112, 214],\n palegoldenrod: [238, 232, 170],\n palegreen: [152, 251, 152],\n paleturquoise: [175, 238, 238],\n palevioletred: [219, 112, 147],\n papayawhip: [255, 239, 213],\n peachpuff: [255, 218, 185],\n peru: [205, 133, 63],\n pink: [255, 192, 203],\n plum: [221, 160, 221],\n powderblue: [176, 224, 230],\n purple: [128, 0, 128],\n rebeccapurple: [102, 51, 153],\n red: [255, 0, 0],\n rosybrown: [188, 143, 143],\n royalblue: [65, 105, 225],\n saddlebrown: [139, 69, 19],\n salmon: [250, 128, 114],\n sandybrown: [244, 164, 96],\n seagreen: [46, 139, 87],\n seashell: [255, 245, 238],\n sienna: [160, 82, 45],\n silver: [192, 192, 192],\n skyblue: [135, 206, 235],\n slateblue: [106, 90, 205],\n slategray: [112, 128, 144],\n slategrey: [112, 128, 144],\n snow: [255, 250, 250],\n springgreen: [0, 255, 127],\n steelblue: [70, 130, 180],\n tan: [210, 180, 140],\n teal: [0, 128, 128],\n thistle: [216, 191, 216],\n tomato: [255, 99, 71],\n turquoise: [64, 224, 208],\n violet: [238, 130, 238],\n wheat: [245, 222, 179],\n white: [255, 255, 255],\n whitesmoke: [245, 245, 245],\n yellow: [255, 255, 0],\n yellowgreen: [154, 205, 50]\n};\nconst p = /* @__PURE__ */ w(b);\nvar m = {\n red: 0,\n orange: 60,\n yellow: 120,\n green: 180,\n blue: 240,\n purple: 300\n};\nfunction T(e) {\n var t, i = [], o = 1, n;\n if (typeof e == \"string\")\n if (e = e.toLowerCase(), p[e])\n i = p[e].slice(), n = \"rgb\";\n else if (e === \"transparent\")\n o = 0, n = \"rgb\", i = [0, 0, 0];\n else if (/^#[A-Fa-f0-9]+$/.test(e)) {\n var s = e.slice(1), a = s.length, h = a <= 4;\n o = 1, h ? (i = [\n parseInt(s[0] + s[0], 16),\n parseInt(s[1] + s[1], 16),\n parseInt(s[2] + s[2], 16)\n ], a === 4 && (o = parseInt(s[3] + s[3], 16) / 255)) : (i = [\n parseInt(s[0] + s[1], 16),\n parseInt(s[2] + s[3], 16),\n parseInt(s[4] + s[5], 16)\n ], a === 8 && (o = parseInt(s[6] + s[7], 16) / 255)), i[0] || (i[0] = 0), i[1] || (i[1] = 0), i[2] || (i[2] = 0), n = \"rgb\";\n } else if (t = /^((?:rgb|hs[lvb]|hwb|cmyk?|xy[zy]|gray|lab|lchu?v?|[ly]uv|lms)a?)\\s*\\(([^\\)]*)\\)/.exec(e)) {\n var l = t[1], f = l === \"rgb\", s = l.replace(/a$/, \"\");\n n = s;\n var a = s === \"cmyk\" ? 4 : s === \"gray\" ? 1 : 3;\n i = t[2].trim().split(/\\s*[,\\/]\\s*|\\s+/).map(function(r, u) {\n if (/%$/.test(r))\n return u === a ? parseFloat(r) / 100 : s === \"rgb\" ? parseFloat(r) * 255 / 100 : parseFloat(r);\n if (s[u] === \"h\") {\n if (/deg$/.test(r))\n return parseFloat(r);\n if (m[r] !== void 0)\n return m[r];\n }\n return parseFloat(r);\n }), l === s && i.push(1), o = f || i[a] === void 0 ? 1 : i[a], i = i.slice(0, a);\n } else\n e.length > 10 && /[0-9](?:\\s|\\/)/.test(e) && (i = e.match(/([0-9]+)/g).map(function(d) {\n return parseFloat(d);\n }), n = e.match(/([a-z])/ig).join(\"\").toLowerCase());\n else\n isNaN(e) ? Array.isArray(e) || e.length ? (i = [e[0], e[1], e[2]], n = \"rgb\", o = e.length === 4 ? e[3] : 1) : e instanceof Object && (e.r != null || e.red != null || e.R != null ? (n = \"rgb\", i = [\n e.r || e.red || e.R || 0,\n e.g || e.green || e.G || 0,\n e.b || e.blue || e.B || 0\n ]) : (n = \"hsl\", i = [\n e.h || e.hue || e.H || 0,\n e.s || e.saturation || e.S || 0,\n e.l || e.lightness || e.L || e.b || e.brightness\n ]), o = e.a || e.alpha || e.opacity || 1, e.opacity != null && (o /= 100)) : (n = \"rgb\", i = [e >>> 16, (e & 65280) >>> 8, e & 255]);\n return {\n space: n,\n values: i,\n alpha: o\n };\n}\nfunction S(e, t) {\n var i = T(e);\n return t == null && (t = i.alpha), i.space[0] === \"h\" ? i.space + [\"a(\", i.values[0], \",\", i.values[1], \"%,\", i.values[2], \"%,\", t, \")\"].join(\"\") : i.space + [\"a(\", i.values, \",\", t, \")\"].join(\"\");\n}\nclass R {\n constructor(t = \"yellow\", i = 8, o = 0.3) {\n this.width = i, this.color = S(t, 0.4);\n }\n /**\n * Draws a \"highlighter stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n draw(t, i) {\n const o = i[0];\n t.beginPath(), t.lineWidth = this.width, t.strokeStyle = this.color, t.lineCap = \"butt\", t.miterLimit = 1, t.moveTo(o.startPoint.x, o.startPoint.y), i.forEach((n) => {\n const { endPoint: s } = n;\n t.lineTo(s.x, s.y);\n }), t.stroke();\n }\n}\nexport {\n E as EraserTool,\n R as HighlighterTool,\n P as Manager,\n C as PenTool\n};\n//# sourceMappingURL=index.es.js.map\n","import {\r\n Manager,\r\n PenTool,\r\n EraserTool,\r\n HighlighterTool,\r\n} from \"../../dist/index.es\";\r\n\r\nwindow.onload = function () {\r\n const canvas = document.getElementById(\"canvas\");\r\n const redPenElem = document.getElementById(\"red-pen\");\r\n const bluePenElem = document.getElementById(\"blue-pen\");\r\n const eraserElem = document.getElementById(\"eraser\");\r\n const highlighterElem = document.getElementById(\"highlighter\");\r\n const clearElem = document.getElementById(\"clear\");\r\n\r\n if (\r\n !redPenElem ||\r\n !bluePenElem ||\r\n !eraserElem ||\r\n !highlighterElem ||\r\n !clearElem\r\n ) {\r\n throw new Error(\"Invalid elements\");\r\n }\r\n\r\n const width = 400;\r\n const height = 400;\r\n\r\n const manager = new Manager(canvas, width, height);\r\n\r\n const redPen = new PenTool(\"red\", 3);\r\n const bluePen = new PenTool(\"blue\", 8);\r\n const eraser = new EraserTool(20);\r\n const highlighterTool = new HighlighterTool(\"yellow\", 30);\r\n\r\n manager.setTool(redPen);\r\n\r\n redPenElem.onclick = function () {\r\n manager.setTool(redPen);\r\n };\r\n\r\n bluePenElem.onclick = function () {\r\n manager.setTool(bluePen);\r\n };\r\n\r\n eraserElem.onclick = function () {\r\n manager.setTool(eraser);\r\n };\r\n\r\n highlighterElem.onclick = function () {\r\n manager.setTool(highlighterTool);\r\n };\r\n\r\n clearElem.onclick = function () {\r\n manager.clear();\r\n };\r\n};\r\n"],"names":["g","y","o","k","n","P","h","C","E","l","f","d","v","u","c","w","b","p","m","T","S","R","canvas","redPenElem","bluePenElem","eraserElem","highlighterElem","clearElem","width","height","manager","Manager","redPen","PenTool","bluePen","eraser","EraserTool","highlighterTool","HighlighterTool"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"example.umd.js","sources":["../../dist/index.es.js","../src/example.ts"],"sourcesContent":["function c(i, t) {\n return Math.sqrt(Math.pow(i.x - t.x, 2) + Math.pow(i.y - t.y, 2));\n}\nfunction k(i, t) {\n const e = c(i, t), s = {\n x: t.x - i.x,\n y: t.y - i.y\n };\n return {\n x: s.x / e,\n y: s.y / e\n };\n}\nclass w {\n constructor(t) {\n this.canvas = t, this.lastTouch = null, this.lastMouse = null, this.sensitivity = 20, this.lastStrokeParts = [], this.onStrokePartHandlers = [], this.onTouchStart = this.onTouchStart.bind(this), this.onTouchEnd = this.onTouchEnd.bind(this), this.onTouchCancel = this.onTouchCancel.bind(this), this.onTouchMove = this.onTouchMove.bind(this), this.destroy = this.destroy.bind(this), this.getRelativePosition = this.getRelativePosition.bind(this), this.onMouseDown = this.onMouseDown.bind(this), this.onMouseUp = this.onMouseUp.bind(this), this.onMouseMove = this.onMouseMove.bind(this), this.canvas.addEventListener(\"touchstart\", this.onTouchStart, {\n passive: !1\n }), this.canvas.addEventListener(\"touchend\", this.onTouchEnd, {\n passive: !1\n }), this.canvas.addEventListener(\"touchcancel\", this.onTouchCancel, {\n passive: !1\n }), this.canvas.addEventListener(\"touchmove\", this.onTouchMove, {\n passive: !1\n }), this.canvas.addEventListener(\"mousedown\", this.onMouseDown, {\n passive: !1\n }), document.addEventListener(\"mouseup\", this.onMouseUp, {\n passive: !1\n }), this.canvas.addEventListener(\"mousemove\", this.onMouseMove, {\n passive: !1\n });\n }\n /**\n * Registers a handler to be fired on a new stroke part\n * @param handler\n */\n onStrokePart(t) {\n this.onStrokePartHandlers.push(t);\n }\n /**\n * Removes all active listeners\n */\n destroy() {\n this.onStrokePartHandlers = [], this.lastStrokeParts = [], this.canvas.removeEventListener(\"touchstart\", this.onTouchStart), this.canvas.removeEventListener(\"touchend\", this.onTouchEnd), this.canvas.removeEventListener(\"touchcancel\", this.onTouchCancel), this.canvas.removeEventListener(\"touchmove\", this.onTouchMove), this.canvas.removeEventListener(\"mousedown\", this.onMouseDown), document.removeEventListener(\"mouseup\", this.onMouseUp), this.canvas.removeEventListener(\"mousemove\", this.onMouseMove);\n }\n /**\n * Get relative position to canvas\n * @param clientX\n * @param clientY\n * @returns IPoint\n */\n getRelativePosition(t, e) {\n const s = this.canvas.getBoundingClientRect();\n return {\n x: (t - s.left) / s.width,\n y: (e - s.top) / s.height\n };\n }\n /**\n * Creates a new touch if one does not\n * already exist\n * @param e\n */\n onTouchStart(t) {\n if (t.preventDefault(), this.lastTouch)\n return;\n const s = t.changedTouches.item(0);\n this.lastTouch = {\n id: s.identifier,\n position: this.getRelativePosition(s.clientX, s.clientY)\n };\n }\n /**\n * Creates a line from last touch to current touch\n * point and emits event. Does no-op if no existing touch\n * @param e\n */\n onTouchMove(t) {\n if (t.preventDefault(), !this.lastTouch)\n return;\n const e = t.changedTouches, s = Array.from(e).find((a) => a.identifier === this.lastTouch.id);\n if (!s)\n return;\n const n = {\n id: s.identifier,\n position: this.getRelativePosition(s.clientX, s.clientY)\n };\n if (this.sensitivity && c(n.position, this.lastTouch.position) < 10 / this.sensitivity)\n return;\n const o = {\n endPoint: n.position,\n startPoint: this.lastTouch.position,\n isStart: this.lastStrokeParts.length === 0,\n isEnd: !1\n };\n this.onStrokePartHandlers.forEach((a) => {\n a(o);\n }), this.lastTouch = n, this.lastStrokeParts.push(o);\n }\n /**\n * Draws a line from last point to final point. Removes\n * the reference to last touch point.\n * @param e\n */\n onTouchEnd(t) {\n if (t.preventDefault(), !this.lastTouch)\n return;\n const e = t.changedTouches, s = Array.from(e).find((a) => a.identifier === this.lastTouch.id);\n if (!s)\n return;\n const n = this.getRelativePosition(s.clientX, s.clientY), o = {\n startPoint: this.lastTouch.position,\n endPoint: n,\n isStart: !1,\n isEnd: !0\n };\n this.onStrokePartHandlers.forEach((a) => {\n a(o);\n }), this.lastTouch = null, this.lastStrokeParts = [];\n }\n /**\n * Removes the current last touch point\n * @param e\n */\n onTouchCancel(t) {\n t.preventDefault(), this.lastTouch = null, this.lastStrokeParts = [];\n }\n onMouseDown(t) {\n this.lastMouse || (this.lastMouse = this.getRelativePosition(t.clientX, t.clientY));\n }\n onMouseUp(t) {\n if (!this.lastMouse)\n return;\n let e = this.getRelativePosition(t.clientX, t.clientY);\n c(this.lastMouse, e) < 1 && (e = {\n x: this.lastMouse.x + 8e-4,\n y: this.lastMouse.y + 8e-4\n });\n const n = {\n startPoint: this.lastMouse,\n endPoint: e,\n isStart: !1,\n isEnd: !0\n };\n this.onStrokePartHandlers.forEach((o) => {\n o(n);\n }), this.lastMouse = null, this.lastStrokeParts = [];\n }\n onMouseMove(t) {\n if (!this.lastMouse)\n return;\n const e = this.getRelativePosition(t.clientX, t.clientY);\n if (this.sensitivity && c(e, this.lastMouse) < 0.05 / this.sensitivity)\n return;\n const s = {\n endPoint: e,\n startPoint: this.lastMouse,\n isStart: this.lastStrokeParts.length === 0,\n isEnd: !1\n };\n this.onStrokePartHandlers.forEach((n) => {\n n(s);\n }), this.lastMouse = e, this.lastStrokeParts.push(s);\n }\n}\nclass M {\n constructor(t, e, s) {\n this.canvas = t, this.ctx = t.getContext(\"2d\", { willReadFrequently: !0 }), this.canvasWidth = e, this.canvasHeight = s, this.currentTool = null, this.currentStroke = [], this.strokeManager = new w(t), this.canvasState = null, this.shouldDraw = !1, this.shouldCommit = !1;\n const n = this.ctx.backingStorePixelRatio || 1, o = window.devicePixelRatio || 1;\n this.pixelRatio = o / n, this.setCanvasSize = this.setCanvasSize.bind(this), this.setTool = this.setTool.bind(this), this.destroy = this.destroy.bind(this), this.clear = this.clear.bind(this), this.draw = this.draw.bind(this), this.onStrokePart = this.onStrokePart.bind(this), this.nextAnimationFrame = window.requestAnimationFrame(this.draw), this.strokeManager.onStrokePart(this.onStrokePart), this.setCanvasSize(e, s);\n }\n /**\n * Sets the canvas desired width and height and sets transform\n * for hifi displays\n * @param width\n * @param height\n */\n setCanvasSize(t, e) {\n this.canvasWidth = t, this.canvasHeight = e;\n const { ctx: s, canvas: n, canvasWidth: o, canvasHeight: a, pixelRatio: r } = this;\n s && (n.width = o * r, n.height = a * r, n.style.width = o + \"px\", n.style.height = a + \"px\", s.scale(r, r));\n }\n /**\n * Sets the current tool for the manager\n * @param tool\n */\n setTool(t) {\n this.currentTool = t;\n }\n /**\n * Remove all event listeners\n */\n destroy() {\n window.cancelAnimationFrame(this.nextAnimationFrame), this.strokeManager.destroy();\n }\n /**\n * Clears the canvas\n */\n clear() {\n this.canvasState = null, this.currentStroke = [], this.shouldDraw = !0, this.shouldCommit = !0;\n }\n /**\n * Adds a new stroke part to the nextStrokes\n * array\n * @param strokePart\n */\n onStrokePart(t) {\n this.currentStroke.push(t), this.shouldDraw = !0, t.isEnd && (this.shouldCommit = !0);\n }\n /**\n * Draws a frame\n */\n draw() {\n this.nextAnimationFrame = window.requestAnimationFrame(this.draw);\n const { ctx: t, canvasWidth: e, canvasHeight: s } = this;\n !this.shouldDraw || !t || (t.clearRect(0, 0, this.canvasWidth, this.canvasHeight), this.canvasState && t.putImageData(this.canvasState, 0, 0), this.currentTool && this.currentStroke.length && (t.save(), this.currentTool.draw(t, this.currentStroke, e, s), t.restore()), this.shouldCommit && (this.canvasState = t.getImageData(\n 0,\n 0,\n e * this.pixelRatio,\n s * this.pixelRatio\n ), this.currentStroke = [], this.shouldCommit = !1), this.shouldDraw = !1);\n }\n}\nclass E {\n constructor(t = \"red\", e = 3) {\n this.color = t, this.width = e;\n }\n /**\n * Draws a \"pen stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n draw(t, e, s, n) {\n const o = e[0];\n t.beginPath(), t.lineWidth = this.width, t.strokeStyle = this.color, t.lineCap = \"round\", t.lineJoin = \"round\", t.moveTo(\n o.startPoint.x * s,\n o.startPoint.y * n\n ), e.forEach((a) => {\n const { endPoint: r } = a;\n t.lineTo(r.x * s, r.y * n);\n }), t.stroke();\n }\n}\nclass C {\n constructor(t = 10, e) {\n this.width = t, e = e || {}, this.handleOpts = {\n hide: e.hide || !1,\n strokeWidth: e.strokeWidth || 2,\n fillColor: e.fillColor || \"white\",\n strokeColor: e.strokeColor || \"black\"\n };\n }\n /**\n * Draws an \"eraser stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n draw(t, e, s, n) {\n const { handleOpts: o } = this, a = this.width / 2;\n e.forEach((l) => {\n const { startPoint: d, endPoint: g } = l, y = c(d, g), h = k(d, g);\n let u = d, f = 0;\n for (; f < y; ) {\n const v = {\n x: u.x * s + h.x,\n y: u.y * n + h.y\n };\n t.clearRect(\n v.x - a,\n v.y - a,\n this.width,\n this.width\n ), f++, u = v;\n }\n });\n const r = e[e.length - 1];\n if (!r.isEnd && !o.hide) {\n t.strokeStyle = o.strokeColor, t.fillStyle = o.fillColor;\n const l = {\n x: r.endPoint.x * s,\n y: r.endPoint.y * n\n };\n t.fillRect(\n l.x - a,\n l.y - a,\n this.width,\n this.width\n ), t.strokeRect(\n l.x - a + 0.5,\n l.y - a + 0.5,\n this.width - 1,\n this.width - 1\n );\n }\n }\n}\nfunction b(i) {\n return i && i.__esModule && Object.prototype.hasOwnProperty.call(i, \"default\") ? i.default : i;\n}\nvar P = {\n aliceblue: [240, 248, 255],\n antiquewhite: [250, 235, 215],\n aqua: [0, 255, 255],\n aquamarine: [127, 255, 212],\n azure: [240, 255, 255],\n beige: [245, 245, 220],\n bisque: [255, 228, 196],\n black: [0, 0, 0],\n blanchedalmond: [255, 235, 205],\n blue: [0, 0, 255],\n blueviolet: [138, 43, 226],\n brown: [165, 42, 42],\n burlywood: [222, 184, 135],\n cadetblue: [95, 158, 160],\n chartreuse: [127, 255, 0],\n chocolate: [210, 105, 30],\n coral: [255, 127, 80],\n cornflowerblue: [100, 149, 237],\n cornsilk: [255, 248, 220],\n crimson: [220, 20, 60],\n cyan: [0, 255, 255],\n darkblue: [0, 0, 139],\n darkcyan: [0, 139, 139],\n darkgoldenrod: [184, 134, 11],\n darkgray: [169, 169, 169],\n darkgreen: [0, 100, 0],\n darkgrey: [169, 169, 169],\n darkkhaki: [189, 183, 107],\n darkmagenta: [139, 0, 139],\n darkolivegreen: [85, 107, 47],\n darkorange: [255, 140, 0],\n darkorchid: [153, 50, 204],\n darkred: [139, 0, 0],\n darksalmon: [233, 150, 122],\n darkseagreen: [143, 188, 143],\n darkslateblue: [72, 61, 139],\n darkslategray: [47, 79, 79],\n darkslategrey: [47, 79, 79],\n darkturquoise: [0, 206, 209],\n darkviolet: [148, 0, 211],\n deeppink: [255, 20, 147],\n deepskyblue: [0, 191, 255],\n dimgray: [105, 105, 105],\n dimgrey: [105, 105, 105],\n dodgerblue: [30, 144, 255],\n firebrick: [178, 34, 34],\n floralwhite: [255, 250, 240],\n forestgreen: [34, 139, 34],\n fuchsia: [255, 0, 255],\n gainsboro: [220, 220, 220],\n ghostwhite: [248, 248, 255],\n gold: [255, 215, 0],\n goldenrod: [218, 165, 32],\n gray: [128, 128, 128],\n green: [0, 128, 0],\n greenyellow: [173, 255, 47],\n grey: [128, 128, 128],\n honeydew: [240, 255, 240],\n hotpink: [255, 105, 180],\n indianred: [205, 92, 92],\n indigo: [75, 0, 130],\n ivory: [255, 255, 240],\n khaki: [240, 230, 140],\n lavender: [230, 230, 250],\n lavenderblush: [255, 240, 245],\n lawngreen: [124, 252, 0],\n lemonchiffon: [255, 250, 205],\n lightblue: [173, 216, 230],\n lightcoral: [240, 128, 128],\n lightcyan: [224, 255, 255],\n lightgoldenrodyellow: [250, 250, 210],\n lightgray: [211, 211, 211],\n lightgreen: [144, 238, 144],\n lightgrey: [211, 211, 211],\n lightpink: [255, 182, 193],\n lightsalmon: [255, 160, 122],\n lightseagreen: [32, 178, 170],\n lightskyblue: [135, 206, 250],\n lightslategray: [119, 136, 153],\n lightslategrey: [119, 136, 153],\n lightsteelblue: [176, 196, 222],\n lightyellow: [255, 255, 224],\n lime: [0, 255, 0],\n limegreen: [50, 205, 50],\n linen: [250, 240, 230],\n magenta: [255, 0, 255],\n maroon: [128, 0, 0],\n mediumaquamarine: [102, 205, 170],\n mediumblue: [0, 0, 205],\n mediumorchid: [186, 85, 211],\n mediumpurple: [147, 112, 219],\n mediumseagreen: [60, 179, 113],\n mediumslateblue: [123, 104, 238],\n mediumspringgreen: [0, 250, 154],\n mediumturquoise: [72, 209, 204],\n mediumvioletred: [199, 21, 133],\n midnightblue: [25, 25, 112],\n mintcream: [245, 255, 250],\n mistyrose: [255, 228, 225],\n moccasin: [255, 228, 181],\n navajowhite: [255, 222, 173],\n navy: [0, 0, 128],\n oldlace: [253, 245, 230],\n olive: [128, 128, 0],\n olivedrab: [107, 142, 35],\n orange: [255, 165, 0],\n orangered: [255, 69, 0],\n orchid: [218, 112, 214],\n palegoldenrod: [238, 232, 170],\n palegreen: [152, 251, 152],\n paleturquoise: [175, 238, 238],\n palevioletred: [219, 112, 147],\n papayawhip: [255, 239, 213],\n peachpuff: [255, 218, 185],\n peru: [205, 133, 63],\n pink: [255, 192, 203],\n plum: [221, 160, 221],\n powderblue: [176, 224, 230],\n purple: [128, 0, 128],\n rebeccapurple: [102, 51, 153],\n red: [255, 0, 0],\n rosybrown: [188, 143, 143],\n royalblue: [65, 105, 225],\n saddlebrown: [139, 69, 19],\n salmon: [250, 128, 114],\n sandybrown: [244, 164, 96],\n seagreen: [46, 139, 87],\n seashell: [255, 245, 238],\n sienna: [160, 82, 45],\n silver: [192, 192, 192],\n skyblue: [135, 206, 235],\n slateblue: [106, 90, 205],\n slategray: [112, 128, 144],\n slategrey: [112, 128, 144],\n snow: [255, 250, 250],\n springgreen: [0, 255, 127],\n steelblue: [70, 130, 180],\n tan: [210, 180, 140],\n teal: [0, 128, 128],\n thistle: [216, 191, 216],\n tomato: [255, 99, 71],\n turquoise: [64, 224, 208],\n violet: [238, 130, 238],\n wheat: [245, 222, 179],\n white: [255, 255, 255],\n whitesmoke: [245, 245, 245],\n yellow: [255, 255, 0],\n yellowgreen: [154, 205, 50]\n};\nconst p = /* @__PURE__ */ b(P);\nvar m = {\n red: 0,\n orange: 60,\n yellow: 120,\n green: 180,\n blue: 240,\n purple: 300\n};\nfunction S(i) {\n var t, e = [], s = 1, n;\n if (typeof i == \"string\")\n if (i = i.toLowerCase(), p[i])\n e = p[i].slice(), n = \"rgb\";\n else if (i === \"transparent\")\n s = 0, n = \"rgb\", e = [0, 0, 0];\n else if (/^#[A-Fa-f0-9]+$/.test(i)) {\n var o = i.slice(1), a = o.length, r = a <= 4;\n s = 1, r ? (e = [\n parseInt(o[0] + o[0], 16),\n parseInt(o[1] + o[1], 16),\n parseInt(o[2] + o[2], 16)\n ], a === 4 && (s = parseInt(o[3] + o[3], 16) / 255)) : (e = [\n parseInt(o[0] + o[1], 16),\n parseInt(o[2] + o[3], 16),\n parseInt(o[4] + o[5], 16)\n ], a === 8 && (s = parseInt(o[6] + o[7], 16) / 255)), e[0] || (e[0] = 0), e[1] || (e[1] = 0), e[2] || (e[2] = 0), n = \"rgb\";\n } else if (t = /^((?:rgb|hs[lvb]|hwb|cmyk?|xy[zy]|gray|lab|lchu?v?|[ly]uv|lms)a?)\\s*\\(([^\\)]*)\\)/.exec(i)) {\n var l = t[1], d = l === \"rgb\", o = l.replace(/a$/, \"\");\n n = o;\n var a = o === \"cmyk\" ? 4 : o === \"gray\" ? 1 : 3;\n e = t[2].trim().split(/\\s*[,\\/]\\s*|\\s+/).map(function(h, u) {\n if (/%$/.test(h))\n return u === a ? parseFloat(h) / 100 : o === \"rgb\" ? parseFloat(h) * 255 / 100 : parseFloat(h);\n if (o[u] === \"h\") {\n if (/deg$/.test(h))\n return parseFloat(h);\n if (m[h] !== void 0)\n return m[h];\n }\n return parseFloat(h);\n }), l === o && e.push(1), s = d || e[a] === void 0 ? 1 : e[a], e = e.slice(0, a);\n } else\n i.length > 10 && /[0-9](?:\\s|\\/)/.test(i) && (e = i.match(/([0-9]+)/g).map(function(g) {\n return parseFloat(g);\n }), n = i.match(/([a-z])/ig).join(\"\").toLowerCase());\n else\n isNaN(i) ? Array.isArray(i) || i.length ? (e = [i[0], i[1], i[2]], n = \"rgb\", s = i.length === 4 ? i[3] : 1) : i instanceof Object && (i.r != null || i.red != null || i.R != null ? (n = \"rgb\", e = [\n i.r || i.red || i.R || 0,\n i.g || i.green || i.G || 0,\n i.b || i.blue || i.B || 0\n ]) : (n = \"hsl\", e = [\n i.h || i.hue || i.H || 0,\n i.s || i.saturation || i.S || 0,\n i.l || i.lightness || i.L || i.b || i.brightness\n ]), s = i.a || i.alpha || i.opacity || 1, i.opacity != null && (s /= 100)) : (n = \"rgb\", e = [i >>> 16, (i & 65280) >>> 8, i & 255]);\n return {\n space: n,\n values: e,\n alpha: s\n };\n}\nfunction T(i, t) {\n var e = S(i);\n return t == null && (t = e.alpha), e.space[0] === \"h\" ? e.space + [\"a(\", e.values[0], \",\", e.values[1], \"%,\", e.values[2], \"%,\", t, \")\"].join(\"\") : e.space + [\"a(\", e.values, \",\", t, \")\"].join(\"\");\n}\nclass R {\n constructor(t = \"yellow\", e = 8, s = 0.3) {\n this.width = e, this.color = T(t, 0.4);\n }\n /**\n * Draws a \"highlighter stroke\" for all line segments\n * @param ctx\n * @param strokeParts\n */\n draw(t, e, s, n) {\n const o = e[0];\n t.beginPath(), t.lineWidth = this.width, t.strokeStyle = this.color, t.lineCap = \"butt\", t.miterLimit = 1, t.moveTo(\n o.startPoint.x * s,\n o.startPoint.y * n\n ), e.forEach((a) => {\n const { endPoint: r } = a;\n t.lineTo(r.x * s, r.y * n);\n }), t.stroke();\n }\n}\nexport {\n C as EraserTool,\n R as HighlighterTool,\n M as Manager,\n E as PenTool\n};\n//# sourceMappingURL=index.es.js.map\n","import {\n Manager,\n PenTool,\n EraserTool,\n HighlighterTool,\n} from \"../../dist/index.es\";\n\nwindow.onload = function () {\n const canvas = document.getElementById(\"canvas\");\n const redPenElem = document.getElementById(\"red-pen\");\n const bluePenElem = document.getElementById(\"blue-pen\");\n const eraserElem = document.getElementById(\"eraser\");\n const highlighterElem = document.getElementById(\"highlighter\");\n const clearElem = document.getElementById(\"clear\");\n\n if (\n !redPenElem ||\n !bluePenElem ||\n !eraserElem ||\n !highlighterElem ||\n !clearElem\n ) {\n throw new Error(\"Invalid elements\");\n }\n\n const width = 400;\n const height = 400;\n\n const manager = new Manager(canvas, width, height);\n\n const redPen = new PenTool(\"red\", 3);\n const bluePen = new PenTool(\"blue\", 8);\n const eraser = new EraserTool(20);\n const highlighterTool = new HighlighterTool(\"yellow\", 30);\n\n manager.setTool(redPen);\n\n redPenElem.onclick = function () {\n manager.setTool(redPen);\n };\n\n bluePenElem.onclick = function () {\n manager.setTool(bluePen);\n };\n\n eraserElem.onclick = function () {\n manager.setTool(eraser);\n };\n\n highlighterElem.onclick = function () {\n manager.setTool(highlighterTool);\n };\n\n clearElem.onclick = function () {\n manager.clear();\n };\n};\n"],"names":["i","k","s","w","n","o","M","E","C","l","d","g","y","h","u","f","v","b","P","p","m","S","T","R","canvas","redPenElem","bluePenElem","eraserElem","highlighterElem","clearElem","width","height","manager","Manager","redPen","PenTool","bluePen","eraser","EraserTool","highlighterTool","HighlighterTool"],"mappings":"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"} \ No newline at end of file diff --git a/src/Manager.ts b/src/Manager.ts index ce83327..4ce2c2c 100644 --- a/src/Manager.ts +++ b/src/Manager.ts @@ -4,6 +4,8 @@ import { StrokeManager } from "./StrokeManager"; export class Manager { // reference to the canvas private canvas: HTMLCanvasElement; + // reference to canvas rendering context + private ctx: CanvasRenderingContext2D | null; // reference to stroke manager private strokeManager: StrokeManager; // holds the pixel ratio between canvas backing @@ -32,6 +34,7 @@ export class Manager { canvasHeight: number, ) { this.canvas = canvas; + this.ctx = canvas.getContext("2d", { willReadFrequently: true }); this.canvasWidth = canvasWidth; this.canvasHeight = canvasHeight; this.currentTool = null; @@ -42,7 +45,7 @@ export class Manager { this.shouldCommit = false; // find pixel ratio relative to backing store and device ratio - const bsr = (canvas.getContext("2d") as any).backingStorePixelRatio || 1; + const bsr = (this.ctx as any).backingStorePixelRatio || 1; const dpr = window.devicePixelRatio || 1; this.pixelRatio = dpr / bsr; @@ -71,16 +74,16 @@ export class Manager { this.canvasWidth = width; this.canvasHeight = height; - const { canvas, canvasWidth, canvasHeight, pixelRatio } = this; + const { ctx, canvas, canvasWidth, canvasHeight, pixelRatio } = this; - const ctx = canvas.getContext("2d"); + if (!ctx) return; // appropriately scale canvas to map to device ratio canvas.width = canvasWidth * pixelRatio; canvas.height = canvasHeight * pixelRatio; canvas.style.width = canvasWidth + "px"; canvas.style.height = canvasHeight + "px"; - ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0); + ctx.scale(pixelRatio, pixelRatio); } /** @@ -133,9 +136,9 @@ export class Manager { // schedule next draw this.nextAnimationFrame = window.requestAnimationFrame(this.draw); - const ctx = this.canvas.getContext("2d"); + const { ctx, canvasWidth, canvasHeight } = this; - if (!this.shouldDraw) { + if (!this.shouldDraw || !ctx) { return; } @@ -151,7 +154,7 @@ export class Manager { // pending strokes, draw them if (this.currentTool && this.currentStroke.length) { ctx.save(); - this.currentTool.draw(ctx, this.currentStroke); + this.currentTool.draw(ctx, this.currentStroke, canvasWidth, canvasHeight); ctx.restore(); } @@ -161,8 +164,8 @@ export class Manager { this.canvasState = ctx.getImageData( 0, 0, - this.canvasWidth * this.pixelRatio, - this.canvasHeight * this.pixelRatio, + canvasWidth * this.pixelRatio, + canvasHeight * this.pixelRatio, ); this.currentStroke = []; this.shouldCommit = false; diff --git a/src/StrokeManager.ts b/src/StrokeManager.ts index 65a215d..fe27ba2 100644 --- a/src/StrokeManager.ts +++ b/src/StrokeManager.ts @@ -15,6 +15,8 @@ export class StrokeManager { private canvas: HTMLCanvasElement; // holds last touch point in a drag private lastTouch: ITouch | null; + // holds last mouse point in drag + private lastMouse: IPoint | null; // value indicates how sensitive the stroke detection is higher is better private sensitivity: number; // holds all of the last emitted stroke parts in a drag @@ -25,6 +27,7 @@ export class StrokeManager { constructor(canvas: HTMLCanvasElement) { this.canvas = canvas; this.lastTouch = null; + this.lastMouse = null; this.sensitivity = 20.0; this.lastStrokeParts = []; this.onStrokePartHandlers = []; @@ -35,6 +38,9 @@ export class StrokeManager { this.onTouchMove = this.onTouchMove.bind(this); this.destroy = this.destroy.bind(this); this.getRelativePosition = this.getRelativePosition.bind(this); + this.onMouseDown = this.onMouseDown.bind(this); + this.onMouseUp = this.onMouseUp.bind(this); + this.onMouseMove = this.onMouseMove.bind(this); this.canvas.addEventListener("touchstart", this.onTouchStart, { passive: false, @@ -48,6 +54,15 @@ export class StrokeManager { this.canvas.addEventListener("touchmove", this.onTouchMove, { passive: false, }); + this.canvas.addEventListener("mousedown", this.onMouseDown, { + passive: false, + }); + document.addEventListener("mouseup", this.onMouseUp, { + passive: false, + }); + this.canvas.addEventListener("mousemove", this.onMouseMove, { + passive: false, + }); } /** @@ -68,6 +83,9 @@ export class StrokeManager { this.canvas.removeEventListener("touchend", this.onTouchEnd); this.canvas.removeEventListener("touchcancel", this.onTouchCancel); this.canvas.removeEventListener("touchmove", this.onTouchMove); + this.canvas.removeEventListener("mousedown", this.onMouseDown); + document.removeEventListener("mouseup", this.onMouseUp); + this.canvas.removeEventListener("mousemove", this.onMouseMove); } /** @@ -80,8 +98,8 @@ export class StrokeManager { const rect = this.canvas.getBoundingClientRect(); return { - x: clientX - rect.left, - y: clientY - rect.top, + x: (clientX - rect.left) / rect.width, + y: (clientY - rect.top) / rect.height, }; } @@ -220,4 +238,81 @@ export class StrokeManager { this.lastTouch = null; this.lastStrokeParts = []; } + + private onMouseDown(e: MouseEvent): void { + // if there is an ongoing drag, ignore this event + if (this.lastMouse) { + return; + } + + // save the drag + this.lastMouse = this.getRelativePosition(e.clientX, e.clientY); + } + + private onMouseUp(e: MouseEvent): void { + // if no last mouse... something is wrong + if (!this.lastMouse) { + return; + } + + let endPoint = this.getRelativePosition(e.clientX, e.clientY); + + const d = getEuclidean(this.lastMouse, endPoint); + + // if line is less than 1 pixel length, generate a fake line + if (d < 1) { + endPoint = { + x: this.lastMouse.x + 0.0008, + y: this.lastMouse.y + 0.0008, + }; + } + + const strokePart: IStrokePart = { + startPoint: this.lastMouse, + endPoint: endPoint, + isStart: false, + isEnd: true, + }; + + this.onStrokePartHandlers.forEach((handler) => { + handler(strokePart); + }); + + this.lastMouse = null; + this.lastStrokeParts = []; + } + + private onMouseMove(e: MouseEvent): void { + // if no last drag... something is wrong + if (!this.lastMouse) { + return; + } + + const nextMouse = this.getRelativePosition(e.clientX, e.clientY); + + // If sensitivity setting has been set, + // check if this point is far enough from last + // drag to be drawn + if ( + this.sensitivity && + getEuclidean(nextMouse, this.lastMouse) < 0.05 / this.sensitivity + ) { + return; + } + + const strokePart: IStrokePart = { + endPoint: nextMouse, + startPoint: this.lastMouse, + isStart: this.lastStrokeParts.length === 0, + isEnd: false, + }; + + this.onStrokePartHandlers.forEach((handler) => { + handler(strokePart); + }); + + // save this drag as last drag + this.lastMouse = nextMouse; + this.lastStrokeParts.push(strokePart); + } } diff --git a/src/tools/EraserTool.ts b/src/tools/EraserTool.ts index ca74e23..d815527 100644 --- a/src/tools/EraserTool.ts +++ b/src/tools/EraserTool.ts @@ -30,12 +30,17 @@ export class EraserTool { * @param ctx * @param strokeParts */ - public draw(ctx: CanvasRenderingContext2D, strokeParts: IStrokePart[]): void { + public draw( + ctx: CanvasRenderingContext2D, + strokeParts: IStrokePart[], + canvasWidth: number, + canvasHeight: number, + ): void { const { handleOpts } = this; const halfWidth = this.width / 2.0; strokeParts.forEach((strokePart) => { - const { startPoint, endPoint, isEnd } = strokePart; + const { startPoint, endPoint } = strokePart; const length = getEuclidean(startPoint, endPoint); const unitVect: IPoint = getUnitVector(startPoint, endPoint); @@ -45,8 +50,8 @@ export class EraserTool { // clear all the way along the drag while (i < length) { const nextPoint: IPoint = { - x: currentPoint.x + unitVect.x, - y: currentPoint.y + unitVect.y, + x: currentPoint.x * canvasWidth + unitVect.x, + y: currentPoint.y * canvasHeight + unitVect.y, }; ctx.clearRect( @@ -69,16 +74,21 @@ export class EraserTool { ctx.strokeStyle = handleOpts.strokeColor; ctx.fillStyle = handleOpts.fillColor; + const lastEndPoint = { + x: lastPart.endPoint.x * canvasWidth, + y: lastPart.endPoint.y * canvasHeight, + }; + ctx.fillRect( - lastPart.endPoint.x - halfWidth, - lastPart.endPoint.y - halfWidth, + lastEndPoint.x - halfWidth, + lastEndPoint.y - halfWidth, this.width, this.width, ); ctx.strokeRect( - lastPart.endPoint.x - halfWidth + 0.5, - lastPart.endPoint.y - halfWidth + 0.5, + lastEndPoint.x - halfWidth + 0.5, + lastEndPoint.y - halfWidth + 0.5, this.width - 1, this.width - 1, ); diff --git a/src/tools/HighlighterTool.ts b/src/tools/HighlighterTool.ts index 3e34ccb..5f09ce1 100644 --- a/src/tools/HighlighterTool.ts +++ b/src/tools/HighlighterTool.ts @@ -22,7 +22,12 @@ export class HighlighterTool { * @param ctx * @param strokeParts */ - public draw(ctx: CanvasRenderingContext2D, strokeParts: IStrokePart[]): void { + public draw( + ctx: CanvasRenderingContext2D, + strokeParts: IStrokePart[], + canvasWidth: number, + canvasHeight: number, + ): void { const firstPart = strokeParts[0]; ctx.beginPath(); @@ -32,11 +37,14 @@ export class HighlighterTool { ctx.lineCap = "butt"; ctx.miterLimit = 1; - ctx.moveTo(firstPart.startPoint.x, firstPart.startPoint.y); + ctx.moveTo( + firstPart.startPoint.x * canvasWidth, + firstPart.startPoint.y * canvasHeight, + ); strokeParts.forEach((strokePart) => { const { endPoint } = strokePart; - ctx.lineTo(endPoint.x, endPoint.y); + ctx.lineTo(endPoint.x * canvasWidth, endPoint.y * canvasHeight); }); ctx.stroke(); diff --git a/src/tools/PenTool.ts b/src/tools/PenTool.ts index 764dd5b..239c482 100644 --- a/src/tools/PenTool.ts +++ b/src/tools/PenTool.ts @@ -14,7 +14,12 @@ export class PenTool { * @param ctx * @param strokeParts */ - public draw(ctx: CanvasRenderingContext2D, strokeParts: IStrokePart[]): void { + public draw( + ctx: CanvasRenderingContext2D, + strokeParts: IStrokePart[], + canvasWidth: number, + canvasHeight: number, + ): void { const firstPart = strokeParts[0]; ctx.beginPath(); @@ -24,11 +29,14 @@ export class PenTool { ctx.lineCap = "round"; ctx.lineJoin = "round"; - ctx.moveTo(firstPart.startPoint.x, firstPart.startPoint.y); + ctx.moveTo( + firstPart.startPoint.x * canvasWidth, + firstPart.startPoint.y * canvasHeight, + ); strokeParts.forEach((strokePart) => { const { endPoint } = strokePart; - ctx.lineTo(endPoint.x, endPoint.y); + ctx.lineTo(endPoint.x * canvasWidth, endPoint.y * canvasHeight); }); ctx.stroke(); diff --git a/src/types.ts b/src/types.ts index aa47867..47f8803 100644 --- a/src/types.ts +++ b/src/types.ts @@ -14,5 +14,10 @@ export interface ILine { } export interface ITool { - draw(ctx: CanvasRenderingContext2D, strokeParts: IStrokePart[]): void; + draw( + ctx: CanvasRenderingContext2D, + strokeParts: IStrokePart[], + canvasWidth: number, + canvasHeight: number, + ): void; }