mirror of
https://github.com/placeAtlas/atlas.git
synced 2024-11-15 14:33:36 +01:00
Merge branch 'cleanup' of github.com:GeoDash897/place-atlas into cleanup
This commit is contained in:
commit
b5bb462748
18 changed files with 2339 additions and 2452 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -13,3 +13,4 @@ combined.js
|
|||
*.DS_Store
|
||||
.vscode/
|
||||
web/atlas-before-ids-migration.json
|
||||
*.pyc
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[![Entry count](https://img.shields.io/badge/dynamic/json?color=blue&label=count&query=%24.length&url=https%3A%2F%2Fgithub.com%2FplaceAtlas%2Fatlas%2Fblob%2Fmaster%2Fweb%2Fatlas.json%3Fraw%3Dtrue)](https://place-atlas.stefanocoding.me/)
|
||||
[![Entry count](https://img.shields.io/badge/dynamic/json?color=blue&label=entries&query=%24.length&url=https%3A%2F%2Fgithub.com%2FplaceAtlas%2Fatlas%2Fblob%2Fmaster%2Fweb%2Fatlas.json%3Fraw%3Dtrue)](https://place-atlas.stefanocoding.me/)
|
||||
![Commit activity](https://img.shields.io/github/commit-activity/w/placeAtlas/atlas)
|
||||
[![Netlify](https://img.shields.io/netlify/1e7291ce-0680-45ed-9843-47a32a992bbb?logo=netlify&logoColor=white)](https://app.netlify.com/sites/place-atlas/deploys)
|
||||
[![License](https://img.shields.io/github/license/placeAtlas/atlas)](https://github.com/placeAtlas/atlas/blob/master/LICENSE)
|
||||
|
|
|
@ -35,7 +35,10 @@
|
|||
}
|
||||
|
||||
CL_REGEX = r'\[(.+?)\]\((.+?)\)'
|
||||
CWTS_REGEX = r'^(?:(?:https?:\/\/)?(?:(?:www|old|new|np)\.)?)?reddit\.com\/r\/([A-Za-z0-9][A-Za-z0-9_]{1,20})(?:\/)$'
|
||||
CWTS_REGEX = {
|
||||
"url": r'^(?:(?:https?:\/\/)?(?:(?:www|old|new|np)\.)?)?reddit\.com\/r\/([A-Za-z0-9][A-Za-z0-9_]{1,20})(?:\/)$',
|
||||
"subreddit": r'^\/*[rR]\/([A-Za-z0-9][A-Za-z0-9_]{1,20})\/?$'
|
||||
}
|
||||
CSTW_REGEX = {
|
||||
"website": r'^https?://[^\s/$.?#].[^\s]*$',
|
||||
"user": r'^\/*u\/([A-Za-z0-9][A-Za-z0-9_]{1,20})$'
|
||||
|
@ -46,6 +49,9 @@
|
|||
USER_TEMPLATE = r"/u/\1"
|
||||
|
||||
def format_subreddit(entry: dict):
|
||||
"""
|
||||
Fix formatting of the value on "subreddit".
|
||||
"""
|
||||
if not "subreddit" in entry or not entry['subreddit']:
|
||||
return entry
|
||||
|
||||
|
@ -65,19 +71,30 @@ def format_subreddit(entry: dict):
|
|||
return entry
|
||||
|
||||
def collapse_links(entry: dict):
|
||||
if not "website" in entry or not entry['website']:
|
||||
return entry
|
||||
|
||||
website = entry["website"];
|
||||
if re.search(CL_REGEX, website):
|
||||
match = re.search(CL_REGEX, website)
|
||||
if match.group(1) == match.group(2):
|
||||
website = match.group(2)
|
||||
if "website" in entry and entry['website']:
|
||||
website = entry["website"];
|
||||
if re.search(CL_REGEX, website):
|
||||
match = re.search(CL_REGEX, website)
|
||||
if match.group(1) == match.group(2):
|
||||
website = match.group(2)
|
||||
|
||||
entry["website"] = website
|
||||
|
||||
if "subreddit" in entry and entry['subreddit']:
|
||||
subreddit = entry["subreddit"];
|
||||
if re.search(CL_REGEX, subreddit):
|
||||
match = re.search(CL_REGEX, subreddit)
|
||||
if match.group(1) == match.group(2):
|
||||
subreddit = match.group(2)
|
||||
|
||||
entry["subreddit"] = subreddit
|
||||
|
||||
entry["website"] = website
|
||||
return entry
|
||||
|
||||
def remove_extras(entry: dict):
|
||||
"""
|
||||
Removing unnecessary extra characters and converts select characters.
|
||||
"""
|
||||
if "subreddit" in entry and entry["subreddit"]:
|
||||
# if not entry["subreddit"].startswith('/r/'):
|
||||
# entry["subreddit"] = re.sub(r'^(.*)(?=\/r\/)', r'', entry["subreddit"])
|
||||
|
@ -94,6 +111,9 @@ def remove_extras(entry: dict):
|
|||
entry[key] = re.sub(r'\n{3,}', r'\n\n', entry[key])
|
||||
entry[key] = re.sub(r'r\/{2,}', r'r\/', entry[key])
|
||||
entry[key] = re.sub(r',{2,}', r',', entry[key])
|
||||
# Smart quotation marks
|
||||
entry[key] = re.sub(r'[\u201c\u201d]', '"', entry[key])
|
||||
entry[key] = re.sub(r'[\u2018\u2019]', "'", entry[key])
|
||||
# Psuedo-empty strings
|
||||
if entry[key] in ["n/a", "N/A", "na", "NA", "-", "null", "none", "None"]:
|
||||
entry[key] = ""
|
||||
|
@ -101,6 +121,9 @@ def remove_extras(entry: dict):
|
|||
return entry
|
||||
|
||||
def fix_r_caps(entry: dict):
|
||||
"""
|
||||
Fixes capitalization of /r/. (/R/place -> /r/place)
|
||||
"""
|
||||
if not "description" in entry or not entry['description']:
|
||||
return entry
|
||||
|
||||
|
@ -110,6 +133,9 @@ def fix_r_caps(entry: dict):
|
|||
return entry
|
||||
|
||||
def fix_no_protocol_urls(entry: dict):
|
||||
"""
|
||||
Fixes URLs with no protocol by adding "https://" protocol.
|
||||
"""
|
||||
if not "website" in entry or not entry['website']:
|
||||
return entry
|
||||
|
||||
|
@ -119,11 +145,21 @@ def fix_no_protocol_urls(entry: dict):
|
|||
return entry
|
||||
|
||||
def convert_website_to_subreddit(entry: dict):
|
||||
"""
|
||||
Converts the subreddit link on "website" to "subreddit" if possible.
|
||||
"""
|
||||
if not "website" in entry or not entry['website']:
|
||||
return entry
|
||||
|
||||
if re.match(CWTS_REGEX, entry["website"]):
|
||||
new_subreddit = re.sub(CWTS_REGEX, SUBREDDIT_TEMPLATE, entry["website"])
|
||||
if re.match(CWTS_REGEX["url"], entry["website"]):
|
||||
new_subreddit = re.sub(CWTS_REGEX["url"], SUBREDDIT_TEMPLATE, entry["website"])
|
||||
if (new_subreddit.lower() == entry["subreddit"].lower()):
|
||||
entry["website"] = ""
|
||||
elif not "subreddit" in entry or entry['subreddit'] == "":
|
||||
entry["subreddit"] = new_subreddit
|
||||
entry["website"] = ""
|
||||
elif re.match(CWTS_REGEX["subreddit"], entry["website"]):
|
||||
new_subreddit = re.sub(CWTS_REGEX["subreddit"], SUBREDDIT_TEMPLATE, entry["website"])
|
||||
if (new_subreddit.lower() == entry["subreddit"].lower()):
|
||||
entry["website"] = ""
|
||||
elif not "subreddit" in entry or entry['subreddit'] == "":
|
||||
|
@ -133,6 +169,9 @@ def convert_website_to_subreddit(entry: dict):
|
|||
return entry
|
||||
|
||||
def convert_subreddit_to_website(entry: dict):
|
||||
"""
|
||||
Converts the links on "subreddit" to a "website" if needed. This also supports Reddit users (/u/reddit).
|
||||
"""
|
||||
if not "subreddit" in entry or not entry['subreddit']:
|
||||
return entry
|
||||
|
||||
|
@ -149,30 +188,104 @@ def convert_subreddit_to_website(entry: dict):
|
|||
entry["subreddit"] = ""
|
||||
|
||||
return entry
|
||||
|
||||
|
||||
def calculate_center(path: list):
|
||||
"""
|
||||
Caluclates the center of a polygon
|
||||
|
||||
adapted from /web/_js/draw.js:calucalteCenter()
|
||||
"""
|
||||
area = 0
|
||||
x = 0
|
||||
y = 0
|
||||
|
||||
for i in range(len(path)):
|
||||
point1 = path[i]
|
||||
point2 = path[i-1 if i != 0 else len(path)-1]
|
||||
f = point1[0] * point2[1] - point2[0] * point1[1]
|
||||
area += f
|
||||
x += (point1[0] + point2[0]) * f
|
||||
y += (point1[1] + point2[1]) * f
|
||||
|
||||
area *= 3
|
||||
|
||||
if area != 0:
|
||||
return [x // area + 0.5, y // area + 0.5]
|
||||
else:
|
||||
# get the center of a straight line
|
||||
max_x = max(i[0] for i in path)
|
||||
min_x = min(i[0] for i in path)
|
||||
max_y = max(i[1] for i in path)
|
||||
min_y = min(i[1] for i in path)
|
||||
return [(max_x + min_x) // 2 + 0.5, (max_y + min_y) // 2 + 0.5]
|
||||
|
||||
def update_center(entry: dict):
|
||||
"""
|
||||
checks if the center of a entry is up to date, and updates it if it's either missing or outdated
|
||||
"""
|
||||
if 'path' not in entry:
|
||||
return entry
|
||||
path = entry['path']
|
||||
if len(path) > 1:
|
||||
calculated_center = calculate_center(path)
|
||||
if 'center' not in entry or entry['center'] != calculated_center:
|
||||
entry['center'] = calculated_center
|
||||
return entry
|
||||
|
||||
def validate(entry: dict):
|
||||
"""
|
||||
Validates the entry. Catch errors and tell warnings related to the entry.
|
||||
|
||||
Status code key:
|
||||
0: All valid, no problems
|
||||
1: Informational logs that may be ignored
|
||||
2: Warnings that may effect user experience when interacting with the entry
|
||||
3: Errors that make the entry inaccessible or broken.
|
||||
"""
|
||||
return_status = 0
|
||||
if (not "id" in entry or (not entry['id'] and not entry['id'] == 0)):
|
||||
print(f"Wait, no id here! How did this happened? {entry}")
|
||||
return
|
||||
return_status = 3
|
||||
entry['id'] = '[MISSING_ID]'
|
||||
if not ("path" in entry and isinstance(entry["path"], list) and len(entry["path"]) > 0):
|
||||
print(f"Entry {entry['id']} has no points!")
|
||||
return_status = 3
|
||||
elif len(entry["path"]) < 3:
|
||||
print(f"Entry {entry['id']} only has {len(entry['path'])} point(s)!")
|
||||
return_status = 3
|
||||
for key in entry:
|
||||
if key in VALIDATE_REGEX and not re.match(VALIDATE_REGEX[key], entry[key]):
|
||||
if return_status < 2: return_status = 2
|
||||
print(f"{key} of entry {entry['id']} is still invalid! {entry[key]}")
|
||||
return return_status
|
||||
|
||||
def per_line_entries(entries: list):
|
||||
"""
|
||||
Returns a string of all the entries, with every entry in one line.
|
||||
"""
|
||||
out = "[\n"
|
||||
for entry in entries:
|
||||
out += json.dumps(entry) + ",\n"
|
||||
if entry:
|
||||
out += json.dumps(entry, ensure_ascii=False) + ",\n"
|
||||
out = out[:-2] + "\n]"
|
||||
return out
|
||||
|
||||
def format_all(entry: dict, silent=False):
|
||||
"""
|
||||
Format using all the available formatters.
|
||||
Outputs a tuple containing the entry and the validation status code.
|
||||
|
||||
Status code key:
|
||||
0: All valid, no problems
|
||||
1: Informational logs that may be ignored
|
||||
2: Warnings that may effect user experience when interacting with the entry
|
||||
3: Errors that make the entry inaccessible or broken.
|
||||
"""
|
||||
def print_(*args, **kwargs):
|
||||
if not silent:
|
||||
print(*args, **kwargs)
|
||||
print_("Fixing r/ capitalization...")
|
||||
entry = fix_r_caps(entry)
|
||||
print_("Fixing links without protocol...")
|
||||
entry = fix_no_protocol_urls(entry)
|
||||
print_("Fix formatting of subreddit...")
|
||||
entry = format_subreddit(entry)
|
||||
print_("Collapsing Markdown links...")
|
||||
|
@ -181,12 +294,16 @@ def print_(*args, **kwargs):
|
|||
entry = convert_website_to_subreddit(entry)
|
||||
print_("Converting subreddit links to website (if needed)...")
|
||||
entry = convert_subreddit_to_website(entry)
|
||||
print_("Fixing links without protocol...")
|
||||
entry = fix_no_protocol_urls(entry)
|
||||
print_("Removing extras...")
|
||||
entry = remove_extras(entry)
|
||||
print_("Updating center")
|
||||
entry = update_center(entry)
|
||||
print_("Validating...")
|
||||
validate(entry)
|
||||
status_code = validate(entry)
|
||||
print_("Completed!")
|
||||
return entry
|
||||
return ( entry, status_code )
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
|
@ -198,7 +315,12 @@ def go(path):
|
|||
entries = json.loads(f1.read())
|
||||
|
||||
for i in range(len(entries)):
|
||||
entries[i] = format_all(entries[i], True)
|
||||
entry_formatted, validation_status = format_all(entries[i], True)
|
||||
if validation_status > 2:
|
||||
print(f"Entry {entry_formatted['id']} will be removed! {json.dumps(entry_formatted)}")
|
||||
entries[i] = None
|
||||
else:
|
||||
entries[i] = entry_formatted
|
||||
if not (i % 500):
|
||||
print(f"{i} checked.")
|
||||
|
||||
|
@ -210,4 +332,3 @@ def go(path):
|
|||
print("Writing completed. All done.")
|
||||
|
||||
go("../web/atlas.json")
|
||||
go("../web/atlas-before-ids-migration.json")
|
|
@ -13,8 +13,8 @@
|
|||
credentials = file.readlines()
|
||||
client_id = credentials[0].strip()
|
||||
client_secret = credentials[1].strip()
|
||||
username = credentials[2].strip()
|
||||
password = credentials[3].strip()
|
||||
username = credentials[2].strip() if len(credentials) > 3 else ""
|
||||
password = credentials[3].strip() if len(credentials) > 3 else ""
|
||||
|
||||
reddit = praw.Reddit(
|
||||
client_id=client_id,
|
||||
|
@ -102,9 +102,6 @@ def set_flair(submission, flair):
|
|||
|
||||
if submission_json:
|
||||
|
||||
# Assert if path does not empty
|
||||
assert len(submission_json["path"]) > 0
|
||||
|
||||
submission_json_dummy = {"id": submission.id, "submitted_by": ""}
|
||||
try:
|
||||
submission_json_dummy["submitted_by"] = submission.author.name
|
||||
|
@ -113,9 +110,12 @@ def set_flair(submission, flair):
|
|||
for key in submission_json:
|
||||
if not key in submission_json_dummy:
|
||||
submission_json_dummy[key] = submission_json[key];
|
||||
submission_json = format_all(submission_json_dummy, True)
|
||||
|
||||
outfile.write(json.dumps(submission_json) + ",\n")
|
||||
(submission_json, validation_status) = format_all(submission_json_dummy, True)
|
||||
|
||||
assert validation_status < 3, \
|
||||
"Submission invalid after validation. This may be caused by not enough points on the path."
|
||||
|
||||
outfile.write(json.dumps(submission_json, ensure_ascii=False) + ",\n")
|
||||
successcount += 1
|
||||
set_flair(submission, "Processed Entry")
|
||||
|
||||
|
|
|
@ -1,23 +1,16 @@
|
|||
|
||||
<!--
|
||||
========================================================================
|
||||
The /r/place Atlas
|
||||
|
||||
An Atlas of Reddit's /r/place, with information to each
|
||||
The 2022 /r/place Atlas
|
||||
|
||||
An Atlas of Reddit's 2022 /r/place, with information to each
|
||||
artwork of the canvas provided by the community.
|
||||
|
||||
Copyright (C) 2017 Roland Rytz <roland@draemm.li>
|
||||
|
||||
Copyright (c) 2017 Roland Rytz <roland@draemm.li>
|
||||
Copyright (c) 2022 r/placeAtlas2 contributors
|
||||
|
||||
Licensed under the GNU Affero General Public License Version 3
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
For more information, see:
|
||||
http://place-atlas.stefanocoding.me/license.txt
|
||||
|
||||
https://place-atlas.stefanocoding.me/license.txt
|
||||
========================================================================
|
||||
-->
|
||||
|
||||
|
|
|
@ -1,22 +1,15 @@
|
|||
/*
|
||||
========================================================================
|
||||
The /r/place Atlas
|
||||
|
||||
An Atlas of Reddit's /r/place, with information to each
|
||||
The 2022 /r/place Atlas
|
||||
|
||||
An Atlas of Reddit's 2022 /r/place, with information to each
|
||||
artwork of the canvas provided by the community.
|
||||
|
||||
Copyright (C) 2017 Roland Rytz <roland@draemm.li>
|
||||
|
||||
Copyright (c) 2017 Roland Rytz <roland@draemm.li>
|
||||
Copyright (c) 2022 r/placeAtlas2 contributors
|
||||
|
||||
Licensed under the GNU Affero General Public License Version 3
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
For more information, see:
|
||||
https://draemm.li/various/place-atlas/license.txt
|
||||
|
||||
https://place-atlas.stefanocoding.me/license.txt
|
||||
========================================================================
|
||||
*/
|
||||
|
||||
|
@ -78,9 +71,7 @@ a:hover {
|
|||
}
|
||||
|
||||
button,
|
||||
#exportDirectPost,
|
||||
#aboutBackButton,
|
||||
#drawBackButton {
|
||||
.button {
|
||||
background-image: linear-gradient(to bottom, #888, #666);
|
||||
border: 1px #000 solid;
|
||||
color: #FFF;
|
||||
|
@ -91,12 +82,15 @@ #drawBackButton {
|
|||
text-shadow: 1px 1px 0 #444;
|
||||
}
|
||||
|
||||
button::-moz-focus-inner {
|
||||
button::-moz-focus-inner,
|
||||
.button::-moz-focus-inner {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
button:disabled,
|
||||
button:disabled:hover {
|
||||
button:disabled:hover,
|
||||
.button:disabled,
|
||||
.button:disabled:hover {
|
||||
background-image: none;
|
||||
background-color: #666;
|
||||
color: #AAA;
|
||||
|
@ -104,9 +98,7 @@ button:disabled:hover {
|
|||
}
|
||||
|
||||
button:hover,
|
||||
#exportDirectPost:hover,
|
||||
#aboutBackButton:hover,
|
||||
#drawBackButton:hover {
|
||||
.button:hover {
|
||||
background-image: linear-gradient(to bottom, #999, #777);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
@ -257,7 +249,7 @@ #loading {
|
|||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 100;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
#loading > div {
|
||||
|
@ -514,7 +506,7 @@ #drawControlsContainer {
|
|||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.draw #drawControlsContainer {
|
||||
[data-mode="draw"] #drawControlsContainer {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
@ -616,6 +608,7 @@ .overlay {
|
|||
background-color: rgba(0, 0, 0, .8);
|
||||
display: none;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
#exportWindow {
|
||||
|
@ -664,15 +657,15 @@ #coordsWrapper {
|
|||
display: flex;
|
||||
gap: 10px;
|
||||
z-index: 100;
|
||||
top: 5px;
|
||||
left: 364px;
|
||||
}
|
||||
.collapsed {
|
||||
|
||||
#wrapper.listHidden #coordsWrapper {
|
||||
top: 49px;
|
||||
left: 149px;
|
||||
}
|
||||
.uncollapsed {
|
||||
top: 49px;
|
||||
left: 380px;
|
||||
}
|
||||
|
||||
@media (max-width: 750px) {
|
||||
#coordsWrapper {
|
||||
display: none;
|
||||
|
@ -681,9 +674,8 @@ @media (max-width: 750px) {
|
|||
#coords {
|
||||
background-color: #555;
|
||||
border: 1px #000 solid;
|
||||
padding: 3px;
|
||||
font-size: 18px;
|
||||
z-index: 1100;
|
||||
padding: 6.5px;
|
||||
font-size: 17px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
@ -702,7 +694,6 @@ #bottomBar {
|
|||
right: 10px;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
div:not(.listHidden) > #bottomBar {
|
||||
|
@ -863,18 +854,18 @@ @media (max-width: 500px) {
|
|||
height: 40px;
|
||||
}
|
||||
|
||||
#entriesListContainer > nav {
|
||||
#entriesListNav {
|
||||
width: calc(100% - 45px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 350px) {
|
||||
#entriesListContainer > nav > a#drawLink {
|
||||
#entriesListNav > a#drawLink {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.draw #entriesListContainer {
|
||||
[data-mode="draw"] #entriesListContainer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
@ -882,55 +873,48 @@ .listHidden #entriesListContainer {
|
|||
display: none;
|
||||
}
|
||||
|
||||
#entriesListContainer > nav {
|
||||
#entriesListNav {
|
||||
margin: 10px 0;
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#entriesListContainer > nav > a,
|
||||
#entriesListContainer > nav > button {
|
||||
background-image: linear-gradient(to bottom, #888, #666);
|
||||
border: 1px #000 solid;
|
||||
color: #FFF;
|
||||
text-align: center;
|
||||
#entriesListNav > * {
|
||||
display: block;
|
||||
padding: 4px;
|
||||
cursor: pointer;
|
||||
width: 120px;
|
||||
height: 30px;
|
||||
margin-right: 10px;
|
||||
text-shadow: 1px 1px 0 #444;
|
||||
}
|
||||
|
||||
#entriesListContainer > nav > button {
|
||||
#entriesListNav > .small {
|
||||
width: 30px;
|
||||
padding: 2px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
#entriesListContainer > nav > button > img {
|
||||
#entriesListNav > .small > img {
|
||||
height: 22px;
|
||||
width: 22px;
|
||||
}
|
||||
|
||||
#entriesListContainer > nav > button:last-child {
|
||||
#entriesListNav > .small:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
#entriesListContainer > nav > a:hover {
|
||||
#entriesListNav > a:hover {
|
||||
text-decoration: none;
|
||||
background-image: linear-gradient(to bottom, #999, #777);
|
||||
}
|
||||
|
||||
#entriesListContainer > nav > button:hover {
|
||||
#entriesListNav > .small:hover {
|
||||
background-image: none;
|
||||
background: transparent;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
#entriesListContainer > nav > button:hover > img {
|
||||
#entriesListDonate:hover > img {
|
||||
text-decoration: none;
|
||||
background-image: linear-gradient(to bottom, #FFAA00, #FFAA00);
|
||||
border-radius: 15px;
|
||||
|
@ -939,7 +923,7 @@ #entriesListContainer > nav > button:hover > img {
|
|||
height: 28px;
|
||||
width: 28px;
|
||||
}
|
||||
#entriesListContainer > nav > button:hover > img.Discord {
|
||||
#entriesListDiscord:hover > img {
|
||||
text-decoration: none;
|
||||
background-image: linear-gradient(to bottom, #7289DA, #7289DA);
|
||||
border-radius: 12px;
|
||||
|
@ -955,12 +939,12 @@ #entriesListBackground {
|
|||
top: 50px;
|
||||
bottom: 0;
|
||||
width: 360px;
|
||||
z-index: -600;
|
||||
z-index: -400;
|
||||
background-color: #333;
|
||||
border-right: 1px #000 solid;
|
||||
}
|
||||
|
||||
.draw #entriesListBackground {
|
||||
[data-mode="draw"] #entriesListBackground {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
@ -994,7 +978,7 @@ #hideListButton:hover {
|
|||
background-color: #555;
|
||||
}
|
||||
|
||||
.draw #hideListButton {
|
||||
[data-mode="draw"] #hideListButton {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
@ -1009,7 +993,7 @@ .listHidden #hideListButton {
|
|||
border-top: 1px #333 solid;
|
||||
width: 130px;
|
||||
height: 35px;
|
||||
z-index: 2000;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
#hideListButton:focus {
|
||||
|
@ -1029,6 +1013,10 @@ #entriesListControls input:focus {
|
|||
border-color: #CCC;
|
||||
}
|
||||
|
||||
[data-mode="explore"] #entriesListControls {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#atlasSize {
|
||||
display: block;
|
||||
margin: 3px 0 5px 0;
|
||||
|
@ -1080,7 +1068,7 @@ #aboutContainer {
|
|||
}
|
||||
|
||||
#aboutBackButton {
|
||||
margin: 20px 20px 0 20px;
|
||||
margin: 20px 0 20px;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
|
@ -1124,11 +1112,10 @@ #contributors a {
|
|||
line-height: 26px;
|
||||
}
|
||||
|
||||
#bitcoinButton {
|
||||
#donateButton {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#bitcoinWindow,
|
||||
#donateWindow {
|
||||
display: inline-block;
|
||||
z-index: 2000;
|
||||
|
@ -1150,10 +1137,6 @@ #donateWindow {
|
|||
max-width: 800px;
|
||||
}
|
||||
|
||||
#donateWindow > #bitcoinQR {
|
||||
|
||||
}
|
||||
|
||||
#donateWindow > p {
|
||||
margin: 2px 0;
|
||||
padding: 0 20px;
|
||||
|
@ -1161,13 +1144,11 @@ #donateWindow > p {
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
#bitcoinWindow > *,
|
||||
#donateWindow > * {
|
||||
display: inline-block;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
#bitcoinWindow > h2,
|
||||
#donateWindow > h2 {
|
||||
font-weight: 200;
|
||||
background-color: #555;
|
||||
|
@ -1177,7 +1158,6 @@ #donateWindow > h2 {
|
|||
text-shadow: 1px 1px 0 #000;
|
||||
}
|
||||
|
||||
#bitcoinWindow input,
|
||||
#donateWindow input {
|
||||
width: 100%;
|
||||
max-width: 350px;
|
||||
|
@ -1188,7 +1168,6 @@ #donateWindow input {
|
|||
color: #FFF;
|
||||
}
|
||||
|
||||
#bitcoinWindow button,
|
||||
#donateWindow button {
|
||||
padding: 10px 20px;
|
||||
margin-bottom: 20px;
|
||||
|
@ -1201,7 +1180,68 @@ h2#abouth2 {
|
|||
text-shadow: 2px 2px 0 #000;
|
||||
}
|
||||
|
||||
#bitcoinNotice {
|
||||
color: #AAA;
|
||||
margin-top: 7px;
|
||||
#viewModes {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#viewModes .buffer {
|
||||
bottom: -10px;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
height: 20px;
|
||||
width: 100%
|
||||
}
|
||||
|
||||
#viewModes .dropdown-content {
|
||||
margin-top: 1.5rem;
|
||||
top: 10px;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
display: none;
|
||||
background: #666;
|
||||
border: 1px #000 solid;
|
||||
cursor: pointer;
|
||||
width: 125%
|
||||
}
|
||||
|
||||
#viewModes .dropdown-content a {
|
||||
color: #FFF;
|
||||
text-align: left;
|
||||
padding: 5px 10px;
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
text-shadow: 1px 1px 0 #444;
|
||||
}
|
||||
|
||||
#viewModes .dropdown-content a:hover {
|
||||
background-image: linear-gradient(to bottom, #999, #777);
|
||||
}
|
||||
|
||||
#viewModes:hover .dropdown-content,
|
||||
#viewModes:active .dropdown-content {
|
||||
display: block;
|
||||
}
|
||||
|
||||
body:not([data-dev]) .show-only-on-dev {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
#netlifyBadges {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: .5rem
|
||||
}
|
||||
|
||||
#donateWindow a.button {
|
||||
padding: 1rem
|
||||
}
|
||||
|
||||
#donateWindow a.button svg {
|
||||
height: 1em;
|
||||
vertical-align: -0.125em;
|
||||
}
|
||||
|
||||
#donateWindow a.button path {
|
||||
color: white;
|
||||
}
|
|
@ -1,22 +1,15 @@
|
|||
/*
|
||||
========================================================================
|
||||
The /r/place Atlas
|
||||
|
||||
An Atlas of Reddit's /r/place, with information to each
|
||||
The 2022 /r/place Atlas
|
||||
|
||||
An Atlas of Reddit's 2022 /r/place, with information to each
|
||||
artwork of the canvas provided by the community.
|
||||
|
||||
Copyright (C) 2017 Roland Rytz <roland@draemm.li>
|
||||
|
||||
Copyright (c) 2017 Roland Rytz <roland@draemm.li>
|
||||
Copyright (c) 2022 r/placeAtlas2 contributors
|
||||
|
||||
Licensed under the GNU Affero General Public License Version 3
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
For more information, see:
|
||||
http://place-atlas.stefanocoding.me/license.txt
|
||||
|
||||
https://place-atlas.stefanocoding.me/license.txt
|
||||
========================================================================
|
||||
*/
|
||||
|
||||
|
@ -25,7 +18,7 @@ window.addEventListener("error", function (e) {
|
|||
var errorMessage = "<p class=\"error\">An error has occurred:</p>";
|
||||
errorMessage += "<p class=\"errorBody\">" + e.message + "</p>";
|
||||
errorMessage += "<p class=\"errorBody\">on line " + e.lineno + "</p>";
|
||||
errorMessage += "<p class=\"error\">If this keeps happening, feel free to send me a <a href=\"mailto:roland.rytz@gmail.com\">mail</a>.</p>";
|
||||
errorMessage += "<p class=\"error\">If this keeps happening, feel free to tell us on <a href=\"https://discord.gg/pJkm23b2nA\">our Discord server</a>.</p>";
|
||||
document.getElementById("loadingContent").innerHTML = errorMessage;
|
||||
});
|
||||
|
||||
|
|
|
@ -1,31 +1,25 @@
|
|||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
The /r/place Atlas
|
||||
|
||||
An Atlas of Reddit's /r/place, with information to each
|
||||
The 2022 /r/place Atlas
|
||||
|
||||
An Atlas of Reddit's 2022 /r/place, with information to each
|
||||
artwork of the canvas provided by the community.
|
||||
|
||||
Copyright (C) 2017 Roland Rytz <roland@draemm.li>
|
||||
|
||||
Copyright (c) 2017 Roland Rytz <roland@draemm.li>
|
||||
Copyright (c) 2022 r/placeAtlas2 contributors
|
||||
|
||||
Licensed under the GNU Affero General Public License Version 3
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
For more information, see:
|
||||
http://place-atlas.stefanocoding.me/license.txt
|
||||
|
||||
https://place-atlas.stefanocoding.me/license.txt
|
||||
========================================================================
|
||||
*/
|
||||
|
||||
|
||||
function initDraw(){
|
||||
|
||||
wrapper.classList.remove('listHidden')
|
||||
|
||||
window.render = render
|
||||
window.renderBackground = renderBackground
|
||||
window.updateHovering = updateHovering
|
||||
|
||||
var finishButton = document.getElementById("finishButton");
|
||||
var resetButton = document.getElementById("resetButton");
|
||||
|
@ -46,14 +40,10 @@ function initDraw(){
|
|||
var lShiftPressed = false;
|
||||
var shiftPressed = false;
|
||||
|
||||
var backgroundCanvas = document.createElement("canvas");
|
||||
backgroundCanvas.width = 2000;
|
||||
backgroundCanvas.height = 2000;
|
||||
var backgroundContext = backgroundCanvas.getContext("2d");
|
||||
|
||||
var highlightUncharted = true;
|
||||
|
||||
renderBackground();
|
||||
applyView();
|
||||
|
||||
container.style.cursor = "crosshair";
|
||||
|
||||
|
@ -62,8 +52,6 @@ function initDraw(){
|
|||
|
||||
var undoHistory = [];
|
||||
|
||||
var lastPos = [0, 0];
|
||||
|
||||
render(path);
|
||||
|
||||
container.addEventListener("mousedown", function(e){
|
||||
|
@ -118,6 +106,8 @@ function initDraw(){
|
|||
window.addEventListener("mousemove", function(e){
|
||||
|
||||
if(!dragging && drawing && path.length > 0){
|
||||
|
||||
console.log(123)
|
||||
|
||||
var coords = getCanvasCoords(e.clientX, e.clientY);
|
||||
render(path.concat([coords]));
|
||||
|
@ -241,33 +231,25 @@ function initDraw(){
|
|||
function calculateCenter(path){
|
||||
|
||||
var area = 0,
|
||||
i,
|
||||
j,
|
||||
point1,
|
||||
point2;
|
||||
i,
|
||||
j,
|
||||
point1,
|
||||
point2,
|
||||
x = 0,
|
||||
y = 0,
|
||||
f;
|
||||
|
||||
for (i = 0, j = path.length - 1; i < path.length; j=i,i++) {
|
||||
point1 = path[i];
|
||||
point2 = path[j];
|
||||
area += point1[0] * point2[1];
|
||||
area -= point1[1] * point2[0];
|
||||
}
|
||||
area *= 3;
|
||||
|
||||
var x = 0,
|
||||
y = 0,
|
||||
f;
|
||||
for (i = 0, j = path.length - 1; i < path.length; j=i,i++) {
|
||||
point1 = path[i];
|
||||
point2 = path[j];
|
||||
f = point1[0] * point2[1] - point2[0] * point1[1];
|
||||
area += f;
|
||||
x += (point1[0] + point2[0]) * f;
|
||||
y += (point1[1] + point2[1]) * f;
|
||||
}
|
||||
area *= 3;
|
||||
|
||||
for (i = 0, j = path.length - 1; i < path.length; j=i,i++) {
|
||||
point1 = path[i];
|
||||
point2 = path[j];
|
||||
f = point1[0] * point2[1] - point2[0] * point1[1];
|
||||
x += (point1[0] + point2[0]) * f;
|
||||
y += (point1[1] + point2[1]) * f;
|
||||
}
|
||||
|
||||
return [~~(x / area)+0.5, ~~(y / area)+0.5];
|
||||
|
||||
return [Math.floor(x / area)+0.5, Math.floor(y / area)+0.5];
|
||||
}
|
||||
|
||||
function undo(){
|
||||
|
@ -390,6 +372,18 @@ function initDraw(){
|
|||
|
||||
}
|
||||
|
||||
function updateHovering(e, tapped){
|
||||
if(!dragging && (!fixed || tapped)){
|
||||
var pos = [
|
||||
(e.clientX - (container.clientWidth/2 - innerContainer.clientWidth/2 + zoomOrigin[0] + container.offsetLeft))/zoom
|
||||
,(e.clientY - (container.clientHeight/2 - innerContainer.clientHeight/2 + zoomOrigin[1] + container.offsetTop))/zoom
|
||||
];
|
||||
var coords_p = document.getElementById("coords_p");
|
||||
coords_p.innerText = Math.ceil(pos[0]) + ", " + Math.ceil(pos[1]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
========================================================================
|
||||
The 2022 /r/place Atlas
|
||||
|
||||
An Atlas of Reddit's 2022 /r/place, with information to each
|
||||
artwork of the canvas provided by the community.
|
||||
|
||||
Copyright (c) 2017 Roland Rytz <roland@draemm.li>
|
||||
Copyright (c) 2022 r/placeAtlas2 contributors
|
||||
|
||||
Licensed under the GNU Affero General Public License Version 3
|
||||
https://place-atlas.stefanocoding.me/license.txt
|
||||
========================================================================
|
||||
*/
|
||||
|
||||
function createInfoBlock(entry) {
|
||||
function createInfoParagraph(name, value){
|
||||
let entryParagraphPositionElement = document.createElement("p");
|
||||
|
@ -35,7 +50,7 @@ function createInfoBlock(entry) {
|
|||
}
|
||||
|
||||
let [x, y] = entry.center;
|
||||
element.appendChild(createInfoParagraph("Position: ", `${Math.floor(x)}x${Math.floor(y)}`));
|
||||
element.appendChild(createInfoParagraph("Position: ", `${Math.floor(x)}, ${Math.floor(y)}`));
|
||||
|
||||
if(entry.path){
|
||||
let area = calcPolygonArea(entry.path);
|
||||
|
|
103
web/_js/main.js
103
web/_js/main.js
|
@ -1,28 +1,19 @@
|
|||
|
||||
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
The /r/place Atlas
|
||||
|
||||
An Atlas of Reddit's /r/place, with information to each
|
||||
The 2022 /r/place Atlas
|
||||
|
||||
An Atlas of Reddit's 2022 /r/place, with information to each
|
||||
artwork of the canvas provided by the community.
|
||||
|
||||
Copyright (C) 2017 Roland Rytz <roland@draemm.li>
|
||||
|
||||
Copyright (c) 2017 Roland Rytz <roland@draemm.li>
|
||||
Copyright (c) 2022 r/placeAtlas2 contributors
|
||||
|
||||
Licensed under the GNU Affero General Public License Version 3
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
For more information, see:
|
||||
http://place-atlas.stefanocoding.me/license.txt
|
||||
|
||||
https://place-atlas.stefanocoding.me/license.txt
|
||||
========================================================================
|
||||
*/
|
||||
|
||||
const prodDomain = "place-atlas.stefanocoding.me"
|
||||
|
||||
var innerContainer = document.getElementById("innerContainer");
|
||||
var container = document.getElementById("container");
|
||||
|
@ -46,12 +37,11 @@ var lastPosition = [0, 0];
|
|||
|
||||
var viewportSize = [0, 0];
|
||||
|
||||
document.getElementById("donateButton").addEventListener("click", function(e){
|
||||
// document.getElementById("bitcoinQR").src = "./_img/bitcoinQR.png?from=index";
|
||||
document.getElementById("entriesListDonate").addEventListener("click", function(e){
|
||||
document.getElementById("donateOverlay").style.display = "flex";
|
||||
});
|
||||
|
||||
document.getElementById("closeBitcoinButton").addEventListener("click", function(e){
|
||||
document.getElementById("closeDonateButton").addEventListener("click", function(e){
|
||||
document.getElementById("donateOverlay").style.display = "none";
|
||||
});
|
||||
|
||||
|
@ -75,6 +65,8 @@ function applyView(){
|
|||
|
||||
var atlas = null;
|
||||
|
||||
if (document.location.host !== prodDomain) document.body.dataset.dev = ""
|
||||
|
||||
init();
|
||||
|
||||
async function init(){
|
||||
|
@ -120,25 +112,20 @@ async function init(){
|
|||
}
|
||||
}
|
||||
|
||||
if(mode == "view"){
|
||||
|
||||
wrapper.className = wrapper.className.replace(/ drawMode/g, "");
|
||||
initView();
|
||||
|
||||
} else if(mode=="draw"){
|
||||
|
||||
wrapper.className += " draw";
|
||||
initDraw();
|
||||
|
||||
} else if(mode=="about"){
|
||||
document.body.dataset.mode = mode
|
||||
|
||||
initGlobal()
|
||||
if (mode !== "draw") initViewGlobal()
|
||||
|
||||
if(mode === "draw"){
|
||||
initDraw();
|
||||
} else if(mode === "about"){
|
||||
window.location = "./about.html";
|
||||
} else if(mode=="overlap"){
|
||||
wrapper.className = wrapper.className.replace(/ drawMode/g, "");
|
||||
} else if(mode === "overlap"){
|
||||
if(initOverlap){
|
||||
initOverlap();
|
||||
}
|
||||
} else if(mode.startsWith("diff")){
|
||||
wrapper.className = wrapper.className.replace(/ drawMode/g, "");
|
||||
try {
|
||||
let liveResp = await fetch("https://place-atlas.stefanocoding.me/atlas.json");
|
||||
let liveJson = await liveResp.json();
|
||||
|
@ -161,12 +148,12 @@ async function init(){
|
|||
a[c.id] = c;
|
||||
return a;
|
||||
},{});
|
||||
let removedEntries = liveJson.map(function(entry) {
|
||||
if(atlasReduced[entry.id] === undefined){
|
||||
entry.diff = "delete";
|
||||
}
|
||||
return entry;
|
||||
});
|
||||
let removedEntries = liveJson.filter(entry =>
|
||||
atlasReduced[entry.id] === undefined
|
||||
).map(entry => {
|
||||
entry.diff = "delete"
|
||||
return entry
|
||||
})
|
||||
atlas.push(...removedEntries)
|
||||
|
||||
if(mode.includes("only")){
|
||||
|
@ -174,11 +161,10 @@ async function init(){
|
|||
return typeof entry.diff == "string"
|
||||
});
|
||||
}
|
||||
|
||||
//TEMP FOR TIME TRAVEL
|
||||
atlasBackup = atlas;
|
||||
} catch (error) {
|
||||
console.log("Diff mode failed to load, reverting to normal view - " + error);
|
||||
console.warn("Diff mode failed to load, reverting to normal view.", error);
|
||||
} finally {
|
||||
if(initOverlap && mode.includes("overlap")){
|
||||
initOverlap();
|
||||
|
@ -186,35 +172,12 @@ async function init(){
|
|||
initView();
|
||||
}
|
||||
}
|
||||
} else if(mode === "explore"){
|
||||
initExplore();
|
||||
} else {
|
||||
initView();
|
||||
}
|
||||
|
||||
function changeOverlapMode(){
|
||||
console.log(mode)
|
||||
switch(mode){
|
||||
case "overlap":
|
||||
window.location.href = "?mode=explore"
|
||||
break;
|
||||
case "explore":
|
||||
window.location.href = "?"
|
||||
break;
|
||||
default:
|
||||
window.location.href = "?mode=overlap"
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const modeMap = {
|
||||
"view": "Overlap",
|
||||
"overlap": "Explore",
|
||||
"explore": "Atlas"
|
||||
}
|
||||
|
||||
const toggleMode = document.getElementById("toggleMode");
|
||||
toggleMode.onclick = changeOverlapMode;
|
||||
toggleMode.innerHTML = modeMap[mode] || "Overlap";
|
||||
|
||||
document.getElementById("loading").style.display = "none";
|
||||
|
||||
document.getElementById("zoomInButton").addEventListener("click", function(e){
|
||||
|
|
|
@ -1,93 +1,32 @@
|
|||
|
||||
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
The /r/place Atlas
|
||||
The 2022 /r/place Atlas
|
||||
|
||||
An Atlas of Reddit's /r/place, with information to each
|
||||
An Atlas of Reddit's 2022 /r/place, with information to each
|
||||
artwork of the canvas provided by the community.
|
||||
|
||||
Copyright (C) 2017 Roland Rytz <roland@draemm.li>
|
||||
Licensed under the GNU Affero General Public License Version 3
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
For more information, see:
|
||||
http://place-atlas.stefanocoding.me/license.txt
|
||||
Copyright (c) 2017 Roland Rytz <roland@draemm.li>
|
||||
Copyright (c) 2022 r/placeAtlas2 contributors
|
||||
|
||||
Licensed under the GNU Affero General Public License Version 3
|
||||
https://place-atlas.stefanocoding.me/license.txt
|
||||
========================================================================
|
||||
*/
|
||||
|
||||
function initOverlap(){
|
||||
|
||||
var wrapper = document.getElementById("wrapper");
|
||||
|
||||
var objectsContainer = document.getElementById("objectsList");
|
||||
|
||||
var linesCanvas = document.getElementById("linesCanvas");
|
||||
var linesContext = linesCanvas.getContext("2d");
|
||||
|
||||
var backgroundCanvas = document.createElement("canvas");
|
||||
backgroundCanvas.width = 2000;
|
||||
backgroundCanvas.height = 2000;
|
||||
var backgroundContext = backgroundCanvas.getContext("2d");
|
||||
|
||||
var filterInput = document.getElementById("searchList");
|
||||
|
||||
var entriesList = document.getElementById("entriesList");
|
||||
var hideListButton = document.getElementById("hideListButton");
|
||||
var entriesListShown = true;
|
||||
|
||||
var entriesLimit = 50;
|
||||
var entriesOffset = 0;
|
||||
var moreEntriesButton = document.createElement("button");
|
||||
moreEntriesButton.innerHTML = "Show "+entriesLimit+" more";
|
||||
moreEntriesButton.id = "moreEntriesButton";
|
||||
moreEntriesButton.onclick = function(){
|
||||
buildObjectsList();
|
||||
};
|
||||
|
||||
var viewportWidth = document.documentElement.clientWidth;
|
||||
window.renderBackground = renderBackground
|
||||
|
||||
var hovered = [];
|
||||
|
||||
var lastPos = [0, 0];
|
||||
|
||||
var fixed = false; // Fix hovered items in place, so that clicking on links is possible
|
||||
|
||||
renderBackground();
|
||||
buildObjectsList(null, null);
|
||||
renderBackground(atlas);
|
||||
render();
|
||||
|
||||
buildObjectsList();
|
||||
|
||||
// parse linked atlas entry id from link hash
|
||||
/*if (window.location.hash.substring(3)){
|
||||
zoom = 4;
|
||||
applyView();
|
||||
highlightEntryFromUrl();
|
||||
}*/
|
||||
|
||||
if(document.documentElement.clientWidth > 2000){
|
||||
entriesListShown = true;
|
||||
wrapper.className = wrapper.className.replace(/ listHidden/g, "");
|
||||
}
|
||||
|
||||
if(document.documentElement.clientWidth < 2000){
|
||||
entriesListShown = false;
|
||||
wrapper.className += " listHidden";
|
||||
}
|
||||
|
||||
applyView();
|
||||
render();
|
||||
updateLines();
|
||||
|
||||
|
||||
|
||||
var args = window.location.search;
|
||||
if(args){
|
||||
id = args.split("id=")[1];
|
||||
|
@ -96,138 +35,7 @@ function initOverlap(){
|
|||
}
|
||||
}
|
||||
|
||||
container.addEventListener("mousemove", function(e){
|
||||
updateHovering(e);
|
||||
});
|
||||
|
||||
filterInput.addEventListener("input", function(e){
|
||||
entriesOffset = 0;
|
||||
entriesList.innerHTML = "";
|
||||
entriesList.appendChild(moreEntriesButton);
|
||||
|
||||
buildObjectsList(this.value.toLowerCase());
|
||||
|
||||
});
|
||||
|
||||
document.getElementById("sort").addEventListener("input", function(e){
|
||||
entriesOffset = 0;
|
||||
entriesList.innerHTML = "";
|
||||
entriesList.appendChild(moreEntriesButton);
|
||||
|
||||
buildObjectsList(filterInput.value.toLowerCase());
|
||||
|
||||
});
|
||||
|
||||
hideListButton.addEventListener("click", function(e){
|
||||
entriesListShown = !entriesListShown;
|
||||
if(entriesListShown){
|
||||
wrapper.className = wrapper.className.replace(/ listHidden/g, "");
|
||||
} else {
|
||||
wrapper.className += " listHidden";
|
||||
}
|
||||
applyView();
|
||||
updateHovering(e);
|
||||
render();
|
||||
updateLines();
|
||||
});
|
||||
|
||||
function highlightEntryFromUrl(){
|
||||
|
||||
var objectsContainer = document.getElementById("objectsList");
|
||||
|
||||
var id = 0;
|
||||
|
||||
var args = window.location.search;
|
||||
if(args){
|
||||
id = args.split("id=")[1];
|
||||
if(id){
|
||||
id = id.split("&")[0];
|
||||
}
|
||||
}
|
||||
|
||||
//var id = parseInt(window.location.hash.substring(3));
|
||||
|
||||
var entry = atlas.filter(function(e){
|
||||
return e.id === id;
|
||||
});
|
||||
|
||||
if (entry.length === 1){
|
||||
entry = entry[0];
|
||||
var infoElement = createInfoBlock(entry);
|
||||
objectsContainer.innerHTML = "";
|
||||
objectsContainer.appendChild(infoElement);
|
||||
|
||||
//console.log(entry.center[0]);
|
||||
//console.log(entry.center[1]);
|
||||
|
||||
zoom = 4;
|
||||
applyView();
|
||||
|
||||
zoomOrigin = [
|
||||
innerContainer.clientWidth/2 - entry.center[0]* zoom// + container.offsetLeft
|
||||
,innerContainer.clientHeight/2 - entry.center[1]* zoom// + container.offsetTop
|
||||
];
|
||||
|
||||
//console.log(zoomOrigin);
|
||||
|
||||
applyView();
|
||||
hovered = [entry];
|
||||
render();
|
||||
hovered[0].element = infoElement;
|
||||
updateLines();
|
||||
fixed = true;
|
||||
}
|
||||
}
|
||||
|
||||
function updateHovering(e){
|
||||
if(!dragging && !fixed){
|
||||
var pos = [
|
||||
(e.clientX - (container.clientWidth/2 - innerContainer.clientWidth/2 + zoomOrigin[0] + container.offsetLeft))/zoom
|
||||
,(e.clientY - (container.clientHeight/2 - innerContainer.clientHeight/2 + zoomOrigin[1] + container.offsetTop))/zoom
|
||||
];
|
||||
|
||||
if(pos[0] <= 2200 && pos[0] >= -100 && pos[0] <= 2200 && pos[0] >= -100){
|
||||
var newHovered = [];
|
||||
for(var i = 0; i < atlas.length; i++){
|
||||
if(pointIsInPolygon(pos, atlas[i].path)){
|
||||
newHovered.push(atlas[i]);
|
||||
}
|
||||
}
|
||||
|
||||
var changed = false;
|
||||
|
||||
if(hovered.length == newHovered.length){
|
||||
for(var i = 0; i < hovered.length; i++){
|
||||
if(hovered[i].id != newHovered[i].id){
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if(changed){
|
||||
hovered = newHovered;
|
||||
|
||||
objectsContainer.innerHTML = "";
|
||||
|
||||
for(var i in hovered){
|
||||
var element = createInfoBlock(hovered[i]);
|
||||
|
||||
objectsContainer.appendChild(element);
|
||||
|
||||
hovered[i].element = element;
|
||||
}
|
||||
|
||||
|
||||
render();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function renderBackground(){
|
||||
function renderBackground(atlas) {
|
||||
|
||||
backgroundContext.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
|
@ -266,277 +74,4 @@ function initOverlap(){
|
|||
console.log(blank+" blank pixels, which are "+Math.round(blank/100)/100+"% of the canvas ("+(100-Math.round(blank/100)/100)+"% mapped)");
|
||||
}
|
||||
|
||||
function buildObjectsList(filter){
|
||||
|
||||
if(entriesList.contains(moreEntriesButton)){
|
||||
entriesList.removeChild(moreEntriesButton);
|
||||
}
|
||||
|
||||
var sortedAtlas;
|
||||
|
||||
if(filter){
|
||||
sortedAtlas = atlas.filter(function(value){
|
||||
return (value.name.toLowerCase().indexOf(filter) !== -1);
|
||||
});
|
||||
document.getElementById("atlasSize").innerHTML = "Found "+sortedAtlas.length+" entries.";
|
||||
} else {
|
||||
sortedAtlas = atlas.concat();
|
||||
document.getElementById("atlasSize").innerHTML = "The Atlas contains "+sortedAtlas.length+" entries.";
|
||||
}
|
||||
|
||||
var sort = document.getElementById("sort").value;
|
||||
|
||||
var sortFunction;
|
||||
|
||||
//console.log(sort);
|
||||
|
||||
switch(sort){
|
||||
case "alphaAsc":
|
||||
sortFunction = function(a, b){
|
||||
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
|
||||
}
|
||||
break;
|
||||
case "alphaDesc":
|
||||
sortFunction = function(a, b){
|
||||
return b.name.toLowerCase().localeCompare(a.name.toLowerCase());
|
||||
}
|
||||
break;
|
||||
case "newest":
|
||||
sortFunction = function(a, b){
|
||||
if (a.id > b.id) {
|
||||
return -1;
|
||||
}
|
||||
if (a.id < b.id) {
|
||||
return 1;
|
||||
}
|
||||
// a must be equal to b
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case "oldest":
|
||||
sortFunction = function(a, b){
|
||||
if (a.id < b.id) {
|
||||
return -1;
|
||||
}
|
||||
if (a.id > b.id) {
|
||||
return 1;
|
||||
}
|
||||
// a must be equal to b
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
sortedAtlas.sort(sortFunction);
|
||||
|
||||
for(var i = entriesOffset; i < entriesOffset+entriesLimit; i++){
|
||||
|
||||
if(i >= sortedAtlas.length){
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
var element = createInfoBlock(sortedAtlas[i]);
|
||||
|
||||
element.entry = sortedAtlas[i];
|
||||
|
||||
element.addEventListener("mouseenter", function(e){
|
||||
if(!fixed && !dragging){
|
||||
objectsContainer.innerHTML = "";
|
||||
zoomOrigin = [
|
||||
innerContainer.clientWidth/2 - this.entry.center[0]* zoom// + container.offsetLeft
|
||||
,innerContainer.clientHeight/2 - this.entry.center[1]* zoom// + container.offsetTop
|
||||
]
|
||||
|
||||
//console.log(zoomOrigin);
|
||||
|
||||
|
||||
applyView();
|
||||
hovered = [this.entry];
|
||||
render();
|
||||
hovered[0].element = this;
|
||||
updateLines();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
element.addEventListener("mouseleave", function(e){
|
||||
if(!fixed && !dragging){
|
||||
hovered = [];
|
||||
updateLines();
|
||||
render();
|
||||
}
|
||||
});
|
||||
|
||||
entriesList.appendChild(element);
|
||||
|
||||
}
|
||||
|
||||
entriesOffset += entriesLimit;
|
||||
|
||||
if(sortedAtlas.length > entriesOffset){
|
||||
moreEntriesButton.innerHTML = "Show "+Math.min(entriesLimit, sortedAtlas.length - entriesOffset)+" more";
|
||||
entriesList.appendChild(moreEntriesButton);
|
||||
}
|
||||
}
|
||||
|
||||
function render(){
|
||||
context.globalCompositeOperation = "source-over";
|
||||
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
if(hovered.length > 0){
|
||||
container.style.cursor = "pointer";
|
||||
} else {
|
||||
container.style.cursor = "default";
|
||||
}
|
||||
|
||||
|
||||
for(var i = 0; i < hovered.length; i++){
|
||||
|
||||
|
||||
var path = hovered[i].path;
|
||||
|
||||
context.beginPath();
|
||||
|
||||
if(path[0]){
|
||||
context.moveTo(path[0][0], path[0][1]);
|
||||
}
|
||||
|
||||
for(var p = 1; p < path.length; p++){
|
||||
context.lineTo(path[p][0], path[p][1]);
|
||||
}
|
||||
|
||||
context.closePath();
|
||||
|
||||
context.globalCompositeOperation = "source-over";
|
||||
|
||||
context.fillStyle = "rgba(0, 0, 0, 1)";
|
||||
context.fill();
|
||||
}
|
||||
|
||||
context.globalCompositeOperation = "source-out";
|
||||
context.drawImage(backgroundCanvas, 0, 0);
|
||||
|
||||
for(var i = 0; i < hovered.length; i++){
|
||||
|
||||
var path = hovered[i].path;
|
||||
|
||||
context.beginPath();
|
||||
|
||||
if(path[0]){
|
||||
context.moveTo(path[0][0], path[0][1]);
|
||||
}
|
||||
|
||||
for(var p = 1; p < path.length; p++){
|
||||
context.lineTo(path[p][0], path[p][1]);
|
||||
}
|
||||
|
||||
context.closePath();
|
||||
|
||||
context.globalCompositeOperation = "source-over";
|
||||
|
||||
context.strokeStyle = "rgba(0, 0, 0, 1)";
|
||||
context.stroke();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
function toggleFixed(e){
|
||||
if(!fixed && hovered.length == 0){
|
||||
return 0;
|
||||
}
|
||||
fixed = !fixed;
|
||||
if(!fixed){
|
||||
updateHovering(e);
|
||||
render();
|
||||
}
|
||||
}
|
||||
|
||||
function updateLines(){
|
||||
|
||||
linesCanvas.width = linesCanvas.clientWidth;
|
||||
linesCanvas.height = linesCanvas.clientHeight;
|
||||
linesContext.lineCap = "round";
|
||||
linesContext.lineWidth = Math.max(Math.min(zoom*1.5, 16*1.5), 6);
|
||||
linesContext.strokeStyle = "#000000";
|
||||
|
||||
for(var i = 0; i < hovered.length; i++){
|
||||
var element = hovered[i].element;
|
||||
|
||||
linesContext.beginPath();
|
||||
//linesContext.moveTo(element.offsetLeft + element.clientWidth - 10, element.offsetTop + 20);
|
||||
linesContext.moveTo(
|
||||
element.getBoundingClientRect().left + document.documentElement.scrollLeft + element.clientWidth/2
|
||||
,element.getBoundingClientRect().top + document.documentElement.scrollTop + 20
|
||||
);
|
||||
linesContext.lineTo(
|
||||
~~(hovered[i].center[0]*zoom) + innerContainer.offsetLeft
|
||||
,~~(hovered[i].center[1]*zoom) + innerContainer.offsetTop
|
||||
);
|
||||
linesContext.stroke();
|
||||
}
|
||||
|
||||
linesContext.lineWidth = Math.max(Math.min(zoom, 16), 4);
|
||||
linesContext.strokeStyle = "#FFFFFF";
|
||||
|
||||
for(var i = 0; i < hovered.length; i++){
|
||||
var element = hovered[i].element;
|
||||
|
||||
linesContext.beginPath();
|
||||
linesContext.moveTo(
|
||||
element.getBoundingClientRect().left + document.documentElement.scrollLeft + element.clientWidth/2
|
||||
,element.getBoundingClientRect().top + document.documentElement.scrollTop + 20
|
||||
);
|
||||
linesContext.lineTo(
|
||||
~~(hovered[i].center[0]*zoom) + innerContainer.offsetLeft
|
||||
,~~(hovered[i].center[1]*zoom) + innerContainer.offsetTop
|
||||
);
|
||||
linesContext.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("resize", updateLines);
|
||||
window.addEventListener("mousemove", updateLines);
|
||||
window.addEventListener("dblClick", updateLines);
|
||||
window.addEventListener("wheel", updateLines);
|
||||
|
||||
container.addEventListener("mousedown", function(e){
|
||||
lastPos = [
|
||||
e.clientX
|
||||
,e.clientY
|
||||
];
|
||||
});
|
||||
|
||||
container.addEventListener("mouseup", function(e){
|
||||
if(Math.abs(lastPos[0] - e.clientX) + Math.abs(lastPos[1] - e.clientY) <= 4){
|
||||
toggleFixed(e);
|
||||
}
|
||||
});
|
||||
|
||||
objectsContainer.addEventListener("scroll", function(e){
|
||||
updateLines();
|
||||
});
|
||||
|
||||
window.addEventListener("resize", function(){
|
||||
//console.log(document.documentElement.clientWidth, document.documentElement.clientHeight);
|
||||
|
||||
if(document.documentElement.clientWidth > 2000 && viewportWidth <= 2000){
|
||||
entriesListShown = true;
|
||||
wrapper.className = wrapper.className.replace(/ listHidden/g, "");
|
||||
}
|
||||
|
||||
if(document.documentElement.clientWidth < 2000 && viewportWidth >= 2000){
|
||||
entriesListShown = false;
|
||||
wrapper.className += " listHidden";
|
||||
}
|
||||
|
||||
viewportWidth = document.documentElement.clientWidth;
|
||||
|
||||
applyView();
|
||||
render();
|
||||
updateLines();
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
|
|
@ -24,9 +24,6 @@ SOFTWARE.
|
|||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
function pointIsInPolygon (point, polygon) {
|
||||
// ray-casting algorithm based on
|
||||
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
========================================================================
|
||||
The 2022 /r/place Atlas
|
||||
|
||||
An Atlas of Reddit's 2022 /r/place, with information to each
|
||||
artwork of the canvas provided by the community.
|
||||
|
||||
Copyright (c) 2017 Roland Rytz <roland@draemm.li>
|
||||
Copyright (c) 2022 r/placeAtlas2 contributors
|
||||
|
||||
Licensed under the GNU Affero General Public License Version 3
|
||||
https://place-atlas.stefanocoding.me/license.txt
|
||||
========================================================================
|
||||
*/
|
||||
|
||||
var areasSum = 0;
|
||||
var areas = [];
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
========================================================================
|
||||
The 2022 /r/place Atlas
|
||||
|
||||
An Atlas of Reddit's 2022 /r/place, with information to each
|
||||
artwork of the canvas provided by the community.
|
||||
|
||||
Copyright (c) 2017 Roland Rytz <roland@draemm.li>
|
||||
Copyright (c) 2022 r/placeAtlas2 contributors
|
||||
|
||||
Licensed under the GNU Affero General Public License Version 3
|
||||
https://place-atlas.stefanocoding.me/license.txt
|
||||
========================================================================
|
||||
*/
|
||||
|
||||
const timeConfig = [
|
||||
{
|
||||
timestamp: 1648822500,
|
||||
|
|
1260
web/_js/view.js
1260
web/_js/view.js
File diff suppressed because it is too large
Load diff
|
@ -1,22 +1,15 @@
|
|||
<!--
|
||||
========================================================================
|
||||
The /r/place Atlas
|
||||
|
||||
An Atlas of Reddit's /r/place, with information to each
|
||||
The 2022 /r/place Atlas
|
||||
|
||||
An Atlas of Reddit's 2022 /r/place, with information to each
|
||||
artwork of the canvas provided by the community.
|
||||
|
||||
Copyright (C) 2017 Roland Rytz <roland@draemm.li>
|
||||
|
||||
Copyright (c) 2017 Roland Rytz <roland@draemm.li>
|
||||
Copyright (c) 2022 r/placeAtlas2 contributors
|
||||
|
||||
Licensed under the GNU Affero General Public License Version 3
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
For more information, see:
|
||||
http://place-atlas.stefanocoding.me/license.txt
|
||||
|
||||
https://place-atlas.stefanocoding.me/license.txt
|
||||
========================================================================
|
||||
-->
|
||||
|
||||
|
@ -34,7 +27,7 @@
|
|||
|
||||
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1">
|
||||
|
||||
<link href="./_css/style.css?version=1.0.33" rel="stylesheet" type="text/css" media="all">
|
||||
<link href="./_css/style.css" rel="stylesheet" type="text/css" media="all">
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
|
@ -56,36 +49,35 @@ <h1>The 2022 /r/place Atlas</h1>
|
|||
|
||||
|
||||
<div id="aboutContainer">
|
||||
<a id="aboutBackButton" href="./">< Back to the Atlas</a>
|
||||
<div id="about">
|
||||
<a href="https://www.netlify.com">
|
||||
<a id="aboutBackButton" class="button" href="./">< Back to the Atlas</a>
|
||||
<a href="https://www.netlify.com" id="netlifyBadges">
|
||||
<img src="https://www.netlify.com/img/global/badges/netlify-color-bg.svg" alt="Deploys by Netlify" />
|
||||
<img src="https://api.netlify.com/api/v1/badges/1e7291ce-0680-45ed-9843-47a32a992bbb/deploy-status" alt="Deploys by Netlify" />
|
||||
</a>
|
||||
<br>
|
||||
<h2 id="abouth2">The 2022 /r/place Atlas</h2>
|
||||
<p>This is an Atlas aiming to chart all the artworks created during the <a href="https://www.reddit.com/r/place/">/r/place</a> April's fools event on <a href="https://www.reddit.com/" target="_blank">Reddit</a> in 2022.</p>
|
||||
<p>The original code was developed by <a href="/" target="_blank" rel="author">Roland Rytz</a> (<a href="mailto:roland.rytz@gmail.com" target="_blank">mail</a>, <a href="https://reddit.com/user/draemmli/" target="_blank">reddit</a>) and is available under the free <a href="https://www.gnu.org/licenses/agpl-3.0.en.html" target="_blank">AGPL license</a> on <a target="_blank" href="https://github.com/RolandR/place-atlas">GitHub</a>.</p>
|
||||
<p>This is an Atlas aiming to chart all the artworks created during the <a href="https://www.reddit.com/r/place/">/r/place</a> April Fools event on <a href="https://www.reddit.com/" target="_blank">Reddit</a> in 2022.</p>
|
||||
<p>The original code was developed by <a href="https://draemm.li/various/place-atlas/" target="_blank" rel="author">Roland Rytz</a> (<a href="mailto:roland.rytz@gmail.com" target="_blank">mail</a>, <a href="https://reddit.com/user/draemmli/" target="_blank">reddit</a>) and is available under the free <a href="https://www.gnu.org/licenses/agpl-3.0.en.html" target="_blank">AGPL license</a> on <a target="_blank" href="https://github.com/RolandR/place-atlas">GitHub</a>.</p>
|
||||
<br>
|
||||
<p>The currently maintained version of the website is managed by <a href="/" target="_blank" rel="author">Stefano Haagmans</a> and is obtainable under the same license within a <a target="_blank" href="https://github.com/placeAtlas/atlas">Github Fork</a>.</p>. Image's provided by <a target="_blank" href="https://place.thatguyalex.com/">Alex Tsernoh</a></p>.
|
||||
<p>Maintaining and updating the website takes work, but I enjoy doing it for free and giving this to people. But if you would like to support me, or the people who helped me with contributions to this project. You're free to support us though <a target="_blank" href="https://paypal.me/codixer">Paypal</a>. (I don't have bitcoin)</p>
|
||||
<p>The currently maintained version of the website is managed by <a href="/" target="_blank" rel="author">Stefano Haagmans</a> and is obtainable under the same license within a <a target="_blank" href="https://github.com/placeAtlas/atlas">GitHub fork</a>. Images are provided by <a target="_blank" href="https://place.thatguyalex.com/">Alex Tsernoh</a>.</p>
|
||||
<p>Maintaining and updating the website takes work, but I enjoy doing it for free and giving this to people. But if you would like to support me, or the people who helped me with contributions to this project. You're free to support us though <a target="_blank" href="https://paypal.me/placeAtlas/5">PayPal</a>, <a target="_blank" href="https://www.patreon.com/placeAtlas">Patreon</a>, or <a target="_blank" href="https://ko-fi.com/placeatlas">Ko-Fi</a>.</p>
|
||||
<p>To maintain the same tradition, I will also be offering stickers to anyone donating more then 20$ (Due to the size increase). But, you're not forced to do anything! This only shows appreciation to us and the people who've worked on this project</p>
|
||||
<br>
|
||||
<p>Roland Rytz worked on the Atlas full-time (and more!) for over two weeks during the 2017 r/place event.</p>
|
||||
<p>If you'd like to support Roland, you can do so by <a target="_blank" href="https://paypal.me/draemmli">PayPal</a>.</p>
|
||||
<p>If you donate more than 10(€/$/CHF/mBTC), He'll (hopefully) send you a nice sticker of the Place canvas! (2017 one)</p>
|
||||
<p>If you donate more than 10(€/$/CHF/mBTC), He'll (hopefully) send you a nice sticker of the 2017 Place canvas!</p>
|
||||
|
||||
<h2>How to contribute</h2>
|
||||
<p>The /r/Place Atlas project relies on user contributions.</p>
|
||||
<p>To contribute a label for an artwork, please read <a href="https://www.reddit.com/r/placeAtlas2/comments/tu203o/how_to_contribute/" target="_blank">this post on reddit</a> to learn how to submit a new entry.</p>
|
||||
<p>To contribute a label for an artwork, please read <a href="https://www.reddit.com/r/placeAtlas2/comments/tu203o/how_to_contribute/" target="_blank">this post on Reddit</a> to learn how to submit a new entry.</p>
|
||||
<p>Alternatively, contributions can be made directly on <a href="https://github.com/placeAtlas/atlas/blob/master/CONTRIBUTING.md">GitHub</a>.</p>
|
||||
<p>The <a href="https://reddit.com/r/placeAtlas2/" target="_blank">/r/placeAtlas2</a> subreddit is also the place to submit all bug reports, feature requests or questions.</p>
|
||||
|
||||
|
||||
<h2>r/placeAtlas2 (Current) Contributors and Maintainers</h2>
|
||||
<div id="contributors">
|
||||
<a href="https://reddit.com/user/TCOOfficiall" target="_blank">TCOOfficiall (Current Maintainer)</a> ·
|
||||
<a href="https://reddit.com/user/prosto_sanja" target="_blank">prosto_sanja (Provided Images)</a> - <a href="https://place.thatguyalex.com/" target="_blank">Website</a> ·
|
||||
<a href="https://reddit.com/user/TCOOfficiall" target="_blank">TCOOfficiall (current maintainer)</a> ·
|
||||
<a href="https://reddit.com/user/prosto_sanja" target="_blank">prosto_sanja (images)</a> <a href="https://place.thatguyalex.com/" target="_blank">(website)</a> ·
|
||||
<a href="https://reddit.com/user/electric-blue" target="_blank">electric-blue</a> ·
|
||||
<a href="https://reddit.com/user/m654zy" target="_blank">m654zy</a> ·
|
||||
<a href="https://reddit.com/user/xXLInkster17Xx" target="_blank">xXLInkster17Xx</a>
|
||||
|
@ -103,14 +95,5 @@ <h2 id="contacth2">Contact?</h2>
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
document.getElementById("closeBitcoinButton").addEventListener("click", function(e) {
|
||||
document.getElementById("bitcoinOverlay").style.display = "none";
|
||||
});
|
||||
|
||||
document.getElementById("bitcoinButton").addEventListener("click", function(e) {
|
||||
document.getElementById("bitcoinOverlay").style.display = "flex";
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
2225
web/atlas.json
2225
web/atlas.json
File diff suppressed because it is too large
Load diff
104
web/index.html
104
web/index.html
|
@ -1,22 +1,15 @@
|
|||
<!--
|
||||
========================================================================
|
||||
The /r/place Atlas
|
||||
|
||||
An Atlas of Reddit's /r/place, with information to each
|
||||
The 2022 /r/place Atlas
|
||||
|
||||
An Atlas of Reddit's 2022 /r/place, with information to each
|
||||
artwork of the canvas provided by the community.
|
||||
|
||||
Copyright (C) 2017 Roland Rytz <roland@draemm.li>
|
||||
|
||||
Copyright (c) 2017 Roland Rytz <roland@draemm.li>
|
||||
Copyright (c) 2022 r/placeAtlas2 contributors
|
||||
|
||||
Licensed under the GNU Affero General Public License Version 3
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
For more information, see:
|
||||
http://place-atlas.stefanocoding.me/license.txt
|
||||
|
||||
https://place-atlas.stefanocoding.me/license.txt
|
||||
========================================================================
|
||||
-->
|
||||
|
||||
|
@ -36,7 +29,7 @@
|
|||
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, minimum-scale=1, maximum-scale=1, shrink-to-fit=no"> <!-- user-scalable=no -->
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
|
||||
<link href="./_css/style.css?version=1.0.33" rel="stylesheet" type="text/css" media="all">
|
||||
<link href="./_css/style.css" rel="stylesheet" type="text/css" media="all">
|
||||
<link rel="manifest" href="./manifest.webmanifest">
|
||||
|
||||
<script type="application/ld+json">
|
||||
|
@ -60,7 +53,7 @@
|
|||
},
|
||||
"copyrightHolder": { "@id": "#RolandRytz" },
|
||||
"copyrightYear": 2017,
|
||||
"license": "http://place-atlas.stefanocoding.me/license.txt",
|
||||
"license": "https://place-atlas.stefanocoding.me/license.txt",
|
||||
"inLanguage": "English",
|
||||
"isAccessibleForFree": true,
|
||||
"keywords": "reddit, /r/place",
|
||||
|
@ -106,14 +99,24 @@ <h1 id="title">The 2022 /r/place Atlas</h1>
|
|||
</div>
|
||||
|
||||
<div id="entriesListContainer">
|
||||
<nav>
|
||||
<a id="aboutLink" href="./about.html">About</a>
|
||||
<a id="drawLink" href="./index.html?mode=draw">Draw</a>
|
||||
<a id="toggleMode" onclick="return changeOverlapMode()">Overlap</a>
|
||||
<button title="Discord" onclick="window.location.href='https://discord.gg/pJkm23b2nA'">
|
||||
<nav id="entriesListNav">
|
||||
<a id="aboutLink" href="./about.html" class="button">About</a>
|
||||
<a id="drawLink" href="./index.html?mode=draw" class="button">Draw</a>
|
||||
<div class="dropdown button" id="viewModes">
|
||||
<span>Modes</span>
|
||||
<span class="buffer"></span>
|
||||
<div class="dropdown-content">
|
||||
<a href="./">Normal</a>
|
||||
<a href="./?mode=explore">Explore</a>
|
||||
<a href="./?mode=overlap">Overlap</a>
|
||||
<a href="./?mode=diff" class="show-only-on-dev">With Diff</a>
|
||||
<a href="./?mode=diffonly" class="show-only-on-dev">Diff Only</a>
|
||||
</div>
|
||||
</div>
|
||||
<a title="Discord" href="https://discord.gg/pJkm23b2nA" class="button small" id="entriesListDiscord">
|
||||
<img class="Discord" alt="Discord Logo" src="./_img/discord.svg">
|
||||
</button>
|
||||
<button title="Donate!" id="donateButton">
|
||||
</a>
|
||||
<button title="Donate!" id="entriesListDonate" class="small">
|
||||
<img alt="Donate" src="data:image/svg+xml;utf8,%3Csvg%0A%20%20%20xmlns%3Adc%3D%22http%3A//purl.org/dc/elements/1.1/%22%0A%20%20%20xmlns%3Acc%3D%22http%3A//creativecommons.org/ns%23%22%0A%20%20%20xmlns%3Ardf%3D%22http%3A//www.w3.org/1999/02/22-rdf-syntax-ns%23%22%0A%20%20%20xmlns%3Asvg%3D%22http%3A//www.w3.org/2000/svg%22%0A%20%20%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%0A%20%20%20version%3D%221.1%22%0A%20%20%20width%3D%2263.97776%22%0A%20%20%20height%3D%2263.985764%22%0A%20%20%20id%3D%22svg2%22%3E%0A%20%20%3Cdefs%0A%20%20%20%20%20id%3D%22defs4%22%20/%3E%0A%20%20%3Cmetadata%0A%20%20%20%20%20id%3D%22metadata7%22%3E%0A%20%20%20%20%3Crdf%3ARDF%3E%0A%20%20%20%20%20%20%3Ccc%3AWork%0A%20%20%20%20%20%20%20%20%20rdf%3Aabout%3D%22%22%3E%0A%20%20%20%20%20%20%20%20%3Cdc%3Aformat%3Eimage/svg+xml%3C/dc%3Aformat%3E%0A%20%20%20%20%20%20%20%20%3Cdc%3Atype%0A%20%20%20%20%20%20%20%20%20%20%20rdf%3Aresource%3D%22http%3A//purl.org/dc/dcmitype/StillImage%22%20/%3E%0A%20%20%20%20%20%20%20%20%3Cdc%3Atitle%3E%3C/dc%3Atitle%3E%0A%20%20%20%20%20%20%3C/cc%3AWork%3E%0A%20%20%20%20%3C/rdf%3ARDF%3E%0A%20%20%3C/metadata%3E%0A%20%20%3Cg%0A%20%20%20%20%20transform%3D%22translate%28-239.44047%2C-363.22698%29%22%0A%20%20%20%20%20id%3D%22layer1%22%3E%0A%20%20%20%20%3Cpath%0A%20%20%20%20%20%20%20d%3D%22m%20290.96332%2C384.19885%20c%20-0.59424%2C-6.27896%20-6.01049%2C-8.39164%20-12.8518%2C-9.00126%20l%200.0128%2C-8.70824%20-5.30062%2C-0.007%20-0.0123%2C8.47872%20c%20-1.39346%2C-0.002%20-2.81788%2C0.0235%20-4.23308%2C0.0496%20l%200.0135%2C-8.53485%20-5.29778%2C-0.008%20-0.0149%2C8.70575%20c%20-1.14765%2C0.0217%20-2.27469%2C0.0414%20-3.3736%2C0.0405%20l%20-5.3e-4%2C-0.0271%20-7.31086%2C-0.0134%20-0.007%2C5.66124%20c%200%2C0%203.91442%2C-0.0688%203.84925%2C0.003%202.14703%2C0.004%202.84397%2C1.25133%203.04562%2C2.32724%20l%20-0.0143%2C9.92049%20c%200.14815%2C0.001%200.34143%2C0.008%200.56022%2C0.0378%20-0.17659%2C-3e-5%20-0.36561%2C-0.002%20-0.55995%2C-1.2e-4%20l%20-0.022%2C13.89765%20c%20-0.0952%2C0.67556%20-0.49402%2C1.75232%20-1.99407%2C1.75269%200.0678%2C0.0602%20-3.85316%2C-0.007%20-3.85316%2C-0.007%20l%20-1.06259%2C6.32874%206.89801%2C0.01%20c%201.28367%2C0.003%202.54669%2C0.0271%203.78665%2C0.0368%20l%20-0.0109%2C8.80736%205.29494%2C0.009%200.0128%2C-8.71427%20c%201.45379%2C0.0322%202.86073%2C0.0459%204.23429%2C0.0466%20l%20-0.0152%2C8.67412%205.30061%2C0.007%200.0147%2C-8.79173%20c%208.91219%2C-0.49805%2015.1527%2C-2.73385%2015.93965%2C-11.10113%200.63533%2C-6.73752%20-2.53%2C-9.74895%20-7.5868%2C-10.97123%203.07554%2C-1.56033%205.00104%2C-4.31475%204.55848%2C-8.90928%20z%20m%20-7.44387%2C18.82121%20c%20-0.007%2C6.58182%20-11.27551%2C5.81643%20-14.86789%2C5.81449%20l%200.0187%2C-11.66923%20c%203.59343%2C0.006%2014.85983%2C-1.01023%2014.84919%2C5.85474%20z%20m%20-2.44078%2C-16.46738%20c%20-0.0106%2C5.98811%20-9.40836%2C5.27536%20-12.40064%2C5.27116%20l%200.016%2C-10.58348%20c%202.99229%2C0.004%2012.39322%2C-0.93337%2012.38461%2C5.31232%20z%22%0A%20%20%20%20%20%20%20id%3D%22path3010%22%0A%20%20%20%20%20%20%20style%3D%22fill%3A%23ffffff%22%20/%3E%0A%20%20%3C/g%3E%0A%3C/svg%3E">
|
||||
</button>
|
||||
</nav>
|
||||
|
@ -156,13 +159,13 @@ <h1 id="title">The 2022 /r/place Atlas</h1>
|
|||
<div id="timeControls">
|
||||
<input type="range" min="1" max="1" value="1" class="slider" id="timeControlsSlider">
|
||||
</div>
|
||||
|
||||
<p><div id="author">Code owned by <a href="https://github.com/placeAtlas/atlas" target="_blank" rel="author">Place Atlas</a>.. Source on <a target="_blank" href="https://github.com/placeAtlas/atlas">GitHub</a>. This site is powered by <a href="https://www.netlify.com">Netlify</a>. Images provided by <a target="_blank" href="https://place.thatguyalex.com/">Alex Tsernoh</a>.</p>
|
||||
<div id="author">
|
||||
<p>Code owned by <a href="https://github.com/placeAtlas/atlas" target="_blank" rel="author">Place Atlas</a>. Source on <a target="_blank" href="https://github.com/placeAtlas/atlas">GitHub</a>. Site powered by <a href="https://www.netlify.com">Netlify</a>. Images provided by <a target="_blank" href="https://place.thatguyalex.com/">Alex Tsernoh</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="drawControlsContainer">
|
||||
<a id="drawBackButton" href="./">< Back to the Atlas</a>
|
||||
<a id="drawBackButton" class="button" href="./">< Back to the Atlas</a>
|
||||
<div id="drawControls">
|
||||
<div>
|
||||
<button id="undoButton" disabled>Undo</button>
|
||||
|
@ -196,7 +199,7 @@ <h1 id="title">The 2022 /r/place Atlas</h1>
|
|||
<p>You can then add more information about your object.</p>
|
||||
<div style="background-color:#7289DA; padding:20px">
|
||||
<p><b>Need Help?</b></p>
|
||||
<b>You can ask for help on our discord server <a href="https://discord.gg/pJkm23b2nA">here</a>!</b><br>
|
||||
<b>You can ask for help on <a href="https://discord.gg/pJkm23b2nA">our Discord server</a>!</b><br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -209,7 +212,7 @@ <h1 id="title">The 2022 /r/place Atlas</h1>
|
|||
<div id="exportWindow">
|
||||
<p><b>Recommended:</b> Post directly after clicking this button. Don't forget to flair it with the "New Entry" tag. </p>
|
||||
<div style="display:flex; flex-direction:column;align-items:center">
|
||||
<a href="_blank" id="exportDirectPost">Post Direct to Reddit</a>
|
||||
<a href="_blank" id="exportDirectPost" class="button">Post Direct to Reddit</a>
|
||||
</div>
|
||||
<hr style="border-bottom: solid black 1px"/>
|
||||
<i>or...</i>
|
||||
|
@ -228,30 +231,41 @@ <h1 id="title">The 2022 /r/place Atlas</h1>
|
|||
<div id="donateWindow">
|
||||
<h2>Donation Links</h2>
|
||||
<p>Current 2022 Atlas Maintainers:</p>
|
||||
<p> - <a target="_blank" href="https://paypal.me/placeAtlas/5">PayPal</a></p>
|
||||
<p> - <a target="_blank" href="https://www.patreon.com/placeAtlas">Patreon</a></p>
|
||||
<p> - <a target="_blank" href="https://ko-fi.com/placeatlas">Ko-Fi</a></p>
|
||||
<a class="button" target="_blank" href="https://paypal.me/placeAtlas/5">
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>PayPal</title><path fill="white" d="M7.076 21.337H2.47a.641.641 0 0 1-.633-.74L4.944.901C5.026.382 5.474 0 5.998 0h7.46c2.57 0 4.578.543 5.69 1.81 1.01 1.15 1.304 2.42 1.012 4.287-.023.143-.047.288-.077.437-.983 5.05-4.349 6.797-8.647 6.797h-2.19c-.524 0-.968.382-1.05.9l-1.12 7.106zm14.146-14.42a3.35 3.35 0 0 0-.607-.541c-.013.076-.026.175-.041.254-.93 4.778-4.005 7.201-9.138 7.201h-2.19a.563.563 0 0 0-.556.479l-1.187 7.527h-.506l-.24 1.516a.56.56 0 0 0 .554.647h3.882c.46 0 .85-.334.922-.788.06-.26.76-4.852.816-5.09a.932.932 0 0 1 .923-.788h.58c3.76 0 6.705-1.528 7.565-5.946.36-1.847.174-3.388-.777-4.471z"/></svg>
|
||||
PayPal
|
||||
</a>
|
||||
<a class="button" target="_blank" href="https://www.patreon.com/placeAtlas">
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Patreon</title><path fill="white" d="M0 .48v23.04h4.22V.48zm15.385 0c-4.764 0-8.641 3.88-8.641 8.65 0 4.755 3.877 8.623 8.641 8.623 4.75 0 8.615-3.868 8.615-8.623C24 4.36 20.136.48 15.385.48z"/></svg>
|
||||
Patreon
|
||||
</a>
|
||||
<a class="button" target="_blank" href="https://ko-fi.com/placeatlas">
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Ko-fi</title><path fill="white" d="M23.881 8.948c-.773-4.085-4.859-4.593-4.859-4.593H.723c-.604 0-.679.798-.679.798s-.082 7.324-.022 11.822c.164 2.424 2.586 2.672 2.586 2.672s8.267-.023 11.966-.049c2.438-.426 2.683-2.566 2.658-3.734 4.352.24 7.422-2.831 6.649-6.916zm-11.062 3.511c-1.246 1.453-4.011 3.976-4.011 3.976s-.121.119-.31.023c-.076-.057-.108-.09-.108-.09-.443-.441-3.368-3.049-4.034-3.954-.709-.965-1.041-2.7-.091-3.71.951-1.01 3.005-1.086 4.363.407 0 0 1.565-1.782 3.468-.963 1.904.82 1.832 3.011.723 4.311zm6.173.478c-.928.116-1.682.028-1.682.028V7.284h1.77s1.971.551 1.971 2.638c0 1.913-.985 2.667-2.059 3.015z"/></svg>
|
||||
Ko-Fi
|
||||
</a>
|
||||
<p>Original 2017 Atlas Developer (draemmli aka Roland Rytz): </p>
|
||||
<p> - <a target="_blank" href="https://paypal.me/draemmli">PayPal</a></p>
|
||||
|
||||
<button id="closeBitcoinButton">Close</button>
|
||||
<a class="button" target="_blank" href="https://paypal.me/draemmli">
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>PayPal</title><path fill="white" d="M7.076 21.337H2.47a.641.641 0 0 1-.633-.74L4.944.901C5.026.382 5.474 0 5.998 0h7.46c2.57 0 4.578.543 5.69 1.81 1.01 1.15 1.304 2.42 1.012 4.287-.023.143-.047.288-.077.437-.983 5.05-4.349 6.797-8.647 6.797h-2.19c-.524 0-.968.382-1.05.9l-1.12 7.106zm14.146-14.42a3.35 3.35 0 0 0-.607-.541c-.013.076-.026.175-.041.254-.93 4.778-4.005 7.201-9.138 7.201h-2.19a.563.563 0 0 0-.556.479l-1.187 7.527h-.506l-.24 1.516a.56.56 0 0 0 .554.647h3.882c.46 0 .85-.334.922-.788.06-.26.76-4.852.816-5.09a.932.932 0 0 1 .923-.788h.58c3.76 0 6.705-1.528 7.565-5.946.36-1.847.174-3.388-.777-4.471z"/></svg>
|
||||
PayPal
|
||||
</a>
|
||||
<br>
|
||||
<button id="closeDonateButton">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="./_js/time.js?version=1.0.3"></script>
|
||||
<script type="text/javascript" src="./_js/infoblock.js?version=1.0"></script>
|
||||
<script type="text/javascript" src="./_js/pointInPolygon.js?version=1.0"></script>
|
||||
<script type="text/javascript" src="./_js/atlas.js?version=1.0.50"></script>
|
||||
<script type="text/javascript" src="./_js/view.js?version=1.0.4"></script>
|
||||
<script type="text/javascript" src="./_js/overlap.js?version=1.0.4"></script>
|
||||
<script type="text/javascript" src="./_js/draw.js?version=1.0.3"></script>
|
||||
<script type="text/javascript" src="./_js/main.js?version=1.0.3"></script>
|
||||
<script type="text/javascript" src="./_js/time.js"></script>
|
||||
<script type="text/javascript" src="./_js/infoblock.js"></script>
|
||||
<script type="text/javascript" src="./_js/pointInPolygon.js"></script>
|
||||
<script type="text/javascript" src="./_js/atlas.js"></script>
|
||||
<script type="text/javascript" src="./_js/view.js"></script>
|
||||
<script type="text/javascript" src="./_js/overlap.js"></script>
|
||||
<script type="text/javascript" src="./_js/draw.js"></script>
|
||||
<script type="text/javascript" src="./_js/main.js"></script>
|
||||
<!--
|
||||
<script type="text/javascript" src="./_js/stats.js?version=1.0.0"></script>
|
||||
<script type="text/javascript" src="./_js/stats.js"></script>
|
||||
|
||||
|
||||
<script type="text/javascript" src="./_js/minified.js?version=1.0.102"></script>
|
||||
<script type="text/javascript" src="./_js/minified.js"></script>
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
|
|
Loading…
Reference in a new issue