commit b7441a2d5b827278f5cd7533e7dfd929a8315eae
parent aa39a0d7cd03d1fa09041dd5ced0cb462039a916
Author: Andy Herbert <andy.herbert@gmail.com>
Date: Fri, 8 Nov 2013 20:44:39 +0000
Add functions to display an in-browser popup, instead of using canvas rendering methods.
Diffstat:
M | ansilove.js | | | 274 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
1 file changed, 220 insertions(+), 54 deletions(-)
diff --git a/ansilove.js b/ansilove.js
@@ -1,6 +1,6 @@
var AnsiLove = (function () {
"use strict";
- var Palette, Font;
+ var Palette, Font, Popup;
function File(bytes) {
var pos, SAUCE_ID, COMNT_ID, commentCount;
@@ -1299,7 +1299,7 @@ var AnsiLove = (function () {
return canvas;
}
- function render(name, bytes, callback, splitRows, options) {
+ function readBytes(name, bytes, callback, splitRows, options) {
var data, font, returnArray, start, splitLength, displayData;
options.icecolors = (options.icecolors >= 0 && options.icecolors <= 1) ? options.icecolors : 0;
@@ -1695,10 +1695,46 @@ var AnsiLove = (function () {
};
}
+ function render(url, callback, options, callbackFail) {
+ httpGet(url, function (bytes) {
+ try {
+ readBytes(url, bytes, callback, 0, options || {});
+ } catch (e) {
+ if (callbackFail) {
+ callbackFail(e);
+ } else {
+ throw e;
+ }
+ }
+ }, callbackFail);
+ }
+
+ function splitRender(url, callback, splitRows, options, callbackFail) {
+ httpGet(url, function (bytes) {
+ try {
+ readBytes(url, bytes, callback, splitRows || 27, options || {});
+ } catch (e) {
+ if (callbackFail) {
+ callbackFail(e);
+ } else {
+ throw e;
+ }
+ }
+ }, callbackFail);
+ }
+
+ function renderBytes(bytes, callback, options) {
+ readBytes("", bytes, callback, 0, options || {});
+ }
+
+ function splitRenderBytes(bytes, callback, splitRows, options) {
+ readBytes("", bytes, callback, splitRows || 27, options || {});
+ }
+
function animate(url, callback, options, callbackFail) {
var ansimation;
httpGet(url, function (bytes) {
- ansimation = new Ansimation(bytes, options);
+ ansimation = new Ansimation(bytes, options || {});
callback(ansimation.canvas, ansimation.sauce);
}, callbackFail);
return {
@@ -1716,62 +1752,192 @@ var AnsiLove = (function () {
};
}
- return {
- "render": function (url, callback, options, callbackFail) {
- httpGet(url, function (bytes) {
- try {
- render(url, bytes, callback, 0, options || {});
- } catch (e) {
- if (callbackFail) {
- callbackFail(e);
- } else {
- throw e;
- }
+ function animateBytes(bytes, callback, options) {
+ var ansimation;
+ ansimation = new Ansimation(bytes, options || {});
+ setTimeout(function () {
+ callback(ansimation.canvas, ansimation.sauce);
+ }, 250);
+ return {
+ "play": function (baud, callback, clearScreen) {
+ ansimation.play(baud, callback, clearScreen);
+ },
+ "stop": function () {
+ ansimation.stop();
+ },
+ "load": function (url, callback, callbackFail) {
+ httpGet(url, function (bytes) {
+ ansimation.load(bytes, callback);
+ }, callbackFail);
+ }
+ };
+ }
+
+ Popup = (function () {
+ var STYLE_DEFAULTS, FIREFOX, CHROME, SAFARI, browser, retina;
+
+ STYLE_DEFAULTS = {"background-color": "transparent", "background-image": "none", "margin": "0", "padding": "0", "border": "0", "font-size": "100%", "font": "inherit", "vertical-align": "baseline", "color": "black", "display": "block", "cursor": "default", "text-align": "left", "text-shadow": "none", "text-transform": "none", "clear": "none", "float": "none", "overflow": "auto", "position": "relative", "visibility": "visible"};
+
+ FIREFOX = 0;
+ CHROME = 1;
+ SAFARI = 2;
+
+ if (navigator.userAgent.indexOf("Firefox") !== -1) {
+ browser = 0;
+ } else if (navigator.userAgent.indexOf("AppleWebKit") !== -1) {
+ if (navigator.userAgent.indexOf("Chrome") !== -1) {
+ browser = 1;
+ } else {
+ browser = 2;
+ }
+ }
+
+ retina = window.devicePixelRatio > 1;
+
+ function findHighestZIndex() {
+ var elements, highest, i, zIndex;
+ for (i = 0, elements = document.getElementsByTagName("*"), highest = 0; i < elements.length; ++i) {
+ zIndex = document.defaultView.getComputedStyle(elements[i]).zIndex;
+ if (zIndex !== "auto") {
+ highest = Math.max(highest, parseInt(zIndex, 10));
}
- }, callbackFail);
- },
- "splitRender": function (url, callback, splitRows, options, callbackFail) {
- httpGet(url, function (bytes) {
- try {
- render(url, bytes, callback, splitRows || 27, options || {});
- } catch (e) {
- if (callbackFail) {
- callbackFail(e);
- } else {
- throw e;
+ }
+ return highest;
+ }
+
+ function applyStyle(element, style) {
+ var name;
+ for (name in style) {
+ if (style.hasOwnProperty(name)) {
+ element.style.setProperty(name, style[name], "important");
+ }
+ }
+ }
+
+ function createDiv(style) {
+ var div;
+ style = style || {};
+ div = document.createElement("div");
+ applyStyle(div, STYLE_DEFAULTS);
+ applyStyle(div, style);
+ return div;
+ }
+
+ function transitionCSS(element, transProperty, transDuration, transFunction, style) {
+ element.style.transitionProperty = transProperty;
+ element.style.transitionDuration = transDuration;
+ element.style.transitionTimingFunction = transFunction;
+ if (style) {
+ setTimeout(function () {
+ applyStyle(element, style);
+ }, 50);
+ }
+ }
+
+ function show(url, baud, options) {
+ var divOverlay, divCanvasContainer;
+
+ function slideUpContainer() {
+ transitionCSS(divCanvasContainer, "top", "0.6s", "ease-in-out", {"top": "0"});
+ }
+
+ function processCanvas(canvas) {
+ if (retina) {
+ switch (browser) {
+ case FIREFOX:
+ canvas.style.imageRendering = "-moz-crisp-edges";
+ break;
+ case SAFARI:
+ canvas.style.imageRendering = "-webkit-optimize-contrast";
+ break;
}
}
- }, callbackFail);
- },
- "renderBytes": function (bytes, callback, options) {
- render("", bytes, callback, 0, options || {});
- },
- "splitRenderBytes": function (bytes, callback, splitRows, options) {
- render("", bytes, callback, splitRows || 27, options || {});
- },
- "animate": function (url, callback, options, callbackFail) {
- return animate(url, callback, options || {}, callbackFail);
- },
- "animateBytes": function (bytes, callback, options) {
- var ansimation;
- ansimation = new Ansimation(bytes, options || {});
+
+ applyStyle(canvas, STYLE_DEFAULTS);
+ canvas.style.verticalAlign = "bottom";
+
+ return canvas;
+ }
+
+ function doubleScale(canvas) {
+ var scaledCanvas, ctx;
+ scaledCanvas = createCanvas(canvas.width * 2, canvas.height * 2);
+ ctx = scaledCanvas.getContext("2d");
+ ctx.webkitImageSmoothingEnabled = false;
+ ctx.drawImage(canvas, 0, 0, scaledCanvas.width, scaledCanvas.height);
+ scaledCanvas.style.width = canvas.width + "px";
+ scaledCanvas.style.height = canvas.height + "px";
+ return scaledCanvas;
+ }
+
+ function error(message) {
+ alert("Error: " + message);
+ document.body.removeChild(divOverlay);
+ }
+
+ function dismiss(evt) {
+ evt.preventDefault();
+ document.body.removeChild(divOverlay);
+ }
+
+ divOverlay = createDiv({"position": "fixed", "left": "0px", "top": "0px", "width": "100%", "height": "100%", "background-color": "rgba(0, 0, 0, 0.8)", "overflow": "scroll", "z-index": (findHighestZIndex() + 1).toString(10), "opacity": "0"});
+ divCanvasContainer = createDiv({"background-color": "black", "box-shadow": "0 8px 32px rgb(0, 0, 0)", "margin": "8px auto", "padding": "16px", "border": "2px solid white", "border-radius": "8px", "top": "100%"});
+
+ divOverlay.appendChild(divCanvasContainer);
+ document.body.appendChild(divOverlay);
+
+ transitionCSS(divOverlay, "opacity", "0.2s", "ease-out", {"opacity": "1.0"});
+
setTimeout(function () {
- callback(ansimation.canvas, ansimation.sauce);
- }, 250);
- return {
- "play": function (baud, callback, clearScreen) {
- ansimation.play(baud, callback, clearScreen);
- },
- "stop": function () {
- ansimation.stop();
- },
- "load": function (url, callback, callbackFail) {
- httpGet(url, function (bytes) {
- ansimation.load(bytes, callback);
- }, callbackFail);
+ var controller;
+ if (baud > 0) {
+ controller = animate(url, function (canvas) {
+ divCanvasContainer.style.width = canvas.width + "px";
+ divCanvasContainer.appendChild(processCanvas(canvas));
+ slideUpContainer();
+ setTimeout(function () {
+ controller.play(baud);
+ }, 750);
+ divOverlay.onclick = dismiss;
+ }, options, error);
+ } else {
+ splitRender(url, function (canvases) {
+ divCanvasContainer.style.width = canvases[0].width + "px";
+ canvases.forEach(function (canvas) {
+ if (retina && browser === CHROME) {
+ canvas = doubleScale(canvas);
+ }
+ divCanvasContainer.appendChild(processCanvas(canvas));
+ });
+ slideUpContainer();
+ divOverlay.onclick = dismiss;
+ }, 100, options, error);
}
- };
- },
+ }, 250);
+ }
+
+ return {
+ "show": show
+ };
+ }());
+
+ function popup(url, options) {
+ Popup.show(url, 0, options || {});
+ }
+
+ function popupAnimation(url, baud, options) {
+ Popup.show(url, baud || 14400, options || {});
+ }
+
+ return {
+ "render": render,
+ "splitRender": splitRender,
+ "renderBytes": renderBytes,
+ "splitRenderBytes": splitRenderBytes,
+ "animate": animate,
+ "animateBytes": animateBytes,
+ "popup": popup,
+ "popupAnimation": popupAnimation,
"displayDataToCanvas": displayDataToCanvas,
"sauce": sauce
};