Mercurial > tiny-letterpress
view index.html @ 11:838be764306f
you can now drag a letter from the palette instead of having to click on it, when not using iphone/ipad.
author | Atul Varma <avarma@mozilla.com> |
---|---|
date | Sun, 02 May 2010 19:26:42 -0700 |
parents | 2a2592d97e56 |
children | 7f3585a8c8a3 |
line wrap: on
line source
<html> <head> <style type="text/css"> body { font-family: Palatino; margin: 0; } div.letter { -webkit-transition-property: -webkit-transform, color; -webkit-transition-duration: 0.1s, 0.2s; -webkit-transition-timing-function: linear; position: absolute; cursor: pointer; font-size: 144pt; } div.letter .info { font-family: Futura, Helvetica; white-space: pre; font-size: 9pt; } div.letter.active { color: red; } div.palette { float: right; width: 1em; overflow: hidden; font-size: 144pt; } div.palette-container { -webkit-transition-property: -webkit-transform; -webkit-transition-duration: 0.5s; -webkit-transition-timing-function: ease-out; -webkit-backface-visibility: hidden; } .letter-prototype { cursor: pointer; color: gray; padding: 1px; border-bottom: 1px solid gray; } </style> </head> <body> <div id="letters" class="palette"> <div class="palette-container"> </div> </div> <script> if (typeof Array.isArray !== 'function') { Array.isArray = function (value) { return Object.prototype.toString.call(value) === '[object Array]'; }; } function $(selector) { return new $.fn.init(selector); } $.fn = $.prototype = { _qsa: function qsa(selector, element) { if (element === undefined) element = document; var nodeList = element.querySelectorAll(selector); var array = []; for (var i = 0; i < nodeList.length; i++) { array.push(nodeList[i]); } return array; }, length: 0, init: function init(selector) { if (typeof(selector) == "string") { this.elems = this._qsa(selector); } else { if (Array.isArray(selector)) { this.elems = selector; } else this.elems = [selector]; } this.length = this.elems.length; }, get: function(i) { if (i !== undefined) return this.elems[i]; return this.elems; }, bind: function(name, handler) { this.elems.forEach(function(elem) { elem.addEventListener(name, handler, false); }); }, css: function(options) { this.elems.forEach(function(elem) { for (name in options) elem.style.setProperty(name, options[name], null); }); }, removeClass: function(name) { this.elems.forEach(function(elem) { var classes = elem.className.split(" "); var index = classes.indexOf(name); if (index != -1) { classes.splice(index, 1); elem.className = classes.join(" "); } }); }, addClass: function(name) { this.elems.forEach(function(elem) { var classes = elem.className.split(" "); var index = classes.indexOf(name); if (index == -1) { classes.push(name); elem.className = classes.join(" "); } }); }, toggleClass: function(name) { this.elems.forEach(function(elem) { var classes = elem.className.split(" "); var index = classes.indexOf(name); if (index == -1) classes.push(name); else classes.splice(index, 1); elem.className = classes.join(" "); }); }, text: function(text) { if (text === undefined) return this.elems[0].textContent; this.elems.forEach(function(elem) { elem.textContent = text; }); }, find: function(selector) { var self = this; var array = []; this.elems.forEach(function(elem) { array = array.concat(self._qsa(selector, elem)); }); return new this.init(array); }, each: function(cb) { this.elems.forEach(function(elem) { cb.call(elem); }); } }; $.fn.init.prototype = $.fn; function makeDraggable(node, matrix) { var startX = 0; var startY = 0; var currX = 0; var currY = 0; function updateInfo() { var msg = ""; if (isMouseDown) msg = "x: " + matrix.e + "\ny: " + matrix.f; $(node).find(".info").text(msg); } function move() { matrix = matrix.translate(currX - startX, currY - startY); node.style.webkitTransform = matrix; } updateInfo(); if (!isTouchSupported) { var isMouseDown; function onMouseDown(event) { event.preventDefault(); startX = event.clientX; startY = event.clientY; isMouseDown = true; $(node).addClass("active"); updateInfo(); } onMouseDown(event); $(node).bind("mousedown", onMouseDown); $(node.ownerDocument).bind("mousemove", function(event) { if (isMouseDown) { currX = event.clientX; currY = event.clientY; move(this); startX = currX; startY = currY; updateInfo(); } }); $(node.ownerDocument).bind("mouseup", function(event) { if (isMouseDown) { event.preventDefault(); isMouseDown = false; $(node).removeClass("active"); updateInfo(); } }); } else { $(node).bind("touchstart", function(event) { event.preventDefault(); startX = event.targetTouches[0].pageX; startY = event.targetTouches[0].pageY; updateInfo(); $(this).addClass("active"); }); $(node).bind("touchmove", function(event) { event.preventDefault(); currX = event.targetTouches[0].pageX; currY = event.targetTouches[0].pageY; move(this); startX = currX; startY = currY; updateInfo(); }); $(node).bind("touchend", function(event) { event.preventDefault(); $(this).removeClass("active"); }); $(node).bind("touchcancel", function(event) { event.preventDefault(); $(this).removeClass("active"); }); } } function makeScrollable() { var node = this; var startY = 0; var floatScrollTop = 0; var touchMoved = false; var matrix = new WebKitCSSMatrix(); var maxHeight = node.parentNode.scrollHeight - node.parentNode.clientHeight; function accelerate(delta) { matrix = matrix.translate(0, delta); if (matrix.f > 0) matrix.f = 0; else if (matrix.f < -maxHeight) matrix.f = -maxHeight; node.style.webkitTransform = matrix; } if (!isTouchSupported) { $(node).bind("mousewheel", function(event) { accelerate(event.wheelDelta); }); $(node).find(".letter-prototype").bind("mousedown", makeLetter); } else { $(node).bind("touchstart", function(event) { event.preventDefault(); startY = event.targetTouches[0].pageY; touchMoved = false; }); $(node).bind("touchmove", function(event) { event.preventDefault(); var currY = event.targetTouches[0].pageY; accelerate((currY - startY) * 2); startY = currY; touchMoved = true; }); $(node).bind("touchend", function(event) { event.preventDefault(); if (!touchMoved) { var target = event.changedTouches[0].target; if (target.nodeType == target.TEXT_NODE) target = target.parentNode; makeLetter.call(target); } }); } } function makeLetter(event) { if (event) event.preventDefault(); var node = this; var doc = this.ownerDocument; var letter = doc.createElement("div"); var char = doc.createTextNode(this.textContent); var info = doc.createElement("div"); letter.className = "letter"; info.className = "info"; letter.appendChild(char); letter.appendChild(info); // TODO: This assumes things about the DOM structure that // we don't want to have to assume. var parentMatrix = new WebKitCSSMatrix(); var matrix = new WebKitCSSMatrix(); parentMatrix.setMatrixValue(this.parentNode.style.webkitTransform); matrix = matrix.translate( this.offsetLeft, this.offsetTop + parentMatrix.f ); letter.style.webkitTransform = matrix; doc.body.appendChild(letter); // Apply a new transform to make the letter animate. if (isTouchSupported) { matrix = matrix.translate(-this.offsetWidth, 0); letter.style.webkitTransform = matrix; } makeDraggable(letter, matrix); } function addLetters() { var node = this; const ALPHABET = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; for (var i = 0; i < ALPHABET.length; i++) { var div = document.createElement("div"); div.textContent = ALPHABET[i]; div.className = "letter-prototype"; node.appendChild(div); } } var isTouchSupported = (function isTouchSupported() { try { document.createEvent("TouchEvent"); return true; } catch (e) { if (e.code != e.NOT_SUPPORTED_ERR) throw e; return false; } })(); $(window).bind("DOMContentLoaded", function() { $("#letters .palette-container").each(addLetters); $("#letters").css({"max-height": document.body.clientHeight}); $(".palette-container").each(makeScrollable); }); </script> </body> </html>