Mercurial > tiny-letterpress
view index.html @ 5:d2f7b69ac319
animation for letter sliding out of palette on spawn
author | Atul Varma <avarma@mozilla.com> |
---|---|
date | Sun, 02 May 2010 15:21:48 -0700 |
parents | 9c7ae0ae7240 |
children | efb34c9b7c18 |
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; max-height: 1em; overflow: hidden; font-size: 144pt; } .letter-prototype { cursor: pointer; color: gray; padding: 1px; border-bottom: 1px solid gray; } </style> </head> <body> <div id="letters" class="palette"></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 = false; $(node).bind("mousedown", function(event) { event.preventDefault(); startX = event.clientX; startY = event.clientY; isMouseDown = true; $(node).addClass("active"); updateInfo(); }); $(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"); }); } } function makeScrollable() { var node = this; var startY = 0; var currY = 0; var floatScrollTop = 0; var timerID; var veloc = 0; var maxHeight = node.scrollHeight - node.clientHeight; function timer() { floatScrollTop += (veloc * 0.05); if (floatScrollTop < 0) floatScrollTop = 0; else if (floatScrollTop > maxHeight) floatScrollTop = maxHeight; node.scrollTop = Math.floor(floatScrollTop); veloc = 0.95 * veloc; if (Math.abs(veloc) < 1) { veloc = 0; clearInterval(timerID); timerID = undefined; } } function accelerate(amount) { veloc += amount; if (timerID === undefined) timerID = setInterval(timer, 10); } if (!isTouchSupported) { $(node).bind("mousewheel", function(event) { accelerate(-event.wheelDelta); }); } else { $(node).bind("touchstart", function(event) { event.preventDefault(); startY = event.targetTouches[0].pageY; }); $(node).bind("touchmove", function(event) { event.preventDefault(); currY = event.targetTouches[0].pageY; accelerate(startY - currY); startY = currY; }); } } function makeLetter() { 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); var matrix = new WebKitCSSMatrix(); console.log(this.offsetLeft + " " + this.offsetTop); // TODO: This assumes things about the DOM structure that // we don't want to have to assume. matrix = matrix.translate( this.offsetLeft, this.offsetTop - this.parentNode.scrollTop ); letter.style.webkitTransform = matrix; doc.body.appendChild(letter); // Apply a new transform to make the letter animate. 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); $(div).bind("click", makeLetter); } } 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").each(addLetters); $("#letters").css({"max-height": document.body.clientHeight}); $(".palette").each(makeScrollable); }); </script> </body> </html>