WebGL render (new feature, should work, but may have issues!) previous CSS3 render can be found at lobby page

This commit is contained in:
Reaby committed 2020-09-28 18:07:18 +03:00
1 parent dad789a73b
commit d2125e734c
24 files changed
+2861 -54

No files matched your search

+3
View File
@@ -64,3 +64,6 @@ Dockerfile is provided for building a docker container. Docker container accepts
`docker build -t reaby/infoscreen .`<br/>
`docker run -p 8000:8000 -e HOST=infoscreen.lan -e PORT=8000 -e ADMIN_USER=admin -e ADMIN_PASS=secret --name infoscreen reaby/infoscreen`<br/>
# Thanks
WebGL renderer bases upon initial working of [Creative WebGL Image Transitions](https://github.com/akella/webGLImageTransitions) repository here at github. Thanks for your awesome article.
+2 -2
View File
@@ -42,10 +42,10 @@ module.exports = {
"username": "operator",
"password": "operator",
"permissions": {
"isAdmin": true,
"isAdmin": false,
"dashboard": {
"addBundle": false,
"addSlides": true,
"addSlides": false,
"addWebPage": false,
}
}
+1 -1
View File
@@ -2,7 +2,7 @@
"displayName": "default",
"background": "bg.jpg",
"duration": 15,
"transition": "tiles3d",
"transition": "Dreamy",
"useWebFonts": false,
"displayTime": true,
"styleHeader": {
+6 -5
View File
@@ -11,7 +11,7 @@
"uploadScale": "Upload and scale 16:9",
"save": "Save",
"savetemplate": "Save as template",
"loadTemplate": "Template",
"loadTemplate": "Template",
"cancel": "Cancel",
"insert": "Insert",
"delete": "Delete",
@@ -123,18 +123,19 @@
"alignCenter": "Align center",
"alignRight": "Align right",
"alignUp": "Align top",
"alignDown": "Align bottom",
"alignDown": "Align bottom",
"alignJustify": "Justify Align",
"fontPlus": "Increase font size",
"fontMinus": "Decrease font size",
"centerHorizontal":"Center Horizontal",
"centerVertical":"Center Vertical",
"centerHorizontal": "Center Horizontal",
"centerVertical": "Center Vertical",
"undo": "Undo last action"
}
},
"index": {
"displays": "Available displays",
"normal": "Normal",
"normal": "WebGl",
"css": "CSS3",
"lite": "Lite",
"splitter": "or"
}
+4 -2
View File
@@ -129,8 +129,10 @@
},
"index": {
"displays": "Näytöt",
"normal": "Normaali",
"normal": "WebGL",
"css": "CSS3",
"lite": "Kevyt",
"splitter": "tai"
"splitter": "tai",
"admin": "Hallinta"
}
}
+2 -3
View File
@@ -475,9 +475,8 @@ class admin {
});
socket.on('edit.saveTemplate', function (data) {
let templates = {};
console.log(data.name);
let templates = {};
if (fs.existsSync("./data/template.json")) {
templates = JSON.parse(fs.readFileSync("./data/template.json").toString());
}
+2 -2
View File
@@ -30,7 +30,7 @@ class display {
* @property {string} streamSource - URL for FLV media stream
* @property {bool} isAnnounce - if the next slide is announce one
* @property {bool} announceMeta - all data needed for announces
* @property {string} transition values supported: bars,blinds,blinds3d,zip,blocks,blocks2,concentric,warp,cube,tiles3d,tiles3dprev,slide,swipe,dissolve
* @property {string} transition values
*/
this.serverOptions = {
displayId: displayId,
@@ -46,7 +46,7 @@ class display {
streamSource: "",
isAnnounce: false,
announceMeta: {},
transition: "tiles3d",
transition: "fade",
displayTime: true,
statusMessage: "",
};
+5 -5
View File
@@ -75,11 +75,11 @@ socket.on("callback.dashboard.sync", function (data) {
$('.currentDisplay').text(displayList[displayId].name);
var transitionArray = [];
var values = ["bars", "blinds", "blinds3d", "zip", "blocks", "blocks2", "concentric", "warp", "cube", "tiles3d", "tiles3dprev", "slide", "swipe", "dissolve"];
// var values = ["bars", "blinds", "blinds3d", "zip", "blocks", "blocks2", "concentric", "warp", "cube", "tiles3d", "tiles3dprev", "slide", "swipe", "dissolve"];
transitionArray.push({ name: "random", value: null });
for (var i in values) {
transitionArray.push({ name: values[i], value: values[i] });
for (var i in SupportedTransitions) {
transitionArray.push({ name: SupportedTransitions[i], value: SupportedTransitions[i] });
}
$('#transitions')
@@ -201,7 +201,7 @@ function addLink() {
}
function createNewVideo() {
editSlide("", "video");
editSlide("", "video");
}
function editSlide(name, type) {
+6 -3
View File
@@ -291,7 +291,7 @@ function nextSlide(data) {
console.log(err);
}
}
} else {
} else {
switch (serverOptions.currentMeta.type) {
case "webpage":
$("#slider").hide();
@@ -310,10 +310,13 @@ function nextSlide(data) {
}, 2500);
break;
default:
var transition = serverOptions.transition;
/* var transition = serverOptions.transition;
if (serverOptions.currentMeta.transition !== null) {
transition = serverOptions.currentMeta.transition;
}
} */
//var values = ["bars", "blinds", "blinds3d", "zip", "blocks", "blocks2", "concentric", "warp", "cube", "tiles3d", "tiles3dprev", "slide", "swipe", "dissolve"];
var transition = "tiles3d";
$("#" + getWebLayer()).addClass("fadeOut").removeClass("fadeIn");
$("#" + getWebLayer(1)).addClass("fadeOut").removeClass("fadeIn");
+503
View File
@@ -0,0 +1,503 @@
/***************************
* window load, init
* **************************/
let bundleData = {
background: "",
duration: 10,
styleHeader: {},
styleText: {},
useWebFonts: false
};
let serverOptions = {};
let sketch = new Sketch(
{
duration: 2000,
debug: false,
easing: TWEEN.Easing.Quadratic.Out
});
sketch.loadManager.onLoad = () => {
try {
sketch.play();
if (sketch.tmpImage) {
sketch.showSlide("temp");
return;
}
setBackground(bundleData.background);
if (checkStream(serverOptions) === false) {
nextSlide();
}
} catch (e) {
console.error(e);
}
}
let connectionTimeoutId;
let layer = 0;
let flvPlayer;
/** bundleData
* @see data/default/bundle.json
*
**/
$(function () {
displayTime();
setInterval(displayTime, 1000);
$('#blackoutLayer').dblclick(toggleFullScreen);
if (isPreview === 0) {
document.addEventListener("keydown", function (e) {
if (e.keyCode == 13) {
toggleFullScreen();
}
}, false);
}
});
function symmetricDifference(a1, a2) {
let result = [];
for (let i = 0; i < a1.length; i++) {
if (a2.indexOf(a1[i]) === -1) {
result.push(a1[i]);
}
}
for (let i = 0; i < a2.length; i++) {
if (a1.indexOf(a2[i]) === -1) {
result.push(a2[i]);
}
}
return result;
}
function toggleFullScreen() {
if (isPreview === 0) {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen();
} else {
if (document.exitFullscreen) {
document.exitFullscreen();
}
}
}
}
function getLayer(offset) {
if (offset === undefined) offset = 0;
return "layer" + (layer + offset) % 2;
}
// socketio callbacks
/** when connected **/
socket.on('connect', function () {
socket.emit("sync");
$("#networkstatus").css("opacity", 0);
});
socket.on('callback.blackout', function (data) {
serverOptions = data.serverOptions;
checkBlackout();
});
socket.on('error', function () {
$("#networkstatus").css("opacity", 1);
});
socket.on('disconnect', function () {
$("#networkstatus").css("opacity", 1);
});
socket.on('pong', function () {
updateTimeout();
});
socket.on('callback.time', function (data) {
serverOptions.displayTime = data;
checkTimeDisplay();
});
/** callback Load **/
socket.on('callback.load', function (data) {
serverOptions = data.serverOptions;
bundleData = data.bundleData;
preloadImages(data);
});
/** callback Update **/
socket.on('callback.update', function (data) {
serverOptions = data.serverOptions;
bundleData = data.bundleData;
checkBlackout();
if (checkStream(serverOptions) === false) {
nextSlide(data);
}
});
socket.on('callback.updateUI', function (data) {
serverOptions = data.serverOptions;
bundleData = data.bundleData;
updateStatusMessage();
});
socket.on('callback.removeSlide', function (data) {
sketch.removeImageByUuid(data.uuid);
});
socket.on('callback.reload', function () {
location.reload(true);
});
socket.on('callback.reloadImage', function (data) {
reloadImage(data);
});
socket.on('callback.announce', function (data) {
checkBlackout();
nextSlide(data);
});
socket.on('callback.forceSlide', function (data) {
checkBlackout();
nextSlide(data);
});
/**
* Displays the local time for bottom of screen
* hh:mm
**/
function displayTime() {
let date = new Date();
let min = date.getMinutes();
if (min < 10) min = "0" + min;
$('#time').html(date.getHours() + ":" + min);
}
function checkTimeDisplay() {
let bool = serverOptions.displayTime;
if (serverOptions.currentMeta.displayTime !== null) {
bool = serverOptions.currentMeta.displayTime;
}
if (bool) {
$('#time').removeClass('flipOutX').addClass("flipInX");
} else {
$('#time').addClass('flipOutX').removeClass("flipInX");
}
}
function checkBlackout() {
updateTimeout();
if (serverOptions.blackout) {
$("#blackoutLayer").css("opacity", 1);
} else {
$("#blackoutLayer").css("opacity", 0);
}
}
function updateStatusMessage() {
if (serverOptions.statusMessage !== "") {
$('#statusMessageOuter').fadeIn();
$('#statusMessage').text(serverOptions.statusMessage);
} else {
$('#statusMessageOuter').fadeOut();
$('#statusMessage').text("");
}
}
function displayVideo(url, loop, mute) {
if (serverOptions.isStreaming) return;
$("#stream").show();
let video = document.getElementById("stream");
video.src = url;
video.loop = loop;
video.volume = mute ? 0.0 : 1.0;
video.load();
video.play();
}
function nextSlide(data) {
if (data) {
serverOptions = data.serverOptions;
bundleData = data.bundleData;
}
checkTimeDisplay();
updateStatusMessage();
$("#helperLayer").removeClass("announce");
if (serverOptions.isAnnounce) {
if (serverOptions.announceMeta.type === "webPage") {
$("#slider").hide();
$("#" + getWebLayer()).css("transform", "scale(" + serverOptions.announceMeta.zoom + ")");
$("#" + getWebLayer()).addClass("fadeIn").removeClass("fadeOut");
if (serverOptions.announceMeta.displayTime) {
$('#time').removeClass('flipOutX').addClass("flipInX");
} else {
$('#time').addClass('flipOutX').removeClass("flipInX");
}
displayWebPage(serverOptions.announceMeta.webUrl);
}
if (serverOptions.announceMeta.type === "video") {
if (serverOptions.announceMeta.displayTime) {
$('#time').removeClass('flipOutX').addClass("flipInX");
} else {
$('#time').addClass('flipOutX').removeClass("flipInX");
}
displayVideo(serverOptions.announceMeta.url, serverOptions.announceMeta.loop, serverOptions.announceMeta.mute);
}
if (serverOptions.announceMeta.type === "image") {
$("#" + getWebLayer()).addClass("fadeOut").removeClass("fadeIn");
$("#" + getWebLayer(1)).addClass("fadeOut").removeClass("fadeIn");
setTimeout(function () {
clearIFrame(getWebLayer());
clearIFrame(getWebLayer(1));
}, 2500);
$("#slider").show();
// $("#helperLayer").addClass("announce");
const id = uuidv4();
const imgUrl = "/tmp/" + serverOptions.displayId + "/?randomId=" + id;
sketch.showTempImage(imgUrl)
}
} else {
switch (serverOptions.currentMeta.type) {
case "webpage":
$("#slider").hide();
let video = document.getElementById("stream");
video.pause();
$("#stream").hide();
$("#" + getWebLayer()).css("transform", "scale(" + serverOptions.currentMeta.zoom + ")");
$("#" + getWebLayer()).addClass("fadeIn").removeClass("fadeOut");
displayWebPage(serverOptions.currentMeta.webUrl);
break;
case "video":
displayVideo(serverOptions.currentMeta.url, serverOptions.currentMeta.loop, serverOptions.currentMeta.mute);
setTimeout(function () {
clearIFrame(getWebLayer());
clearIFrame(getWebLayer(1));
}, 2500);
break;
default:
let transition = serverOptions.transition;
if (serverOptions.currentMeta.transition !== null) {
transition = serverOptions.currentMeta.transition;
}
$("#" + getWebLayer()).addClass("fadeOut").removeClass("fadeIn");
$("#" + getWebLayer(1)).addClass("fadeOut").removeClass("fadeIn");
$("#stream").fadeOut();
$("#slider").show();
sketch.showSlide(serverOptions.currentFile, transition);
setTimeout(function () {
let video = document.getElementById("stream");
video.pause();
clearIFrame(getWebLayer());
clearIFrame(getWebLayer(1));
}, 2500);
break;
}
}
setBackground(bundleData.background);
}
function setBackground(background) {
background = encodeURI("/background/" + background);
if (serverOptions.isStreaming) return;
const video = document.getElementById("bgvid");
const bg = $("#bg");
const bgImage = document.getElementById("bgimg");
if (background.indexOf(".mp4") !== -1) {
if (parseUrl(video.src) !== background) {
bg.fadeOut();
try {
video.src = background;
video.load();
video.play();
$(video).show();
} catch (e) {
console.error(e);
}
}
} else {
if (parseUrl(bgImage.src) !== background) {
bgImage.src = background;
bg.fadeIn();
// unload video
video.pause();
video.removeAttribute("src");
video.load();
$(video).hide();
}
}
}
function parseUrl(url) {
return '/background' + url.split('background')[1]
}
function showBackgroundOnly() {
$("#" + getLayer(1)).css("opacity", 0);
$("#" + getLayer()).css("opacity", 0);
}
function checkStream(serverOptions) {
if (serverOptions.isStreaming) {
if (flvjs.isSupported()) {
$("#stream").show();
const videoElement = document.getElementById('stream');
flvPlayer = flvjs.createPlayer({
type: 'flv',
url: serverOptions.streamSource
});
try {
flvPlayer.attachMediaElement(videoElement);
flvPlayer.volume = videoVolume;
flvPlayer.load();
flvPlayer.play();
streamStarted = true;
return true;
} catch (err) {
$('#stream').hide();
console.log(err);
streamStarted = false;
return false;
}
}
} else if (serverOptions.isStreaming === false) {
if (typeof flvPlayer !== "undefined") {
if (flvPlayer != null) {
flvPlayer.pause();
flvPlayer.unload();
flvPlayer.detachMediaElement();
flvPlayer.destroy();
flvPlayer = null;
streamStarted = false;
}
return false;
}
$("#stream").hide();
return false;
}
return true;
}
/**
* preload images
* @param data
*/
async function preloadImages(data) {
sketch.stop();
sketch.clearImages();
const allSlides = data.slides;
for (let i in allSlides) {
try {
if (allSlides[i].type === "slide") {
await sketch.loadImage("/render/" + serverOptions.currentBundle + "/" + allSlides[i].uuid + ".png", allSlides[i].uuid);
}
} catch (err) {
console.log(err);
}
}
}
async function reloadImage(data) {
if (serverOptions.currentBundle === data.bundleName) {
await sketch.loadImage("/render/" + data.bundleName + "/" + data.uuid + ".png?" + uuidv4(), data.uuid);
}
}
/** not in use */
/*
async function checkImages(allSlides) {
let fluxIds = [];
let allIds = [];
for (let i in sketch.textures) {
fluxIds.push(sketch.textures[j].image.uuid);
}
for (let k in allSlides) {
if (allSlides[k].type === "slide") {
allIds.push(allSlides[k].uuid);
}
}
// new slides count is less than slides in rotation
// remove slides
if (allIds.length < fluxIds.length) {
let diffIds = symmetricDifference(fluxIds, allIds);
for (let l in diffIds) {
sketch.removeImageByUuid(diffIds[l]);
}
} else
// else count is greater, so add slides
{
for (let i in allIds) {
try {
await sketch.loadImage("/render/" + serverOptions.currentBundle + "/" + allIds[i] + ".png", allIds[i]);
} catch (e) {
console.error(e);
}
}
return true;
}
return false;
}
*/
/** Generate an uuid
* @url https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript#2117523 **/
function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
let r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
function updateTimeout() {
clearTimeout(connectionTimeoutId);
$("#networkstatus").css("opacity", 0);
connectionTimeoutId = setTimeout(function () {
$("#networkstatus").css("opacity", 1);
}, 30000)
}
function displayWebPage(url) {
$("#" + getWebLayer()).attr('src', url).addClass("fadeIn").removeClass("fadeOut");
$("#" + getWebLayer(1)).addClass("fadeOut").removeClass("fadeIn");
clearIFrame(getWebLayer(1));
layer++;
if (layer > 1) {
layer = 0;
}
}
function getWebLayer(offset) {
if (offset === undefined) offset = 0;
return "webLayer" + (layer + offset) % 2;
}
function clearIFrame(id) {
if ($('#' + id).attr('src') !== "/empty") {
$('#' + id).attr('src', '/empty');
}
}
+3 -4
View File
@@ -342,11 +342,10 @@ socket.on('callback.edit', function (data) {
}
var transitionArray = [];
var values = ["bars", "blinds", "blinds3d", "zip", "blocks", "blocks2", "concentric", "warp", "cube", "tiles3d", "tiles3dprev", "slide", "swipe", "dissolve"];
//var values = ["bars", "blinds", "blinds3d", "zip", "blocks", "blocks2", "concentric", "warp", "cube", "tiles3d", "tiles3dprev", "slide", "swipe", "dissolve"];
transitionArray.push({ name: "default", value: null });
for (var i in values) {
transitionArray.push({ name: values[i], value: values[i] });
for (var i in SupportedTransitions) {
transitionArray.push({ name: SupportedTransitions[i], value: SupportedTransitions[i] });
}
$('#transitions')
+2
View File
@@ -0,0 +1,2 @@
window.GLTransitions=
[{"name":"Bounce","paramsTypes":{"shadow_colour":"vec4","shadow_height":"float","bounces":"float"},"defaultParams":{"shadow_colour":[0,0,0,0.6],"shadow_height":0.075,"bounces":3},"glsl":"// Author: Adrian Purser\n// License: MIT\n\nuniform vec4 shadow_colour; // = vec4(0.,0.,0.,.6)\nuniform float shadow_height; // = 0.075\nuniform float bounces; // = 3.0\n\nconst float PI = 3.14159265358;\n\nvec4 transition (vec2 uv) {\n float time = progress;\n float stime = sin(time * PI / 2.);\n float phase = time * PI * bounces;\n float y = (abs(cos(phase))) * (1.0 - stime);\n float d = uv.y - y;\n return mix(\n mix(\n getToColor(uv),\n shadow_colour,\n step(d, shadow_height) * (1. - mix(\n ((d / shadow_height) * shadow_colour.a) + (1.0 - shadow_colour.a),\n 1.0,\n smoothstep(0.95, 1., progress) // fade-out the shadow at the end\n ))\n ),\n getFromColor(vec2(uv.x, uv.y + (1.0 - y))),\n step(d, 0.0)\n );\n}\n","author":"Adrian Purser","license":"MIT","createdAt":"Fri, 10 Nov 2017 17:01:45 +0000","updatedAt":"Sat, 11 Nov 2017 08:50:40 +0100"},{"name":"BowTieHorizontal","paramsTypes":{},"defaultParams":{},"glsl":"// Author: huynx\n// License: MIT\n\nvec2 bottom_left = vec2(0.0, 1.0);\nvec2 bottom_right = vec2(1.0, 1.0);\nvec2 top_left = vec2(0.0, 0.0);\nvec2 top_right = vec2(1.0, 0.0);\nvec2 center = vec2(0.5, 0.5);\n\nfloat check(vec2 p1, vec2 p2, vec2 p3)\n{\n return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);\n}\n\nbool PointInTriangle (vec2 pt, vec2 p1, vec2 p2, vec2 p3)\n{\n bool b1, b2, b3;\n b1 = check(pt, p1, p2) < 0.0;\n b2 = check(pt, p2, p3) < 0.0;\n b3 = check(pt, p3, p1) < 0.0;\n return ((b1 == b2) && (b2 == b3));\n}\n\nbool in_left_triangle(vec2 p){\n vec2 vertex1, vertex2, vertex3;\n vertex1 = vec2(progress, 0.5);\n vertex2 = vec2(0.0, 0.5-progress);\n vertex3 = vec2(0.0, 0.5+progress);\n if (PointInTriangle(p, vertex1, vertex2, vertex3))\n {\n return true;\n }\n return false;\n}\n\nbool in_right_triangle(vec2 p){\n vec2 vertex1, vertex2, vertex3;\n vertex1 = vec2(1.0-progress, 0.5);\n vertex2 = vec2(1.0, 0.5-progress);\n vertex3 = vec2(1.0, 0.5+progress);\n if (PointInTriangle(p, vertex1, vertex2, vertex3))\n {\n return true;\n }\n return false;\n}\n\nfloat blur_edge(vec2 bot1, vec2 bot2, vec2 top, vec2 testPt)\n{\n vec2 lineDir = bot1 - top;\n vec2 perpDir = vec2(lineDir.y, -lineDir.x);\n vec2 dirToPt1 = bot1 - testPt;\n float dist1 = abs(dot(normalize(perpDir), dirToPt1));\n \n lineDir = bot2 - top;\n perpDir = vec2(lineDir.y, -lineDir.x);\n dirToPt1 = bot2 - testPt;\n float min_dist = min(abs(dot(normalize(perpDir), dirToPt1)), dist1);\n \n if (min_dist < 0.005) {\n return min_dist / 0.005;\n }\n else {\n return 1.0;\n };\n}\n\n\nvec4 transition (vec2 uv) {\n if (in_left_triangle(uv))\n {\n if (progress < 0.1)\n {\n return getFromColor(uv);\n }\n if (uv.x < 0.5)\n {\n vec2 vertex1 = vec2(progress, 0.5);\n vec2 vertex2 = vec2(0.0, 0.5-progress);\n vec2 vertex3 = vec2(0.0, 0.5+progress);\n return mix(\n getFromColor(uv),\n getToColor(uv),\n blur_edge(vertex2, vertex3, vertex1, uv)\n );\n }\n else\n {\n if (progress > 0.0)\n {\n return getToColor(uv);\n }\n else\n {\n return getFromColor(uv);\n }\n } \n }\n else if (in_right_triangle(uv))\n {\n if (uv.x >= 0.5)\n {\n vec2 vertex1 = vec2(1.0-progress, 0.5);\n vec2 vertex2 = vec2(1.0, 0.5-progress);\n vec2 vertex3 = vec2(1.0, 0.5+progress);\n return mix(\n getFromColor(uv),\n getToColor(uv),\n blur_edge(vertex2, vertex3, vertex1, uv)\n ); \n }\n else\n {\n return getFromColor(uv);\n }\n }\n else {\n return getFromColor(uv);\n }\n}","author":"huynx","license":"MIT","createdAt":"Sat, 24 Mar 2018 12:54:26 +0100","updatedAt":"Sat, 24 Mar 2018 12:54:26 +0100"},{"name":"BowTieVertical","paramsTypes":{},"defaultParams":{},"glsl":"// Author: huynx\r\n// License: MIT\r\n\r\nfloat check(vec2 p1, vec2 p2, vec2 p3)\r\n{\r\n return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);\r\n}\r\n\r\nbool PointInTriangle (vec2 pt, vec2 p1, vec2 p2, vec2 p3)\r\n{\r\n bool b1, b2, b3;\r\n b1 = check(pt, p1, p2) < 0.0;\r\n b2 = check(pt, p2, p3) < 0.0;\r\n b3 = check(pt, p3, p1) < 0.0;\r\n return ((b1 == b2) && (b2 == b3));\r\n}\r\n\r\nbool in_top_triangle(vec2 p){\r\n vec2 vertex1, vertex2, vertex3;\r\n vertex1 = vec2(0.5, progress);\r\n vertex2 = vec2(0.5-progress, 0.0);\r\n vertex3 = vec2(0.5+progress, 0.0);\r\n if (PointInTriangle(p, vertex1, vertex2, vertex3))\r\n {\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\nbool in_bottom_triangle(vec2 p){\r\n vec2 vertex1, vertex2, vertex3;\r\n vertex1 = vec2(0.5, 1.0 - progress);\r\n vertex2 = vec2(0.5-progress, 1.0);\r\n vertex3 = vec2(0.5+progress, Line truncated
+67
View File
@@ -0,0 +1,67 @@
var SupportedTransitions = [
"Bounce",
"BowTieVertical",
"CircleCrop",
"ColourDistance",
"CrazyParametricFun",
"CrossZoom",
"Directional",
"DoomScreenTransition",
"Dreamy",
"DreamyZoom",
"GlitchDisplace",
"GlitchMemories",
"GridFlip",
"InvertedPageCurl",
"LinearBlur",
"Mosaic",
"PolkaDotsCurtain",
"Radial",
"SimpleZoom",
"StereoViewer",
"Swirl",
"WaterDrop",
"ZoomInCircles",
"angular",
"burn",
"cannabisleaf",
"circle",
"circleopen",
"colorphase",
"crosshatch",
"crosswarp",
"cube",
"directionalwarp",
"directionalwipe",
"displacement",
"doorway",
"fade",
"fadecolor",
"fadegrayscale",
"flyeye",
"heart",
"hexagonalize",
"kaleidoscope",
"luma",
"luminance_melt",
"morph",
"multiply_blend",
"perlin",
"pinwheel",
"pixelize",
"polar_function",
"randomsquares",
"ripple",
"rotate_scale_fade",
"squareswire",
"squeeze",
"swap",
"undulatingBurnOut",
"wind",
"windowblinds",
"windowslice",
"wipeDown",
"wipeLeft",
"wipeRight",
"wipeUp"
];
+338
View File
@@ -0,0 +1,338 @@
/**
* Sketch
*
* initially based upon resource found at:
* https://github.com/akella/webGLImageTransitions
*
* Original lisence:
* This resource can be used freely if integrated or build upon in personal or commercial projects such as websites,
* web apps and web templates intended for sale. It is not allowed to take the resource "as-is" and sell it, redistribute,
* re-publish it, or sell "pluginized" versions of it. Free plugins built using this resource should have a visible mention and
* link to the original work. Always consider the licenses of all included libraries, scripts and images used.
*
* ! notice: heavily modified for infoscreen3 use !
*/
class Sketch {
resizeCover(r) {
return ".5+(uv-.5)*vec2(min(ratio/" + r + ",1.),min(" + r + "/ratio,1.))";
}
makeFragment(transitionGlsl) {
return `
precision highp float;
varying vec2 _uv;
uniform sampler2D texture1, texture2;
uniform float progress, ratio, _fromR, _toR;
vec4 getFromColor(vec2 uv) {
return texture2D(texture1, uv);
}
vec4 getToColor(vec2 uv){
return texture2D(texture2, uv);
}
${transitionGlsl}
void main() {
gl_FragColor = transition(_uv);
}
`;
}
constructor(opts) {
this.clock = new THREE.Clock();
this.loadManager = new THREE.LoadingManager();
this.loader = new THREE.TextureLoader(this.loadManager);
this.delta = 0;
this.interval = 1 / 60; // 60 fps
this.tempImages = [];
this.currentTransition = "fade";
this.bcounter = null;
this.scene = new THREE.Scene();
this.vertex = `
varying vec2 _uv;
void main() {
_uv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`;
this.fragment = `
vec4 transition (vec2 uv) {
return mix(
getFromColor(uv),
getToColor(uv),
progress);
}`;
this.renderer = new THREE.WebGLRenderer({ alpha: true, antialias: false });
this.width = window.innerWidth;
this.height = window.innerHeight;
this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.setSize(this.width, this.height);
this.duration = opts.duration || 1;
this.debug = opts.debug || false;
this.easing = opts.easing || 'easeInOut';
this.uniforms = {};
this.nextTexture = null;
this.tmpImage = false;
this.container = document.getElementById("slider");
this.images = JSON.parse(this.container.getAttribute('data-images')) || [];
this.width = this.container.offsetWidth;
this.height = this.container.offsetHeight;
this.container.appendChild(this.renderer.domElement);
this.camera = new THREE.PerspectiveCamera(
70,
window.innerWidth / window.innerHeight,
0.001,
1000
);
this.camera.position.set(0, 0, 2);
this.time = 0;
this.current = 0;
this.textures = [];
this.paused = true;
this.setupResize();
this.addObjects();
this.resize();
this.settings();
this.play();
}
getTextureId(uuid) {
for (const idx in this.textures) {
if (this.textures[idx].image && this.textures[idx].image.id == uuid) {
return idx;
}
}
return undefined;
}
clearImages() {
for (let idx in this.textures) {
this.textures[idx].dispose();
this.textures.splice(idx, 1);
};
this.current = 0;
}
removeImageByUrl(url) {
const idx = this.getTextureId(url);
for (const idx in this.textures) {
if (this.textures[idx].image.src.indexOf(url) !== -1) {
this.textures[idx].dispose();
this.textures.splice(idx, 1);
return;
}
}
}
removeImageByUuid(uuid) {
for (const idx in this.textures) {
if (this.textures[idx].image.id === uuid) {
this.textures[idx].dispose();
this.textures.splice(idx, 1);
}
}
}
async loadImage(url, uuid) {
const idx = this.getTextureId(url);
if (idx) {
// replace texture with a new resource
this.textures[idx].dispose();
this.textures[idx] = await this.loader.load(url, () => {
this.textures[idx].minFilter = THREE.LinearFilter;
this.textures[idx].image.id = uuid;
});
} else {
// load new texture
const texture = await this.loader.load(url, () => {
texture.minFilter = THREE.LinearFilter;
texture.image.id = uuid;
this.textures.push(texture);
});
}
}
settings() {
if (this.debug) {
if (this.gui) {
this.gui.destroy();
}
this.gui = new dat.GUI();
this._settings = {};
Object.keys(this.material.uniforms).forEach((item) => {
if (!["progress", "texture1", "texture2", "_fromR", "_toR", "ratio", "resolution"].includes(item)) {
this._settings[item] = this.material.uniforms[item].value;
if (typeof (this._settings[item]) !== "object") {
this.gui.add(this._settings, item, 0);
}
}
});
this.gui.show();
}
}
setupResize() {
window.addEventListener("resize", this.resize.bind(this));
}
resize() {
this.width = this.container.offsetWidth;
this.height = this.container.offsetHeight;
this.renderer.setSize(this.width, this.height);
this.camera.aspect = this.width / this.height;
// image cover
this.imageAspect = 16 / 9;
const dist = this.camera.position.z;
const height = 1;
this.camera.fov = 2 * (180 / Math.PI) * Math.atan(height / (2 * dist));
this.plane.scale.x = this.camera.aspect;
this.plane.scale.y = 1;
this.camera.updateProjectionMatrix();
}
getUniformBase(cur, next) {
if (!cur) cur = 0;
if (!next) next = 0;
return {
progress: { type: "f", value: 0 },
texture1: { type: "f", value: this.textures[cur] },
texture2: { type: "f", value: this.textures[next] },
ratio: { type: "f", value: 16 / 9 },
_fromR: { type: "f", value: 16 / 9 },
_toR: { type: "f", value: 16 / 9 },
};
}
addObjects() {
this.material = new THREE.ShaderMaterial({
extensions: {
derivatives: "#extension GL_OES_standard_derivatives : enable",
},
side: THREE.DoubleSide,
uniforms: { ...this.getUniformBase() },
transparent: true,
vertexShader: this.vertex,
fragmentShader: this.makeFragment(this.fragment),
});
this.geometry = new THREE.PlaneGeometry(1, 1, 2, 2);
this.plane = new THREE.Mesh(this.geometry, this.material);
this.scene.add(this.plane);
}
stop() {
this.paused = true;
}
play() {
this.paused = false;
this.render();
}
showSlide(uuid, transition) {
const len = this.textures.length;
let nextIdx = this.getTextureId(uuid);
this.nextTexture = this.textures[nextIdx];
if (len < 1) return;
if (!this.nextTexture) return;
if (transition && this.currentTransition != transition && uuid != "temp") {
this.currentTransition = transition;
this.changeTransition(transition, this.current, nextIdx);
}
if (this.isRunning) {
this.current = nextIdx;
this.material.uniforms.texture1.value = this.nextTexture;
return;
}
else {
this.isRunning = true;
this.material.uniforms.texture2.value = this.nextTexture;
}
this.tmpImage = false;
let tween = new TWEEN.Tween(this.material.uniforms.progress);
tween.to({ value: 1.0 }, this.duration)
.easing(this.easing)
.onStart(() => {
})
.onComplete(() => {
this.current = nextIdx;
this.material.uniforms.texture1.value = this.nextTexture;
this.material.uniforms.progress.value = 0.0;
this.isRunning = false;
this.removeImageByUuid('temp');
}).start();
}
async showTempImage(url) {
this.tmpImage = true;
await this.loadImage(url, 'temp');
}
render(time) {
if (this.paused) return;
TWEEN.update(time);
requestAnimationFrame(this.render.bind(this));
this.delta += this.clock.getDelta();
if (this.delta > this.interval) {
if (this.debug) {
Object.keys(this._settings).forEach((item) => {
this.material.uniforms[item].value = this._settings[item];
});
}
this.renderer.render(this.scene, this.camera);
this.delta = this.delta % this.interval;
}
}
changeTransition(name, cur, next) {
let transition = window.GLTransitions.find((obj) => {
return obj.name == name;
});
if (!transition) {
transition = window.GLTransitions[39];
}
let uniforms = {};
for (const key in transition.defaultParams) {
if (transition.paramsTypes[key] !== "sampler2D") {
uniforms[key] = { type: transition.paramsTypes[key], value: transition.defaultParams[key] };
}
}
// do the change
this.material.fragmentShader = this.makeFragment(transition.glsl);
this.material.uniforms = { ...this.getUniformBase(cur, next), ...uniforms };
this.material.needsUpdate = true;
this.settings();
this.renderer.render(this.scene, this.camera);
}
}
+1010
View File
File diff suppressed because it is too large. Load diff
+800
View File
@@ -0,0 +1,800 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.TWEEN = factory());
}(this, (function () { 'use strict';
var NOW;
// Include a performance.now polyfill.
// In node.js, use process.hrtime.
// eslint-disable-next-line
// @ts-ignore
if (typeof self === 'undefined' && typeof process !== 'undefined' && process.hrtime) {
NOW = function () {
// eslint-disable-next-line
// @ts-ignore
var time = process.hrtime();
// Convert [seconds, nanoseconds] to milliseconds.
return time[0] * 1000 + time[1] / 1000000;
};
}
// In a browser, use self.performance.now if it is available.
else if (typeof self !== 'undefined' && self.performance !== undefined && self.performance.now !== undefined) {
// This must be bound, because directly assigning this function
// leads to an invocation exception in Chrome.
NOW = self.performance.now.bind(self.performance);
}
// Use Date.now if it is available.
else if (Date.now !== undefined) {
NOW = Date.now;
}
// Otherwise, use 'new Date().getTime()'.
else {
NOW = function () {
return new Date().getTime();
};
}
var NOW$1 = NOW;
/**
* Controlling groups of tweens
*
* Using the TWEEN singleton to manage your tweens can cause issues in large apps with many components.
* In these cases, you may want to create your own smaller groups of tween
*/
var Group = /** @class */ (function () {
function Group() {
this._tweens = {};
this._tweensAddedDuringUpdate = {};
}
Group.prototype.getAll = function () {
var _this = this;
return Object.keys(this._tweens).map(function (tweenId) {
return _this._tweens[tweenId];
});
};
Group.prototype.removeAll = function () {
this._tweens = {};
};
Group.prototype.add = function (tween) {
this._tweens[tween.getId()] = tween;
this._tweensAddedDuringUpdate[tween.getId()] = tween;
};
Group.prototype.remove = function (tween) {
delete this._tweens[tween.getId()];
delete this._tweensAddedDuringUpdate[tween.getId()];
};
Group.prototype.update = function (time, preserve) {
var tweenIds = Object.keys(this._tweens);
if (tweenIds.length === 0) {
return false;
}
time = time !== undefined ? time : NOW$1();
// Tweens are updated in "batches". If you add a new tween during an
// update, then the new tween will be updated in the next batch.
// If you remove a tween during an update, it may or may not be updated.
// However, if the removed tween was added during the current batch,
// then it will not be updated.
while (tweenIds.length > 0) {
this._tweensAddedDuringUpdate = {};
for (var i = 0; i < tweenIds.length; i++) {
var tween = this._tweens[tweenIds[i]];
if (tween && tween.update(time) === false && !preserve) {
delete this._tweens[tweenIds[i]];
}
}
tweenIds = Object.keys(this._tweensAddedDuringUpdate);
}
return true;
};
return Group;
}());
/**
* The Ease class provides a collection of easing functions for use with tween.js.
*/
var Easing = {
Linear: {
None: function (amount) {
return amount;
},
},
Quadratic: {
In: function (amount) {
return amount * amount;
},
Out: function (amount) {
return amount * (2 - amount);
},
InOut: function (amount) {
if ((amount *= 2) < 1) {
return 0.5 * amount * amount;
}
return -0.5 * (--amount * (amount - 2) - 1);
},
},
Cubic: {
In: function (amount) {
return amount * amount * amount;
},
Out: function (amount) {
return --amount * amount * amount + 1;
},
InOut: function (amount) {
if ((amount *= 2) < 1) {
return 0.5 * amount * amount * amount;
}
return 0.5 * ((amount -= 2) * amount * amount + 2);
},
},
Quartic: {
In: function (amount) {
return amount * amount * amount * amount;
},
Out: function (amount) {
return 1 - --amount * amount * amount * amount;
},
InOut: function (amount) {
if ((amount *= 2) < 1) {
return 0.5 * amount * amount * amount * amount;
}
return -0.5 * ((amount -= 2) * amount * amount * amount - 2);
},
},
Quintic: {
In: function (amount) {
return amount * amount * amount * amount * amount;
},
Out: function (amount) {
return --amount * amount * amount * amount * amount + 1;
},
InOut: function (amount) {
if ((amount *= 2) < 1) {
return 0.5 * amount * amount * amount * amount * amount;
}
return 0.5 * ((amount -= 2) * amount * amount * amount * amount + 2);
},
},
Sinusoidal: {
In: function (amount) {
return 1 - Math.cos((amount * Math.PI) / 2);
},
Out: function (amount) {
return Math.sin((amount * Math.PI) / 2);
},
InOut: function (amount) {
return 0.5 * (1 - Math.cos(Math.PI * amount));
},
},
Exponential: {
In: function (amount) {
return amount === 0 ? 0 : Math.pow(1024, amount - 1);
},
Out: function (amount) {
return amount === 1 ? 1 : 1 - Math.pow(2, -10 * amount);
},
InOut: function (amount) {
if (amount === 0) {
return 0;
}
if (amount === 1) {
return 1;
}
if ((amount *= 2) < 1) {
return 0.5 * Math.pow(1024, amount - 1);
}
return 0.5 * (-Math.pow(2, -10 * (amount - 1)) + 2);
},
},
Circular: {
In: function (amount) {
return 1 - Math.sqrt(1 - amount * amount);
},
Out: function (amount) {
return Math.sqrt(1 - --amount * amount);
},
InOut: function (amount) {
if ((amount *= 2) < 1) {
return -0.5 * (Math.sqrt(1 - amount * amount) - 1);
}
return 0.5 * (Math.sqrt(1 - (amount -= 2) * amount) + 1);
},
},
Elastic: {
In: function (amount) {
if (amount === 0) {
return 0;
}
if (amount === 1) {
return 1;
}
return -Math.pow(2, 10 * (amount - 1)) * Math.sin((amount - 1.1) * 5 * Math.PI);
},
Out: function (amount) {
if (amount === 0) {
return 0;
}
if (amount === 1) {
return 1;
}
return Math.pow(2, -10 * amount) * Math.sin((amount - 0.1) * 5 * Math.PI) + 1;
},
InOut: function (amount) {
if (amount === 0) {
return 0;
}
if (amount === 1) {
return 1;
}
amount *= 2;
if (amount < 1) {
return -0.5 * Math.pow(2, 10 * (amount - 1)) * Math.sin((amount - 1.1) * 5 * Math.PI);
}
return 0.5 * Math.pow(2, -10 * (amount - 1)) * Math.sin((amount - 1.1) * 5 * Math.PI) + 1;
},
},
Back: {
In: function (amount) {
var s = 1.70158;
return amount * amount * ((s + 1) * amount - s);
},
Out: function (amount) {
var s = 1.70158;
return --amount * amount * ((s + 1) * amount + s) + 1;
},
InOut: function (amount) {
var s = 1.70158 * 1.525;
if ((amount *= 2) < 1) {
return 0.5 * (amount * amount * ((s + 1) * amount - s));
}
return 0.5 * ((amount -= 2) * amount * ((s + 1) * amount + s) + 2);
},
},
Bounce: {
In: function (amount) {
return 1 - Easing.Bounce.Out(1 - amount);
},
Out: function (amount) {
if (amount < 1 / 2.75) {
return 7.5625 * amount * amount;
}
else if (amount < 2 / 2.75) {
return 7.5625 * (amount -= 1.5 / 2.75) * amount + 0.75;
}
else if (amount < 2.5 / 2.75) {
return 7.5625 * (amount -= 2.25 / 2.75) * amount + 0.9375;
}
else {
return 7.5625 * (amount -= 2.625 / 2.75) * amount + 0.984375;
}
},
InOut: function (amount) {
if (amount < 0.5) {
return Easing.Bounce.In(amount * 2) * 0.5;
}
return Easing.Bounce.Out(amount * 2 - 1) * 0.5 + 0.5;
},
},
};
/**
*
*/
var Interpolation = {
Linear: function (v, k) {
var m = v.length - 1;
var f = m * k;
var i = Math.floor(f);
var fn = Interpolation.Utils.Linear;
if (k < 0) {
return fn(v[0], v[1], f);
}
if (k > 1) {
return fn(v[m], v[m - 1], m - f);
}
return fn(v[i], v[i + 1 > m ? m : i + 1], f - i);
},
Bezier: function (v, k) {
var b = 0;
var n = v.length - 1;
var pw = Math.pow;
var bn = Interpolation.Utils.Bernstein;
for (var i = 0; i <= n; i++) {
b += pw(1 - k, n - i) * pw(k, i) * v[i] * bn(n, i);
}
return b;
},
CatmullRom: function (v, k) {
var m = v.length - 1;
var f = m * k;
var i = Math.floor(f);
var fn = Interpolation.Utils.CatmullRom;
if (v[0] === v[m]) {
if (k < 0) {
i = Math.floor((f = m * (1 + k)));
}
return fn(v[(i - 1 + m) % m], v[i], v[(i + 1) % m], v[(i + 2) % m], f - i);
}
else {
if (k < 0) {
return v[0] - (fn(v[0], v[0], v[1], v[1], -f) - v[0]);
}
if (k > 1) {
return v[m] - (fn(v[m], v[m], v[m - 1], v[m - 1], f - m) - v[m]);
}
return fn(v[i ? i - 1 : 0], v[i], v[m < i + 1 ? m : i + 1], v[m < i + 2 ? m : i + 2], f - i);
}
},
Utils: {
Linear: function (p0, p1, t) {
return (p1 - p0) * t + p0;
},
Bernstein: function (n, i) {
var fc = Interpolation.Utils.Factorial;
return fc(n) / fc(i) / fc(n - i);
},
Factorial: (function () {
var a = [1];
return function (n) {
var s = 1;
if (a[n]) {
return a[n];
}
for (var i = n; i > 1; i--) {
s *= i;
}
a[n] = s;
return s;
};
})(),
CatmullRom: function (p0, p1, p2, p3, t) {
var v0 = (p2 - p0) * 0.5;
var v1 = (p3 - p1) * 0.5;
var t2 = t * t;
var t3 = t * t2;
return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1;
},
},
};
/**
* Utils
*/
var Sequence = /** @class */ (function () {
function Sequence() {
}
Sequence.nextId = function () {
return Sequence._nextId++;
};
Sequence._nextId = 0;
return Sequence;
}());
/**
* Tween.js - Licensed under the MIT license
* https://github.com/tweenjs/tween.js
* ----------------------------------------------
*
* See https://github.com/tweenjs/tween.js/graphs/contributors for the full list of contributors.
* Thank you all, you're awesome!
*/
var Tween = /** @class */ (function () {
function Tween(_object, _group) {
if (_group === void 0) { _group = TWEEN; }
this._object = _object;
this._group = _group;
this._isPaused = false;
this._pauseStart = 0;
this._valuesStart = {};
this._valuesEnd = {};
this._valuesStartRepeat = {};
this._duration = 1000;
this._initialRepeat = 0;
this._repeat = 0;
this._yoyo = false;
this._isPlaying = false;
this._reversed = false;
this._delayTime = 0;
this._startTime = 0;
this._easingFunction = TWEEN.Easing.Linear.None;
this._interpolationFunction = TWEEN.Interpolation.Linear;
this._chainedTweens = [];
this._onStartCallbackFired = false;
this._id = TWEEN.nextId();
this._isChainStopped = false;
}
Tween.prototype.getId = function () {
return this._id;
};
Tween.prototype.isPlaying = function () {
return this._isPlaying;
};
Tween.prototype.isPaused = function () {
return this._isPaused;
};
Tween.prototype.to = function (properties, duration) {
for (var prop in properties) {
this._valuesEnd[prop] = properties[prop];
}
if (duration !== undefined) {
this._duration = duration;
}
return this;
};
Tween.prototype.duration = function (d) {
this._duration = d;
return this;
};
Tween.prototype.start = function (time) {
if (this._isPlaying) {
return this;
}
// eslint-disable-next-line
// @ts-ignore FIXME?
this._group.add(this);
this._repeat = this._initialRepeat;
if (this._reversed) {
// If we were reversed (f.e. using the yoyo feature) then we need to
// flip the tween direction back to forward.
this._reversed = false;
for (var property in this._valuesStartRepeat) {
this._swapEndStartRepeatValues(property);
this._valuesStart[property] = this._valuesStartRepeat[property];
}
}
this._isPlaying = true;
this._isPaused = false;
this._onStartCallbackFired = false;
this._isChainStopped = false;
this._startTime =
time !== undefined ? (typeof time === 'string' ? TWEEN.now() + parseFloat(time) : time) : TWEEN.now();
this._startTime += this._delayTime;
this._setupProperties(this._object, this._valuesStart, this._valuesEnd, this._valuesStartRepeat);
return this;
};
Tween.prototype._setupProperties = function (_object, _valuesStart, _valuesEnd, _valuesStartRepeat) {
for (var property in _valuesEnd) {
var startValue = _object[property];
var startValueIsArray = Array.isArray(startValue);
var propType = startValueIsArray ? 'array' : typeof startValue;
var isInterpolationList = !startValueIsArray && Array.isArray(_valuesEnd[property]);
// If `to()` specifies a property that doesn't exist in the source object,
// we should not set that property in the object
if (propType === 'undefined' || propType === 'function') {
continue;
}
// Check if an Array was provided as property value
if (isInterpolationList) {
var endValues = _valuesEnd[property];
if (endValues.length === 0) {
continue;
}
// handle an array of relative values
endValues = endValues.map(this._handleRelativeValue.bind(this, startValue));
// Create a local copy of the Array with the start value at the front
_valuesEnd[property] = [startValue].concat(endValues);
}
// handle the deepness of the values
if ((propType === 'object' || startValueIsArray) && startValue && !isInterpolationList) {
_valuesStart[property] = startValueIsArray ? [] : {};
// eslint-disable-next-line
for (var prop in startValue) {
// eslint-disable-next-line
// @ts-ignore FIXME?
_valuesStart[property][prop] = startValue[prop];
}
_valuesStartRepeat[property] = startValueIsArray ? [] : {}; // TODO? repeat nested values? And yoyo? And array values?
// eslint-disable-next-line
// @ts-ignore FIXME?
this._setupProperties(startValue, _valuesStart[property], _valuesEnd[property], _valuesStartRepeat[property]);
}
else {
// Save the starting value, but only once.
if (typeof _valuesStart[property] === 'undefined') {
_valuesStart[property] = startValue;
}
if (!startValueIsArray) {
// eslint-disable-next-line
// @ts-ignore FIXME?
_valuesStart[property] *= 1.0; // Ensures we're using numbers, not strings
}
if (isInterpolationList) {
// eslint-disable-next-line
// @ts-ignore FIXME?
_valuesStartRepeat[property] = _valuesEnd[property].slice().reverse();
}
else {
_valuesStartRepeat[property] = _valuesStart[property] || 0;
}
}
}
};
Tween.prototype.stop = function () {
if (!this._isChainStopped) {
this._isChainStopped = true;
this.stopChainedTweens();
}
if (!this._isPlaying) {
return this;
}
// eslint-disable-next-line
// @ts-ignore FIXME?
this._group.remove(this);
this._isPlaying = false;
this._isPaused = false;
if (this._onStopCallback) {
this._onStopCallback(this._object);
}
return this;
};
Tween.prototype.end = function () {
this.update(Infinity);
return this;
};
Tween.prototype.pause = function (time) {
if (this._isPaused || !this._isPlaying) {
return this;
}
this._isPaused = true;
this._pauseStart = time === undefined ? TWEEN.now() : time;
// eslint-disable-next-line
// @ts-ignore FIXME?
this._group.remove(this);
return this;
};
Tween.prototype.resume = function (time) {
if (!this._isPaused || !this._isPlaying) {
return this;
}
this._isPaused = false;
this._startTime += (time === undefined ? TWEEN.now() : time) - this._pauseStart;
this._pauseStart = 0;
// eslint-disable-next-line
// @ts-ignore FIXME?
this._group.add(this);
return this;
};
Tween.prototype.stopChainedTweens = function () {
for (var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i++) {
this._chainedTweens[i].stop();
}
return this;
};
Tween.prototype.group = function (group) {
this._group = group;
return this;
};
Tween.prototype.delay = function (amount) {
this._delayTime = amount;
return this;
};
Tween.prototype.repeat = function (times) {
this._initialRepeat = times;
this._repeat = times;
return this;
};
Tween.prototype.repeatDelay = function (amount) {
this._repeatDelayTime = amount;
return this;
};
Tween.prototype.yoyo = function (yoyo) {
this._yoyo = yoyo;
return this;
};
Tween.prototype.easing = function (easingFunction) {
this._easingFunction = easingFunction;
return this;
};
Tween.prototype.interpolation = function (interpolationFunction) {
this._interpolationFunction = interpolationFunction;
return this;
};
Tween.prototype.chain = function () {
var tweens = [];
for (var _i = 0; _i < arguments.length; _i++) {
tweens[_i] = arguments[_i];
}
this._chainedTweens = tweens;
return this;
};
Tween.prototype.onStart = function (callback) {
this._onStartCallback = callback;
return this;
};
Tween.prototype.onUpdate = function (callback) {
this._onUpdateCallback = callback;
return this;
};
Tween.prototype.onRepeat = function (callback) {
this._onRepeatCallback = callback;
return this;
};
Tween.prototype.onComplete = function (callback) {
this._onCompleteCallback = callback;
return this;
};
Tween.prototype.onStop = function (callback) {
this._onStopCallback = callback;
return this;
};
Tween.prototype.update = function (time) {
var property;
var elapsed;
var endTime = this._startTime + this._duration;
if (time > endTime && !this._isPlaying) {
return false;
}
// If the tween was already finished,
if (!this.isPlaying) {
this.start(time);
}
if (time < this._startTime) {
return true;
}
if (this._onStartCallbackFired === false) {
if (this._onStartCallback) {
this._onStartCallback(this._object);
}
this._onStartCallbackFired = true;
}
elapsed = (time - this._startTime) / this._duration;
elapsed = this._duration === 0 || elapsed > 1 ? 1 : elapsed;
var value = this._easingFunction(elapsed);
// properties transformations
this._updateProperties(this._object, this._valuesStart, this._valuesEnd, value);
if (this._onUpdateCallback) {
this._onUpdateCallback(this._object, elapsed);
}
if (elapsed === 1) {
if (this._repeat > 0) {
if (isFinite(this._repeat)) {
this._repeat--;
}
// Reassign starting values, restart by making startTime = now
for (property in this._valuesStartRepeat) {
if (!this._yoyo && typeof this._valuesEnd[property] === 'string') {
this._valuesStartRepeat[property] =
// eslint-disable-next-line
// @ts-ignore FIXME?
this._valuesStartRepeat[property] + parseFloat(this._valuesEnd[property]);
}
if (this._yoyo) {
this._swapEndStartRepeatValues(property);
}
this._valuesStart[property] = this._valuesStartRepeat[property];
}
if (this._yoyo) {
this._reversed = !this._reversed;
}
if (this._repeatDelayTime !== undefined) {
this._startTime = time + this._repeatDelayTime;
}
else {
this._startTime = time + this._delayTime;
}
if (this._onRepeatCallback) {
this._onRepeatCallback(this._object);
}
return true;
}
else {
if (this._onCompleteCallback) {
this._onCompleteCallback(this._object);
}
for (var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i++) {
// Make the chained tweens start exactly at the time they should,
// even if the `update()` method was called way past the duration of the tween
this._chainedTweens[i].start(this._startTime + this._duration);
}
this._isPlaying = false;
return false;
}
}
return true;
};
Tween.prototype._updateProperties = function (_object, _valuesStart, _valuesEnd, value) {
for (var property in _valuesEnd) {
// Don't update properties that do not exist in the source object
if (_valuesStart[property] === undefined) {
continue;
}
var start = _valuesStart[property] || 0;
var end = _valuesEnd[property];
var startIsArray = Array.isArray(_object[property]);
var endIsArray = Array.isArray(end);
var isInterpolationList = !startIsArray && endIsArray;
if (isInterpolationList) {
_object[property] = this._interpolationFunction(end, value);
}
else if (typeof end === 'object' && end) {
// eslint-disable-next-line
// @ts-ignore FIXME?
this._updateProperties(_object[property], start, end, value);
}
else {
// Parses relative end values with start as base (e.g.: +10, -3)
end = this._handleRelativeValue(start, end);
// Protect against non numeric properties.
if (typeof end === 'number') {
// eslint-disable-next-line
// @ts-ignore FIXME?
_object[property] = start + (end - start) * value;
}
}
}
};
Tween.prototype._handleRelativeValue = function (start, end) {
if (typeof end !== 'string') {
return end;
}
if (end.charAt(0) === '+' || end.charAt(0) === '-') {
return start + parseFloat(end);
}
else {
return parseFloat(end);
}
};
Tween.prototype._swapEndStartRepeatValues = function (property) {
var tmp = this._valuesStartRepeat[property];
if (typeof this._valuesEnd[property] === 'string') {
// eslint-disable-next-line
// @ts-ignore FIXME?
this._valuesStartRepeat[property] = this._valuesStartRepeat[property] + parseFloat(this._valuesEnd[property]);
}
else {
this._valuesStartRepeat[property] = this._valuesEnd[property];
}
this._valuesEnd[property] = tmp;
};
return Tween;
}());
var VERSION = '18.6.0';
/**
* Tween.js - Licensed under the MIT license
* https://github.com/tweenjs/tween.js
* ----------------------------------------------
*
* See https://github.com/tweenjs/tween.js/graphs/contributors for the full list of contributors.
* Thank you all, you're awesome!
*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
/**
* Controlling groups of tweens
*
* Using the TWEEN singleton to manage your tweens can cause issues in large apps with many components.
* In these cases, you may want to create your own smaller groups of tween
*/
var Main = /** @class */ (function (_super) {
__extends(Main, _super);
function Main() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.version = VERSION;
_this.now = NOW$1;
_this.Group = Group;
_this.Easing = Easing;
_this.Interpolation = Interpolation;
_this.nextId = Sequence.nextId;
_this.Tween = Tween;
return _this;
}
return Main;
}(Group));
var TWEEN = new Main();
return TWEEN;
})));
+1 -2
View File
@@ -90,8 +90,7 @@ module.exports = function (pluginManager, websocket, dispatcher) {
req.busboy.on('file', function (fieldname, file, filename, encoding, mimeType) {
if (fieldname === "newBackground")
if (filename.length > 0 && (mimeType === "image/jpeg" || mimeType === "video/mp4" || mimeType === "image/png")) {
console.log(filename)
if (filename.length > 0 && (mimeType === "image/jpeg" || mimeType === "video/mp4" || mimeType === "image/png")) {
let fstream = fs.createWriteStream('./data/backgrounds/' + filename);
file.pipe(fstream);
} else {
+18 -1
View File
@@ -65,7 +65,8 @@ module.exports = function (pluginManager, websocket, dispatcher) {
});
});
router.get('/display/:id', function (req, res, next) {
router.get('/display/:id/css', function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
let idx = parseInt(req.params.id);
let preview = parseInt(req.query['isPreview']) || 0;
@@ -81,6 +82,22 @@ module.exports = function (pluginManager, websocket, dispatcher) {
});
});
router.get('/display/:id', function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
let idx = parseInt(req.params.id);
let preview = parseInt(req.query['isPreview']) || 0;
let volume = parseFloat(req.query['videoVolume']) || 1.;
let extra = pluginManager.getDisplayAdditions();
res.render('displayWebGl', {
config: config,
display: availableDisplays[idx],
displayId: idx,
videoVolume: volume,
extra: extra,
isPreview: preview
});
});
router.get('/images/:dir/:name', function (req, res, next) {
let options = {
root: './data/bundles/' + req.params.dir + '/images/',
+2 -2
View File
@@ -4,10 +4,10 @@
"duration": 20,
"useWebFonts": false,
"displayTime": true,
"transition": "blocks2",
"transition": "fade",
"styleHeader": {
"fill": "#fff",
"fontSize": 64,
"fontSize": 72,
"fontWeight": 900,
"fontFamily": "Arial",
"stroke": "",
+4 -3
View File
@@ -2,6 +2,7 @@
{% block header %}
<script src="/socket.io/socket.io.js"></script>
<script src="/js/sharedScript.js"></script>
{% if config.useLocalAssets %}
<script src="/assets/jquery.jeditable.min.js"></script>
<script src="/assets/vue.js"></script>
@@ -19,7 +20,7 @@
{{ t("infoscreen") }}
</a>
<div id="displays" class="ui dropdown item">
<div id="displays" class="ui scrolling dropdown item">
<div class="ui small breadcrumb">
<span class="section">{{ t("navs.display") }}</span>
<i class="right chevron icon divider"></i>
@@ -28,7 +29,7 @@
<i class="dropdown icon"></i>
</div>
<div id="bundles" class="ui dropdown item">
<div id="bundles" class="ui scrolling dropdown item">
<div class="ui small breadcrumb">
<span class="section">{{ t("navs.bundle") }}</span>
<i class="right chevron icon divider"></i>
@@ -37,7 +38,7 @@
<i class="dropdown icon"></i>
</div>
<div id="transitions" class="ui dropdown item">
<div id="transitions" class="ui scrolling dropdown item">
<div class="ui small breadcrumb">
<span class="section">{{ t("navs.transition") }}</span>
<i class="right chevron icon divider"></i>
+5 -5
View File
@@ -2,6 +2,7 @@
{% block header %}
<script src="/socket.io/socket.io.js"></script>
<script src="/js/sharedScript.js"></script>
{% endblock %}
{% block body %}
@@ -36,7 +37,7 @@
</div>
<div class="field">
<label>{{ t("admin.editBundleProperties.transition") }}</label>
<div id="transitions" class="ui selection dropdown">
<div id="transitions" class="ui selection scrolling dropdown">
<input type="text" id="inputTransition" name="transition" value="{{ bundleData.transition }}" hidden/>
<div class="ui small breadcrumb">
<span id="currentTransition" class="section"></span>
@@ -160,11 +161,10 @@
$(function () {
var transitionArray = [];
var values = ["bars", "blinds", "blinds3d", "zip", "blocks", "blocks2", "concentric", "warp", "cube", "tiles3d", "tiles3dprev", "slide", "swipe", "dissolve"];
// var values = ["bars", "blinds", "blinds3d", "zip", "blocks", "blocks2", "concentric", "warp", "cube", "tiles3d", "tiles3dprev", "slide", "swipe", "dissolve"];
transitionArray.push({name: "random", value: ""});
for (var i in values) {
transitionArray.push({name: values[i], value: values[i]});
for (var i in SupportedTransitions) {
transitionArray.push({name: SupportedTransitions[i], value: SupportedTransitions[i]});
}
$('#transitions')
+2 -1
View File
@@ -3,6 +3,7 @@
{% block header %}
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="/js/sharedScript.js"></script>
<script>
var bundle = "{{ bundle }}";
var file = "{{ file }}";
@@ -54,7 +55,7 @@
<label for="lbl">{{ t("navs.time") }}</label>
</div>
</div>
<div id="transitions" class="ui dropdown item">
<div id="transitions" class="ui scrolling dropdown item">
<div class="ui small breadcrumb">
<span class="section">{{ t("navs.transition") }}</span>
<i class="right chevron icon divider"></i>
+57
View File
@@ -0,0 +1,57 @@
{% extends 'layout/view.twig' %}
{% block header %}
{% if config.mediaServer %}
{% if config.useLocalAssets %}
<script src="/assets/flv.min.js"></script>
{% else %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/flv.js/1.5.0/flv.min.js"></script>
{% endif %}
{% endif %}
<script src="/socket.io/socket.io.js"></script>
<script src="/js/three.js" type="text/javascript" charset="utf-8"></script>
<script src="/js/gl-transitions.js" type="text/javascript" charset="utf-8"></script>
<script src="/js/tween.js" type="text/javascript" charset="utf-8"></script>
<script src="/js/sketch.js" type="text/javascript" charset="utf-8"></script>
<title>InfoScreen3 - {{ display.name }}</title>
{% endblock %}
{% block body %}
<div id="blackoutLayer" class="animated"></div>
{{ extra }}
<div id="time" class="noselect animated">00:00</div>
<div id="statusMessageOuter" class="noselect animated">
<span id="statusMessage"></span>
</div>
<div id="networkstatus" class="noselect animated"><i class="spinner loading icon"></i></div>
<video id="stream" class="fsimage" poster=""></video>
<div id="helperLayer" class="gpu animated"></div>
<iframe id="webLayer0" scrolling="no" class="web fsimage animated"></iframe>
<iframe id="webLayer1" scrolling="no" class="web fsimage animated"></iframe>
<div id="slider" class="fsimage" style="overflow:">
</div>
<div id="bg">
<img id="bgimg" class="fsimage" src="/img/wait.png"/>
</div>
<video loop autoplay id="bgvid" class="fsimage" poster="">
</video>
<script>
var socket = io("{{ config.serverUrl }}:{{ config.serverListenPort }}/display-{{ displayId }}");
var videoVolume = {{ videoVolume }};
var isPreview = {{ isPreview }};
</script>
<script src="/js/displayWebGl.js"></script>
{% endblock %}
+18 -13
View File
@@ -35,19 +35,24 @@
var output = "";
for (var i in data.displays) {
var display = data.displays[i];
var html = '<div class="ui card">' +
'<div class="image" style="background: black;">' +
'<img src="' + data.previewImages[i] + '" />' +
'</div>' +
'<div class="content">' +
'<h3 class="ui center aligned header">' + display.name + '</h3>' +
'<div class="ui attached buttons">' +
'<a href="display/' + index.toString() + '" class="ui positive button">{{ t("index.normal") }}</a>' +
'<div class="or" data-text="{{ t("index.splitter") }}"></div>' +
'<a href="display/' + index.toString() + '/lite" class="ui button">{{ t("index.lite") }}</a>' +
'</div>' +
'</div>' +
'</div>';
var html = `
<div class="ui card">
<h3 class="ui center aligned top attached header ">${display.name}</h3>
<div onclick="window.location='display/${index.toString()}'" class="image" style="background: black;">
<img src="${data.previewImages[i]}" />
</div>
<div class="content">
<div class="ui attached buttons">
<a href="/display/${index.toString()}" class="ui positive button">{{ t("index.normal") }}</a>
<div class="or" data-text="{{ t("index.splitter") }}"></div>
<a href="/display/${index.toString()}/css" class="ui button">{{ t("index.css") }}</a>
<div class="or" data-text="{{ t("index.splitter") }}"></div>
<a href="/display/${index.toString()}/lite" class="ui button">{{ t("index.lite") }}</a>
</div>
</div><br>
<a href="/admin/display/${index.toString()}" class="ui bottom attached gray button">{{ t("index.admin") }}</a>
</div>`;
output += html;
index += 1;
}