2023-03-22 16:38:18 +01:00
|
|
|
/*!
|
|
|
|
* The 2022 r/place Atlas
|
|
|
|
* Copyright (c) 2017 Roland Rytz <roland@draemm.li>
|
|
|
|
* Copyright (c) 2022 Place Atlas contributors
|
|
|
|
* Licensed under AGPL-3.0 (https://place-atlas.stefanocoding.me/license.txt)
|
|
|
|
*/
|
2017-04-04 01:24:46 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
const innerContainer = document.getElementById("innerContainer")
|
|
|
|
const container = document.getElementById("container")
|
2023-04-07 11:44:33 +02:00
|
|
|
const highlightCanvas = document.getElementById("highlightCanvas")
|
|
|
|
const imageCanvas = document.getElementById('image')
|
|
|
|
const highlightContext = highlightCanvas.getContext("2d")
|
2017-04-04 01:24:46 +02:00
|
|
|
|
2023-04-07 11:44:33 +02:00
|
|
|
highlightCanvas.width = canvasSize.x
|
|
|
|
highlightCanvas.height = canvasSize.y
|
|
|
|
imageCanvas.width = canvasSize.x
|
|
|
|
imageCanvas.height = canvasSize.y
|
2023-03-20 14:44:25 +01:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
let zoom = 1
|
2017-04-08 03:27:51 +02:00
|
|
|
|
2022-04-16 14:44:50 +02:00
|
|
|
if (window.devicePixelRatio) {
|
2022-05-06 09:41:22 +02:00
|
|
|
zoom = 1 / window.devicePixelRatio
|
2017-04-08 03:27:51 +02:00
|
|
|
}
|
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
const maxZoom = 128
|
|
|
|
const minZoom = 0.1
|
2017-04-08 05:57:12 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
let zoomOrigin = [0, 0]
|
|
|
|
let scaleZoomOrigin = [0, 0]
|
2017-04-04 01:24:46 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
let dragging = false
|
|
|
|
let lastPosition = [0, 0]
|
2017-04-04 01:24:46 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
const viewportSize = [0, 0]
|
2017-04-06 19:15:16 +02:00
|
|
|
|
2023-03-26 13:58:17 +02:00
|
|
|
// TODO Probably merge both functions
|
2022-04-16 14:44:50 +02:00
|
|
|
function applyView() {
|
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
//console.log(zoomOrigin, scaleZoomOrigin)
|
|
|
|
//console.log(scaleZoomOrigin[0])
|
2017-04-10 16:28:22 +02:00
|
|
|
|
2023-03-26 13:58:17 +02:00
|
|
|
scaleZoomOrigin[0] = Math.max(-canvasCenter.x, Math.min(canvasCenter.x, scaleZoomOrigin[0]))
|
|
|
|
scaleZoomOrigin[1] = Math.max(-canvasCenter.y, Math.min(canvasCenter.y, scaleZoomOrigin[1]))
|
2017-04-10 16:28:22 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
zoomOrigin = [scaleZoomOrigin[0] * zoom, scaleZoomOrigin[1] * zoom]
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2023-03-19 07:03:49 +01:00
|
|
|
innerContainer.style.height = (~~(zoom * canvasSize.x)) + "px"
|
|
|
|
innerContainer.style.width = (~~(zoom * canvasSize.y)) + "px"
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
innerContainer.style.left = ~~(container.clientWidth / 2 - innerContainer.clientWidth / 2 + zoomOrigin[0] + container.offsetLeft) + "px"
|
|
|
|
innerContainer.style.top = ~~(container.clientHeight / 2 - innerContainer.clientHeight / 2 + zoomOrigin[1] + container.offsetTop) + "px"
|
2017-04-05 20:48:32 +02:00
|
|
|
|
|
|
|
}
|
2017-04-04 01:24:46 +02:00
|
|
|
|
2023-03-26 13:58:17 +02:00
|
|
|
function setView(x, y, zoomN = zoom) {
|
|
|
|
|
|
|
|
zoom = zoomN
|
|
|
|
scaleZoomOrigin = [
|
|
|
|
canvasCenter.x - x,
|
|
|
|
canvasCenter.y - y
|
|
|
|
]
|
|
|
|
applyView()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
let atlas = null
|
2022-04-10 11:11:34 +02:00
|
|
|
window.atlas = atlas
|
2022-04-16 14:44:50 +02:00
|
|
|
let atlasAll = null
|
2022-04-10 11:11:34 +02:00
|
|
|
window.atlasAll = atlasAll
|
2022-04-05 11:48:15 +02:00
|
|
|
|
2022-04-08 17:35:21 +02:00
|
|
|
if (document.location.host !== prodDomain) document.body.dataset.dev = ""
|
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
init()
|
2017-04-04 01:24:46 +02:00
|
|
|
|
2022-04-16 14:44:50 +02:00
|
|
|
async function init() {
|
2022-04-06 17:34:04 +02:00
|
|
|
// For Reviewing Reddit Changes
|
2023-03-21 13:29:18 +01:00
|
|
|
//let resp = await fetch("../tools/temp-atlas.json")
|
2022-05-06 09:41:22 +02:00
|
|
|
const resp = await fetch("./atlas.json")
|
|
|
|
atlas = await resp.json()
|
2022-04-05 11:48:15 +02:00
|
|
|
atlas.sort(function (a, b) {
|
|
|
|
if (a.center[1] < b.center[1]) {
|
2022-05-06 09:41:22 +02:00
|
|
|
return -1
|
2022-04-05 11:48:15 +02:00
|
|
|
}
|
|
|
|
if (a.center[1] > b.center[1]) {
|
2022-05-06 09:41:22 +02:00
|
|
|
return 1
|
2022-04-05 11:48:15 +02:00
|
|
|
}
|
|
|
|
// a must be equal to b
|
2022-05-06 09:41:22 +02:00
|
|
|
return 0
|
|
|
|
})
|
2022-04-15 05:46:27 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
atlasAll = updateAtlasAll(atlas)
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
let mode = "view"
|
2017-04-04 01:24:46 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
const args = window.location.search
|
2022-04-16 14:44:50 +02:00
|
|
|
const params = new URLSearchParams(args)
|
|
|
|
if (args) {
|
2023-04-07 11:44:33 +02:00
|
|
|
mode = params.get("mode") || "view"
|
2022-04-09 21:09:57 +02:00
|
|
|
|
|
|
|
// Backwards compatibility for old links using "search" id arg
|
2023-04-07 11:44:33 +02:00
|
|
|
if (params.has('id') && mode !== 'draw') {
|
2022-04-16 14:26:31 +02:00
|
|
|
const id = params.get('id')
|
2022-04-14 06:35:14 +02:00
|
|
|
params.delete('id')
|
2022-04-16 14:26:31 +02:00
|
|
|
const newLocation = new URL(window.location)
|
2022-04-14 06:35:14 +02:00
|
|
|
newLocation.hash = id
|
|
|
|
newLocation.search = params
|
|
|
|
window.history.replaceState({}, '', newLocation)
|
2022-04-09 21:09:57 +02:00
|
|
|
}
|
2017-04-04 01:24:46 +02:00
|
|
|
}
|
|
|
|
|
2022-04-29 16:11:01 +02:00
|
|
|
const hash = window.location.hash.substring(1)
|
2022-05-06 09:41:22 +02:00
|
|
|
const [, period] = hash.split('/')
|
2022-04-29 16:11:01 +02:00
|
|
|
|
|
|
|
if (period) {
|
2022-05-06 09:41:22 +02:00
|
|
|
const [, targetPeriod, targetVariation] = parsePeriod(period)
|
2022-04-29 16:11:01 +02:00
|
|
|
await updateTime(targetPeriod, targetVariation)
|
|
|
|
} else {
|
|
|
|
await updateTime(currentPeriod, currentVariation)
|
|
|
|
}
|
2022-04-29 15:48:40 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
//console.log(document.documentElement.clientWidth, document.documentElement.clientHeight)
|
2022-04-29 15:48:40 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
zoomOrigin = [0, 0]
|
|
|
|
applyView()
|
2022-04-29 15:48:40 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
let initialPinchDistance = 0
|
|
|
|
let initialPinchZoom = 0
|
|
|
|
let initialPinchZoomOrigin = [0, 0]
|
2022-04-29 15:48:40 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
let desiredZoom
|
|
|
|
let zoomAnimationFrame
|
2022-04-29 15:48:40 +02:00
|
|
|
|
2022-04-09 05:41:40 +02:00
|
|
|
document.body.dataset.mode = mode
|
|
|
|
|
2022-04-09 11:27:14 +02:00
|
|
|
initGlobal()
|
|
|
|
if (mode !== "draw") initViewGlobal()
|
|
|
|
|
2022-04-16 14:44:50 +02:00
|
|
|
if (mode === "draw") {
|
2022-05-06 09:41:22 +02:00
|
|
|
initDraw()
|
2022-04-16 14:44:50 +02:00
|
|
|
} else if (mode === "about") {
|
2022-05-06 09:41:22 +02:00
|
|
|
window.location = "./about.html"
|
2022-04-16 14:44:50 +02:00
|
|
|
} else if (mode === "overlap") {
|
|
|
|
if (initOverlap) {
|
2022-05-06 09:41:22 +02:00
|
|
|
initOverlap()
|
2017-04-06 23:20:08 +02:00
|
|
|
}
|
2023-04-07 11:44:33 +02:00
|
|
|
} else if (mode === "explore") {
|
|
|
|
initExplore()
|
2022-04-16 14:44:50 +02:00
|
|
|
} else if (mode.startsWith("diff")) {
|
2022-04-08 06:06:16 +02:00
|
|
|
try {
|
2023-03-20 14:09:23 +01:00
|
|
|
const liveResp = await fetch(`https://${prodDomain}/atlas.json`)
|
2022-05-06 09:41:22 +02:00
|
|
|
let liveJson = await liveResp.json()
|
2022-04-15 10:06:37 +02:00
|
|
|
liveJson = updateAtlasAll(liveJson)
|
|
|
|
|
2022-04-16 14:44:50 +02:00
|
|
|
const liveAtlasReduced = liveJson.reduce(function (a, c) {
|
2022-05-06 09:41:22 +02:00
|
|
|
a[c.id] = c
|
|
|
|
return a
|
|
|
|
}, {})
|
2022-04-08 22:02:14 +02:00
|
|
|
// Mark added/edited entries
|
2022-04-16 14:44:50 +02:00
|
|
|
atlasAll = atlasAll.map(function (entry) {
|
|
|
|
if (liveAtlasReduced[entry.id] === undefined) {
|
2022-05-06 09:41:22 +02:00
|
|
|
entry.diff = "add"
|
2022-04-16 14:44:50 +02:00
|
|
|
} else if (JSON.stringify(entry) !== JSON.stringify(liveAtlasReduced[entry.id])) {
|
2022-05-06 09:41:22 +02:00
|
|
|
entry.diff = "edit"
|
2022-04-08 06:06:16 +02:00
|
|
|
}
|
2022-05-06 09:41:22 +02:00
|
|
|
return entry
|
|
|
|
})
|
2022-04-08 22:02:14 +02:00
|
|
|
|
|
|
|
// Mark removed entries
|
2022-04-16 14:44:50 +02:00
|
|
|
const atlasReduced = atlasAll.reduce(function (a, c) {
|
2022-05-06 09:41:22 +02:00
|
|
|
a[c.id] = c
|
|
|
|
return a
|
|
|
|
}, {})
|
2022-04-16 14:44:50 +02:00
|
|
|
const removedEntries = liveJson.filter(entry =>
|
2022-04-09 06:09:32 +02:00
|
|
|
atlasReduced[entry.id] === undefined
|
|
|
|
).map(entry => {
|
|
|
|
entry.diff = "delete"
|
|
|
|
return entry
|
|
|
|
})
|
2022-04-15 10:06:37 +02:00
|
|
|
atlasAll.push(...removedEntries)
|
2022-04-08 22:02:14 +02:00
|
|
|
|
2022-04-16 14:44:50 +02:00
|
|
|
if (mode.includes("only")) {
|
|
|
|
atlasAll = atlasAll.filter(function (entry) {
|
2023-03-17 18:30:33 +01:00
|
|
|
return typeof entry.diff === "string"
|
2022-05-06 09:41:22 +02:00
|
|
|
})
|
2022-04-08 22:02:14 +02:00
|
|
|
}
|
2022-04-15 10:06:37 +02:00
|
|
|
|
2022-04-08 06:06:16 +02:00
|
|
|
} catch (error) {
|
2022-05-06 09:41:22 +02:00
|
|
|
console.warn("Diff mode failed to load, reverting to normal view.", error)
|
2022-04-08 06:06:16 +02:00
|
|
|
} finally {
|
2022-04-16 14:51:51 +02:00
|
|
|
await updateTime()
|
2022-04-16 14:44:50 +02:00
|
|
|
if (initOverlap && mode.includes("overlap")) {
|
2022-05-06 09:41:22 +02:00
|
|
|
initOverlap()
|
2022-04-08 22:02:14 +02:00
|
|
|
} else {
|
2022-05-06 09:41:22 +02:00
|
|
|
initView()
|
2022-04-08 22:02:14 +02:00
|
|
|
}
|
2022-04-08 06:06:16 +02:00
|
|
|
}
|
2022-04-09 05:41:40 +02:00
|
|
|
} else {
|
2022-05-06 09:41:22 +02:00
|
|
|
initView()
|
2017-04-06 23:09:37 +02:00
|
|
|
}
|
2017-04-10 17:57:13 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
document.getElementById("loading").classList.add("d-none")
|
2017-04-10 17:57:13 +02:00
|
|
|
|
2023-03-18 02:05:40 +01:00
|
|
|
document.getElementById("zoomInButton").addEventListener("click", function () {
|
2017-04-04 01:24:46 +02:00
|
|
|
|
2017-04-10 12:25:04 +02:00
|
|
|
/*if(zoomAnimationFrame){
|
2022-05-06 09:41:22 +02:00
|
|
|
window.cancelAnimationFrame(zoomAnimationFrame)
|
2017-04-10 12:25:04 +02:00
|
|
|
}*/
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
const x = container.clientWidth / 2
|
|
|
|
const y = container.clientHeight / 2
|
2017-04-04 01:24:46 +02:00
|
|
|
|
2017-04-08 05:57:12 +02:00
|
|
|
initialPinchZoomOrigin = [
|
|
|
|
scaleZoomOrigin[0],
|
|
|
|
scaleZoomOrigin[1]
|
2022-05-06 09:41:22 +02:00
|
|
|
]
|
2017-04-04 01:24:46 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
initialPinchZoom = zoom
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
lastPosition = [x, y]
|
2023-04-07 11:44:33 +02:00
|
|
|
zoom *= 2
|
2022-05-06 09:41:22 +02:00
|
|
|
zoom = Math.max(minZoom, Math.min(maxZoom, zoom))
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
applyZoom(x, y, zoom)
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
})
|
2017-04-05 00:53:10 +02:00
|
|
|
|
2023-03-18 02:05:40 +01:00
|
|
|
document.getElementById("zoomOutButton").addEventListener("click", function () {
|
2017-04-08 05:57:12 +02:00
|
|
|
|
2017-04-10 12:25:04 +02:00
|
|
|
/*if(zoomAnimationFrame){
|
2022-05-06 09:41:22 +02:00
|
|
|
window.cancelAnimationFrame(zoomAnimationFrame)
|
2017-04-10 12:25:04 +02:00
|
|
|
}*/
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
const x = container.clientWidth / 2
|
|
|
|
const y = container.clientHeight / 2
|
2017-04-08 05:57:12 +02:00
|
|
|
|
|
|
|
initialPinchZoomOrigin = [
|
|
|
|
scaleZoomOrigin[0],
|
|
|
|
scaleZoomOrigin[1]
|
2022-05-06 09:41:22 +02:00
|
|
|
]
|
2017-04-08 05:57:12 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
initialPinchZoom = zoom
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
lastPosition = [x, y]
|
2023-03-19 10:07:44 +01:00
|
|
|
zoom /= 2
|
2022-05-06 09:41:22 +02:00
|
|
|
zoom = Math.max(minZoom, Math.min(maxZoom, zoom))
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
applyZoom(x, y, zoom)
|
|
|
|
})
|
2017-04-05 00:53:10 +02:00
|
|
|
|
2023-03-18 02:05:40 +01:00
|
|
|
document.getElementById("zoomResetButton").addEventListener("click", function () {
|
2022-05-06 09:41:22 +02:00
|
|
|
zoom = 1
|
|
|
|
zoomOrigin = [0, 0]
|
|
|
|
scaleZoomOrigin = [0, 0]
|
|
|
|
updateLines()
|
|
|
|
applyView()
|
|
|
|
})
|
2017-04-05 00:53:10 +02:00
|
|
|
|
2023-04-07 11:44:33 +02:00
|
|
|
container.addEventListener("dblclick", e => {
|
2017-04-10 12:25:04 +02:00
|
|
|
/*if(zoomAnimationFrame){
|
2022-05-06 09:41:22 +02:00
|
|
|
window.cancelAnimationFrame(zoomAnimationFrame)
|
2017-04-10 12:25:04 +02:00
|
|
|
}*/
|
2017-04-08 05:57:12 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
const x = e.clientX - container.offsetLeft
|
|
|
|
const y = e.clientY - container.offsetTop
|
2017-04-08 05:57:12 +02:00
|
|
|
|
|
|
|
initialPinchZoomOrigin = [
|
|
|
|
scaleZoomOrigin[0],
|
|
|
|
scaleZoomOrigin[1]
|
2022-05-06 09:41:22 +02:00
|
|
|
]
|
2017-04-08 05:57:12 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
initialPinchZoom = zoom
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
lastPosition = [x, y]
|
2017-04-08 05:57:12 +02:00
|
|
|
|
2023-03-19 10:07:44 +01:00
|
|
|
if (e.ctrlKey) zoom /= 2
|
|
|
|
else zoom *= 2
|
2017-04-08 05:57:12 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
zoom = Math.max(minZoom, Math.min(maxZoom, zoom))
|
|
|
|
applyZoom(x, y, zoom)
|
2017-04-08 05:57:12 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
e.preventDefault()
|
|
|
|
})
|
2017-04-04 01:24:46 +02:00
|
|
|
|
|
|
|
|
2023-04-07 11:44:33 +02:00
|
|
|
container.addEventListener("wheel", e => {
|
2017-04-08 05:57:12 +02:00
|
|
|
|
2017-04-10 12:25:04 +02:00
|
|
|
/*if(zoomAnimationFrame){
|
2022-05-06 09:41:22 +02:00
|
|
|
window.cancelAnimationFrame(zoomAnimationFrame)
|
2017-04-10 12:25:04 +02:00
|
|
|
}*/
|
2017-04-08 05:57:12 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
const x = e.clientX - container.offsetLeft
|
|
|
|
const y = e.clientY - container.offsetTop
|
2017-04-08 05:57:12 +02:00
|
|
|
|
|
|
|
initialPinchZoomOrigin = [
|
|
|
|
scaleZoomOrigin[0],
|
|
|
|
scaleZoomOrigin[1]
|
2022-05-06 09:41:22 +02:00
|
|
|
]
|
2017-04-08 05:57:12 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
initialPinchZoom = zoom
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
lastPosition = [x, y]
|
2017-04-04 01:24:46 +02:00
|
|
|
|
2022-04-06 22:42:48 +02:00
|
|
|
// Check if we are zooming by pixels
|
|
|
|
// https://developer.mozilla.org/en-US/docs/Web/API/WheelEvent/deltaMode
|
|
|
|
if (e.deltaMode === 0) {
|
|
|
|
// Scale the pixel delta by the current zoom factor
|
|
|
|
// We want to zoom faster when closer, and slower when further
|
|
|
|
// This creates a smoother experience
|
2022-05-06 09:41:22 +02:00
|
|
|
zoom -= e.deltaY * (0.001 * zoom)
|
2022-04-06 22:42:48 +02:00
|
|
|
} else {
|
2023-04-07 11:44:33 +02:00
|
|
|
if (e.deltaY > 0) zoom /= 2
|
|
|
|
else if (e.deltaY < 0) zoom *= 2
|
2017-04-04 01:24:46 +02:00
|
|
|
}
|
2017-04-06 19:29:54 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
zoom = Math.max(minZoom, Math.min(maxZoom, zoom))
|
|
|
|
applyZoom(x, y, zoom)
|
|
|
|
}, { passive: true })
|
2017-04-04 01:24:46 +02:00
|
|
|
|
2017-04-10 12:25:04 +02:00
|
|
|
/*function setDesiredZoom(x, y, target){
|
2022-05-06 09:41:22 +02:00
|
|
|
zoom = (zoom*2 + target)/3
|
|
|
|
//console.log(zoom)
|
2017-04-08 05:57:12 +02:00
|
|
|
if(Math.abs(1 - zoom/target) <= 0.01){
|
2022-05-06 09:41:22 +02:00
|
|
|
zoom = target
|
2017-04-08 05:57:12 +02:00
|
|
|
}
|
2022-05-06 09:41:22 +02:00
|
|
|
applyZoom(x, y, zoom)
|
2017-04-08 05:57:12 +02:00
|
|
|
if(zoom != target){
|
|
|
|
zoomAnimationFrame = window.requestAnimationFrame(function(){
|
2022-05-06 09:41:22 +02:00
|
|
|
setDesiredZoom(x, y, target)
|
|
|
|
})
|
2017-04-08 05:57:12 +02:00
|
|
|
}
|
2017-04-10 12:25:04 +02:00
|
|
|
}*/
|
2017-04-08 05:57:12 +02:00
|
|
|
|
2023-04-07 11:44:33 +02:00
|
|
|
container.addEventListener("mousedown", e => {
|
2022-05-06 09:41:22 +02:00
|
|
|
mousedown(e.clientX, e.clientY)
|
|
|
|
e.preventDefault()
|
|
|
|
})
|
2017-04-10 23:56:35 +02:00
|
|
|
|
2023-04-07 11:44:33 +02:00
|
|
|
container.addEventListener("touchstart", e => {
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2023-03-17 18:30:33 +01:00
|
|
|
if (e.touches.length === 2) {
|
2022-05-06 09:41:22 +02:00
|
|
|
e.preventDefault()
|
2017-04-10 23:56:35 +02:00
|
|
|
}
|
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
touchstart(e)
|
2017-04-10 23:56:35 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
}, { passive: true })
|
2017-04-08 03:27:51 +02:00
|
|
|
|
2022-04-16 14:44:50 +02:00
|
|
|
function mousedown(x, y) {
|
2022-05-06 09:41:22 +02:00
|
|
|
lastPosition = [x, y]
|
|
|
|
dragging = true
|
2017-04-08 03:27:51 +02:00
|
|
|
}
|
|
|
|
|
2022-04-16 14:44:50 +02:00
|
|
|
function touchstart(e) {
|
|
|
|
|
2023-03-17 18:30:33 +01:00
|
|
|
if (e.touches.length === 1) {
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
mousedown(e.touches[0].clientX, e.touches[0].clientY)
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2023-03-17 18:30:33 +01:00
|
|
|
} else if (e.touches.length === 2) {
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2017-04-08 03:27:51 +02:00
|
|
|
initialPinchDistance = Math.sqrt(
|
2022-04-16 14:44:50 +02:00
|
|
|
Math.pow(e.touches[0].clientX - e.touches[1].clientX, 2)
|
2017-04-08 03:27:51 +02:00
|
|
|
+ Math.pow(e.touches[0].clientY - e.touches[1].clientY, 2)
|
2022-05-06 09:41:22 +02:00
|
|
|
)
|
2017-04-08 03:27:51 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
initialPinchZoom = zoom
|
2017-04-08 03:27:51 +02:00
|
|
|
initialPinchZoomOrigin = [
|
|
|
|
scaleZoomOrigin[0],
|
|
|
|
scaleZoomOrigin[1]
|
2022-05-06 09:41:22 +02:00
|
|
|
]
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2017-04-08 03:27:51 +02:00
|
|
|
mousedown(
|
2022-04-16 14:44:50 +02:00
|
|
|
(e.touches[0].clientX + e.touches[1].clientX) / 2,
|
|
|
|
(e.touches[0].clientY + e.touches[1].clientY) / 2
|
2022-05-06 09:41:22 +02:00
|
|
|
)
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2017-04-08 03:27:51 +02:00
|
|
|
}
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2017-04-08 03:27:51 +02:00
|
|
|
}
|
2017-04-04 01:24:46 +02:00
|
|
|
|
2023-04-07 11:44:33 +02:00
|
|
|
window.addEventListener("mousemove", e => {
|
2022-05-06 09:41:22 +02:00
|
|
|
updateLines()
|
|
|
|
mousemove(e.clientX, e.clientY)
|
2022-04-16 14:44:50 +02:00
|
|
|
if (dragging) {
|
2022-05-06 09:41:22 +02:00
|
|
|
e.preventDefault()
|
2017-04-10 16:09:56 +02:00
|
|
|
}
|
2022-05-06 09:41:22 +02:00
|
|
|
})
|
2023-04-07 11:44:33 +02:00
|
|
|
window.addEventListener("touchmove", e => {
|
2017-04-10 23:56:35 +02:00
|
|
|
|
2023-03-17 18:30:33 +01:00
|
|
|
if (e.touches.length === 2 || e.scale > 1) {
|
2022-05-06 09:41:22 +02:00
|
|
|
e.preventDefault()
|
2017-04-10 23:56:35 +02:00
|
|
|
}
|
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
touchmove(e)
|
2017-04-10 23:56:35 +02:00
|
|
|
|
|
|
|
},
|
2022-04-16 14:44:50 +02:00
|
|
|
{ passive: false }
|
2022-05-06 09:41:22 +02:00
|
|
|
)
|
2017-04-08 03:27:51 +02:00
|
|
|
|
2022-04-16 14:44:50 +02:00
|
|
|
function mousemove(x, y) {
|
|
|
|
if (dragging) {
|
2022-05-07 00:08:45 +02:00
|
|
|
container.style.cursor = "move"
|
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
const deltaX = x - lastPosition[0]
|
|
|
|
const deltaY = y - lastPosition[1]
|
|
|
|
lastPosition = [x, y]
|
2017-04-04 01:24:46 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
zoomOrigin[0] += deltaX
|
|
|
|
zoomOrigin[1] += deltaY
|
2017-04-04 01:24:46 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
scaleZoomOrigin[0] += deltaX / zoom
|
|
|
|
scaleZoomOrigin[1] += deltaY / zoom
|
2017-04-08 03:27:51 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
previousZoomOrigin = [zoomOrigin[0], zoomOrigin[1]]
|
|
|
|
previousScaleZoomOrigin = [scaleZoomOrigin[0], scaleZoomOrigin[1]]
|
2017-04-10 16:28:22 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
updateLines()
|
|
|
|
applyView()
|
2017-04-08 03:27:51 +02:00
|
|
|
}
|
|
|
|
}
|
2017-04-06 19:29:54 +02:00
|
|
|
|
2022-04-16 14:44:50 +02:00
|
|
|
function touchmove(e) {
|
2017-04-09 02:08:35 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
updateLines()
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2023-03-17 18:30:33 +01:00
|
|
|
if (e.touches.length === 1) {
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
mousemove(e.touches[0].clientX, e.touches[0].clientY)
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2023-03-17 18:30:33 +01:00
|
|
|
} else if (e.touches.length === 2) {
|
2022-04-16 14:44:50 +02:00
|
|
|
|
|
|
|
const newPinchDistance = Math.sqrt(
|
|
|
|
Math.pow(e.touches[0].clientX - e.touches[1].clientX, 2)
|
2017-04-08 03:27:51 +02:00
|
|
|
+ Math.pow(e.touches[0].clientY - e.touches[1].clientY, 2)
|
2022-05-06 09:41:22 +02:00
|
|
|
)
|
2017-04-08 03:27:51 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
zoom = initialPinchZoom * newPinchDistance / initialPinchDistance
|
2017-04-08 03:27:51 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
const x = (e.touches[0].clientX + e.touches[1].clientX) / 2 - container.offsetLeft
|
|
|
|
const y = (e.touches[0].clientY + e.touches[1].clientY) / 2 - container.offsetTop
|
2017-04-08 03:27:51 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
applyZoom(x, y, zoom)
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2017-04-08 05:57:12 +02:00
|
|
|
}
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2017-04-08 05:57:12 +02:00
|
|
|
}
|
2017-04-08 03:27:51 +02:00
|
|
|
|
2022-04-16 14:44:50 +02:00
|
|
|
function applyZoom(x, y, zoom) {
|
2017-04-08 03:27:51 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
const deltaX = x - lastPosition[0]
|
|
|
|
const deltaY = y - lastPosition[1]
|
2017-04-08 03:27:51 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
const pinchTranslateX = (x - container.clientWidth / 2 - deltaX)
|
|
|
|
const pinchTranslateY = (y - container.clientHeight / 2 - deltaY)
|
2017-04-08 05:57:12 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
scaleZoomOrigin[0] = initialPinchZoomOrigin[0] + deltaX / zoom + pinchTranslateX / zoom - pinchTranslateX / initialPinchZoom
|
|
|
|
scaleZoomOrigin[1] = initialPinchZoomOrigin[1] + deltaY / zoom + pinchTranslateY / zoom - pinchTranslateY / initialPinchZoom
|
2017-04-08 05:57:12 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
zoomOrigin[0] = scaleZoomOrigin[0] * zoom
|
|
|
|
zoomOrigin[1] = scaleZoomOrigin[1] * zoom
|
2017-04-08 05:57:12 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
applyView()
|
|
|
|
updateLines()
|
2017-04-08 03:27:51 +02:00
|
|
|
}
|
2017-04-04 01:24:46 +02:00
|
|
|
|
2023-04-07 11:44:33 +02:00
|
|
|
window.addEventListener("mouseup", e => {
|
2022-05-07 00:08:45 +02:00
|
|
|
if (hovered.length > 0) {
|
|
|
|
container.style.cursor = "pointer"
|
2023-03-17 18:30:33 +01:00
|
|
|
} else if (drawing === true) {
|
2022-05-08 07:22:01 +02:00
|
|
|
container.style.cursor = "crosshair"
|
2022-05-07 00:08:45 +02:00
|
|
|
} else {
|
|
|
|
container.style.cursor = "default"
|
|
|
|
}
|
2022-04-16 14:44:50 +02:00
|
|
|
if (dragging) {
|
2022-05-06 09:41:22 +02:00
|
|
|
e.preventDefault()
|
2017-04-10 16:09:56 +02:00
|
|
|
}
|
2022-05-06 09:41:22 +02:00
|
|
|
mouseup(e.clientX, e.clientY)
|
|
|
|
})
|
|
|
|
window.addEventListener("touchend", touchend)
|
2017-04-08 03:27:51 +02:00
|
|
|
|
2022-04-16 14:44:50 +02:00
|
|
|
function mouseup(x, y) {
|
|
|
|
if (dragging) {
|
2022-05-06 09:41:22 +02:00
|
|
|
dragging = false
|
2017-04-04 01:24:46 +02:00
|
|
|
}
|
2017-04-08 03:27:51 +02:00
|
|
|
}
|
|
|
|
|
2022-04-16 14:44:50 +02:00
|
|
|
function touchend(e) {
|
|
|
|
|
2023-03-17 18:30:33 +01:00
|
|
|
if (e.touches.length === 0) {
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
mouseup()
|
2023-04-07 11:14:07 +02:00
|
|
|
setTimeout(() => updateLines(), 0)
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2023-03-17 18:30:33 +01:00
|
|
|
} else if (e.touches.length === 1) {
|
2022-05-06 09:41:22 +02:00
|
|
|
initialPinchZoom = zoom
|
|
|
|
lastPosition = [e.touches[0].clientX, e.touches[0].clientY]
|
2017-04-08 03:27:51 +02:00
|
|
|
}
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2017-04-08 03:27:51 +02:00
|
|
|
}
|
2017-04-04 01:24:46 +02:00
|
|
|
|
2022-04-16 14:44:50 +02:00
|
|
|
window.addEventListener("resize", function () {
|
2022-05-06 09:41:22 +02:00
|
|
|
//console.log(document.documentElement.clientWidth, document.documentElement.clientHeight)
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2022-05-06 09:41:22 +02:00
|
|
|
applyView()
|
|
|
|
})
|
2022-04-16 14:44:50 +02:00
|
|
|
|
2022-04-12 14:18:53 +02:00
|
|
|
document.body.dataset.initDone = ''
|
|
|
|
|
2017-04-04 01:24:46 +02:00
|
|
|
}
|
2022-04-15 10:06:37 +02:00
|
|
|
|
2022-05-01 06:06:04 +02:00
|
|
|
function updateAtlasAll(atlas = atlasAll) {
|
2022-04-16 14:26:31 +02:00
|
|
|
for (const atlasIndex in atlas) {
|
2022-05-17 14:33:31 +02:00
|
|
|
const currentLinks = atlas[atlasIndex].links
|
|
|
|
atlas[atlasIndex].links = {
|
|
|
|
website: [],
|
|
|
|
subreddit: [],
|
|
|
|
discord: [],
|
|
|
|
wiki: [],
|
|
|
|
...currentLinks
|
2022-04-15 10:06:37 +02:00
|
|
|
}
|
2022-05-17 14:33:31 +02:00
|
|
|
const currentPath = atlas[atlasIndex].path
|
|
|
|
const currentCenter = atlas[atlasIndex].center
|
|
|
|
for (const key in currentPath) {
|
|
|
|
currentPath[key] = currentPath[key].map(point => point.map(int => int + 0.5))
|
2022-04-15 10:06:37 +02:00
|
|
|
}
|
2022-05-17 14:33:31 +02:00
|
|
|
for (const key in currentCenter) {
|
|
|
|
currentCenter[key] = currentCenter[key].map(int => int + 0.5)
|
2022-04-15 10:06:37 +02:00
|
|
|
}
|
2022-05-17 14:33:31 +02:00
|
|
|
atlas[atlasIndex].path = currentPath
|
|
|
|
atlas[atlasIndex].center = currentCenter
|
2022-04-15 10:06:37 +02:00
|
|
|
}
|
|
|
|
return atlas
|
|
|
|
}
|