+Copyright (c) 2011, The Dominion of Awesome
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/* Copyright 2011 The Dominion of Awesome
+ * See COPYING for licensing information */
+enyo.kind({
+ name: "HacksSelector",
+ kind: "Control",
+ nodeTag: "canvas",
+ className: "hacks-selector",
+ style: "opacity: 0",
+ width: "748px",
+ height: "192px",
+ index: 0,
+ published: {
+ hacksList: null
+ },
+ hacksThumbs: {},
+ rendered: function() {
+ this.inherited(arguments);
+ var node = this.hasNode();
+ node.width = 748;
+ node.height = 192;
+ this.ctx = node.getContext('2d');
+ this.ctx.fillStyle = 'white';
+ this.fadeGradient = this.ctx.createLinearGradient(0, 0, 0, 128);
+ this.fadeGradient.addColorStop(0.6, 'rgba(0,0,0,0)');
+ this.fadeGradient.addColorStop(1.0, 'rgba(255,255,255,0.5)');
+ },
+ setHacksList: function(newHacksList) {
+ this.hacksList = newHacksList;
+ for (var i = 0; i < this.hacksList.length; i++) {
+ if (this.hacksThumbs[this.hacksList[i]])
+ continue;
+ var img = new Image();
+ img.src = "hacks/" + this.hacksList[i] + "/thumbnail.png";
+ img.onload = this.draw.bind(this);
+ this.hacksThumbs[this.hacksList[i]] = img;
+ }
+ },
+ show: function() {
+ if (this.hideTimer)
+ clearTimeout(this.hideTimer);
+ this.hideTimer = setTimeout(function() {
+ this.setStyle('opacity: 0; -webkit-transition: opacity 0.5s linear');
+ }.bind(this), 1500);
+ this.setStyle('opacity: 1.0; -webkit-transition: opacity 0.25s linear');
+ },
+ draw: function() {
+ this.ctx.clearRect(0, 0, 750, 256);
+ if (!this.hacksList) return;
+ for (var i = -2; i <= 3; i++) {
+ var frac = this.index - Math.floor(this.index);
+ var x = 311 + (i - frac) * 146;
+ var j = Math.floor(this.index) + i;
+ if (j < 0 || j > this.hacksList.length - 1)
+ continue;
+ var h = this.hacksList[j];
+
+ this.ctx.save();
+ this.ctx.translate(x, 0);
+ this.ctx.drawImage(this.hacksThumbs[h], 0, 0);
+ this.ctx.scale(1, -1);
+ this.ctx.translate(0, -256);
+ this.ctx.beginPath();
+ this.ctx.fillStyle = this.fadeGradient;
+ this.ctx.rect(0, 0, 128, 128);
+ this.ctx.fill();
+ this.ctx.globalCompositeOperation = 'source-in';
+ this.ctx.drawImage(this.hacksThumbs[h], 0, 0);
+ this.ctx.restore();
+
+ this.ctx.save();
+ this.ctx.shadowColor = 'white';
+ this.ctx.shadowBlur = '3';
+ this.ctx.beginPath();
+ this.ctx.arc(374, 160, 5, 0, Math.PI * 2);
+ this.ctx.fill();
+ this.ctx.restore();
+ }
+ }
+});
+/* Copyright 2011 The Dominion of Awesome
+ * See COPYING for licensing information */
+@font-face {
+ font-family: PCSenior;
+ src: url(fonts/pcsenior.ttf);
+}
+
+.hacks-selector {
+ position: absolute;
+ bottom: 64px;
+ margin-left: -374px;
+ left: 50%;
+}
+
+.info {
+ position: absolute;
+ left: 0;
+ bottom: 0;
+ width: 100%;
+ padding: 24px;
+ font-size: 24px;
+ -webkit-transition-property: opacity;
+ -webkit-transition-duration: 0.6s;
+ color: #303030;
+}
+
+.info.dark {
+ color: #AFAFAf;
+}
+/* Copyright 2011 The Dominion of Awesome
+ * See COPYING for licensing information */
+enyo.kind({
+ name: "Main",
+ kind: "VFlexBox",
+ style: "background-color: black",
+ components: [
+ {kind: "ApplicationEvents", onWindowActivated: "windowActivated", onWindowDeactivated: "windowDeactivated"},
+ {name: "hacksCarousel", kind: "Carousel", flex: 1, onGetLeft: "getLeft", onGetRight: "getRight", onScroll: "scrolling", onScrollStart: "startScroll", onScrollStop: "stopScroll"},
+ //{name: "hacksSelector", kind: "HacksSelector"}
+ {name: "info", kind: "HFlexBox", className: "info", style: "opacity: 0", showing: false, components: [
+ {name: "title"},
+ {kind: "Spacer"},
+ {name: "notice", className: "notice"}
+ ]}
+ ],
+ hacksList: [
+ {name: "Nimbus", kind: "Nimbus", dark: false},
+ {name: "Landscape", kind: "Landscape", dark: false},
+ {name: "Munch", kind: "Munch", dark: true},
+ {name: "Orbit", kind: "Orbit", dark: false},
+ {name: "Pixelfade", kind: "Pixelfade", dark: true},
+ //{name: "Swarm", kind: "Swarm", dark: false}, // crashy
+ //{name: "Spinner.CGA", kind: "XSpinnerCGA", dark: true}, // no webfont support
+ {name: "Spinner", kind: "XSpinner", dark: true}
+ ],
+ create: function() {
+ this.inherited(arguments);
+ /*
+ this.index = localStorage.getItem('hack.index');
+ if (!this.index)
+ this.index = 0;
+ */
+ this.index = 0;
+ this.lastScrollPos = 0;
+ this.$.hacksCarousel.setCenterView(this.getHack(this.index));
+ //this.$.hacksSelector.setHacksList(this.hacksList);
+ },
+ ready: function() {
+ this.startHack();
+ window.addEventListener('resize', this.resizeHack.bind(this), false);
+ this.setNotice('Swipe for more...');
+ this.setTitle(this.hacksList[this.index].name);
+ },
+ setTitle: function(title) {
+ this.$.title.setContent(title);
+ this.infoFade();
+ },
+ setNotice: function(notice) {
+ this.$.notice.setContent(notice);
+ this.infoFade();
+ },
+ infoFade: function() {
+ this.$.info.setStyle('opacity: 1');
+ this.$.info.show();
+
+ clearTimeout(this.noticeTimer);
+ this.noticeTimer = setTimeout(function() {
+ this.$.info.setStyle('opacity: 0');
+ setTimeout(function() {
+ this.$.info.hide();
+ this.setNotice('');
+ this.setTitle('');
+ }.bind(this), 600);
+ }.bind(this), 5000);
+ },
+ windowActivated: function() {
+ this.startHack();
+ },
+ windowDeactivated: function() {
+ this.stopHack();
+ },
+ startHack: function(direction) {
+ var view = this.$.hacksCarousel.fetchView(direction || 'center');
+ //enyo.log('starting view ' + view);
+ if (view)
+ view.start();
+ //localStorage.setItem('hack.index', this.index);
+ },
+ stopHack: function(direction) {
+ var view = this.$.hacksCarousel.fetchView(direction || 'center');
+ //enyo.log('stopping view ' + view);
+ if (view)
+ view.stop();
+ },
+ resizeHack: function() {
+ var view = this.$.hacksCarousel.fetchView('center');
+
+ //enyo.log('resizing view ' + view);
+ if (view)
+ view.resize(window.innerWidth, window.innerHeight);
+ },
+ hackHidden: function(direction) {
+ var view = this.$.hacksCarousel.fetchView(direction);
+ //enyo.log('view ' + view + ' hidden');
+ if (view)
+ view.hidden();
+ },
+ getHack: function(index) {
+ return {kind: this.hacksList[index].kind};
+ },
+ getLeft: function(inSender, inSnap) {
+ if (inSnap && this.index > 0) {
+ this.index--;
+ this.hackHidden('right');
+ this.setTitle(this.hacksList[this.index].name);
+ this.$.info.addRemoveClass('dark', this.hacksList[this.index].dark);
+ }
+ if (this.index == 0)
+ return null;
+ else
+ return this.getHack(this.index - 1);
+ },
+ getRight: function(inSender, inSnap) {
+ if (inSnap && this.index < this.hacksList.length) {
+ this.index++;
+ this.hackHidden('left');
+ this.setTitle(this.hacksList[this.index].name);
+ this.$.info.addRemoveClass('dark', this.hacksList[this.index].dark);
+ }
+ if (this.index == this.hacksList.length - 1)
+ return null;
+ else
+ return this.getHack(this.index + 1);
+ },
+ scrolling: function(inSender) {
+ if (inSender.scrollLeft == 0 || inSender.scrollLeft == inSender.getBoundaries().right)
+ this.startHack();
+ //this.$.hacksSelector.index = this.index + ((inSender.scrollLeft - this.lastScrollPos) / window.innerWidth);
+ //this.$.hacksSelector.draw();
+ },
+ startScroll: function(inSender) {
+ this.stopHack();
+ },
+ stopScroll: function(inSender) {
+ this.lastScrollPos = this.$.hacksCarousel.scrollLeft;
+ this.startHack();
+ }
+});
+{
+ "id": "com.dominionofawesome.hacks",
+ "version": "1.0.0",
+ "vendor": "The Dominion of Awesome",
+ "type": "web",
+ "main": "index.html",
+ "title": "Hacks!",
+ "icon": "icon.png",
+ "uiRevision": 2,
+ "dockMode": true
+}
+enyo.depends(
+ "Main.js",
+ "Main.css",
+ //"HacksSelector.js",
+ "hacks/Hack.js",
+ "hacks/Nimbus/Nimbus.js",
+ "hacks/Landscape/Landscape.js",
+ "hacks/Munch/Munch.js",
+ "hacks/Orbit/Orbit.js",
+ "hacks/Pixelfade/Pixelfade.js",
+ //"hacks/Swarm/Swarm.js",
+ //"hacks/XSpinnerCGA/XSpinnerCGA.js",
+ "hacks/XSpinner/XSpinner.js"
+);
+/* Copyright 2011 The Dominion of Awesome
+ * See COPYING for licensing information */
+enyo.kind({
+ name: "Hack",
+ kind: "VFlexBox",
+ stop: function() {
+ },
+ start: function() {
+ },
+ resize: function() {
+ },
+ hidden: function() {
+ }
+});
+/* Copyright 2011 The Dominion of Awesome
+ * See COPYING for licensing information */
+enyo.kind({
+ name: "Landscape",
+ kind: "Hack",
+ style: "background-color: #2ab40f",
+ components: [
+ {name: "clouds", style: "height: 200px; background-image: url(hacks/landscape/clouds.png)"},
+ {name: "mountains", style: "height: 200px; background-image: url(hacks/landscape/mountains.png)"},
+ {name: "trees", style: "height: 200px; background-image: url(hacks/landscape/trees.png)"}
+ ],
+ create: function() {
+ this.inherited(arguments);
+ this.n = 0;
+ },
+ start: function() {
+ if (!this.timer)
+ this.timer = setInterval(this.draw.bind(this), 33);
+ },
+ stop: function() {
+ clearInterval(this.timer);
+ this.timer = null;
+ },
+ draw: function() {
+ this.n--;
+ if (this.n == -1600)
+ this.n = 0;
+
+ this.$.clouds.applyStyle("background-position", (this.n * 1.5) + "px top");
+ this.$.mountains.applyStyle("background-position", (this.n * 2.5) + "px top");
+ this.$.trees.applyStyle("background-position", (this.n * 7.5) + "px top");
+ }
+});
+/* Copyright 2011 The Dominion of Awesome
+ * See COPYING for licensing information */
+enyo.kind({
+ name: 'Munch',
+ kind: 'Hack',
+ pack: "center",
+ align: "center",
+ style: "background-color: black",
+ components: [
+ {kind: enyo.Control, nodeTag: "canvas", name: "display", width: "512px", height: "512px"}
+ ],
+
+ t: 0,
+ timer: null,
+
+ rendered: function() {
+ var node = this.$.display.hasNode();
+ node.width = 256;
+ node.height = 256;
+ this.ctx = node.getContext('2d');
+ this.ctx.fillStyle = 'black';
+ this.ctx.fillRect(0, 0, 255, 255);
+ this.ctx.fillStyle = 'rgba(0,0,0,0.075)';
+ this.ctx.strokeStyle = '#00FF00';
+ this.draw();
+ },
+
+ draw: function() {
+ this.ctx.fillRect(0, 0, 256, 256);
+ this.ctx.beginPath();
+ for (var x = 0; x < 256; x++) {
+ var y = x ^ this.t;
+ this.ctx.moveTo(x, y);
+ this.ctx.lineTo(x+1, y+1);
+ }
+ this.ctx.stroke();
+ this.t = (this.t + 1) % 255;
+ },
+
+ start: function() {
+ if (this.timer) return;
+ this.timer = setInterval(this.draw.bind(this), 20);
+ },
+
+ stop: function() {
+ clearInterval(this.timer);
+ this.timer = null;
+ }
+});
+/* Copyright 2011 The Dominion of Awesome
+ * See COPYING for licensing information */
+enyo.kind({
+ name: "Drop",
+ constructor: function() {
+ this.live = false;
+ },
+ start: function(w, h, perspective) {
+ this.x = Math.random() * w;
+ this.y = (Math.random() * h) / perspective;
+ this.t = (new Date()).getTime();
+ this.live = true;
+ },
+ draw: function(ctx, t) {
+ var dt = t - this.t;
+ if (dt < 100) {
+ ctx.save();
+ ctx.globalAlpha = 0.25;
+ ctx.beginPath();
+ ctx.moveTo(this.x, 0);
+ ctx.lineTo(this.x, this.y);
+ ctx.stroke();
+ ctx.restore();
+ } else if (dt < 750) {
+ ctx.save();
+ ctx.globalAlpha = (1.0 - ((dt - 500) / 250));
+ ctx.beginPath();
+ ctx.arc(this.x, this.y, Math.sqrt(dt) * 5, 0, 2 * Math.PI, false);
+ ctx.stroke();
+ ctx.restore();
+ } else {
+ this.live = false;
+ }
+ }
+});
+
+enyo.kind({
+ name: "Nimbus",
+ kind: "Hack",
+ style: "background-color: white",
+ drop_c: 0,
+ drops: [],
+ perspective: 0.3,
+ components: [
+ {name: "raindrops", nodeTag: "canvas"}
+ ],
+ rendered: function() {
+ this.raindrops = this.$.raindrops.hasNode();
+ this.ctx = this.raindrops.getContext('2d');
+ this.resize(window.innerWidth, window.innerHeight);
+
+ for (var i = 0; i < 100; i++)
+ this.drops.push(new Drop());
+ },
+ start: function() {
+ if (!this.timer)
+ this.timer = setInterval(this.draw.bind(this), 50);
+ },
+ stop: function() {
+ clearInterval(this.timer);
+ this.timer = null;
+ },
+ resize: function(w, h) {
+ this.raindrops.width = this.w = w;
+ this.raindrops.height = this.h = h;
+
+ this.ctx.fillStyle = 'rgba(255,255,255,0.7)';
+ this.ctx.strokeStyle = 'rgb(128,128,128)';
+ this.ctx.lineWidth = '2';
+ },
+ draw: function() {
+ if (Math.random() > 0.3) {
+ this.drops[this.drop_c].start(this.w, this.h, this.perspective);
+ this.drop_c = (this.drop_c + 1) % 100;
+ }
+ var now = (new Date()).getTime();
+ this.ctx.fillRect(0, 0, this.w, this.h);
+ this.ctx.save();
+ this.ctx.scale(1.0, this.perspective);
+ for (var i = 0; i < this.drops.length; i++)
+ if (this.drops[i].live)
+ this.drops[i].draw(this.ctx, now);
+ this.ctx.restore();
+ }
+});
+/* Copyright 2011 The Dominion of Awesome
+ * See COPYING for licensing information */
+enyo.kind({
+ name: "Orbit",
+ kind: "Hack",
+ pack: "center",
+ align: "center",
+ style: "background-color: lightgray",
+ components: [
+ {kind: "Control", nodeTag: "canvas", name: "canvas", width: "250px", height: "250px"}
+ ],
+ rendered: function() {
+ var canvas = this.$.canvas.hasNode();
+ canvas.width = 250;
+ canvas.height = 250;
+ this.context = canvas.getContext('2d');
+
+ this.center_x = canvas.width / 2;
+ this.center_y = canvas.height / 2;
+ this.radius = 100;
+ this.zr = 0;
+ this.xr = 0;
+
+ this.chromeball = new Image();
+ this.chromeball.onload = this.setReady.bind(this);
+ this.chromeball.src = "hacks/orbit/chrome_ball.png";
+ },
+ setReady: function() {
+ this.ready = true;
+ this.engine();
+ },
+ start: function() {
+ if (this.ready && !this.timer)
+ this.timer = setInterval(this.engine.bind(this), 20);
+ },
+ stop: function() {
+ clearInterval(this.timer);
+ this.timer = null;
+ },
+ engine: function() {
+ this.context.clearRect(this.center_x - this.radius - 25, this.center_y - this.radius - 25, this.radius * 2 + 50, this.radius * 2 + 50);
+ this.zr += 0.1;
+ this.xr += 0.05;
+ var objects = [];
+ for (var i = 0; i < 8; i++) {
+ var czr = this.zr + i * Math.PI/4;
+ var cxr = this.xr + Math.PI + i * Math.PI/4;
+ var cx = this.center_x + this.radius * Math.sin(czr);
+ var cy = this.center_y + this.radius * Math.cos(czr) * Math.cos(this.xr);
+ var r = 20 + 10 * Math.cos(czr) * Math.cos(this.xr + Math.PI/2);
+
+ objects.push({
+ x: cx - r,
+ y: cy - r,
+ s: r * 2
+ });
+ }
+ // Sort by size to simulate z-ordering
+ objects.sort(function(a,b) {
+ return a.s - b.s;
+ });
+ for (var i = 0; i < 8; i++)
+ this.context.drawImage(this.chromeball, objects[i].x, objects[i].y, objects[i].s, objects[i].s);
+ }
+});
+/* Copyright 2011 The Dominion of Awesome
+ * See COPYING for licensing information */
+enyo.kind({
+ name: "Pixelfade",
+ kind: "Hack",
+ style: "background-color: yellow; background-position: center center",
+ components: [
+ {name: "canvas", nodeTag: "canvas", onclick: "canvasClick"},
+ {name: "wallpaperService", kind: "PalmService",
+ service: 'palm://com.palm.systemservice',
+ method: 'getPreferences',
+ onSuccess: "gotWallpaper"}
+ ],
+ create: function() {
+ this.inherited(arguments);
+ this.$.wallpaperService.call({
+ keys: ['wallpaper'],
+ subscribe: false
+ });
+ },
+ rendered: function() {
+ this.canvas = this.$.canvas.hasNode();
+ this.context = this.canvas.getContext('2d');
+ this.resize(window.innerWidth, window.innerHeight);
+ this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);
+
+ this.faders = [];
+ for (var i = 0; i < 10; i++) {
+ var img = new Image();
+ img.src = "hacks/Pixelfade/pixelfade" + i + ".gif";
+ this.faders.push(img);
+ }
+ },
+ start: function() {
+ this.resize(window.innerWidth, window.innerHeight);
+
+ if (this.timer)
+ clearInterval(this.timer);
+ this.fade_val = 9;
+ this.fade_dir = -1;
+ this.fade_end = -1;
+ this.timer = setInterval(this.fade_all.bind(this), 50);
+
+ if (!this.spotTimer)
+ this.spotTimer = setInterval(this.do_fade_spot.bind(this), 3000);
+ },
+ stop: function() {
+ clearInterval(this.timer);
+ this.timer = null;
+ clearInterval(this.spotTimer);
+ this.spotTimer = null;
+ clearTimeout(this.fadeInTimer);
+ this.fadeInTimer = null;
+ },
+ resize: function(w, h) {
+ this.canvas.style.width = w + 'px';
+ this.canvas.style.height = h + 'px';
+ this.canvas.width = w;
+ this.canvas.height = h;
+ this.context.fillColor = 'black';
+ this.context.fillRect(0, 0, w, h);
+ },
+ hidden: function() {
+ this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);
+ },
+ canvasClick: function(inSender, inEvent) {
+ clearTimeout(this.fadeInTimer);
+ clearInterval(this.spotTimer);
+ this.spotTimer = setInterval(this.do_fade_spot.bind(this), 3000);
+ this.fader_go(inEvent.clientX, inEvent.clientY);
+ },
+ gotWallpaper: function(inSender, inResponse) {
+ enyo.log("got background: " + JSON.stringify(inResponse));
+ this.setStyle('background-image: url(' + inResponse.wallpaper.wallpaperFile + '); background-alignment: center center');
+ },
+ do_fade_spot: function() {
+ var x = Math.floor(Math.random() * this.canvas.width);
+ var y = Math.floor(Math.random() * this.canvas.height);
+ this.fader_go(x, y);
+ },
+ fade_all: function() {
+ this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
+ if (this.fade_val == this.fade_end) {
+ clearInterval(this.timer);
+ this.timer = null;
+ if (this.fade_dir == -1)
+ this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
+ else
+ this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);
+ } else {
+ for (var x = 0; x < this.canvas.width; x += 64) {
+ for (var y = 0; y < this.canvas.height; y += 64) {
+ this.context.drawImage(this.faders[this.fade_val], x, y);
+ }
+ }
+ }
+ this.fade_val += this.fade_dir;
+ },
+ fader_go: function(x, y) {
+ this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
+ this.fader_count = 0;
+ this.time_faders(x, y);
+ this.faderptr = new Array(10);
+ for (var i=0; i < 10; i++)
+ this.faderptr[i] = 0;
+ this.t0 = (new Date()).getTime();
+ this.faderRunning = true;
+ clearInterval(this.timer);
+ this.timer = setInterval(this.fader.bind(this), 50);
+ },
+ time_faders: function(xpos, ypos) {
+ this.fadertimes = [];
+ for (var y = 0; y < this.canvas.height; y += 64) {
+ for (var x = 0; x < this.canvas.width; x += 64) {
+ var xd = x - xpos;
+ var yd = y - ypos;
+ this.fadertimes.push({
+ t: 125 - Math.sqrt(xd*xd + yd*yd) / 8,
+ x: x,
+ y: y
+ });
+ }
+ }
+ this.fadertimes.sort(function(a, b) { return a.t - b.t });
+ },
+ fader: function() {
+ var tnow = (new Date()).getTime();
+ var td = (tnow - this.t0) / 8.0;
+ for (var i = 0; i < 10; i++) {
+ while (this.faderptr[i] < this.fadertimes.length && this.fadertimes[this.faderptr[i]].t < td - i * 10) {
+ var xpos = this.fadertimes[this.faderptr[i]].x;
+ var ypos = this.fadertimes[this.faderptr[i]].y;
+ this.context.clearRect(xpos, ypos, 64, 64);
+ this.context.drawImage(this.faders[i], xpos, ypos);
+ this.faderptr[i]++;
+ }
+ }
+ if (this.faderptr[9] >= this.fadertimes.length) {
+ clearTimeout(this.timer);
+ this.fadeInTimer = setTimeout(function() {
+ this.fade_val = 9;
+ this.fade_dir = -1;
+ this.fade_end = -1;
+ this.timer = setInterval(this.fade_all.bind(this), 50);
+ }.bind(this), 750);
+ }
+ }
+});
+/* Copyright 2011 The Dominion of Awesome
+ * See COPYING for licensing information */
+enyo.kind({
+ name: "Pixel",
+ constructor: function(canvas) {
+ this.x = Math.random() * canvas.width;
+ this.y = Math.random() * canvas.height;
+ this.vx = Math.random() * 20.0 - 10.0;
+ this.vy = Math.random() * 20.0 - 10.0;
+ this.lastupdate = (new Date()).getTime();
+ },
+ accel: function(x, y) {
+ this.vx += x;
+ if (this.vx > 200.0)
+ this.vx = 200.0;
+ else if (this.vx < -200.0)
+ this.vx = -200.0;
+ this.vy += y;
+ if (this.vy > 200.0)
+ this.vy = 200.0;
+ else if (this.vy < -200.0)
+ this.vy = -200.0;
+ },
+ update: function() {
+ var now = (new Date()).getTime();
+ var dt = (now - this.lastupdate) / 75.0;
+ this.x += this.vx * dt;
+ this.y += this.vy * dt;
+ this.lastupdate = now;
+ },
+ draw: function(ctx) {
+ ctx.beginPath();
+ ctx.moveTo(this.x,this.y);
+ ctx.lineTo(this.x - this.vx / 4.0, this.y - this.vy / 4.0);
+ ctx.stroke();
+ ctx.closePath();
+ }
+});
+
+enyo.kind({
+ name: "Swarm",
+ kind: "Hack",
+ align: "stretch",
+ pack: "stretch",
+ components: [
+ {name: "canvas", nodeTag: "canvas", style: "background-color: gray",
+ onmousemove: "mouseMove", onmousedown: "mouseDown"}
+ ],
+ npixels: 100,
+ pixels: [],
+ rendered: function() {
+ this.canvas = this.$.canvas.hasNode();
+ this.resize();
+ this.mx = this.canvas.width / 2;
+ this.my = this.canvas.width / 2;
+ for (var x = 0; x < this.npixels; x++)
+ this.pixels.push(new Pixel(this.canvas));
+ //this.stopTime = (new Date()).getTime();
+ this.engine();
+ },
+ start: function() {
+ if (this.stopTime) {
+ var delta = (new Date()).getTime() - this.stopTime;
+ for (var i = 0; i < this.npixels; i++)
+ this.pixels[i].lastupdate += delta;
+ this.stopTime = null;
+ }
+ if (!this.timer)
+ this.timer = setInterval(this.engine.bind(this), 20);
+ },
+ stop: function() {
+ this.stopTime = (new Date()).getTime();
+ clearInterval(this.timer);
+ this.timer = null;
+ },
+ resize: function(w, h) {
+ this.canvas.width = w;
+ this.canvas.height = h;
+ //this.canvas.style.width = w + 'px';
+ //this.canvas.style.height = h + 'px';
+ this.context = this.canvas.getContext('2d');
+ this.context.strokeStyle = '#000000';
+ this.context.lineCap = 'round';
+ this.context.lineWidth = 1.5;
+ },
+ mouseMove: function(inSender, inEvent) {
+ this.mx = inEvent.clientX;
+ this.my = inEvent.clientY;
+ },
+ mouseDown: function(inSender, inEvent) {
+ this.mouseMove(inSender, inEvent);
+ // Apply force to each pixel outwards from the mouse
+ for (var i = 0; i < this.npixels; i++) {
+ // Get the direction
+ var dx = this.pixels[i].x - inEvent.clientX;
+ var dy = this.pixels[i].y - inEvent.clientY;
+ var mag = Math.sqrt(dx*dx + dy*dy);
+ dx /= mag;
+ dy /= mag;
+
+ // Apply force.
+ this.pixels[i].accel(dx * 40.0, dy * 40.0);
+ }
+ },
+ engine: function() {
+ // Clear the canvas
+ this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
+ // Update all pixel objects
+ for (var i = 0; i < this.npixels; i++) {
+ // Get distance
+ var dx = this.mx - this.pixels[i].x;
+ var dy = this.my - this.pixels[i].y;
+ var d = Math.sqrt(dx*dx + dy*dy);
+
+ // Apply acceleration to pixels towards the mouse cursor
+ var ax = dx / 50.0;
+ var ay = dy / 50.0;
+
+ // Apply a drag proportional to the distance from the cursor
+ if (d > 100.0) {
+ ax += -this.pixels[i].vx * (d - 100.0) / 2000.0;
+ ay += -this.pixels[i].vy * (d - 100.0) / 2000.0;
+ }
+
+ // And a "chaotic" acceleration inversely proportional
+ // to the distance from the cursor
+ ax += (Math.random() * 160.0 - 80.0) / d;
+ ay += (Math.random() * 160.0 - 80.0) / d;
+
+ this.pixels[i].accel(ax,ay);
+ this.pixels[i].update();
+ this.pixels[i].draw(this.context);
+ }
+
+ this.context.strokeRect(this.mx - 10, this.my - 10, 20, 20);
+ }
+});
+/* Copyright 2011 The Dominion of Awesome
+ * See COPYING for licensing information */
+enyo.kind({
+ name: "XSpinner",
+ kind: "Hack",
+ style: "background-color: black; color: #00FF00; font-family: Courier, sans-serif; font-size: 12px",
+ pack: "center",
+ align: "center",
+ components: [
+ {style: "border: 2px solid green; padding: 4px", components: [
+ {name: "terminal", nodeTag: "pre", style: "margin: 0"},
+ {nodeTag: "pre", style: "margin: 0",
+content: "SESSION 1 80x24 CAPS NUM SCR <span style=\"color: black; background-color: #00FF00\" id=\"spinner_blinker\">RAVE</blink>"}
+ ]}
+ ],
+ create: function() {
+ this.inherited(arguments);
+ this.w = 80;
+ this.h = 24;
+ this.delay = 20;
+ this.rate = 360.0 / 1000.0;
+ this.cw = this.w / 2;
+ this.ch = this.h / 2;
+ },
+ rendered: function() {
+ this.terminal = this.$.terminal.hasNode();
+ this.blinker = document.getElementById('spinner_blinker');
+ this.blink_active = true;
+ this.spinner();
+ },
+ start: function() {
+ if (!this.timer) {
+ this.timer = setInterval(this.spinner.bind(this), this.delay);
+ this.blinkerTimer = setInterval(this.blink.bind(this), 500);
+ }
+ },
+ stop: function() {
+ clearInterval(this.timer);
+ clearInterval(this.blinkerTimer);
+ this.timer = null;
+ this.blinkerTimer = null;
+ },
+ spinner: function() {
+ // Get date
+ var ms = (new Date()).getMilliseconds();
+ var r = ms * this.rate;
+ var a = Math.tan((r / 180.0) * Math.PI);
+ var b = Math.tan(((r+90) / 180.0) * Math.PI);
+
+ var t = '';
+ for (var j=0; j < this.h; j++) {
+ for (var i=0; i < this.w; i++) {
+ if ((r > 90 && r <= 180) || (r > 270 && r < 360) || r == 0) {
+ if ((j-this.ch) * 2 > a * (i-this.cw) && (j-this.ch) * 2 < b * (i-this.cw) ||
+ (j-this.ch) * 2 < a * (i-this.cw) && (j-this.ch) * 2 > b * (i-this.cw) ) {
+ t += '*';
+ } else {
+ t += ' ';
+ }
+ } else {
+ if ((j-this.ch) * 2 > a * (i-this.cw) && (j-this.ch) * 2 > b * (i-this.cw) ||
+ (j-this.ch) * 2 < a * (i-this.cw) && (j-this.ch) * 2 < b * (i-this.cw) ) {
+ t += '*';
+ } else {
+ t += ' ';
+ }
+ }
+ }
+ t += "\n";
+ }
+ this.terminal.innerHTML = t;
+ },
+ blink: function() {
+ if (this.blink_active)
+ this.blinker.style.color = '#00FF00';
+ else
+ this.blinker.style.color = 'black';
+ this.blink_active = !this.blink_active;
+ }
+});
+/* Copyright 2011 The Dominion of Awesome
+ * See COPYING for licensing information */
+enyo.kind({
+ name: "XSpinnerCGA",
+ kind: "Hack",
+ style: "background-color: black",
+ pack: "center",
+ align: "center",
+ components: [
+ {style: "border: 2px solid green; padding: 4px", components: [
+ {name: "terminal", nodeTag: "pre", style: "margin: 0; font-family: PCSenior; font-size: 16px"}
+ ]}
+ ],
+ create: function() {
+ this.inherited(arguments);
+ this.w = 40;
+ this.h = 24;
+ this.delay = 20;
+ this.rate = 360.0 / 1000.0;
+ this.cw = this.w / 2;
+ this.ch = this.h / 2;
+ },
+ rendered: function() {
+ this.terminal = this.$.terminal.hasNode();
+ this.blinker = document.getElementById('spinner_blinker');
+ this.blink_active = true;
+ this.spinner();
+ },
+ start: function() {
+ if (!this.timer) {
+ this.timer = setInterval(this.spinner.bind(this), this.delay);
+ this.blinkerTimer = setInterval(this.blink.bind(this), 500);
+ }
+ },
+ stop: function() {
+ clearInterval(this.timer);
+ clearInterval(this.blinkerTimer);
+ this.timer = null;
+ this.blinkerTimer = null;
+ },
+ spinner: function() {
+ // Get date
+ var ms = (new Date()).getMilliseconds();
+ var r = ms * this.rate;
+ var a = Math.tan((r / 180.0) * Math.PI);
+ var b = Math.tan(((r+90) / 180.0) * Math.PI);
+
+ var t = '';
+ for (var j=0; j < this.h; j++) {
+ for (var i=0; i < this.w; i++) {
+ if ((r > 90 && r <= 180) || (r > 270 && r < 360) || r == 0) {
+ if ((j-this.ch) * 2 > a * (i-this.cw) && (j-this.ch) * 2 < b * (i-this.cw) ||
+ (j-this.ch) * 2 < a * (i-this.cw) && (j-this.ch) * 2 > b * (i-this.cw) ) {
+ t += '*';
+ } else {
+ t += ' ';
+ }
+ } else {
+ if ((j-this.ch) * 2 > a * (i-this.cw) && (j-this.ch) * 2 > b * (i-this.cw) ||
+ (j-this.ch) * 2 < a * (i-this.cw) && (j-this.ch) * 2 < b * (i-this.cw) ) {
+ t += '*';
+ } else {
+ t += ' ';
+ }
+ }
+ }
+ t += "\n";
+ }
+ this.terminal.innerHTML = t;
+ },
+ blink: function() {
+ if (this.blink_active)
+ this.blinker.style.color = '#00FF00';
+ else
+ this.blinker.style.color = 'black';
+ this.blink_active = !this.blink_active;
+ }
+});
+<!DOCTYPE html>
+<!-- Copyright 2011 The Dominion of Awesome
+ See COPYING for license information -->
+<html>
+<head>
+<title>Hacks!</title>
+<script src="/Program%20Files%20(x86)/HP%20webOS/SDK/share/refcode/webos-framework/enyo/1.0/framework/enyo.js" type="text/javascript"></script>
+</head>
+<body>
+<script type="text/javascript">
+var munch = enyo.create({kind: "Main"}).renderInto(document.body);
+</script>
+</body>
+</html>