From 56b6eb2a13dfd1fc1ffa1653e2ebd94bdfcbe8f2 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sat, 30 Jan 2021 03:23:17 +0300 Subject: [PATCH] v1.5.04 - Emblems better positioning and rescaling --- main.js | 17 +++++++++- modules/coa-generator.js | 5 +++ modules/ui/layers.js | 68 +++++++++++++++++++++++++++------------- modules/ui/style.js | 3 +- modules/utils.js | 2 +- 5 files changed, 69 insertions(+), 26 deletions(-) diff --git a/main.js b/main.js index 697e7340..9ef68fde 100644 --- a/main.js +++ b/main.js @@ -437,10 +437,25 @@ function invokeActiveZooming() { const relative = Math.max(rn((desired + desired / scale) / 2, 2), 1); this.getAttribute("font-size", relative); const hidden = hideLabels.checked && (relative * scale < 6 || relative * scale > 50); - if (hidden) this.classList.add("hidden"); else this.classList.remove("hidden"); + if (hidden) this.classList.add("hidden"); + else this.classList.remove("hidden"); }); } + // rescale emblems on zoom + if (emblems.style("display") !== "none") { + const fontSize = rn(1 / scale ** .1, 4); + emblems.attr("font-size", fontSize); + // const realSize = fontSize * scale; + + // emblems.selectAll("use").each(function(d) { + + // const hidden = realSize < 20 || realSize > 350; + // if (hidden) this.classList.add("hidden"); + // else this.classList.remove("hidden"); + // }); + } + // turn off ocean pattern if scale is big (improves performance) oceanPattern.select("rect").attr("fill", scale > 10 ? "#fff" : "url(#oceanic)").attr("opacity", scale > 10 ? .2 : null); diff --git a/modules/coa-generator.js b/modules/coa-generator.js index 9f473711..9250d7f7 100644 --- a/modules/coa-generator.js +++ b/modules/coa-generator.js @@ -202,6 +202,11 @@ // emblems layer for old maps // define emblems layer style for all styles // add coa on click events for loaded map + // generatate state/prov/burg - remove all rendered coas + // remove state/prov/burg - remove rendered coa + // style settings for emblems layer + // fix download svg/png + // test in FF const t1 = parent && P(.25) ? parent.t1 : getTincture("field"); const coa = {t1}; diff --git a/modules/ui/layers.js b/modules/ui/layers.js index 018c1b2a..8e4d11dc 100644 --- a/modules/ui/layers.js +++ b/modules/ui/layers.js @@ -1244,8 +1244,6 @@ function drawEmblems() { TIME && console.time("drawEmblems"); const {states, provinces, burgs, cells} = pack; - let svg = ""; - // const sizeBurgs = +emblems.attr("size-burgs") || 15; // burgs.filter(b => b.i && !b.removed && b.coa).forEach(burg => { // const {x, y} = burg; @@ -1253,39 +1251,65 @@ function drawEmblems() { // svg += ``; // }); - const sizeProvinces = +emblems.attr("size-provinces") || 25; - const provinceCOAs = provinces.filter(p => p.i && !p.removed && p.coa).map(province => { + const validStates = states.filter(s => s.i && !s.removed && s.coa); + const validProvinces = provinces.filter(p => p.i && !p.removed && p.coa); + + const sizeMod = +emblems.attr("size-modifier") || 1; + const getStateEmblemsSize = () => { + const startSize = (graphHeight + graphWidth) / 40; + const statesMod = (1 + validStates.length / 100) - (15 - validStates.length) / 200; // states number modifier + const size = rn(startSize / statesMod * sizeMod); // target size ~50px on 1536x754 map with 15 states + return Math.min(Math.max(size, 10), 100); + }; + + const getProvinceEmblemsSize = () => { + const startSize = (graphHeight + graphWidth) / 80; + const provincesMod = (1 + validProvinces.length / 1000) - (115 - validProvinces.length) / 1000; // states number modifier + const size = rn(startSize / provincesMod * sizeMod); // target size ~50px on 1536x754 map with 15 states + return Math.min(Math.max(size, 5), 75); + } + + const sizeProvinces = getProvinceEmblemsSize(); + const provinceCOAs = validProvinces.map(province => { if (!province.pole) getProvincesVertices(); const [x, y] = province.pole; COArenderer.trigger("provinceCOA"+province.i, province.coa); - //svg += ``; - return {type: "province", id: "provinceCOA"+province.i, x: x - sizeProvinces/2, y: y - sizeProvinces/2, size: sizeProvinces, el: province}; + return {type: "province", id: "provinceCOA"+province.i, x, y, size: sizeProvinces, el: province}; }); - const sizeStates = +emblems.attr("size-states") || 50; - const stateCOAs = states.filter(s => s.i && !s.removed && s.coa).map(state => { + const sizeStates = getStateEmblemsSize(); + const stateCOAs = validStates.map(state => { const [x, y] = state.pole; COArenderer.trigger("stateCOA"+state.i, state.coa); - //svg += ``; - return {type: "state", id: "stateCOA"+state.i, x: x - sizeStates/2, y: y - sizeStates/2, size: sizeStates, el: state}; + return {type: "state", id: "stateCOA"+state.i, x, y, size: sizeStates, el: state}; }); const nodes = provinceCOAs.concat(stateCOAs); - // emblems.html(svg); - const simulation = d3.forceSimulation(nodes) - .alphaMin(.6).alphaDecay(.2) - .force('collision', d3.forceCollide().radius(d => d.size/2)); + .alphaMin(.6).alphaDecay(.2).velocityDecay(.6) + .force('collision', d3.forceCollide().radius(d => d.size/2)) + .stop(); - const node = emblems.selectAll("use").data(nodes).join("use") - .attr("href", d => "#"+d.id) - .attr("x", d => d.x) - .attr("y", d => d.y) - .attr("width", d => d.size) - .attr("height", d => d.size); + debug.attr("fill", "#fff").attr("stroke", "#000") + .selectAll("circle").data(nodes).join("circle") + .attr("cx", d => d.x) + .attr("cy", d => d.y) + .attr("r", 2); - simulation.on("tick", () => { - node.attr("x", d => d.x).attr("y", d => d.y); + d3.timeout(function() { + const n = Math.ceil(Math.log(simulation.alphaMin()) / Math.log(1 - simulation.alphaDecay())); + for (let i = 0; i < n; ++i) { + simulation.tick(); + } + + emblems.selectAll("use").data(nodes).join("use") + .attr("href", d => "#"+d.id) + .attr("x", d => d.x - d.size / 2) + .attr("y", d => d.y - d.size / 2) + .attr("width", d => d.size + "em") + .attr("height", d => d.size + "em"); + + invokeActiveZooming(); }); TIME && console.timeEnd("drawEmblems"); diff --git a/modules/ui/style.js b/modules/ui/style.js index 13a9d5f0..19a5923a 100644 --- a/modules/ui/style.js +++ b/modules/ui/style.js @@ -795,8 +795,7 @@ function applyDefaultStyle() { labels.select("#addedLabels").attr("fill", "#3e3e4b").attr("opacity", 1).attr("stroke", "#3a3a3a").attr("stroke-width", 0).attr("font-family", "Almendra SC").attr("data-font", "Almendra+SC").attr("font-size", 18).attr("data-size", 18).attr("filter", null); fogging.attr("opacity", .98).attr("fill", "#30426f"); - - emblems.attr("opacity", .9).attr("size-states", 50).attr("size-provinces", 25).attr("size-burgs", 15).attr("filter", null); + emblems.attr("opacity", .9).attr("font-size", 1).attr("size-modifier", 1).attr("filter", null) } // apply style settings in JSON diff --git a/modules/utils.js b/modules/utils.js index 005d0738..3e34336c 100644 --- a/modules/utils.js +++ b/modules/utils.js @@ -232,7 +232,7 @@ function gauss(expected = 100, deviation = 30, min = 0, max = 300, round = 0) { return rn(Math.max(Math.min(d3.randomNormal(expected, deviation)(), max), min), round); } -/** This is a description of the foo function. */ +// probability shorthand for floats function Pint(float) { return ~~float + +P(float % 1); }