feat: vignette layer

This commit is contained in:
Azgaar 2023-11-25 18:04:59 +04:00
parent 425c2954c4
commit 7f60a4a12a
8 changed files with 106 additions and 64 deletions

View file

@ -362,25 +362,14 @@
<mask id="vignette-mask">
<rect x="0" y="0" width="100%" height="100%" fill="white"></rect>
<rect
id="vignette-rect"
transform="translate(25%, 25%)"
x="0%"
y="0%"
width="100%"
height="100%"
fill="black"
filter="blur(50px)"
rx="5%"
ry="5%"
></rect>
<rect id="vignette-rect" fill="black"></rect>
</mask>
</defs>
<g id="viewbox"></g>
<g id="vignette" mask="url(#vignette-mask)" fill="black" opacity="0.5">
<g id="scaleBar"></g>
<g id="vignette" mask="url(#vignette-mask)">
<rect x="0" y="0" width="100%" height="100%" />
</g>
<g id="scaleBar"></g>
</svg>
<div id="loading">
@ -722,6 +711,15 @@
>
Scale Bar
</li>
<li
id="toggleVignette"
data-tip="Vignette (border fading): click to toggle. Ctrl + click to edit style"
data-shortcut="[ (left bracket)"
onclick="toggleVignette(event)"
class="solid"
>
Vignette
</li>
</ul>
<div id="viewMode" data-tip="Set view node">
@ -935,15 +933,15 @@
<td style="display: flex; flex-direction: column; gap: 2px">
<div>
<span>x </span>
<input id="styleVignetteX" type="number" min="0" max="100" style="width: 5em" />
<input id="styleVignetteX" type="number" min="0" max="100" step="0.1" style="width: 5em" />
<span>width&nbsp; </span>
<input id="styleVignetteWidth" type="number" min="0" max="100" style="width: 5em" />
<input id="styleVignetteWidth" type="number" min="0" max="100" step="0.1" style="width: 5em" />
</div>
<div>
<span>y </span>
<input id="styleVignetteY" type="number" min="0" max="100" style="width: 5em" />
<input id="styleVignetteY" type="number" min="0" max="100" step="0.1" style="width: 5em" />
<span>height </span>
<input id="styleVignetteHeight" type="number" min="0" max="100" style="width: 5em" />
<input id="styleVignetteHeight" type="number" min="0" max="100" step="0.1" style="width: 5em" />
</div>
</td>
</tr>
@ -7971,7 +7969,7 @@
<script src="config/heightmap-templates.js"></script>
<script src="config/precreated-heightmaps.js"></script>
<script src="modules/heightmap-generator.js?v=1.88.00"></script>
<script src="modules/ocean-layers.js?v=1.93.07"></script>
<script src="modules/ocean-layers.js?v=1.95.00"></script>
<script src="modules/river-generator.js?v=1.89.13"></script>
<script src="modules/lakes.js"></script>
<script src="modules/biomes.js"></script>
@ -8032,12 +8030,12 @@
<script defer src="modules/ui/markers-editor.js"></script>
<script defer src="modules/ui/3d.js?v=1.94.03"></script>
<script defer src="modules/ui/submap.js?v=1.94.03"></script>
<script defer src="modules/ui/hotkeys.js?v=1.93.00"></script>
<script defer src="modules/ui/hotkeys.js?v=1.95.00"></script>
<script defer src="modules/coa-renderer.js?v=1.94.00"></script>
<script defer src="libs/rgbquant.min.js"></script>
<script defer src="libs/jquery.ui.touch-punch.min.js"></script>
<script defer src="modules/io/save.js?v=1.93.02"></script>
<script defer src="modules/io/load.js?v=1.94.05"></script>
<script defer src="modules/io/load.js?v=1.95.00"></script>
<script defer src="modules/io/cloud.js?v=1.94.04"></script>
<script defer src="modules/io/export.js?v=1.94.03"></script>
<script defer src="modules/io/formats.js"></script>

View file

@ -1,7 +1,7 @@
// Azgaar (azgaar.fmg@yandex.com). Minsk, 2017-2022. MIT License
"use strict";
// Azgaar (azgaar.fmg@yandex.com). Minsk, 2017-2023. MIT License
// https://github.com/Azgaar/Fantasy-Map-Generator
"use strict";
// set debug options
const PRODUCTION = location.hostname && location.hostname !== "localhost" && location.hostname !== "127.0.0.1";
const DEBUG = localStorage.getItem("debug");

View file

@ -710,4 +710,30 @@ export function resolveVersionConflicts(version) {
drawTexture();
}
}
if (version < 1.95) {
// v1.95.00 added vignette visual layer
const mask = defs.append("mask").attr("id", "vignette-mask");
mask.append("rect").attr("fill", "white").attr("x", 0).attr("y", 0).attr("width", "100%").attr("height", "100%");
mask
.append("rect")
.attr("id", "vignette-rect")
.attr("fill", "black")
.attr("x", "0.3%")
.attr("y", "0.4%")
.attr("width", "99.4%")
.attr("height", "99.2%")
.attr("rx", "5%")
.attr("ry", "5%")
.attr("filter", "blur(20px)");
const vignette = svg
.append("g")
.attr("id", "vignette")
.attr("mask", "url(#vignette-mask)")
.attr("opacity", 0.3)
.attr("fill", "#000000")
.style("display", "none");
vignette.append("rect").attr("x", 0).attr("y", 0).attr("width", "100%").attr("height", "100%");
}
}

View file

@ -10,7 +10,7 @@ async function quickLoad() {
}
async function loadFromDropbox() {
const mapPath = document.getElementById("loadFromDropboxSelect")?.value;
const mapPath = byId("loadFromDropboxSelect")?.value;
DEBUG && console.log("Loading map from Dropbox:", mapPath);
const blob = await Cloud.providers.dropbox.load(mapPath);
@ -19,8 +19,8 @@ async function loadFromDropbox() {
async function createSharableDropboxLink() {
const mapFile = document.querySelector("#loadFromDropbox select").value;
const sharableLink = document.getElementById("sharableLink");
const sharableLinkContainer = document.getElementById("sharableLinkContainer");
const sharableLink = byId("sharableLink");
const sharableLinkContainer = byId("sharableLinkContainer");
try {
const previewLink = await Cloud.providers.dropbox.getLink(mapFile);
@ -110,7 +110,7 @@ function uploadMap(file, callback) {
const fileReader = new FileReader();
fileReader.onloadend = async function (fileLoadedEvent) {
if (callback) callback();
document.getElementById("coas").innerHTML = ""; // remove auto-generated emblems
byId("coas").innerHTML = ""; // remove auto-generated emblems
const result = fileLoadedEvent.target.result;
const [mapData, mapVersion] = await parseLoadedResult(result);
@ -408,15 +408,14 @@ async function parseLoadedData(data) {
})();
void (function restoreLayersState() {
// helper functions
const notHidden = selection => selection.node() && selection.style("display") !== "none";
const isVisible = selection => selection.node() && selection.style("display") !== "none";
const isVisibleNode = node => node && node.style.display !== "none";
const hasChildren = selection => selection.node()?.hasChildNodes();
const hasChild = (selection, selector) => selection.node()?.querySelector(selector);
const turnOn = el => document.getElementById(el).classList.remove("buttonoff");
const turnOn = el => byId(el).classList.remove("buttonoff");
// turn all layers off
document
.getElementById("mapLayers")
byId("mapLayers")
.querySelectorAll("li")
.forEach(el => el.classList.add("buttonoff"));
@ -427,27 +426,28 @@ async function parseLoadedData(data) {
if (hasChildren(cells)) turnOn("toggleCells");
if (hasChildren(gridOverlay)) turnOn("toggleGrid");
if (hasChildren(coordinates)) turnOn("toggleCoordinates");
if (notHidden(compass) && hasChild(compass, "use")) turnOn("toggleCompass");
if (isVisible(compass) && hasChild(compass, "use")) turnOn("toggleCompass");
if (hasChildren(rivers)) turnOn("toggleRivers");
if (notHidden(terrain) && hasChildren(terrain)) turnOn("toggleRelief");
if (isVisible(terrain) && hasChildren(terrain)) turnOn("toggleRelief");
if (hasChildren(relig)) turnOn("toggleReligions");
if (hasChildren(cults)) turnOn("toggleCultures");
if (hasChildren(statesBody)) turnOn("toggleStates");
if (hasChildren(provs)) turnOn("toggleProvinces");
if (hasChildren(zones) && notHidden(zones)) turnOn("toggleZones");
if (notHidden(borders) && hasChild(borders, "path")) turnOn("toggleBorders");
if (notHidden(routes) && hasChild(routes, "path")) turnOn("toggleRoutes");
if (hasChildren(zones) && isVisible(zones)) turnOn("toggleZones");
if (isVisible(borders) && hasChild(borders, "path")) turnOn("toggleBorders");
if (isVisible(routes) && hasChild(routes, "path")) turnOn("toggleRoutes");
if (hasChildren(temperature)) turnOn("toggleTemp");
if (hasChild(population, "line")) turnOn("togglePopulation");
if (hasChildren(ice)) turnOn("toggleIce");
if (hasChild(prec, "circle")) turnOn("togglePrec");
if (notHidden(emblems) && hasChild(emblems, "use")) turnOn("toggleEmblems");
if (notHidden(labels)) turnOn("toggleLabels");
if (notHidden(icons)) turnOn("toggleIcons");
if (hasChildren(armies) && notHidden(armies)) turnOn("toggleMilitary");
if (isVisible(emblems) && hasChild(emblems, "use")) turnOn("toggleEmblems");
if (isVisible(labels)) turnOn("toggleLabels");
if (isVisible(icons)) turnOn("toggleIcons");
if (hasChildren(armies) && isVisible(armies)) turnOn("toggleMilitary");
if (hasChildren(markers)) turnOn("toggleMarkers");
if (notHidden(ruler)) turnOn("toggleRulers");
if (notHidden(scaleBar)) turnOn("toggleScaleBar");
if (isVisible(ruler)) turnOn("toggleRulers");
if (isVisible(scaleBar)) turnOn("toggleScaleBar");
if (isVisibleNode(byId("vignette"))) turnOn("toggleVignette");
getCurrentPreset();
})();
@ -462,7 +462,7 @@ async function parseLoadedData(data) {
{
// dynamically import and run auto-update script
const versionNumber = parseFloat(params[0]);
const {resolveVersionConflicts} = await import("../dynamic/auto-update.js?v=1.94.00");
const {resolveVersionConflicts} = await import("../dynamic/auto-update.js?v=1.95.00");
resolveVersionConflicts(versionNumber);
}

View file

@ -91,6 +91,7 @@ function handleKeyup(event) {
else if (code === "KeyK") toggleMarkers();
else if (code === "Equal" && !customization) toggleRulers();
else if (code === "Slash") toggleScaleBar();
else if (code === "BracketLeft") toggleVignette();
else if (code === "ArrowLeft") zoom.translateBy(svg, 10, 0);
else if (code === "ArrowRight") zoom.translateBy(svg, -10, 0);
else if (code === "ArrowUp") zoom.translateBy(svg, 0, 10);

View file

@ -14,7 +14,8 @@ function getDefaultPresets() {
"toggleRivers",
"toggleRoutes",
"toggleScaleBar",
"toggleStates"
"toggleStates",
"toggleVignette"
],
cultural: [
"toggleBorders",
@ -23,7 +24,8 @@ function getDefaultPresets() {
"toggleLabels",
"toggleRivers",
"toggleRoutes",
"toggleScaleBar"
"toggleScaleBar",
"toggleVignette"
],
religions: [
"toggleBorders",
@ -32,12 +34,13 @@ function getDefaultPresets() {
"toggleReligions",
"toggleRivers",
"toggleRoutes",
"toggleScaleBar"
"toggleScaleBar",
"toggleVignette"
],
provinces: ["toggleBorders", "toggleIcons", "toggleProvinces", "toggleRivers", "toggleScaleBar"],
biomes: ["toggleBiomes", "toggleIce", "toggleRivers", "toggleScaleBar"],
heightmap: ["toggleHeight", "toggleRivers"],
physical: ["toggleCoordinates", "toggleHeight", "toggleIce", "toggleRivers", "toggleScaleBar"],
provinces: ["toggleBorders", "toggleIcons", "toggleProvinces", "toggleRivers", "toggleScaleBar", "toggleVignette"],
biomes: ["toggleBiomes", "toggleIce", "toggleRivers", "toggleScaleBar", "toggleVignette"],
heightmap: ["toggleHeight", "toggleRivers", "toggleVignette"],
physical: ["toggleCoordinates", "toggleHeight", "toggleIce", "toggleRivers", "toggleScaleBar", "toggleVignette"],
poi: [
"toggleBorders",
"toggleHeight",
@ -46,7 +49,8 @@ function getDefaultPresets() {
"toggleMarkers",
"toggleRivers",
"toggleRoutes",
"toggleScaleBar"
"toggleScaleBar",
"toggleVignette"
],
military: [
"toggleBorders",
@ -56,7 +60,8 @@ function getDefaultPresets() {
"toggleRivers",
"toggleRoutes",
"toggleScaleBar",
"toggleStates"
"toggleStates",
"toggleVignette"
],
emblems: [
"toggleBorders",
@ -66,7 +71,8 @@ function getDefaultPresets() {
"toggleRivers",
"toggleRoutes",
"toggleScaleBar",
"toggleStates"
"toggleStates",
"toggleVignette"
],
landmass: ["toggleScaleBar"]
};
@ -1862,6 +1868,18 @@ function drawEmblems() {
TIME && console.timeEnd("drawEmblems");
}
function toggleVignette(event) {
if (!layerIsOn("toggleVignette")) {
turnButtonOn("toggleVignette");
$("#vignette").fadeIn();
if (event && isCtrlClick(event)) editStyle("vignette");
} else {
if (event && isCtrlClick(event)) return editStyle("vignette");
$("#vignette").fadeOut();
turnButtonOff("toggleVignette");
}
}
function layerIsOn(el) {
const buttonoff = document.getElementById(el).classList.contains("buttonoff");
return !buttonoff;

View file

@ -386,17 +386,17 @@
"filter": null
},
"#vignette": {
"opacity": 0.5,
"opacity": 0.3,
"fill": "#000000",
"filter": null
},
"#vignette-rect": {
"x": "1%",
"y": "2%",
"width": "98%",
"height": "96%",
"rx": "10%",
"ry": "10%",
"x": "0.3%",
"y": "0.4%",
"width": "99.6%",
"height": "99.2%",
"rx": "5%",
"ry": "5%",
"filter": "blur(20px)"
}
}

View file

@ -1,7 +1,7 @@
"use strict";
// version and caching control
const version = "1.94.06"; // generator version, update each time
const version = "1.95.00"; // generator version, update each time
{
document.title += " v" + version;
@ -28,6 +28,7 @@ const version = "1.94.06"; // generator version, update each time
<ul>
<strong>Latest changes:</strong>
<li>Vignette visual layer and vignette color options</li>
<li>Ability to define custom heightmap color scheme</li>
<li>New style preset Night and new heightmap color schemes</li>
<li>Random encounter markers (integration with <a href="https://deorum.vercel.app/" target="_blank">Deorum</a>)</li>
@ -39,8 +40,6 @@ const version = "1.94.06"; // generator version, update each time
<li>New 3D scene options and improvements</li>
<li>Autosave feature (in Options)</li>
<li>Google translation support (in Options)</li>
<li>Religions can be edited and redrawn like cultures</li>
<li>Lock states, provinces, cultures, and religions from regeneration</li>
</ul>
<p>Join our <a href="${discord}" target="_blank">Discord server</a> and <a href="${reddit}" target="_blank">Reddit community</a> to ask questions, share maps, discuss the Generator and Worlbuilding, report bugs and propose new features.</p>