major rework of configration parameters.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
__version__ = "20220328.0"
|
__version__ = "20220607.0"
|
||||||
|
|
||||||
|
|
||||||
def get_version():
|
def get_version():
|
||||||
|
|||||||
244
mirva/mirva.py
244
mirva/mirva.py
@@ -4,8 +4,11 @@ import sys
|
|||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
from argparse import ArgumentParser
|
import random
|
||||||
|
from argparse import ArgumentParser, HelpFormatter
|
||||||
|
|
||||||
from mirva import get_version
|
from mirva import get_version
|
||||||
|
from tqdm import tqdm
|
||||||
|
|
||||||
|
|
||||||
class Mirva:
|
class Mirva:
|
||||||
@@ -22,23 +25,48 @@ class Mirva:
|
|||||||
".*\.jpg$|.*\.jpeg$|.*\.png$|.*\.gif$|.*\.tif$", re.I
|
".*\.jpg$|.*\.jpeg$|.*\.png$|.*\.gif$|.*\.tif$", re.I
|
||||||
)
|
)
|
||||||
self.video_match = re.compile(".*\.mp4$", re.I)
|
self.video_match = re.compile(".*\.mp4$", re.I)
|
||||||
|
self.site_defaults = {
|
||||||
|
"title": {"default": "", "help": "Title of the site"},
|
||||||
|
"sub_title": {
|
||||||
|
"default": "",
|
||||||
|
"help": "Subtitle of the site, shown under the title",
|
||||||
|
},
|
||||||
|
"intro": {
|
||||||
|
"default": "",
|
||||||
|
"help": "Intro text shown before first image",
|
||||||
|
},
|
||||||
|
"image_size": {
|
||||||
|
"default": "1920",
|
||||||
|
"help": "Resize images for faster loading. Use 'link' for symbolic links without resizing.",
|
||||||
|
},
|
||||||
|
"scroll": {
|
||||||
|
"default": "smooth",
|
||||||
|
"help": "Transition to next image with keyboard: smooth or auto",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
## Init ##
|
||||||
self.get_options()
|
self.get_options()
|
||||||
os.chdir(self.options.folder)
|
os.chdir(self.options.folder)
|
||||||
self.write_resources()
|
|
||||||
self.file_list = self.get_files()
|
self.file_list = self.get_files()
|
||||||
if self.options.config or not os.path.exists(self.config_file):
|
|
||||||
self.create_config()
|
if self.run_commands["config"]:
|
||||||
print(
|
|
||||||
"Config created: Exiting without gallery creation. Check config first."
|
self.write_resources()
|
||||||
)
|
updated = self.create_config()
|
||||||
return
|
if updated:
|
||||||
self.get_config()
|
print(
|
||||||
if self.options.exif:
|
"Config created or updated: Check config contents: {}".format(
|
||||||
self.append_exif()
|
self.config_file
|
||||||
self.create_posts()
|
)
|
||||||
self.write_index()
|
)
|
||||||
self.write_mediums()
|
|
||||||
print("Gallery written.")
|
if self.run_commands["generator"]:
|
||||||
|
self.get_config()
|
||||||
|
self.create_posts()
|
||||||
|
self.write_index()
|
||||||
|
self.write_mediums()
|
||||||
|
print("Gallery written.")
|
||||||
|
|
||||||
def create_config(self):
|
def create_config(self):
|
||||||
|
|
||||||
@@ -46,23 +74,48 @@ class Mirva:
|
|||||||
self.config.read(self.config_file)
|
self.config.read(self.config_file)
|
||||||
config_changed = False
|
config_changed = False
|
||||||
if not "SITE" in self.config:
|
if not "SITE" in self.config:
|
||||||
self.config["SITE"] = {
|
self.config["SITE"] = {}
|
||||||
"title": "",
|
|
||||||
"sub_title": "",
|
|
||||||
"intro": "",
|
|
||||||
"image_size": 850,
|
|
||||||
}
|
|
||||||
config_changed = True
|
config_changed = True
|
||||||
|
|
||||||
|
for key in self.site_defaults:
|
||||||
|
if not key in self.config["SITE"]:
|
||||||
|
config_changed = True
|
||||||
|
self.config["SITE"][key] = self.site_defaults[key]["default"]
|
||||||
|
|
||||||
|
if self.options.set:
|
||||||
|
for key, value in self.options.set:
|
||||||
|
if key not in self.site_defaults:
|
||||||
|
raise KeyError("Key '{}' is not a config keyword".format(key))
|
||||||
|
self.config["SITE"][key] = value
|
||||||
|
config_changed = True
|
||||||
|
|
||||||
for f in self.file_list:
|
for f in self.file_list:
|
||||||
if not f in self.config:
|
if not f in self.config:
|
||||||
title, _ = os.path.splitext(f)
|
title, _ = os.path.splitext(f)
|
||||||
title = title.replace("_", " ")
|
title = title.replace("_", " ")
|
||||||
self.config[f] = {"title": title, "description": ""}
|
self.config[f] = {"title": title, "description": ""}
|
||||||
config_changed = True
|
config_changed = True
|
||||||
|
print("Added {}".format(f))
|
||||||
|
|
||||||
|
if self.options.purge:
|
||||||
|
unnecessary = []
|
||||||
|
for f in self.config:
|
||||||
|
if f in ("SITE", "DEFAULT"):
|
||||||
|
continue
|
||||||
|
if f not in self.file_list:
|
||||||
|
print("{} not found in files".format(f))
|
||||||
|
unnecessary.append(f)
|
||||||
|
for f in unnecessary:
|
||||||
|
del self.config[f]
|
||||||
|
config_changed = True
|
||||||
|
|
||||||
|
if self.options.exif:
|
||||||
|
self.append_exif()
|
||||||
|
config_changed = True
|
||||||
|
|
||||||
if config_changed:
|
if config_changed:
|
||||||
self.write_config()
|
self.write_config()
|
||||||
|
return config_changed
|
||||||
|
|
||||||
def create_posts(self):
|
def create_posts(self):
|
||||||
|
|
||||||
@@ -93,7 +146,6 @@ class Mirva:
|
|||||||
self.config.write(fp)
|
self.config.write(fp)
|
||||||
|
|
||||||
def get_files(self):
|
def get_files(self):
|
||||||
image_match = re.compile(".*\.jpg$|.*\.jpeg$|.*\.png$|.*\.gif$|.*\.tif$", re.I)
|
|
||||||
files = []
|
files = []
|
||||||
for f in sorted(os.listdir(".")):
|
for f in sorted(os.listdir(".")):
|
||||||
if f.startswith("."):
|
if f.startswith("."):
|
||||||
@@ -104,24 +156,24 @@ class Mirva:
|
|||||||
return files
|
return files
|
||||||
|
|
||||||
def get_options(self):
|
def get_options(self):
|
||||||
parser = ArgumentParser(
|
parser = ArgumentParser(prog="mirva", formatter_class=SmartFormatter)
|
||||||
prog="mirva",
|
|
||||||
epilog='Configuration note: item "image_size = [integer]" is the '
|
|
||||||
+ "middle sized image max width/height in pixels. It also accepts a special "
|
|
||||||
+ 'value "link" to make symbolic links.',
|
|
||||||
)
|
|
||||||
# parser.add_argument("-v", default=False, action="store_true")
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--config",
|
"--version",
|
||||||
default=False,
|
action="version",
|
||||||
action="store_true",
|
version="%(prog)s {version}".format(version=get_version()),
|
||||||
help="Write config and exit. Required if more images are added.",
|
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--force",
|
"--folder",
|
||||||
|
type=str,
|
||||||
|
default=".",
|
||||||
|
help="Folder for gallery. Default current folder.",
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--purge",
|
||||||
default=False,
|
default=False,
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="Force regeneration of middle sized images",
|
help="Remove non-existent files in image list. Required if images are removed.",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--exif",
|
"--exif",
|
||||||
@@ -130,20 +182,43 @@ class Mirva:
|
|||||||
help="Append EXIF information to image descriptions",
|
help="Append EXIF information to image descriptions",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--version",
|
"--set",
|
||||||
action="version",
|
"-s",
|
||||||
version="%(prog)s {version}".format(version=get_version()),
|
default=None,
|
||||||
|
nargs=2,
|
||||||
|
action="append",
|
||||||
|
metavar=("key", "value"),
|
||||||
|
help="smart|Configurable options: \n"
|
||||||
|
+ "\n".join(
|
||||||
|
["{}: {}".format(k, v["help"]) for k, v in self.site_defaults.items()]
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--force",
|
||||||
|
default=False,
|
||||||
|
action="store_true",
|
||||||
|
help="Force regeneration of middle sized images",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"folder",
|
"--command",
|
||||||
type=str,
|
"-c",
|
||||||
default=".",
|
default="all",
|
||||||
nargs="?",
|
action="store",
|
||||||
help="Folder for gallery",
|
choices=["all", "config", "generator"],
|
||||||
|
help="Run only part of the process. Defaults to all. Config is run always if it doesn't exist.",
|
||||||
)
|
)
|
||||||
self.options = parser.parse_args()
|
|
||||||
|
|
||||||
def get_index(self, page_title, sub_title, intro, posts):
|
self.options = parser.parse_args()
|
||||||
|
self.run_commands = {
|
||||||
|
"config": self.options.command == "config"
|
||||||
|
or self.options.command == "all"
|
||||||
|
or not os.path.exists(self.config_file),
|
||||||
|
"generator": self.options.command == "generator"
|
||||||
|
or self.options.command == "all",
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_index(self, posts):
|
||||||
|
|
||||||
return """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
return """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
<!--
|
<!--
|
||||||
@@ -164,10 +239,10 @@ Released : 20110306
|
|||||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||||
<link rel="shortcut icon" href="{resource}/mirva.ico"/>
|
<link rel="shortcut icon" href="{resource}/mirva.ico"/>
|
||||||
<title>{page_title}</title>
|
<title>{page_title}</title>
|
||||||
<link href="{resource}/style.css" rel="stylesheet" type="text/css" media="screen" />
|
<link href="{resource}/mirva.css" rel="stylesheet" type="text/css" media="screen" />
|
||||||
<script src="{resource}/mirva.js"></script>
|
<script src="{resource}/mirva.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body data-scroll="{scroll}">
|
||||||
<div id="wrapper">
|
<div id="wrapper">
|
||||||
<div id="header">
|
<div id="header">
|
||||||
<div id="logo">
|
<div id="logo">
|
||||||
@@ -183,7 +258,7 @@ Released : 20110306
|
|||||||
<div id="page-bgbtm">
|
<div id="page-bgbtm">
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<div class="post">
|
<div class="post">
|
||||||
<div class="entry">
|
<div class="entry intro">
|
||||||
{intro}
|
{intro}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -199,9 +274,10 @@ Released : 20110306
|
|||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>""".format(
|
</html>""".format(
|
||||||
page_title=page_title,
|
page_title=self.config["SITE"]["title"],
|
||||||
sub_title=sub_title,
|
sub_title=self.config["SITE"]["sub_title"],
|
||||||
intro=intro,
|
intro=self.config["SITE"]["intro"],
|
||||||
|
scroll=self.config["SITE"]["scroll"],
|
||||||
posts="\n".join(posts),
|
posts="\n".join(posts),
|
||||||
resource=self.resource_dir,
|
resource=self.resource_dir,
|
||||||
)
|
)
|
||||||
@@ -212,7 +288,7 @@ Released : 20110306
|
|||||||
return """
|
return """
|
||||||
<div class="post">
|
<div class="post">
|
||||||
<div class="navigation"> </div>
|
<div class="navigation"> </div>
|
||||||
<div class=center><a href="{image}">
|
<div class="image_wrapper center"><a href="{image}">
|
||||||
<video class=post_image controls preload="metadata">
|
<video class=post_image controls preload="metadata">
|
||||||
<source src="{image}" type="video/mp4" >
|
<source src="{image}" type="video/mp4" >
|
||||||
</video>
|
</video>
|
||||||
@@ -227,7 +303,9 @@ Released : 20110306
|
|||||||
return """
|
return """
|
||||||
<div class="post">
|
<div class="post">
|
||||||
<div class="navigation"> </div>
|
<div class="navigation"> </div>
|
||||||
<div class=center><a href="{image}"><img loading=lazy class=post_image src="{med_dir}/{image}.jpg"></a></div>
|
<div class="image_wrapper center"><a href="{image}">
|
||||||
|
<img loading=lazy class=post_image src="{med_dir}/{image}.jpg">
|
||||||
|
</a></div>
|
||||||
<div class="meta"><div class="name">{title}</div></div>
|
<div class="meta"><div class="name">{title}</div></div>
|
||||||
<div style="clear: both;"> </div>
|
<div style="clear: both;"> </div>
|
||||||
<div class="entry">{content}</div>
|
<div class="entry">{content}</div>
|
||||||
@@ -253,14 +331,7 @@ Released : 20110306
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
with open("index.html", "wt") as fp:
|
with open("index.html", "wt") as fp:
|
||||||
fp.write(
|
fp.write(self.get_index(self.posts))
|
||||||
self.get_index(
|
|
||||||
self.config["SITE"]["title"],
|
|
||||||
self.config["SITE"]["sub_title"],
|
|
||||||
self.config["SITE"]["intro"],
|
|
||||||
self.posts,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def write_resources(self):
|
def write_resources(self):
|
||||||
|
|
||||||
@@ -270,19 +341,47 @@ Released : 20110306
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
for f in (
|
for f in (
|
||||||
"style.css",
|
"mirva.css",
|
||||||
"arrow_up.png",
|
"arrow_up.png",
|
||||||
"arrow_down.png",
|
"arrow_down.png",
|
||||||
"banner.jpg",
|
|
||||||
"mirva.ico",
|
"mirva.ico",
|
||||||
"mirva.js",
|
"mirva.js",
|
||||||
):
|
):
|
||||||
if os.path.exists(os.path.join(self.resource_dir, f)):
|
if os.path.exists(os.path.join(self.resource_dir, f)):
|
||||||
continue
|
continue
|
||||||
shutil.copy(
|
shutil.copy(
|
||||||
os.path.join(self.resource_src, f), os.path.join(self.resource_dir, f)
|
os.path.join(self.resource_src, f),
|
||||||
|
os.path.join(self.resource_dir, f),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if not os.path.exists(os.path.join(self.resource_dir, "banner.jpg")):
|
||||||
|
try:
|
||||||
|
f = random.choice(self.file_list)
|
||||||
|
outfile = os.path.join(self.resource_dir, "banner.jpg")
|
||||||
|
res = "1920x"
|
||||||
|
convargs = [
|
||||||
|
"convert",
|
||||||
|
"{}[0]".format(f),
|
||||||
|
"-background",
|
||||||
|
"white",
|
||||||
|
"-flatten",
|
||||||
|
"-resize",
|
||||||
|
res,
|
||||||
|
"+contrast",
|
||||||
|
"+contrast",
|
||||||
|
"+contrast",
|
||||||
|
"-quality",
|
||||||
|
"85",
|
||||||
|
outfile,
|
||||||
|
]
|
||||||
|
subprocess.run(convargs)
|
||||||
|
print("Random banner written to {}".format(outfile))
|
||||||
|
except Exception:
|
||||||
|
shutil.copy(
|
||||||
|
os.path.join(self.resource_src, "banner.jpg"),
|
||||||
|
os.path.join(self.resource_dir, "banner.jpg"),
|
||||||
|
)
|
||||||
|
|
||||||
def write_mediums(self):
|
def write_mediums(self):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -290,14 +389,14 @@ Released : 20110306
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
r = self.config["SITE"].get("image_size", 850)
|
r = self.config["SITE"].get("image_size", 1920)
|
||||||
link = str(r).lower() == "link"
|
link = str(r).lower() == "link"
|
||||||
if link:
|
if link:
|
||||||
r = 0
|
r = 0
|
||||||
|
|
||||||
res = "{:d}x{:d}>".format(int(r), int(r))
|
res = "{:d}x{:d}>".format(int(r), int(r))
|
||||||
force = self.options.force
|
force = self.options.force
|
||||||
for f in self.file_list:
|
for f in tqdm(self.file_list):
|
||||||
if self.video_match.match(f):
|
if self.video_match.match(f):
|
||||||
continue
|
continue
|
||||||
outfile = os.path.join(self.medium_dir, "{}.jpg".format(f))
|
outfile = os.path.join(self.medium_dir, "{}.jpg".format(f))
|
||||||
@@ -309,14 +408,11 @@ Released : 20110306
|
|||||||
|
|
||||||
if not os.path.exists(outfile):
|
if not os.path.exists(outfile):
|
||||||
if link:
|
if link:
|
||||||
# TODO: Get absolute path to f?
|
|
||||||
os.symlink("../../{}".format(f), outfile)
|
os.symlink("../../{}".format(f), outfile)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
convargs = [
|
convargs = [
|
||||||
"convert",
|
"convert",
|
||||||
"-define",
|
|
||||||
"jpeg:size={}x{}".format(r, r),
|
|
||||||
"{}[0]".format(f),
|
"{}[0]".format(f),
|
||||||
"-background",
|
"-background",
|
||||||
"white",
|
"white",
|
||||||
@@ -327,8 +423,6 @@ Released : 20110306
|
|||||||
"85",
|
"85",
|
||||||
outfile,
|
outfile,
|
||||||
]
|
]
|
||||||
sys.stdout.write(".")
|
|
||||||
sys.stdout.flush()
|
|
||||||
subprocess.run(convargs)
|
subprocess.run(convargs)
|
||||||
sys.stdout.write("\n")
|
sys.stdout.write("\n")
|
||||||
|
|
||||||
@@ -359,7 +453,6 @@ Released : 20110306
|
|||||||
|
|
||||||
self.config[f]["description"] += p.stdout.decode("utf-8")
|
self.config[f]["description"] += p.stdout.decode("utf-8")
|
||||||
sys.stdout.write("\n")
|
sys.stdout.write("\n")
|
||||||
self.write_config()
|
|
||||||
|
|
||||||
|
|
||||||
def human_size(file_name, precision=1):
|
def human_size(file_name, precision=1):
|
||||||
@@ -379,3 +472,10 @@ def human_size(file_name, precision=1):
|
|||||||
size = size / 1024.0
|
size = size / 1024.0
|
||||||
defPrecision = precision
|
defPrecision = precision
|
||||||
return "%s%.*f%s" % (sign, defPrecision, size, suffixes[suffixIndex])
|
return "%s%.*f%s" % (sign, defPrecision, size, suffixes[suffixIndex])
|
||||||
|
|
||||||
|
|
||||||
|
class SmartFormatter(HelpFormatter):
|
||||||
|
def _split_lines(self, help, width):
|
||||||
|
if help.startswith("smart|"):
|
||||||
|
return help[6:].splitlines()
|
||||||
|
return HelpFormatter._split_lines(self, help, width)
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 5.5 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 5.5 KiB |
@@ -64,7 +64,7 @@ a:hover {
|
|||||||
height: 330px;
|
height: 330px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
background: url(banner.jpg) no-repeat left top;
|
background: url(banner.jpg) no-repeat center center;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,4 +264,4 @@ a:hover {
|
|||||||
|
|
||||||
.float_down {
|
.float_down {
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
@@ -1,82 +1,156 @@
|
|||||||
let current=-1;
|
let current = -1;
|
||||||
function r(f){/in/.test(document.readyState)?setTimeout('r('+f+')',9):f()}
|
let currentScrolled = -1;
|
||||||
r(function(){
|
let scrollTimer = null;
|
||||||
create_nav();
|
let scrollEventTimer = null;
|
||||||
document.onkeydown = keyboard_entry;
|
|
||||||
document.onwheel = scroll_event;
|
|
||||||
|
|
||||||
|
function r(f) {
|
||||||
|
/in/.test(document.readyState) ? setTimeout('r(' + f + ')', 9) : f()
|
||||||
|
}
|
||||||
|
r(function() {
|
||||||
|
create_nav();
|
||||||
|
document.onkeydown = keyboard_entry;
|
||||||
});
|
});
|
||||||
|
|
||||||
function create_nav() {
|
function create_nav() {
|
||||||
let navis = document.getElementsByClassName("navigation");
|
let navis = document.getElementsByClassName("navigation");
|
||||||
for (let i = 0; i<navis.length; i++) {
|
for (let i = 0; i < navis.length; i++) {
|
||||||
if (i==navis.length-1) {
|
if (i == navis.length - 1) {
|
||||||
navis[i].appendChild(create_button("up", navis[0], 0));
|
navis[i].appendChild(create_button("up", navis[0], 0));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (navis[i-1]) {
|
if (navis[i - 1]) {
|
||||||
navis[i].appendChild(create_button("up", navis[i-1], i-1));
|
navis[i].appendChild(create_button("up", navis[i - 1], i - 1));
|
||||||
} else {
|
} else {
|
||||||
navis[i].appendChild(create_button("up", document.body, 0));
|
navis[i].appendChild(create_button("up", document.body, 0));
|
||||||
}
|
}
|
||||||
if (navis[i+1]) {
|
if (navis[i + 1]) {
|
||||||
navis[i].appendChild(create_button("down", navis[i+1], i+1));
|
navis[i].appendChild(create_button("down", navis[i + 1], i + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function create_button(direction, to, next) {
|
function create_button(direction, to, next) {
|
||||||
let container = document.createElement('div');
|
let container = document.createElement('div');
|
||||||
container.classList.add("float_" + direction);
|
container.classList.add("float_" + direction);
|
||||||
let button = document.createElement('img');
|
let button = document.createElement('img');
|
||||||
button.src = ".mirva/arrow_" + direction + ".png";
|
button.src = ".mirva/arrow_" + direction + ".png";
|
||||||
button.classList.add("navigation_button");
|
button.classList.add("navigation_button");
|
||||||
button.onclick = function(){
|
button.onclick = function() {
|
||||||
to.parentElement.scrollIntoView({behavior: "smooth"});
|
to.parentElement.scrollIntoView({
|
||||||
current = next;
|
behavior: "smooth"
|
||||||
|
});
|
||||||
|
current = next;
|
||||||
};
|
};
|
||||||
container.appendChild(button);
|
container.appendChild(button);
|
||||||
return container
|
return container
|
||||||
}
|
}
|
||||||
function is_visible(el) {
|
|
||||||
let rect = el.getBoundingClientRect();
|
function is_visible(el, type) {
|
||||||
|
let rect = el.getBoundingClientRect();
|
||||||
|
if (type == "fully") {
|
||||||
|
return rect.top >= 0 && rect.top < window.innerHeight && rect.bottom >= 0 && rect.bottom <= window.innerHeight
|
||||||
|
} else {
|
||||||
return rect.top < window.innerHeight && rect.bottom >= 0;
|
return rect.top < window.innerHeight && rect.bottom >= 0;
|
||||||
}
|
|
||||||
function scroll_event(ev) {
|
|
||||||
let navis = document.getElementsByClassName("navigation");
|
|
||||||
for (let i = 0; i<navis.length; i++) {
|
|
||||||
if (is_visible(navis[i])) {
|
|
||||||
current = i -1;
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function get_position() {
|
||||||
|
let intro = document.getElementsByClassName("intro");
|
||||||
|
for (let i = 0; i < intro.length; i++) {
|
||||||
|
if (is_visible(intro[i], "fully")) {
|
||||||
|
return {
|
||||||
|
"current": -1,
|
||||||
|
"next": 0,
|
||||||
|
"previous": -1,
|
||||||
|
"type": "top"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let posts = document.getElementsByClassName("image_wrapper");
|
||||||
|
for (let i = 0; i < posts.length; i++) {
|
||||||
|
if (is_visible(posts[i], "fully")) {
|
||||||
|
return {
|
||||||
|
"current": i,
|
||||||
|
"next": i + 1,
|
||||||
|
"previous": i - 1,
|
||||||
|
"type": "full"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let partials = [];
|
||||||
|
for (let i = 0; i < posts.length; i++) {
|
||||||
|
if (is_visible(posts[i], "partial")) {
|
||||||
|
partials.push(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (partials.length == 1) {
|
||||||
|
return {
|
||||||
|
"current": partials[0],
|
||||||
|
"next": partials[0] + 1,
|
||||||
|
"previous": partials[0] - 1,
|
||||||
|
"type": "partial single"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (partials.length > 1) {
|
||||||
|
return {
|
||||||
|
"current": partials[0],
|
||||||
|
"next": partials[0] + 1,
|
||||||
|
"previous": partials[0],
|
||||||
|
"type": "partial multi"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
"current": current,
|
||||||
|
"next": current + 1,
|
||||||
|
"previous": current - 1,
|
||||||
|
"type": "unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function keyboard_entry(ev) {
|
function keyboard_entry(ev) {
|
||||||
let kC = ev.keyCode;
|
let kC = ev.keyCode;
|
||||||
let ctrlDown = ev.ctrlKey || ev.metaKey;
|
let ctrlDown = ev.ctrlKey || ev.metaKey;
|
||||||
if (ctrlDown) {
|
if (ctrlDown) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ([32,33,34,35,36,37,38,39,40].indexOf(kC) == -1) {
|
if ([32, 33, 34, 35, 36, 37, 38, 39, 40].indexOf(kC) == -1) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let navis = document.getElementsByClassName("navigation");
|
let posts = document.getElementsByClassName("image_wrapper");
|
||||||
|
let position = get_position();
|
||||||
if (kC == '36') { // home
|
if (kC == '36') { // home
|
||||||
current = -1;
|
return
|
||||||
return
|
} else if (kC == '35') { // end
|
||||||
}
|
return
|
||||||
else if (kC == '35') { // end
|
} else if (kC == '39') { // right
|
||||||
current = navis.length;
|
current = position.next;
|
||||||
return
|
} else if (kC == '37') { // left
|
||||||
}
|
current = position.previous;
|
||||||
else if (kC == '39') { // right
|
|
||||||
current += 1;
|
|
||||||
}
|
|
||||||
else if (kC == '37') { // left
|
|
||||||
current -= 1;
|
|
||||||
} else {
|
} else {
|
||||||
setTimeout(scroll_event, 100);
|
return
|
||||||
|
}
|
||||||
|
if (current == -1) {
|
||||||
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
current = Math.max(0, current);
|
current = Math.max(0, current);
|
||||||
current = Math.min(navis.length-1, current);
|
current = Math.min(posts.length - 1, current);
|
||||||
navis[current].parentElement.scrollIntoView({behavior: "smooth"});
|
/* Scroll smooth, if no frequent keypress */
|
||||||
}
|
if (scrollTimer) {
|
||||||
|
posts[current].parentElement.scrollIntoView({
|
||||||
|
behavior: "auto"
|
||||||
|
});
|
||||||
|
clearTimeout(scrollTimer);
|
||||||
|
} else {
|
||||||
|
posts[current].parentElement.scrollIntoView({
|
||||||
|
behavior: "smooth"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
scrollTimer = setTimeout(function() {
|
||||||
|
scrollTimer = null;
|
||||||
|
},
|
||||||
|
200
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user