mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
commit
36870a3881
13 changed files with 273 additions and 235 deletions
41
index.css
41
index.css
|
|
@ -2089,9 +2089,10 @@ svg.button {
|
|||
padding: 1.2em;
|
||||
border: solid 1px #000;
|
||||
font-size: 1.2em;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
#promptTest {
|
||||
#promptText {
|
||||
padding: 0 0 .6em 0;
|
||||
font-weight: bold;
|
||||
font-family: sans-serif;
|
||||
|
|
@ -2125,6 +2126,44 @@ svg.button {
|
|||
stroke-width: 0;
|
||||
}
|
||||
|
||||
.pell {
|
||||
border: 1px solid hsla(0,0%,4%,.1)
|
||||
}
|
||||
|
||||
.pell,.pell-content {
|
||||
box-sizing: border-box
|
||||
}
|
||||
|
||||
.pell-content {
|
||||
height: 14em;
|
||||
outline: 0;
|
||||
overflow-y: auto;
|
||||
padding: .6em;
|
||||
font-family: Copperplate, monospace;
|
||||
background-color: #fff;
|
||||
border: 1px solid #dedede;
|
||||
}
|
||||
|
||||
.pell-actionbar {
|
||||
background-color: #fff;
|
||||
border: 1px solid #dedede;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.pell-button {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
height: 30px;
|
||||
outline: 0;
|
||||
width: 30px;
|
||||
vertical-align: bottom
|
||||
}
|
||||
|
||||
.pell-button-selected {
|
||||
background-color: #f0f0f0
|
||||
}
|
||||
|
||||
#debug {
|
||||
font-size: 1px;
|
||||
opacity: .8;
|
||||
|
|
|
|||
20
index.html
20
index.html
|
|
@ -2412,9 +2412,9 @@
|
|||
<i data-tip="Marker Icon" class="icon-info"></i>
|
||||
<button id="markerIconSelect" data-tip="Click to select icon"></button>
|
||||
<i data-tip="Change marker horizontal shift" class="icon-resize-horizontal"></i>
|
||||
<input id="markerIconShiftX" data-tip="Change icon horizontal shift" type="number" value=50 style="width:3em">
|
||||
<input id="markerIconShiftX" data-tip="Change icon horizontal shift" type="number" value=50>
|
||||
<i data-tip="Change marker vertical shift" class="icon-resize-vertical"></i>
|
||||
<input id="markerIconShiftY" data-tip="Change vertical shift" type="number" min=0 max=100 value=50 style="width:3em">
|
||||
<input id="markerIconShiftY" data-tip="Change vertical shift" type="number" min=0 max=100 value=50>
|
||||
</div>
|
||||
|
||||
<button id="markerStyle" data-tip="Change marker size and colors" class="icon-brush"></button>
|
||||
|
|
@ -2538,7 +2538,7 @@
|
|||
<span>Attackers</span>
|
||||
<div style="float: right; font-size: .7em">
|
||||
<meter id="battleMorale_attackers" data-tip="Attackers morale: " min=0 max=100 low=33 high=66 optimum=80></meter>
|
||||
<div id="battlePower_attackers" data-tip="Attackers strength during this phase. Strength defines dealt damage" style="width: 3.2em; display: inline-block; text-align: center" class="icon-button-power"></div>
|
||||
<div id="battlePower_attackers" data-tip="Attackers strength during this phase. Strength defines dealt damage" style="display: inline-block; text-align: center" class="icon-button-power"></div>
|
||||
<div style="display: inline-block;">
|
||||
<button id="battlePhase_attackers" style="width: 3.2em"></button>
|
||||
<div class="battlePhases" style="display: none"></div>
|
||||
|
|
@ -2551,7 +2551,7 @@
|
|||
<span></span>Defenders</span>
|
||||
<div style="float: right; font-size: .7em">
|
||||
<meter id="battleMorale_defenders" data-tip="Defenders morale: " min=0 max=100 low=33 high=66 optimum=80></meter>
|
||||
<div id="battlePower_defenders" data-tip="Defenders strength during this phase. Strength defines dealt damage" style="width: 3.2em; display: inline-block; text-align: center" class="icon-button-power"></div>
|
||||
<div id="battlePower_defenders" data-tip="Defenders strength during this phase. Strength defines dealt damage" style="display: inline-block; text-align: center" class="icon-button-power"></div>
|
||||
<div style="display: inline-block;">
|
||||
<button id="battlePhase_defenders" style="width: 3.2em"></button>
|
||||
<div class="battlePhases" style="display: none"></div>
|
||||
|
|
@ -3209,14 +3209,12 @@
|
|||
<span>Select object: </span>
|
||||
<select id="notesSelect" data-tip="Select object" style="width: 12em"></select>
|
||||
<span>Object name: </span>
|
||||
<input id="notesName" data-tip="Type to change object name" autocorrect="off" spellcheck="false" style="width: 17em">
|
||||
</div>
|
||||
<div>
|
||||
<span>Legend:</span><br>
|
||||
<textarea id="notesText" rows="7" data-tip="Type object description" placeholder="Type object description"></textarea>
|
||||
<input id="notesName" data-tip="Type to change object name" autocorrect="off" spellcheck="false" style="width: 16em">
|
||||
</div>
|
||||
<div id="notesText" data-tip="Type and style object description" style="padding: .4em 0"></div>
|
||||
<div>
|
||||
<button id="notesFocus" data-tip="Focus on selected object" class="icon-target"></button>
|
||||
<button id="notesPin" data-tip="Toggle notes box dispay: hide or do not hide the box on mouse move" class="icon-pin"></button>
|
||||
<button id="notesDownload" data-tip="Download notes to PC" class="icon-download"></button>
|
||||
<button id="notesUpload" data-tip="Upload notes from PC" class="icon-upload"></button>
|
||||
<button id="notesRemove" data-tip="Remove this note" class="icon-trash fastDelete"></button>
|
||||
|
|
@ -3672,7 +3670,7 @@
|
|||
|
||||
<div id="prompt" style="display: none" class="dialog">
|
||||
<form id="promptForm">
|
||||
<div id="promptTest"></div>
|
||||
<div id="promptText"></div>
|
||||
<input id="promptInput" type="number" step=.01 placeholder="type value" autocomplete="off" required>
|
||||
<button type="submit">Confirm</button>
|
||||
<button type="button" id="promptCancel" formnovalidate>Cancel</button>
|
||||
|
|
@ -3762,5 +3760,5 @@
|
|||
<script defer src="modules/ui/3d.js"></script>
|
||||
<script defer src="libs/rgbquant.js"></script>
|
||||
<script defer src="libs/jquery.ui.touch-punch.min.js"></script>
|
||||
<script defer src="libs/publicstorage.js"></script>
|
||||
<script defer src="libs/pell.js"></script>
|
||||
</body>
|
||||
|
|
|
|||
163
libs/pell.js
Normal file
163
libs/pell.js
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
(global.Pell = factory());
|
||||
}(this, (function () { 'use strict';
|
||||
|
||||
const defaultParagraphSeparatorString = 'defaultParagraphSeparator'
|
||||
const formatBlock = 'formatBlock'
|
||||
const addEventListener = (parent, type, listener) => parent.addEventListener(type, listener)
|
||||
const appendChild = (parent, child) => parent.appendChild(child)
|
||||
const createElement = tag => document.createElement(tag)
|
||||
const queryCommandState = command => document.queryCommandState(command)
|
||||
const queryCommandValue = command => document.queryCommandValue(command)
|
||||
const exec = (command, value = null) => document.execCommand(command, false, value)
|
||||
|
||||
const defaultActions = {
|
||||
bold: {
|
||||
icon: '<b>B</b>',
|
||||
title: 'Bold',
|
||||
state: () => queryCommandState('bold'),
|
||||
result: () => exec('bold')
|
||||
},
|
||||
italic: {
|
||||
icon: '<i>I</i>',
|
||||
title: 'Italic',
|
||||
state: () => queryCommandState('italic'),
|
||||
result: () => exec('italic')
|
||||
},
|
||||
underline: {
|
||||
icon: '<u>U</u>',
|
||||
title: 'Underline',
|
||||
state: () => queryCommandState('underline'),
|
||||
result: () => exec('underline')
|
||||
},
|
||||
strikethrough: {
|
||||
icon: '<strike>S</strike>',
|
||||
title: 'Strike-through',
|
||||
state: () => queryCommandState('strikeThrough'),
|
||||
result: () => exec('strikeThrough')
|
||||
},
|
||||
heading1: {
|
||||
icon: '<b>H<sub>1</sub></b>',
|
||||
title: 'Heading 1',
|
||||
result: () => exec(formatBlock, '<h1>')
|
||||
},
|
||||
heading2: {
|
||||
icon: '<b>H<sub>2</sub></b>',
|
||||
title: 'Heading 2',
|
||||
result: () => exec(formatBlock, '<h2>')
|
||||
},
|
||||
paragraph: {
|
||||
icon: '¶',
|
||||
title: 'Paragraph',
|
||||
result: () => exec(formatBlock, '<p>')
|
||||
},
|
||||
quote: {
|
||||
icon: '“ ”',
|
||||
title: 'Quote',
|
||||
result: () => exec(formatBlock, '<blockquote>')
|
||||
},
|
||||
olist: {
|
||||
icon: '#',
|
||||
title: 'Ordered List',
|
||||
result: () => exec('insertOrderedList')
|
||||
},
|
||||
ulist: {
|
||||
icon: '•',
|
||||
title: 'Unordered List',
|
||||
result: () => exec('insertUnorderedList')
|
||||
},
|
||||
code: {
|
||||
icon: '</>',
|
||||
title: 'Code',
|
||||
result: () => exec(formatBlock, '<pre>')
|
||||
},
|
||||
line: {
|
||||
icon: '―',
|
||||
title: 'Horizontal Line',
|
||||
result: () => exec('insertHorizontalRule')
|
||||
},
|
||||
link: {
|
||||
icon: '🔗',
|
||||
title: 'Link',
|
||||
result: () => navigator.clipboard.readText().then(url => exec('createLink', url))
|
||||
},
|
||||
image: {
|
||||
icon: '📷',
|
||||
title: 'Image',
|
||||
result: () => {
|
||||
navigator.clipboard.readText().then(url => exec('insertImage', url))
|
||||
exec('enableObjectResizing')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const defaultClasses = {
|
||||
actionbar: 'pell-actionbar',
|
||||
button: 'pell-button',
|
||||
content: 'pell-content',
|
||||
selected: 'pell-button-selected'
|
||||
}
|
||||
|
||||
const init = settings => {
|
||||
const actions = settings.actions
|
||||
? (
|
||||
settings.actions.map(action => {
|
||||
if (typeof action === 'string') return defaultActions[action]
|
||||
else if (defaultActions[action.name]) return { ...defaultActions[action.name], ...action }
|
||||
return action
|
||||
})
|
||||
)
|
||||
: Object.keys(defaultActions).map(action => defaultActions[action])
|
||||
|
||||
const classes = { ...defaultClasses, ...settings.classes }
|
||||
|
||||
const defaultParagraphSeparator = settings[defaultParagraphSeparatorString] || 'div'
|
||||
|
||||
const actionbar = createElement('div')
|
||||
actionbar.className = classes.actionbar
|
||||
appendChild(settings.element, actionbar)
|
||||
|
||||
const content = settings.element.content = createElement('div')
|
||||
content.contentEditable = true
|
||||
content.className = classes.content
|
||||
content.oninput = ({ target: { firstChild } }) => {
|
||||
if (firstChild && firstChild.nodeType === 3) exec(formatBlock, `<${defaultParagraphSeparator}>`)
|
||||
else if (content.innerHTML === '<br>') content.innerHTML = ''
|
||||
settings.onChange(content.innerHTML)
|
||||
}
|
||||
content.onkeydown = event => {
|
||||
if (event.key === 'Enter' && queryCommandValue(formatBlock) === 'blockquote') {
|
||||
setTimeout(() => exec(formatBlock, `<${defaultParagraphSeparator}>`), 0)
|
||||
}
|
||||
}
|
||||
appendChild(settings.element, content)
|
||||
|
||||
actions.forEach(action => {
|
||||
const button = createElement('button')
|
||||
button.className = classes.button
|
||||
button.innerHTML = action.icon
|
||||
button.title = action.title
|
||||
button.setAttribute('type', 'button')
|
||||
button.onclick = () => action.result() && content.focus()
|
||||
|
||||
if (action.state) {
|
||||
const handler = () => button.classList[action.state() ? 'add' : 'remove'](classes.selected)
|
||||
addEventListener(content, 'keyup', handler)
|
||||
addEventListener(content, 'mouseup', handler)
|
||||
addEventListener(button, 'click', handler)
|
||||
}
|
||||
|
||||
appendChild(actionbar, button)
|
||||
})
|
||||
|
||||
if (settings.styleWithCSS) exec('styleWithCSS')
|
||||
exec(defaultParagraphSeparatorString, defaultParagraphSeparator)
|
||||
|
||||
return settings.element
|
||||
}
|
||||
|
||||
return {exec, init}
|
||||
|
||||
})));
|
||||
|
|
@ -1,188 +0,0 @@
|
|||
// https://github.com/Highbrainer/jeevaneo-js-publicstorage. MIT
|
||||
const IFRAME_ROOT_URL = "https://publicstorage.neocities.org/shared-iframe.html";
|
||||
|
||||
class PublicStorageAccess {
|
||||
|
||||
constructor ({debug=false}={}) {
|
||||
this.uid = this.uniqueId();
|
||||
this.debug=debug;
|
||||
}
|
||||
|
||||
uniqueId() {
|
||||
function chr4(){
|
||||
return Math.random().toString(16).slice(-4);
|
||||
}
|
||||
return chr4() + chr4() +
|
||||
'-' + chr4() +
|
||||
'-' + chr4() +
|
||||
'-' + chr4() +
|
||||
'-' + chr4() + chr4() + chr4();
|
||||
}
|
||||
|
||||
_debug(msg) {
|
||||
if(this.debug) {
|
||||
if(console && console.debug) {
|
||||
console.debug(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prepareIFrame() {
|
||||
const that = this;
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.id=that.uid;
|
||||
iframe.src=IFRAME_ROOT_URL + "?uid=init-"+that.uid;
|
||||
iframe.style.cssText="display:none;";
|
||||
return new Promise(function(resolve, reject) {
|
||||
window.addEventListener('message', function mafunc(tkn) {
|
||||
|
||||
if (IFRAME_ROOT_URL.indexOf(tkn.origin)<0) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const packet = JSON.parse(tkn.data);
|
||||
|
||||
if(!(packet.frameId === "init-" + that.uid)) {
|
||||
// ignore
|
||||
return;
|
||||
}
|
||||
|
||||
if(packet.ready) {
|
||||
resolve(iframe);
|
||||
}
|
||||
} catch (e) {
|
||||
reject(tkn.data);
|
||||
}
|
||||
window.removeEventListener('message', mafunc);
|
||||
});
|
||||
onLoadThen().then(() => {
|
||||
document.getElementsByTagName("body")[0].appendChild(iframe);
|
||||
});
|
||||
|
||||
setTimeout(()=>reject(`Request ${that.uid} TIMEOUTED!`), 20000);
|
||||
});
|
||||
}
|
||||
|
||||
access(access, prop, value = null, level = "local") {
|
||||
|
||||
if(!(access === "get" || access === "set" || access === "delete")) {
|
||||
throw new Error("access can only be 'set', 'get' or 'delete' - not '" + access + "'");
|
||||
}
|
||||
|
||||
if (!prop) {
|
||||
throw new Error("Prop name is mandatory");
|
||||
}
|
||||
|
||||
if(!(level === "local" || level === "session")) {
|
||||
throw new Error("level can only be 'session' or 'local' - not '" + access + "'");
|
||||
}
|
||||
|
||||
const that = this;
|
||||
|
||||
const promise = new Promise(function(resolve, reject) {
|
||||
that.prepareIFrame().then(iframe => {
|
||||
window.addEventListener('message', function mafunc(tkn) {
|
||||
if (IFRAME_ROOT_URL.indexOf(tkn.origin)<0) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
var packet = JSON.parse(tkn.data);
|
||||
|
||||
if(!(packet.uid === that.uid)) {
|
||||
// ignore
|
||||
return;
|
||||
}
|
||||
resolve(packet.body);
|
||||
} catch (e) {
|
||||
reject(tkn.data);
|
||||
}
|
||||
iframe.parentNode.removeChild(iframe);
|
||||
window.removeEventListener('message', mafunc);
|
||||
});
|
||||
|
||||
const request = {uid:that.uid, access:access, prop:prop, value:value, level:level};
|
||||
iframe.contentWindow.postMessage(JSON.stringify(request), '*');
|
||||
setTimeout(()=>reject("TIMEOUTED!"), 20000);
|
||||
});
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function __createDebugIFrame() {
|
||||
onLoadThen().then(function(){
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.src=IFRAME_ROOT_URL + "?for-debug-only";
|
||||
iframe.style.cssText="display:none;";
|
||||
document.getElementsByTagName("body")[0].appendChild(iframe);
|
||||
});
|
||||
}
|
||||
|
||||
class PublicStorage {
|
||||
|
||||
constructor({debug=false}={}) {
|
||||
if(debug) {
|
||||
__createDebugIFrame();
|
||||
}
|
||||
}
|
||||
|
||||
sessionGet(prop) {
|
||||
return new PublicStorageAccess().access("get", prop, null, "session");
|
||||
}
|
||||
sessionSet(prop, value) {
|
||||
return new PublicStorageAccess().access("set", prop, value, "session");
|
||||
}
|
||||
sessionUnset(prop) {
|
||||
return new PublicStorageAccess().access("delete", prop, null, "session");
|
||||
}
|
||||
localGet(prop) {
|
||||
return new PublicStorageAccess().access("get", prop, null, "local");
|
||||
}
|
||||
localSet(prop, value) {
|
||||
return new PublicStorageAccess().access("set", prop, value, "local");
|
||||
}
|
||||
localUnset(prop) {
|
||||
return new PublicStorageAccess().access("delete", prop, null, "local");
|
||||
}
|
||||
get(prop) {
|
||||
return this.localGet(prop);
|
||||
}
|
||||
set(prop, value) {
|
||||
return this.localSet(prop, value);
|
||||
}
|
||||
unset(prop) {
|
||||
return this.localUnset(prop);
|
||||
}
|
||||
}
|
||||
|
||||
const publicstorage = new PublicStorage();
|
||||
|
||||
function onLoadThen() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
if (window) {
|
||||
if(document.getElementsByTagName('BODY')[0]) {
|
||||
resolve();
|
||||
} else {
|
||||
registerOnLoad(function unregisterme() {
|
||||
resolve();
|
||||
window.removeEventListener('load', unregisterme);
|
||||
});
|
||||
}
|
||||
}
|
||||
setTimeout(function() {reject(new Error("Timeout waiting for onLoad!"));}, 10000);
|
||||
});
|
||||
}
|
||||
|
||||
function registerOnLoad(lambda) {
|
||||
if (window.addEventListener) {
|
||||
window.addEventListener('load', lambda);
|
||||
} else if (window.attachEvent) {
|
||||
window.attachEvent('onload', lambda);
|
||||
}
|
||||
}
|
||||
|
||||
onLoadThen().then(() => window.publicstorage = publicstorage).catch(e=> console.error(e));
|
||||
//export {onLoadThen, PublicStorage, publicstorage as default}
|
||||
// module.exports = onLoadThen();
|
||||
2
main.js
2
main.js
|
|
@ -117,7 +117,7 @@ let scale = 1, viewX = 0, viewY = 0;
|
|||
const zoom = d3.zoom().scaleExtent([1, 20]).on("zoom", zoomed);
|
||||
|
||||
// default options
|
||||
let options = {}; // options object
|
||||
let options = {pinNotes:false}; // options object
|
||||
let mapCoordinates = {}; // map coordinates on globe
|
||||
options.winds = [225, 45, 225, 315, 135, 315]; // default wind directions
|
||||
|
||||
|
|
|
|||
|
|
@ -599,14 +599,15 @@
|
|||
|
||||
// generate historical conflicts of each state
|
||||
const generateCampaigns = function() {
|
||||
const wars = {"War":4, "Conflict":2, "Campaign":4, "Invasion":2, "Rebellion":2, "Conquest":2, "Intervention":1, "Expedition":1, "Crusade":1};
|
||||
const wars = {"War":6, "Conflict":2, "Campaign":4, "Invasion":2, "Rebellion":2, "Conquest":2, "Intervention":1, "Expedition":1, "Crusade":1};
|
||||
|
||||
pack.states.forEach(s => {
|
||||
if (!s.i || s.removed) return;
|
||||
const n = s.neighbors.length ? s.neighbors : [0];
|
||||
s.campaigns = n.map(i => {
|
||||
const name = i && P(.8) ? pack.states[i].name : Names.getCultureShort(s.culture);
|
||||
const start = gauss(options.year-100, 150, 1, options.year-6), end = start + gauss(4, 5, 1, options.year - start - 1);
|
||||
const start = gauss(options.year-100, 150, 1, options.year-6);
|
||||
const end = start + gauss(4, 5, 1, options.year - start - 1);
|
||||
return {name:getAdjective(name) + " " + rw(wars), start, end};
|
||||
}).sort((a, b) => a.start - b.start);
|
||||
});
|
||||
|
|
@ -689,9 +690,10 @@
|
|||
|
||||
// start a war
|
||||
const war = [`${an}-${trimVowels(dn)}ian War`,`${an} declared a war on its rival ${dn}`];
|
||||
const start = options.year - gauss(2, 2, 0, 5);
|
||||
states[attacker].campaigns.push({name: `${trimVowels(dn)}ian War`, start, end:options.year});
|
||||
states[defender].campaigns.push({name: `${trimVowels(an)}ian War`, start, end:options.year});
|
||||
const end = options.year;
|
||||
const start = end - gauss(2, 2, 0, 5);
|
||||
states[attacker].campaigns.push({name: `${trimVowels(dn)}ian War`, start, end});
|
||||
states[defender].campaigns.push({name: `${trimVowels(an)}ian War`, start, end});
|
||||
|
||||
// attacker vassals join the war
|
||||
ad.forEach((r, d) => {if (r === "Suzerain") {
|
||||
|
|
|
|||
|
|
@ -526,7 +526,7 @@ function uploadMap(file, callback) {
|
|||
} else {
|
||||
load = true;
|
||||
message = `The map version (${mapVersion}) does not match the Generator version (${version}).
|
||||
<br>The map will be auto-updated. In case of issues please keep using an ${archive} of the Generator`;
|
||||
<br>Click OK to get map auto-updated. In case of issues please keep using an ${archive} of the Generator`;
|
||||
}
|
||||
alertMessage.innerHTML = message;
|
||||
$("#alert").dialog({title: "Version conflict", width: "38em", buttons: {
|
||||
|
|
@ -937,7 +937,7 @@ function parseLoadedData(data) {
|
|||
|
||||
if (version < 1.3) {
|
||||
// v 1.3 added global options object
|
||||
const winds = options.slice(); // previostly wnd was saved in settings[19]
|
||||
const winds = options.slice(); // previostly wind was saved in settings[19]
|
||||
const year = rand(100, 2000);
|
||||
const era = Names.getBaseShort(P(.7) ? 1 : rand(nameBases.length)) + " Era";
|
||||
const eraShort = era[0] + "E";
|
||||
|
|
@ -1047,6 +1047,11 @@ function parseLoadedData(data) {
|
|||
}()
|
||||
|
||||
changeMapSize();
|
||||
|
||||
// set options
|
||||
yearInput.value = options.year;
|
||||
eraInput.value = options.era;
|
||||
|
||||
if (window.restoreDefaultEvents) restoreDefaultEvents();
|
||||
focusOn(); // based on searchParams focus on point, cell or burg
|
||||
invokeActiveZooming();
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ function showElevationProfile(data, routeLen, isRiver) {
|
|||
chartData.ma = Math.max(chartData.ma, chartData.height[i]);
|
||||
}
|
||||
|
||||
if (lastBurgIndex != 0 && lastBurgCell == chartData.cell[data.length-1] && lastBurgIndex < data.length) {
|
||||
if (lastBurgIndex != 0 && lastBurgCell == chartData.cell[data.length-1] && lastBurgIndex < data.length-1) {
|
||||
chartData.burg[data.length-1] = chartData.burg[lastBurgIndex];
|
||||
chartData.burg[lastBurgIndex] = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ function moved() {
|
|||
|
||||
// show note box on hover (if any)
|
||||
function showNotes(e, i) {
|
||||
if (notesEditor.offsetParent) return;
|
||||
let id = e.target.id || e.target.parentNode.id || e.target.parentNode.parentNode.id;
|
||||
if (e.target.parentNode.parentNode.id === "burgLabels") id = "burg" + e.target.dataset.id; else
|
||||
if (e.target.parentNode.parentNode.id === "burgIcons") id = "burg" + e.target.dataset.id;
|
||||
|
|
@ -70,7 +71,7 @@ function showNotes(e, i) {
|
|||
document.getElementById("notes").style.display = "block";
|
||||
document.getElementById("notesHeader").innerHTML = note.name;
|
||||
document.getElementById("notesBody").innerHTML = note.legend;
|
||||
} else {
|
||||
} else if (!options.pinNotes) {
|
||||
document.getElementById("notes").style.display = "none";
|
||||
document.getElementById("notesHeader").innerHTML = "";
|
||||
document.getElementById("notesBody").innerHTML = "";
|
||||
|
|
|
|||
|
|
@ -5,6 +5,18 @@ function editNotes(id, name) {
|
|||
select.options.length = 0;
|
||||
for (const note of notes) {select.options.add(new Option(note.id, note.id));}
|
||||
|
||||
// initiate pell (html editor)
|
||||
const editor = Pell.init({
|
||||
element: document.getElementById("notesText"),
|
||||
onChange: html => {
|
||||
const id = document.getElementById("notesSelect").value;
|
||||
const note = notes.find(note => note.id === id);
|
||||
if (!note) return;
|
||||
note.legend = html;
|
||||
showNote(note);
|
||||
}
|
||||
});
|
||||
|
||||
// select an object
|
||||
if (notes.length || id) {
|
||||
if (!id) id = notes[0].id;
|
||||
|
|
@ -17,17 +29,18 @@ function editNotes(id, name) {
|
|||
}
|
||||
select.value = id;
|
||||
notesName.value = note.name;
|
||||
notesText.value = note.legend;
|
||||
editor.content.innerHTML = note.legend;
|
||||
showNote(note);
|
||||
} else {
|
||||
const value = "There are no added notes. Click on element (e.g. label) and add a free text note";
|
||||
document.getElementById("notesText").value = value;
|
||||
editor.content.innerHTML = "There are no added notes. Click on element (e.g. label) and add a free text note";
|
||||
document.getElementById("notesName").value = "";
|
||||
}
|
||||
|
||||
// open a dialog
|
||||
$("#notesEditor").dialog({
|
||||
title: "Notes Editor", minWidth: "40em",
|
||||
position: {my: "center", at: "center", of: "svg"}
|
||||
position: {my: "center", at: "center", of: "svg"},
|
||||
close: () => notesText.innerHTML = ""
|
||||
});
|
||||
|
||||
if (modules.editNotes) return;
|
||||
|
|
@ -36,18 +49,24 @@ function editNotes(id, name) {
|
|||
// add listeners
|
||||
document.getElementById("notesSelect").addEventListener("change", changeObject);
|
||||
document.getElementById("notesName").addEventListener("input", changeName);
|
||||
document.getElementById("notesText").addEventListener("input", changeText);
|
||||
document.getElementById("notesPin").addEventListener("click", () => options.pinNotes = !options.pinNotes);
|
||||
document.getElementById("notesFocus").addEventListener("click", validateHighlightElement);
|
||||
document.getElementById("notesDownload").addEventListener("click", downloadLegends);
|
||||
document.getElementById("notesUpload").addEventListener("click", () => legendsToLoad.click());
|
||||
document.getElementById("legendsToLoad").addEventListener("change", function() {uploadFile(this, uploadLegends)});
|
||||
document.getElementById("notesRemove").addEventListener("click", triggerNotesRemove);
|
||||
|
||||
function showNote(note) {
|
||||
document.getElementById("notes").style.display = "block";
|
||||
document.getElementById("notesHeader").innerHTML = note.name;
|
||||
document.getElementById("notesBody").innerHTML = note.legend;
|
||||
}
|
||||
|
||||
function changeObject() {
|
||||
const note = notes.find(note => note.id === this.value);
|
||||
if (!note) return;
|
||||
notesName.value = note.name;
|
||||
notesText.value = note.legend;
|
||||
editor.content.innerHTML = note.legend;
|
||||
}
|
||||
|
||||
function changeName() {
|
||||
|
|
@ -55,13 +74,7 @@ function editNotes(id, name) {
|
|||
const note = notes.find(note => note.id === id);
|
||||
if (!note) return;
|
||||
note.name = this.value;
|
||||
}
|
||||
|
||||
function changeText() {
|
||||
const id = document.getElementById("notesSelect").value;
|
||||
const note = notes.find(note => note.id === id);
|
||||
if (!note) return;
|
||||
note.legend = this.value;
|
||||
showNote(note);
|
||||
}
|
||||
|
||||
function validateHighlightElement() {
|
||||
|
|
|
|||
|
|
@ -109,6 +109,8 @@ optionsContent.addEventListener("change", function(event) {
|
|||
if (id === "zoomExtentMin" || id === "zoomExtentMax") changeZoomExtent(value);
|
||||
else if (id === "optionsSeed") generateMapWithSeed();
|
||||
else if (id === "uiSizeInput") changeUIsize(value);
|
||||
else if (id === "yearInput") changeYear();
|
||||
else if (id === "eraInput") changeEra();
|
||||
});
|
||||
|
||||
optionsContent.addEventListener("click", function(event) {
|
||||
|
|
@ -397,7 +399,7 @@ function randomizeCultureSet() {
|
|||
function generateEra() {
|
||||
if (!stored("year")) yearInput.value = rand(100, 2000); // current year
|
||||
if (!stored("era")) eraInput.value = Names.getBaseShort(P(.7) ? 1 : rand(nameBases.length)) + " Era";
|
||||
options.year = yearInput.value;
|
||||
options.year = +yearInput.value;
|
||||
options.era = eraInput.value;
|
||||
options.eraShort = options.era.split(" ").map(w => w[0].toUpperCase()).join(""); // short name for era
|
||||
}
|
||||
|
|
@ -408,6 +410,18 @@ function regenerateEra() {
|
|||
options.eraShort = options.era.split(" ").map(w => w[0].toUpperCase()).join("");
|
||||
}
|
||||
|
||||
function changeYear() {
|
||||
if (!yearInput.value) return;
|
||||
if (isNaN(+yearInput.value)) {tip("Current year should be a number", false, "error"); return;}
|
||||
options.year = +yearInput.value;
|
||||
}
|
||||
|
||||
function changeEra() {
|
||||
if (!eraInput.value) return;
|
||||
lock("era");
|
||||
options.era = eraInput.value;
|
||||
}
|
||||
|
||||
// remove all saved data from LocalStorage and reload the page
|
||||
function restoreDefaultOptions() {
|
||||
localStorage.clear();
|
||||
|
|
|
|||
|
|
@ -454,15 +454,6 @@ function editStates() {
|
|||
});
|
||||
armies.select("g#army"+state).remove();
|
||||
|
||||
const military = pack.states[elSelected.dataset.state].military;
|
||||
const regIndex = military.indexOf(regiment());
|
||||
if (regIndex === -1) return;
|
||||
military.splice(regIndex, 1);
|
||||
|
||||
const index = notes.findIndex(n => n.id === elSelected.id);
|
||||
if (index != -1) notes.splice(index, 1);
|
||||
elSelected.remove();
|
||||
|
||||
const capital = pack.states[state].capital;
|
||||
pack.burgs[capital].capital = 0;
|
||||
pack.burgs[capital].state = 0;
|
||||
|
|
|
|||
|
|
@ -602,10 +602,10 @@ void function() {
|
|||
const prompt = document.getElementById("prompt");
|
||||
const form = prompt.querySelector("#promptForm");
|
||||
|
||||
window.prompt = function(promptTest = "Please provide an input", options = {default:1, step:.01, min:0, max:100}, callback) {
|
||||
window.prompt = function(promptText = "Please provide an input", options = {default:1, step:.01, min:0, max:100}, callback) {
|
||||
if (options.default === undefined) {console.error("Prompt: options object does not have default value defined"); return;}
|
||||
const input = prompt.querySelector("#promptInput");
|
||||
prompt.querySelector("#promptTest").innerHTML = promptTest;
|
||||
prompt.querySelector("#promptText").innerHTML = promptText;
|
||||
const type = typeof(options.default) === "number" ? "number" : "text";
|
||||
input.type = type;
|
||||
if (options.step !== undefined) input.step = options.step;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue