From b8a3d60bf600c1c1c61b026d418096be3246b037 Mon Sep 17 00:00:00 2001 From: Johnathon Gaines Date: Sat, 20 Apr 2024 14:39:40 +0000 Subject: [PATCH 1/8] HEXDOC - Added light mode and setup the renderer to read values from CSS --- .../_templates/hexcasting_render.js.jinja | 351 ++++++++++-------- .../_templates/index.css.jinja | 38 ++ 2 files changed, 227 insertions(+), 162 deletions(-) diff --git a/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja b/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja index 6913755be..90cdef7a3 100644 --- a/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja +++ b/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja @@ -14,11 +14,6 @@ import { initializeElem } from "./hexcasting.js"; //package here: https://www.npmjs.com/package/hex_renderer_javascript import init_renderer, {draw_bound_pattern} from "https://cdn.jsdelivr.net/npm/hex_renderer_javascript@0.1.2/hex_renderer_javascript.js"; - -//used for when type hints are needed for the functions (doesn't actually import it in runtime) -//requires hex_renderer_javascript to be installed (npm install hex_renderer_javascript) -// import init_renderer, {draw_bound_pattern} from "hex_renderer_javascript"; - //initializes the WASM code used in the hex_renderer_javascript library init_renderer(); @@ -29,24 +24,46 @@ init_renderer(); * @typedef {import('hex_renderer_javascript').Color} Color * @typedef {import('hex_renderer_javascript').Intersections} Intersections * @typedef {import('hex_renderer_javascript').Point} Point + * @typedef {import('hex_renderer_javascript').Lines} Lines */ //renders the patterns in a collapsible menu //It reads the previous data of the images/animation, uses it to draw the new one //and then it deletes the old -function render_collapsible(draw_options, collapsible) { +function render_collapsible(draw_options, collapsible, palette, class_name) { let patterns = Array.from(collapsible.getElementsByClassName("spell-viz")); for (let pat of patterns) { - var attr = pat.attributes; - var start_dir = attr["data-start"].value; - var pattern_str = attr["data-string"].value; - var width = attr["width"].value; - var height = attr["height"].value; + let img = pat; + if (img.tagName != "IMG") { + var attr = pat.attributes; + + img = new Image(); + img.setAttribute("data-start", attr["data-start"].value); + img.setAttribute("data-string", attr["data-string"].value); + img.setAttribute("width", attr["width"].value); + img.setAttribute("height", attr["height"].value); + img.setAttribute("data-per-world", attr["data-per-world"].value); + + //img.setAttribute("class", "spell-viz"); + + img.innerHTML = pat.innerHTML; - var per_world = "True" == attr["data-per-world"].value; + pat.parentElement?.appendChild(img); + pat.remove() + } else { + URL.revokeObjectURL(img.src); + } + + img.setAttribute("class", class_name + " pattern-settings spell-viz"); + + let per_world = "True" == img.attributes["data-per-world"].value; + let start_dir = img.attributes["data-start"].value; + let pattern_str = img.attributes["data-string"].value; + let width = img.attributes["width"].value; + let height = img.attributes["height"].value; var pattern = { great_spell: per_world, @@ -54,23 +71,19 @@ function render_collapsible(draw_options, collapsible) { angle_sigs: pattern_str, }; - let img_data = draw_bound_pattern(draw_options, pattern, 0.35, width, height); + let style = getStyles(img); - let img = new Image(); - img.src = URL.createObjectURL(new Blob([img_data.buffer], { type: 'image/png' })) + let grid_options = draw_options(style, palette); + console.log({ + options: grid_options, + pattern: pattern, + width: width, + height: height + }); - img.setAttribute("data-start", start_dir); - img.setAttribute("data-string", pattern_str); - img.setAttribute("width", width); - img.setAttribute("height", height); - img.setAttribute("data-per-world", attr["data-per-world"].value); + let img_data = draw_bound_pattern(grid_options, pattern, 0.35, width, height); - img.setAttribute("class", "spell-viz"); - - img.innerHTML = pat.innerHTML; - - pat.parentElement?.appendChild(img); - pat.remove() + img.src = URL.createObjectURL(new Blob([img_data.buffer], { type: 'image/png' })) } } @@ -80,18 +93,18 @@ let last_load_func = null; //lazily renders all of the images with the chosen render options //loads all of the currently open ones and then adds event listeners to open the rest when they're opened -function render_images(draw_options) { +function render_images(draw_options, palette, class_name) { let collapsibles = document.getElementsByClassName("details-collapsible"); let load_func = (event) => { - render_collapsible(draw_options, event.target); + render_collapsible(draw_options, event.target, palette, class_name); } for (let collapsible of collapsibles) { // @ts-ignore collapsible.removeEventListener("toggle", last_load_func, {once: true}); if (collapsible.hasAttribute("open")) { - render_collapsible(draw_options, collapsible); + render_collapsible(draw_options, collapsible, palette, class_name); } else { collapsible.addEventListener("toggle", load_func, {once: true}); } @@ -138,7 +151,10 @@ function load_animated() { if (open) { initializeElem(canvas); } - + + if (pattern.tagName == "IMG") { + URL.revokeObjectURL(/** @type {HTMLImageElement} */ (pattern).src); + } pattern.remove() } } @@ -147,99 +163,152 @@ function load_animated() { } -/** @type {Point} */ -const intersection_point = { - type: "Single", - marker: { - color: [255, 255, 255, 255], - radius: 0.07, - } -}; +/** + * + * @param {string} color + * @returns {Color} + */ +function parseColor(color) { + let num = Number("0x" + color.trim().substring(1)); + let first = Math.floor(num/Math.pow(16,4)); + let second = Math.floor((num/Math.pow(16,2))%256); + let third = Math.floor(num%256); -/** @type {Intersections} */ -const intersections = { - type: "EndsAndMiddle", - start: { - type: "BorderedMatch", - match_radius: 0.04, - border: intersection_point.marker - }, - middle: intersection_point, - end: { - type: "Point", - point: intersection_point - } -}; + return [first, second, third, 255] +} -const line_thickness = 0.12; -/** @type {Color[]} */ -const default_colors = [ - [255, 107, 255, 255], - [168, 30, 227, 255], - [100, 144, 237, 255], - [177, 137, 199, 255], -]; +/** + * + * @param {Element} elem + * @returns {CSSStyleDeclaration} + */ +function getStyles(elem) { + return window.getComputedStyle(elem); +} -/** @type {Point} */ -const center_dot = { - type: "None" -}; +/** + * + * @param {CSSStyleDeclaration} style + * @param {string} palette + * @returns {Color[]} + */ +function getPalette(style, palette) { + return style.getPropertyValue("--" + palette) + .split(',') + .map(row => parseColor(row.trim())); +} -/** @type {GridOptions} */ -const monocolor = { - line_thickness: line_thickness, - center_dot: center_dot, - pattern_options: { - type: "Uniform", - lines: { +/** + * + * @param {CSSStyleDeclaration} style + * @param {Lines} lines + * @returns {GridOptions} + */ +function generateGridOptions(style, lines) { + /** @type {Point} */ + let intersection_point = { + type: "Single", + marker: { + color: parseColor(style.getPropertyValue("--point-color")), + radius: Number(style.getPropertyValue("--point-outer-radius")) + } + }; + + /** @type {Intersections} */ + let intersections = { + type: "EndsAndMiddle", + start: { + type: "BorderedMatch", + match_radius: Number(style.getPropertyValue("--point-inner-radius")), + border: intersection_point.marker + }, + middle: intersection_point, + end: { + type: "Point", + point: intersection_point + } + }; + + return { + line_thickness: Number(style.getPropertyValue("--line-thickness")), + center_dot: { + type: "None" + }, + pattern_options: { + type: "Uniform", + lines: lines, + intersections: intersections + } + } +} + +/** + * @param {CSSStyleDeclaration} style + * @param {string} palette + * @returns + */ +function generateMonocolor(style, palette) { + let palette_offset = Number(style.getPropertyValue("--palette-offset")); + + /** @type {Lines} */ + let lines = { type: "Monocolor", - color: default_colors[0], + color: getPalette(style, palette)[palette_offset], bent: true - }, - intersections: intersections, - }, -}; + } -/** @type {GridOptions} */ -const gradient = { - line_thickness: line_thickness, - center_dot: center_dot, - pattern_options: { - type: "Uniform", - lines: { - type: "Gradient", - colors: default_colors, - bent: true, - segments_per_color: 15, - }, - intersections: intersections, - }, -}; + return generateGridOptions(style, lines); +} + +/** + * + * @param {CSSStyleDeclaration} style + * @param {string} palette + * @returns + */ +function generateSegment(style, palette) { + let triangle_inner_radius = Number(style.getPropertyValue("--triangle-inner-radius")); + let triangle_outer_radius = Number(style.getPropertyValue("--triangle-outer-radius")); + let triangle_color = parseColor(style.getPropertyValue("--triangle-color")); -/** @type {GridOptions} */ -const segment = { - line_thickness: line_thickness, - pattern_options: { - type: "Uniform", - intersections: intersections, - lines: { + /** @type {Lines} */ + let lines = { type: "SegmentColors", - colors: default_colors, + colors: getPalette(style, palette), triangles: { - type: "BorderStartMatch", - match_radius: 0.13, - border: { - color: [255, 255, 255, 255], - radius: 0.20, - } + type: "BorderStartMatch", + match_radius: triangle_inner_radius, + border: { + color: triangle_color, + radius: triangle_outer_radius + } }, collisions: { - type: "ParallelLines" + type: "ParallelLines" } - } - }, - center_dot: center_dot, + } + return generateGridOptions(style, lines); +} + +/** + * + * @param {CSSStyleDeclaration} style + * @param {string} palette + * @returns + */ +function generateGradient(style, palette) { + let segs_per_color = Number(style.getPropertyValue("--segs-per-color")); + + /** @type {Lines} */ + let lines = { + type: "Gradient", + colors: getPalette(style, palette), + bent: true, + segments_per_color: segs_per_color + }; + + return generateGridOptions(style, lines); } let selected = "animated"; @@ -247,11 +316,12 @@ let selected = "animated"; //this is not programmed to accept the Changing pattern option type (it will crash) //it doesn't make sense in this context (as it's rendering single patterns) //and it would take more complex color palettes to work properly + let options = { "animated": -1, - "monocolor": monocolor, - "gradient": gradient, - "segment": segment, + "monocolor": generateMonocolor, + "gradient": generateGradient, + "segment": generateSegment, }; function load_render(name) { @@ -264,47 +334,16 @@ function load_render(name) { if (name == "animated") { load_animated(); } else { - render_images(options[name]); + render_images(options[name], last_palette, name + "-settings"); } } -//all palettes must be an array of colors (to switch between) -//the monocolor option only selects the first color in the palette -//each color is 4 values RGBA (Red, Green, Blue, Alpha (Transparency)) +//palette values stored via css so they can be changedaround let palette_options = { - default: default_colors, - turbo: [ - [63, 61, 156, 255], - [64, 150, 254, 255], - [25, 227, 184, 255], - [132, 254, 80, 255], - [223, 222, 54, 255], - [253, 140, 39, 255], - [214, 52, 5, 255], - [122, 4, 2, 255], - ], - dark2: [ - [27, 158, 119, 255], - [217, 95, 2, 255], - [117, 112, 179, 255], - [231, 41, 138, 255], - [102, 166, 30, 255], - [230, 171, 2, 255], - [166, 118, 29, 255], - [102, 102, 102, 255], - ], - tab10: [ - [31, 119, 180, 255], - [255, 127, 14, 255], - [44, 160, 44, 255], - [214, 39, 40, 255], - [148, 103, 189, 255], - [140, 86, 75, 255], - [227, 119, 194, 255], - [127, 127, 127, 255], - [188, 189, 34, 255], - [23, 190, 207, 255], - ] + default: true, + turbo: true, + dark2: true, + tab10: true } let last_palette = "default"; @@ -317,22 +356,10 @@ export function load_palette(name) { return; } - for (let key in options) { - if (!(options[key] instanceof Object) || !options[key].pattern_options || !options[key].pattern_options.lines) { - continue; - } - - if (options[key].pattern_options.lines.color) { - options[key].pattern_options.lines.color = palette_options[name][0]; - } else { - options[key].pattern_options.lines.colors = palette_options[name]; - } - } - last_palette = name; if (selected != "animated") { - render_images(options[selected]); + render_images(options[selected], last_palette, selected + "-settings"); } } diff --git a/doc/src/hexdoc_hexcasting/_templates/index.css.jinja b/doc/src/hexdoc_hexcasting/_templates/index.css.jinja index 1f9481c35..d609633a5 100644 --- a/doc/src/hexdoc_hexcasting/_templates/index.css.jinja +++ b/doc/src/hexdoc_hexcasting/_templates/index.css.jinja @@ -77,3 +77,41 @@ img.spell-viz { .spell-settings-toggle { font-size: large; } + +.palettes, .pattern-settings { + --default: #ff6bff, #a81ee3, #6490ed, #b189c7; + --turbo: #3f3d9c, #4096fe, #19e3b8, #84fe50, #dfde36, #fd8c27, #d63405, #7a0402; + --dark2: #1b9e77, #d95f02, #7570b3, #e7298a, #66a61e, #e6ab02, #a6761d, #666666; + --tab10: #1f77b4, #ff7f0e, #2ca02c, #d62728, #9467bd, #8c564b, #e377c2, #7f7f7f, #bcbd22, #17becf; +} + +.pattern-settings { + --line-thickness: 0.12; + --point-color: #ffffff; + --point-inner-radius: 0.04; + --point-outer-radius: 0.07; +} +@media (prefers-color-scheme: light) { + .pattern-settings { + --point-color: #000000; + } +} + +.monocolor-settings { + --palette-offset: 0 +} + +.gradient-settings { + --segs-per-color: 15; +} + +.segment-settings { + --triangle-inner-radius: 0.13; + --triangle-outer-radius: 0.2; + --triangle-color: #ffffff; +} +@media (prefers-color-scheme: light) { + .segment-settings { + --triangle-color: #000000; + } +} \ No newline at end of file From 7e4b423d697978f0367810b613d7eb1027b5b2a6 Mon Sep 17 00:00:00 2001 From: Johnathon Gaines Date: Sat, 20 Apr 2024 14:44:44 +0000 Subject: [PATCH 2/8] Removed debugging statements --- .../hexdoc_hexcasting/_templates/hexcasting_render.js.jinja | 6 ------ 1 file changed, 6 deletions(-) diff --git a/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja b/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja index 90cdef7a3..1e37dd25b 100644 --- a/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja +++ b/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja @@ -74,12 +74,6 @@ function render_collapsible(draw_options, collapsible, palette, class_name) { let style = getStyles(img); let grid_options = draw_options(style, palette); - console.log({ - options: grid_options, - pattern: pattern, - width: width, - height: height - }); let img_data = draw_bound_pattern(grid_options, pattern, 0.35, width, height); From 6494f041b257394ed3f0a231856b64f1cab99171 Mon Sep 17 00:00:00 2001 From: Johnathon Gaines Date: Thu, 9 May 2024 22:19:01 +0000 Subject: [PATCH 3/8] Updated hex_renderer_javascript to fix antialiasing --- doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja b/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja index 1e37dd25b..3e570d2cb 100644 --- a/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja +++ b/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja @@ -12,7 +12,7 @@ import { initializeElem } from "./hexcasting.js"; // @ts-ignore //actual import of the renderer //package here: https://www.npmjs.com/package/hex_renderer_javascript -import init_renderer, {draw_bound_pattern} from "https://cdn.jsdelivr.net/npm/hex_renderer_javascript@0.1.2/hex_renderer_javascript.js"; +import init_renderer, {draw_bound_pattern} from "https://cdn.jsdelivr.net/npm/hex_renderer_javascript@0.1.4/hex_renderer_javascript.js"; //initializes the WASM code used in the hex_renderer_javascript library init_renderer(); From 170ce0c2eba1dd1d1e78eeba8200c20ec6b3fe12 Mon Sep 17 00:00:00 2001 From: Johnathon Gaines Date: Fri, 10 May 2024 14:37:48 +0000 Subject: [PATCH 4/8] Stopped caching options for better refresh and added auto update function --- .../_templates/hexcasting_render.js.jinja | 75 +++++++++++++++++-- 1 file changed, 68 insertions(+), 7 deletions(-) diff --git a/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja b/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja index 3e570d2cb..9acc3f66f 100644 --- a/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja +++ b/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja @@ -319,19 +319,80 @@ let options = { }; function load_render(name) { - if (selected == name) { + /*if (selected == name) { return; - } - - selected = name; + }*/ - if (name == "animated") { + if (name == "animated" && selected != name) { load_animated(); } else { render_images(options[name], last_palette, name + "-settings"); } + + selected = name; +} + +function checkEqual(ob1, ob2) { + if (ob1 == ob2) { + return true; + } else if (ob1 == null || ob2 == null) { + return false; + } else if (Object.keys(ob1).length != Object.keys(ob2).length) { + return false; + } + + for (let key in ob1) { + if (!(key in ob2)) { + return false; + } else if (typeof ob1[key] != typeof ob2[key]) { + return false; + } else if (typeof ob1[key] == "object") { + if (!checkEqual(ob1[key], ob2[key])) { + return false; + } + } else if (ob1[key] != ob2[key]) { + return false; + } + } + return true; } +let autoUpdateInterval = null; +function autoUpdateRenderer(interval) { + let real_interval = interval; + if (autoUpdateInterval != null) { + clearInterval(autoUpdateInterval); + } + + if (real_interval == null) { + real_interval = 500; + } else if (real_interval <= 0) { + return; + } + let old_settings = null; + autoUpdateInterval = setInterval(() => { + if (selected == "animated") { + return; + } + let first_pattern = document.querySelector("img.spell-viz"); + if (first_pattern == null) return; + + let styles = getStyles(first_pattern); + + let new_settings = options[selected](styles, last_palette); + if (!checkEqual(new_settings,old_settings)) { + console.log("update!"); + + old_settings = new_settings; + + load_render(selected); + } + + }, real_interval); +} + +window.autoUpdateRenderer = autoUpdateRenderer; + //palette values stored via css so they can be changedaround let palette_options = { default: true, @@ -342,9 +403,9 @@ let palette_options = { let last_palette = "default"; export function load_palette(name) { - if (last_palette == name) { + /*if (last_palette == name) { return; - } + }*/ if (!palette_options[name]) { return; From 88ae5441527c878b714312256fb0af237f14f39a Mon Sep 17 00:00:00 2001 From: Johnathon Gaines Date: Sat, 11 May 2024 18:41:59 +0000 Subject: [PATCH 5/8] Cached auto update element, removed old code, cleaned up code, and did some minor code improvements --- .../_templates/hexcasting_render.js.jinja | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja b/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja index 9acc3f66f..494879feb 100644 --- a/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja +++ b/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja @@ -319,12 +319,12 @@ let options = { }; function load_render(name) { - /*if (selected == name) { - return; - }*/ - if (name == "animated" && selected != name) { - load_animated(); + if (name == "animated") { + if (selected != name) { + cachedPatternImage = null; + load_animated(); + } } else { render_images(options[name], last_palette, name + "-settings"); } @@ -358,37 +358,38 @@ function checkEqual(ob1, ob2) { } let autoUpdateInterval = null; -function autoUpdateRenderer(interval) { - let real_interval = interval; +let cachedPatternImage = null; +function autoUpdateRenderer(interval = 500) { if (autoUpdateInterval != null) { clearInterval(autoUpdateInterval); } - - if (real_interval == null) { - real_interval = 500; - } else if (real_interval <= 0) { + if (interval <= 0) { + console.log(`Invalid interval for autoUpdateRenderer: ${interval}`); return; } + let old_settings = null; autoUpdateInterval = setInterval(() => { if (selected == "animated") { return; } - let first_pattern = document.querySelector("img.spell-viz"); - if (first_pattern == null) return; + if (cachedPatternImage == null) { + cachedPatternImage = document.querySelector("img.spell-viz"); + if (cachedPatternImage == null) return; + } - let styles = getStyles(first_pattern); + let styles = getStyles(cachedPatternImage); let new_settings = options[selected](styles, last_palette); if (!checkEqual(new_settings,old_settings)) { - console.log("update!"); + console.log("updated pattern render from css"); old_settings = new_settings; load_render(selected); } - }, real_interval); + }, interval); } window.autoUpdateRenderer = autoUpdateRenderer; @@ -403,9 +404,6 @@ let palette_options = { let last_palette = "default"; export function load_palette(name) { - /*if (last_palette == name) { - return; - }*/ if (!palette_options[name]) { return; From d7e2be05f94f18ad73c233246387bbd65a116311 Mon Sep 17 00:00:00 2001 From: Johnathon Gaines Date: Sat, 11 May 2024 19:22:54 +0000 Subject: [PATCH 6/8] Fixed color parser --- .../_templates/hexcasting_render.js.jinja | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja b/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja index 494879feb..be6088396 100644 --- a/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja +++ b/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja @@ -163,7 +163,12 @@ function load_animated() { * @returns {Color} */ function parseColor(color) { - let num = Number("0x" + color.trim().substring(1)); + let num = Number("0x" + color.trim().substring(1,7)); + + if (Number.isNaN(num)) { + throw new Error("Failed to parse color!"); + } + let first = Math.floor(num/Math.pow(16,4)); let second = Math.floor((num/Math.pow(16,2))%256); let third = Math.floor(num%256); From 90b142fc0ff5c9452f75e518971dc0d2b233acec Mon Sep 17 00:00:00 2001 From: Johnathon Gaines Date: Sat, 11 May 2024 20:08:00 +0000 Subject: [PATCH 7/8] Further improved color parser and made it refersh when opening/closing pattern panes --- .../_templates/hexcasting_render.js.jinja | 93 +++++++++++++------ 1 file changed, 64 insertions(+), 29 deletions(-) diff --git a/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja b/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja index be6088396..170213a56 100644 --- a/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja +++ b/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja @@ -163,16 +163,27 @@ function load_animated() { * @returns {Color} */ function parseColor(color) { - let num = Number("0x" + color.trim().substring(1,7)); + let trimmed_color = color.trim().substring(1,7); + + let first = 0; + let second = 0; + let third = 0; + + //color is either 12 bits (RGB) or 16 bits (RGBA) + if (trimmed_color.length == 3 || trimmed_color.length == 4) { + first = Number("0x" + trimmed_color[0]) * 16; + second = Number("0x" + trimmed_color[1]) * 16; + third = Number("0x" + trimmed_color[2]) * 16; + } else { //color is either 24 bits (RGB) or 32 bits (RGBA) + first = Number("0x" + trimmed_color.substring(0,2)); + second = Number("0x" + trimmed_color.substring(2,4)); + third = Number("0x" + trimmed_color.substring(4,6)); + } - if (Number.isNaN(num)) { + if (Number.isNaN(first) || Number.isNaN(second) || Number.isNaN(third)) { throw new Error("Failed to parse color!"); } - let first = Math.floor(num/Math.pow(16,4)); - let second = Math.floor((num/Math.pow(16,2))%256); - let third = Math.floor(num%256); - return [first, second, third, 255] } @@ -332,6 +343,9 @@ function load_render(name) { } } else { render_images(options[name], last_palette, name + "-settings"); + + //update cached settings to avoid double update + old_settings = getSettings(name); } selected = name; @@ -364,6 +378,35 @@ function checkEqual(ob1, ob2) { let autoUpdateInterval = null; let cachedPatternImage = null; + +let old_settings = null; + +function getSettings(render_option) { + if (cachedPatternImage == null) { + cachedPatternImage = document.querySelector("img.spell-viz"); + if (cachedPatternImage == null) return; + } + + let styles = getStyles(cachedPatternImage); + + return options[render_option](styles, last_palette); +} +function updateRenders() { + if (selected == "animated") { + return; + } + + let new_settings = getSettings(selected); + + if (!checkEqual(new_settings,old_settings)) { + console.log("updated pattern render from css"); + + old_settings = new_settings; + + load_render(selected); + } +} + function autoUpdateRenderer(interval = 500) { if (autoUpdateInterval != null) { clearInterval(autoUpdateInterval); @@ -373,28 +416,7 @@ function autoUpdateRenderer(interval = 500) { return; } - let old_settings = null; - autoUpdateInterval = setInterval(() => { - if (selected == "animated") { - return; - } - if (cachedPatternImage == null) { - cachedPatternImage = document.querySelector("img.spell-viz"); - if (cachedPatternImage == null) return; - } - - let styles = getStyles(cachedPatternImage); - - let new_settings = options[selected](styles, last_palette); - if (!checkEqual(new_settings,old_settings)) { - console.log("updated pattern render from css"); - - old_settings = new_settings; - - load_render(selected); - } - - }, interval); + autoUpdateInterval = setInterval(updateRenders, interval); } window.autoUpdateRenderer = autoUpdateRenderer; @@ -466,4 +488,17 @@ function setup_menus() { } -setup_menus(); \ No newline at end of file +function setup_update_triggers() { + let collapsibles = document.getElementsByClassName("details-collapsible"); + + for (let collapsible of collapsibles) { + collapsible.addEventListener("toggle", () => { + if (collapsible.open) { + updateRenders(); + } + }, {once: false}); + } +} + +setup_menus(); +setup_update_triggers(); \ No newline at end of file From f6f4c0b4d7478f504b0c08fe92f867702c9852ca Mon Sep 17 00:00:00 2001 From: Johnathon Gaines Date: Sat, 11 May 2024 20:47:10 +0000 Subject: [PATCH 8/8] Removed autoUpdateRenderer in favor of opening/closing panes --- .../_templates/hexcasting_render.js.jinja | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja b/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja index 170213a56..f034eb085 100644 --- a/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja +++ b/doc/src/hexdoc_hexcasting/_templates/hexcasting_render.js.jinja @@ -376,7 +376,6 @@ function checkEqual(ob1, ob2) { return true; } -let autoUpdateInterval = null; let cachedPatternImage = null; let old_settings = null; @@ -407,19 +406,6 @@ function updateRenders() { } } -function autoUpdateRenderer(interval = 500) { - if (autoUpdateInterval != null) { - clearInterval(autoUpdateInterval); - } - if (interval <= 0) { - console.log(`Invalid interval for autoUpdateRenderer: ${interval}`); - return; - } - - autoUpdateInterval = setInterval(updateRenders, interval); -} - -window.autoUpdateRenderer = autoUpdateRenderer; //palette values stored via css so they can be changedaround let palette_options = {