From c25d4e69d36579da743fa7e0059cad781813c639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Mur=C3=A7a?= Date: Mon, 9 Jan 2023 09:52:46 -0300 Subject: [PATCH] Add embossed visualization --- src/file-renderer/pattern.js | 42 +++++++++++++++++++++++++++++++----- src/utils/rgbToHex.js | 15 +++++++++++++ src/utils/shadeColor.js | 20 +++++++++++++++++ 3 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 src/utils/rgbToHex.js create mode 100644 src/utils/shadeColor.js diff --git a/src/file-renderer/pattern.js b/src/file-renderer/pattern.js index 59ebe24..ab58964 100644 --- a/src/file-renderer/pattern.js +++ b/src/file-renderer/pattern.js @@ -1,3 +1,6 @@ +import { rgbToHex } from "../utils/rgbToHex"; +import { shadeColor } from "../utils/shadeColor"; + function Stitch(x, y, flags, color) { this.flags = flags; this.x = x; @@ -149,28 +152,57 @@ Pattern.prototype.fixColorCount = function () { Pattern.prototype.drawShapeTo = function (canvas) { canvas.width = this.right; canvas.height = this.bottom; + + let gradient, tx, ty; + let lastStitch = this.stitches[0]; + let gWidth = 100; if (canvas.getContext) { const ctx = canvas.getContext("2d"); + ctx.lineWidth = 3; + ctx.lineJoin = "round"; + let color = this.colors[this.stitches[0].color]; - ctx.beginPath(); - ctx.strokeStyle = "rgb(" + color.r + "," + color.g + "," + color.b + ")"; for (let i = 0; i < this.stitches.length; i++) { const currentStitch = this.stitches[i]; + if (i > 0) lastStitch = this.stitches[i - 1]; + tx = currentStitch.x - lastStitch.x; + ty = currentStitch.y - lastStitch.y; + + gWidth = Math.sqrt(tx * tx + ty * ty); + gradient = ctx.createRadialGradient( + currentStitch.x - tx, + currentStitch.y - ty, + 0, + currentStitch.x - tx, + currentStitch.y - ty, + gWidth * 1.4 + ); + + gradient.addColorStop("0", shadeColor(rgbToHex(color), -60)); + gradient.addColorStop("0.05", rgbToHex(color)); + gradient.addColorStop("0.5", shadeColor(rgbToHex(color), 60)); + gradient.addColorStop("0.9", rgbToHex(color)); + gradient.addColorStop("1.0", shadeColor(rgbToHex(color), -60)); + + ctx.strokeStyle = gradient; if ( currentStitch.flags === stitchTypes.jump || currentStitch.flags === stitchTypes.trim || currentStitch.flags === stitchTypes.stop ) { - ctx.stroke(); color = this.colors[currentStitch.color]; ctx.beginPath(); ctx.strokeStyle = - "rgb(" + color.r + "," + color.g + "," + color.b + ")"; + "rgba(" + color.r + "," + color.g + "," + color.b + ",0)"; ctx.moveTo(currentStitch.x, currentStitch.y); + ctx.stroke(); } + ctx.beginPath(); + ctx.moveTo(lastStitch.x, lastStitch.y); ctx.lineTo(currentStitch.x, currentStitch.y); + ctx.stroke(); + lastStitch = currentStitch; } - ctx.stroke(); } }; diff --git a/src/utils/rgbToHex.js b/src/utils/rgbToHex.js new file mode 100644 index 0000000..a09eac5 --- /dev/null +++ b/src/utils/rgbToHex.js @@ -0,0 +1,15 @@ +function componentToHex(c) { + var hex = c.toString(16); + return hex.length == 1 ? "0" + hex : hex; +} + +function rgbToHex(color) { + return ( + "#" + + componentToHex(color.r) + + componentToHex(color.g) + + componentToHex(color.b) + ); +} + +export { rgbToHex }; diff --git a/src/utils/shadeColor.js b/src/utils/shadeColor.js new file mode 100644 index 0000000..7afff5a --- /dev/null +++ b/src/utils/shadeColor.js @@ -0,0 +1,20 @@ +function shadeColor(color, percent) { + const num = parseInt(color.slice(1), 16), + amt = Math.round(2.55 * percent), + R = (num >> 16) + amt, + G = ((num >> 8) & 0x00ff) + amt, + B = (num & 0x0000ff) + amt; + return ( + "#" + + ( + 0x1000000 + + (R < 255 ? (R < 1 ? 0 : R) : 255) * 0x10000 + + (G < 255 ? (G < 1 ? 0 : G) : 255) * 0x100 + + (B < 255 ? (B < 1 ? 0 : B) : 255) + ) + .toString(16) + .slice(1) + ); +} + +export { shadeColor };