ketr.photos/frontend/elements/photo-lightbox.html
James Ketrenos caab741e2c Trying to limit input events
Signed-off-by: James Ketrenos <james_git@ketrenos.com>
2018-10-14 15:52:09 -07:00

254 lines
5.7 KiB
HTML

<!doctype html>
<html>
<head>
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/iron-icon/iron-icon.html">
<link rel="import" href="../bower_components/iron-icons/iron-icons.html">
<link rel="import" href="../bower_components/iron-iconset/iron-iconset.html">
<link rel="import" href="../bower_components/iron-pages/iron-pages.html">
<link rel="import" href="../bower_components/paper-button/paper-button.html">
<link rel="import" href="../bower_components/paper-spinner/paper-spinner.html">
<link rel="import" href="../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
</head>
<dom-module id="photo-lightbox">
<template>
<style is="custom-style" include="iron-flex iron-flex-alignment iron-positioning">
:host {
display: none;
position: fixed;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
transition: opacity 0.5s ease-in-out;
-webkit-transition: opacity 0.5s ease-in-out;
box-sizing: border-box;
pointer-events: all;
}
#image {
display: inline-block;
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background-size: contain;
background-position: center center;
background-repeat: no-repeat;
transition: opacity 0.5s ease-in-out;
-webkit-transition: opacity 0.5s ease-in-out;
}
#image paper-icon-button {
color: white;
}
#overlay {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
pointer-events: none;
}
#overlay > div {
height: 100%;
}
</style>
<div id="image" class="layout vertical" on-tap="onTap">
<paper-icon-button on-tap="download" class="start-end" icon="file-download"></paper-icon-button>
</div>
<div id="overlay" class="layout vertical center">
<div class="layout horizontal center">
<paper-spinner hidden$="[[!loading]]" active$="[[loading]]" class="thin"></paper-spinner>
</div>
</div>
</template>
<script>
"use strict";
Polymer({
is: "photo-lightbox",
properties: {
"src": {
type: String
},
"thumb": {
type: String
},
loading: {
type: Boolean,
value: false
}
},
observers: [
"srcChanged(src)"
],
listeners: {
"keydown": "onKeyDown",
"blur": "onBlur",
"focus": "onFocus",
"scroll": "onScroll"
},
onScroll: function(event) {
console.log("Scroll attempt in lightbox");
event.preventDefault();
event.stopImmediatePropagation();
event.stopPropagation();
},
onFocus: function() {
this.hasFocus = true;
},
onBlur: function() {
this.hasFocus = false;
},
next: function() {
this.fire("next");
},
previous: function() {
this.fire("previous");
},
onKeyDown: function(e) {
if (e.ctrlKey || e.altKey || e.metaKey || e.shiftKey) {
return;
}
switch (e.keyCode) {
case 39: /* right */
if (this.hasFocus) {
this.next();
}
break;
case 37: /* left */
if (this.hasFocus) {
this.previous();
}
break;
case 27: /* escape */
this.hasFocus = false;
this.close();
break;
default:
console.log(e.keyCode);
break;
}
if (this.hasFocus) {
e.preventDefault();
e.stopPropagation();
}
},
download: function(event) {
console.log("Download tapped");
var anchor = document.createElement('a');
anchor.href = this.base + this.item.path + "/" + this.item.filename;
anchor.setAttribute("download", this.src.replace(/.*\/([^/]+)$/, "$1"));
anchor.style.display = "none";
document.body.appendChild(anchor);
anchor.click();
document.body.removeChild(anchor);
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
},
close: function() {
this.style.opacity = 0;
this.async(function() {
this.style.display = 'none';
this.image = undefined;
this.$.image.style.opacity = 0;
this.$.image.style.removeProperty('background-image');
this.closed = true;
this.opened = false;
this.fire("close");
}, 250);
},
srcChanged: function(src) {
this.loadImage(src);
},
onTap: function(event) {
if (!this.style.display || this.style.display == "none") {
return;
}
if (event.detail.x <= 0.1 * this.offsetWidth) {
this.previous();
} else if (event.detail.x >= 0.9 * this.offsetWidth) {
this.next();
} else {
this.close();
}
},
open: function() {
this.closed = false;
this.opened = true;
this.loadImage(this.src);
this.style.opacity = 1;
this.style.display = 'block';
this.focus();
},
loadImage: function(image) {
if (this.$.image.style.opacity != 0) {
this.waitUntil = (Date.now() / 1000) + 500;
} else {
this.waitUntil = 0;
}
this.$.image.style.opacity = 0;
this.image = new Image();
this.requested = image;
this.loading = true;
this.image.onload = function(src) {
this.loading = false;
var remaining = Math.max(this.waitUntil - Date.now() / 1000, 0);
this.async(function() {
if (!this.image || this.requested != src) {
return;
}
this.$.image.style.backgroundImage = 'url("' + this.image.src + '")';
this.$.image.style.opacity = 1;
this.image = undefined;
}, remaining);
}.bind(this, image);
this.image.src = image;
},
attached: function() {
var base = document.querySelector("base");
if (base) {
this.base = new URL(base.href).pathname.replace(/\/$/, ""); /* Remove trailing slash if there */
} else {
this.base = "";
}
}
});
</script>
</dom-module>
</html>