367 lines
8.0 KiB
HTML
367 lines
8.0 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%;
|
|
}
|
|
|
|
#info {
|
|
color: white;
|
|
position: absolute;
|
|
padding: 0.5em;
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
opacity: 0;
|
|
bottom: 0px;
|
|
left: 0px;
|
|
right: 0px;
|
|
font-size: 0.6em;
|
|
pointer-events: none;
|
|
transition: opacity 0.5s ease-in-out;
|
|
}
|
|
|
|
#actions {
|
|
display: flex;
|
|
padding: 0.5em;
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
opacity: 0;
|
|
font-size: 0.6em;
|
|
color: #ddd;
|
|
pointer-events: none;
|
|
transition: opacity 0.5s ease-in-out;
|
|
}
|
|
|
|
:host([active]) #info,
|
|
:host([active]) #actions {
|
|
opacity: 1;
|
|
pointer-events: all;
|
|
}
|
|
|
|
</style>
|
|
|
|
<div id="image" class="layout vertical" on-tap="onTap">
|
|
<div id="actions" on-tap="_hideActions" class="flex horziontal layout center end-justified">
|
|
<paper-icon-button on-tap="download" class="start-end" icon="file-download"></paper-icon-button>
|
|
<template is="dom-repeat" items="[[actions]]">
|
|
<paper-icon-button on-tap="_fireAction" icon="[[item]]"></paper-icon-button>
|
|
</template>
|
|
</div>
|
|
|
|
<div id="info" on-tap="_hideActions" class="layout vertical start">
|
|
<div>[[item.name]] ([[item.id]])</div>
|
|
<div>[[item.taken]]</div>
|
|
<div on-tap="_pathTap">[[item.path]]</div>
|
|
</div>
|
|
</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: {
|
|
"active": {
|
|
type: Boolean,
|
|
reflectToAttribute: true,
|
|
value: false
|
|
},
|
|
"src": {
|
|
type: String,
|
|
value: ""
|
|
},
|
|
"thumb": {
|
|
type: String
|
|
},
|
|
"loading": {
|
|
type: Boolean,
|
|
value: false
|
|
},
|
|
"unique": {
|
|
type: String,
|
|
value: ""
|
|
}
|
|
},
|
|
|
|
observers: [
|
|
"srcChanged(src, unique)"
|
|
],
|
|
|
|
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;
|
|
},
|
|
|
|
delete: function() {
|
|
this.fire("action", "delete");
|
|
},
|
|
|
|
next: function() {
|
|
this.fire("next");
|
|
},
|
|
|
|
previous: function() {
|
|
this.fire("previous");
|
|
},
|
|
|
|
onKeyDown: function(e) {
|
|
if (!this.active) {
|
|
return;
|
|
}
|
|
|
|
if (e.ctrlKey || e.altKey || e.metaKey || e.shiftKey) {
|
|
return;
|
|
}
|
|
|
|
if (this.hasFocus) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
}
|
|
|
|
switch (e.keyCode) {
|
|
case 46: /* delete */
|
|
if (this.hasFocus) {
|
|
this.delete();
|
|
}
|
|
break;
|
|
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;
|
|
}
|
|
},
|
|
|
|
reload: function() {
|
|
this.unique = parseInt(this.unique || 0) + 1;
|
|
},
|
|
|
|
_fireAction: function(event) {
|
|
event.preventDefault();
|
|
event.stopImmediatePropagation();
|
|
event.stopPropagation();
|
|
|
|
this.fire("action", event.model.item);
|
|
},
|
|
|
|
download: function(event) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
event.stopImmediatePropagation();
|
|
|
|
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);
|
|
},
|
|
|
|
close: function() {
|
|
if (this.closed) {
|
|
return;
|
|
}
|
|
|
|
this.style.opacity = 0;
|
|
|
|
this.async(function() {
|
|
this.setActive(false);
|
|
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) {
|
|
if (!src) {
|
|
return;
|
|
}
|
|
this.loadImage(src);
|
|
},
|
|
|
|
onTap: function(event) {
|
|
if (!this.style.display || this.style.display == "none") {
|
|
return;
|
|
}
|
|
|
|
if ((event.detail.y < this.$.actions.offsetHeight) ||
|
|
(event.detail.y > this.offsetHeight - this.$.info.offsetHeight)) {
|
|
this.setActive(true);
|
|
return;
|
|
}
|
|
|
|
if (event.detail.x <= 0.1 * this.offsetWidth) {
|
|
this.previous();
|
|
return;
|
|
}
|
|
|
|
if (event.detail.x >= 0.9 * this.offsetWidth) {
|
|
this.next();
|
|
return;
|
|
}
|
|
|
|
this.close();
|
|
},
|
|
|
|
open: function() {
|
|
this.setActive(true);
|
|
this.closed = false;
|
|
this.opened = true;
|
|
this.loadImage(this.src);
|
|
this.style.opacity = 1;
|
|
this.style.display = 'block';
|
|
this.focus();
|
|
},
|
|
|
|
_hideActions: function(event) {
|
|
event.preventDefault();
|
|
event.stopImmediatePropagation();
|
|
event.stopPropagation();
|
|
|
|
this.setActive(false);
|
|
},
|
|
|
|
setActive: function(active) {
|
|
this.active = active;
|
|
},
|
|
|
|
loadImage: function(path) {
|
|
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 = path;
|
|
this.loading = true;
|
|
|
|
this.image.onload = function(path) {
|
|
this.loading = false;
|
|
var remaining = Math.max(this.waitUntil - Date.now() / 1000, 0);
|
|
this.async(function() {
|
|
if (!this.image || this.requested != path) {
|
|
return;
|
|
}
|
|
|
|
this.$.image.style.backgroundImage = 'url("' + this.image.src + '")';
|
|
this.$.image.style.opacity = 1;
|
|
this.image = undefined;
|
|
this.setActive(true);
|
|
}, remaining);
|
|
}.bind(this, path);
|
|
|
|
this.image.src = path + (this.unique ? ("?" + this.unique) : "");
|
|
},
|
|
|
|
attached: function() {
|
|
var base = document.querySelector("base");
|
|
if (base) {
|
|
this.base = new URL(base.href).pathname.replace(/\/$/, "") + "/"; /* Make sure there is a trailing slash */
|
|
} else {
|
|
this.base = "/";
|
|
}
|
|
}
|
|
});
|
|
</script>
|
|
</dom-module>
|
|
</html>
|