Added ken-burns slideshow
Signed-off-by: James Ketrenos <james.p.ketrenos@intel.com>
This commit is contained in:
parent
5f6699e7b1
commit
dd94173334
192
frontend/elements/ken-burns.html
Executable file
192
frontend/elements/ken-burns.html
Executable file
@ -0,0 +1,192 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="import" href="../bower_components/polymer/polymer.html">
|
||||||
|
<link rel="import" href="../bower_components/paper-icon-button/paper-icon-button.html">
|
||||||
|
<link rel="import" href="../bower_components/iron-flex-layout/iron-flex-layout-classes.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-pages/iron-pages.html">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<dom-module id="ken-burns">
|
||||||
|
<template>
|
||||||
|
<style is="custom-style" include="iron-flex iron-flex-alignment iron-positioning">
|
||||||
|
:host {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<img id="image">
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
"use strict";
|
||||||
|
Polymer({
|
||||||
|
is: "ken-burns",
|
||||||
|
properties: {
|
||||||
|
"src": {
|
||||||
|
type: String,
|
||||||
|
value: ""
|
||||||
|
},
|
||||||
|
"unique": {
|
||||||
|
type: String,
|
||||||
|
value: ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
listeners: {
|
||||||
|
},
|
||||||
|
|
||||||
|
observers: [
|
||||||
|
"widthChanged(width)",
|
||||||
|
"thumbChanged(thumbpath, visible)",
|
||||||
|
"srcChanged(src, unique)"
|
||||||
|
],
|
||||||
|
|
||||||
|
srcChanged: function(src) {
|
||||||
|
if (!src) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.loadImage(src);
|
||||||
|
},
|
||||||
|
|
||||||
|
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.showImage();
|
||||||
|
|
||||||
|
this.$.image.src = 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) : "");
|
||||||
|
},
|
||||||
|
|
||||||
|
formatDateTime: function(date) {
|
||||||
|
return window.moment(new Date(date)).format("lll");
|
||||||
|
},
|
||||||
|
|
||||||
|
widthChanged: function(width) {
|
||||||
|
this.style.width = width + "px";
|
||||||
|
this.style.height = width + "px";
|
||||||
|
},
|
||||||
|
|
||||||
|
safeItemThumbFilepath: function(item, base, unique) {
|
||||||
|
if (item === undefined|| base === undefined || item.path === undefined) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return base + item.path + "thumbs/" + item.filename + (this.unique ? ("?" + this.unique) : "");
|
||||||
|
},
|
||||||
|
|
||||||
|
date: function(item) {
|
||||||
|
var datetime = item.taken || item.modified || item.added;
|
||||||
|
return datetime.replace(/T.*$/, "");
|
||||||
|
},
|
||||||
|
|
||||||
|
reload: function() {
|
||||||
|
this.unique = parseInt(this.unique || 0) + 1;
|
||||||
|
},
|
||||||
|
|
||||||
|
randomizer: function(min,max) {
|
||||||
|
return Math.random() * (max - min) + min;
|
||||||
|
},
|
||||||
|
|
||||||
|
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 = "/";
|
||||||
|
}
|
||||||
|
|
||||||
|
this.showImage();
|
||||||
|
},
|
||||||
|
|
||||||
|
showImage: function() {
|
||||||
|
var maxscale = 1.4;
|
||||||
|
var minscale = 1.1;
|
||||||
|
var minMov = 5;
|
||||||
|
var maxMov = 10;
|
||||||
|
var scalar = this.randomizer(minscale,maxscale).toFixed(2);
|
||||||
|
var moveX = this.randomizer(minMov,maxMov).toFixed(2);
|
||||||
|
|
||||||
|
moveX = Math.random() < 0.5 ? -Math.abs(moveX) : Math.abs(moveX);
|
||||||
|
|
||||||
|
var moveY = this.randomizer(minMov,maxMov).toFixed(2);
|
||||||
|
moveY = Math.random() < 0.5 ? -Math.abs(moveY) : Math.abs(moveY);
|
||||||
|
|
||||||
|
var prefix = "";
|
||||||
|
if (CSSRule.WEBKIT_KEYFRAMES_RULE) {
|
||||||
|
prefix = "-webkit-";
|
||||||
|
} else if (CSSRule.MOZ_KEYFRAMES_RULE) {
|
||||||
|
prefix = "-moz-";
|
||||||
|
}
|
||||||
|
|
||||||
|
var style =
|
||||||
|
"#image { " +
|
||||||
|
"animation: zoom 12s alternate infinite; " +
|
||||||
|
"position: absolute; " +
|
||||||
|
"top: 0; left:-5%; width: 110%; height: 110%; " +
|
||||||
|
"}" +
|
||||||
|
"\n" +
|
||||||
|
"@" + prefix + "keyframes burnseffect { " +
|
||||||
|
"10% { " +
|
||||||
|
prefix + "transform: scale(1);" +
|
||||||
|
"} " +
|
||||||
|
"90% { " +
|
||||||
|
prefix + "transform: scale(" + scalar +" ) translate(" + moveX +"%," + moveY + "%);" +
|
||||||
|
"} " +
|
||||||
|
"100% { " +
|
||||||
|
prefix + "transform: scale(" + scalar + ") translate(" + moveX +"%," + moveY +"%);" +
|
||||||
|
"}" +
|
||||||
|
"}";
|
||||||
|
|
||||||
|
if (this.animStyle) {
|
||||||
|
this.root.removeChild(this.animStyle);
|
||||||
|
}
|
||||||
|
this.animStyle = document.createElement("style");
|
||||||
|
this.animStyle.appendChild(document.createTextNode(style));
|
||||||
|
this.root.insertBefore(this.animStyle, this.firstChild);
|
||||||
|
|
||||||
|
this.$.image.style.animationName = 'burnseffect';
|
||||||
|
this.$.image.style.webkitAnimationName = 'burnseffect';
|
||||||
|
this.$.image.style.mozAnimationName = 'burnseffect';
|
||||||
|
this.$.image.style.animationName = 'burnseffect';
|
||||||
|
|
||||||
|
this.updateStyles();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</dom-module>
|
||||||
|
</html>
|
@ -37,6 +37,7 @@
|
|||||||
<link rel="import" href="../../elements/user-profile.html">
|
<link rel="import" href="../../elements/user-profile.html">
|
||||||
<link rel="import" href="../../elements/photo-lightbox.html">
|
<link rel="import" href="../../elements/photo-lightbox.html">
|
||||||
<link rel="import" href="../../elements/photo-thumbnail.html">
|
<link rel="import" href="../../elements/photo-thumbnail.html">
|
||||||
|
<link rel="import" href="../../elements/ken-burns.html">
|
||||||
|
|
||||||
<script src="fetch.js"></script>
|
<script src="fetch.js"></script>
|
||||||
|
|
||||||
@ -334,11 +335,14 @@
|
|||||||
<paper-tab tab="memories"><paper-icon-button icon="today"></paper-icon-button></paper-tab>
|
<paper-tab tab="memories"><paper-icon-button icon="today"></paper-icon-button></paper-tab>
|
||||||
<paper-tab tab="albums"><paper-icon-button icon="folder"></paper-icon-button></paper-tab>
|
<paper-tab tab="albums"><paper-icon-button icon="folder"></paper-icon-button></paper-tab>
|
||||||
<paper-tab tab="holiday"><paper-icon-button icon="redeem"></paper-icon-button></paper-tab>
|
<paper-tab tab="holiday"><paper-icon-button icon="redeem"></paper-icon-button></paper-tab>
|
||||||
|
<paper-tab tab="slideshow">S</paper-tab>
|
||||||
<paper-tab hidden$="[[!user.maintainer]]" tab="duplicates"><paper-icon-button icon="compare-arrows"></paper-icon-button></paper-tab>
|
<paper-tab hidden$="[[!user.maintainer]]" tab="duplicates"><paper-icon-button icon="compare-arrows"></paper-icon-button></paper-tab>
|
||||||
<paper-tab hidden$="[[!user.maintainer]]" tab="trash"><paper-icon-button icon="delete"></paper-icon-button></paper-tab>
|
<paper-tab hidden$="[[!user.maintainer]]" tab="trash"><paper-icon-button icon="delete"></paper-icon-button></paper-tab>
|
||||||
</paper-tabs>
|
</paper-tabs>
|
||||||
<iron-pages id="pages" attr-for-selected="id" selected="[[mode]]" fallback-selection="loading">
|
<iron-pages id="pages" attr-for-selected="id" selected="[[mode]]" fallback-selection="loading">
|
||||||
<div id="loading"></div>
|
<div id="loading"></div>
|
||||||
|
<div id="slideshow" class="flex layout vertical">
|
||||||
|
</div>
|
||||||
<div id="holiday" class="flex layout vertical">
|
<div id="holiday" class="flex layout vertical">
|
||||||
<div>Holidays</div>
|
<div>Holidays</div>
|
||||||
<template is="dom-repeat" items="[[holidays]]">
|
<template is="dom-repeat" items="[[holidays]]">
|
||||||
@ -411,6 +415,9 @@
|
|||||||
<div tabindex="0" on-tap="loadPath">[[item.name]] /</div>
|
<div tabindex="0" on-tap="loadPath">[[item.name]] /</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
<div mode="slideshow" class="layout horizontal">
|
||||||
|
<div>[[slideshowInfo]]</div>
|
||||||
|
</div>
|
||||||
<div mode="holiday" class="layout horizontal">
|
<div mode="holiday" class="layout horizontal">
|
||||||
<div>[[holidayTitle]]</div>
|
<div>[[holidayTitle]]</div>
|
||||||
<div class='isNext' hidden$="[[!isNextHoliday(holidayTitle, nextHoliday)]]">(next upcoming Holiday!!)</div>
|
<div class='isNext' hidden$="[[!isNextHoliday(holidayTitle, nextHoliday)]]">(next upcoming Holiday!!)</div>
|
||||||
@ -435,6 +442,7 @@
|
|||||||
<div>~ Loading ~</div>
|
<div>~ Loading ~</div>
|
||||||
</div>
|
</div>
|
||||||
<user-profile id="profile"></user-profile>
|
<user-profile id="profile"></user-profile>
|
||||||
|
<div id="slideshow"><ken-burns id="kenBurns"></ken-burns></div>
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<div id="thumbnails" class="layout horizontal wrap"></div>
|
<div id="thumbnails" class="layout horizontal wrap"></div>
|
||||||
<div id="bottom" class="layout vertical center">
|
<div id="bottom" class="layout vertical center">
|
||||||
@ -1225,8 +1233,30 @@
|
|||||||
this.async(this.processItems.bind(this));
|
this.async(this.processItems.bind(this));
|
||||||
|
|
||||||
console.log("Total pending: " + this.pendingPhotos.length);
|
console.log("Total pending: " + this.pendingPhotos.length);
|
||||||
|
|
||||||
|
if (this.mode == "slideshow" && !this.slideshowTimeout) {
|
||||||
|
this.slideshowNext();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
slideshowNext: function() {
|
||||||
|
if (this.mode != "slideshow") {
|
||||||
|
window.cancelTimeout(this.slideshowTimeout);
|
||||||
|
delete this.slideshowTimeout;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.slideshowTimeout = window.setTimeout(this.slideshowNext.bind(this), 24 * 1000);
|
||||||
|
if (!this.thumbnails.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var photo = this.thumbnails[Math.floor(this.thumbnails.length * Math.random())];
|
||||||
|
this.$.kenBurns.item = photo.item;
|
||||||
|
this.$.kenBurns.src = this.base + photo.item.path + "thumbs/scaled/" + photo.item.filename;
|
||||||
|
var datetime = (photo.taken || photo.modified || photo.added).replace(/T.*/, "");
|
||||||
|
this.slideshowInfo = "In the year of " + datetime.replace(/(....).*/, "$1");
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
/* Asynchronously load items into the DOM */
|
/* Asynchronously load items into the DOM */
|
||||||
processItems: function() {
|
processItems: function() {
|
||||||
if (this.processing) {
|
if (this.processing) {
|
||||||
@ -1761,7 +1791,7 @@
|
|||||||
path = mode;
|
path = mode;
|
||||||
if (mode == "time") {
|
if (mode == "time") {
|
||||||
path = "";
|
path = "";
|
||||||
} else if (mode == "memories") {
|
} else if (mode == "memories" || mode == "slideshow") {
|
||||||
path = "memories/" + (this.date.replace(this.year + "-", "") || "");
|
path = "memories/" + (this.date.replace(this.year + "-", "") || "");
|
||||||
} else if (mode == "holiday") {
|
} else if (mode == "holiday") {
|
||||||
path = "holiday/" + this.holiday;
|
path = "holiday/" + this.holiday;
|
||||||
@ -1780,7 +1810,7 @@
|
|||||||
(mode != this.mode) ||
|
(mode != this.mode) ||
|
||||||
((mode == "albums") && (path != (this.path || ""))) ||
|
((mode == "albums") && (path != (this.path || ""))) ||
|
||||||
((mode == "holiday") && (path != ("holiday/" + this.holiday))) ||
|
((mode == "holiday") && (path != ("holiday/" + this.holiday))) ||
|
||||||
((mode == "memories") && (path != ("memories/" + (this.date.replace(this.year + "-", "") || ""))))) {
|
((mode == "memories" || mode == "slideshow") && (path != ("memories/" + (this.date.replace(this.year + "-", "") || ""))))) {
|
||||||
console.log("Skipping results for old query. Triggering re-fetch of photos for new path or mode.");
|
console.log("Skipping results for old query. Triggering re-fetch of photos for new path or mode.");
|
||||||
this._loadPhotos();
|
this._loadPhotos();
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user