784 lines
28 KiB
JavaScript
784 lines
28 KiB
JavaScript
/**
|
|
* Christmas Light Smashfest
|
|
*
|
|
* Adapted from XLSF 2007 as originally used on http://schillmania.com/?theme=2007&christmas=1
|
|
* Requires YUI3 library - http://yuilibrary.com/projects/yui3/
|
|
*/
|
|
|
|
(function() {
|
|
|
|
var YUI_SEED_URL = 'http://yui.yahooapis.com/3.8.0/build/yui/yui-min.js';
|
|
|
|
function initChristmasLights() {
|
|
|
|
YUI().use('anim', function(Y) {
|
|
|
|
function XLSF(oTarget) {
|
|
var writeDebug = soundManager._wD;
|
|
writeDebug('XLSF()');
|
|
var IS_MOON_COMPUTER = false;
|
|
var isIE = navigator.userAgent.match(/msie/i);
|
|
var isTouchDevice = navigator.userAgent.match(/ipad|ipod|iphone|android/i);
|
|
var self = this;
|
|
var xlsf = self;
|
|
var useAngle = window.location.href.match(/angle/i);
|
|
var useFollow = window.location.toString().match(/follow/i);
|
|
var classBase = 'xlsf-light' + (useAngle ? ' xlsf-angled' : '');
|
|
var animDuration = 1;
|
|
var lastMouseX = 0;
|
|
var lastMouseY = 0;
|
|
var mmhTimer = null;
|
|
var activeLights = [];
|
|
var testDiv = document.createElement('div');
|
|
var offset = 0;
|
|
var transforms = {
|
|
ie: (typeof testDiv.style['-ms-transform'] !== 'undefined' ? '-ms-transform' : null),
|
|
moz: (typeof testDiv.style.MozTransform !== 'undefined' ? 'MozTransform' : null),
|
|
opera: (typeof testDiv.style['OTransform'] !== 'undefined' ? 'OTransform' : null),
|
|
webkit: (typeof testDiv.style.webkitTransform !== 'undefined' ? 'webkitTransform' : null),
|
|
prop: null
|
|
}
|
|
transforms.prop = (transforms.moz || transforms.webkit || transforms.ie || transforms.opera);
|
|
this.oFrag = document.createDocumentFragment();
|
|
this.oExplosionTarget = document.getElementById('explosion-box');
|
|
if (!this.oExplosionTarget) {
|
|
this.oExplosionTarget = document.createElement('div');
|
|
this.oExplosionTarget.id = 'explosion-box';
|
|
document.body.appendChild(this.oExplosionTarget);
|
|
}
|
|
this.oTarget = (oTarget ? oTarget : document.documentElement);
|
|
this.oExplosionBox = document.createElement('div');
|
|
this.oExplosionBox.className = 'xlsf-fragment-box';
|
|
this.oExplosionFrag = document.createElement('div');
|
|
this.oExplosionFrag.className = 'xlsf-fragment';
|
|
this.lights = [];
|
|
this.lightClasses = {
|
|
pico: 32,
|
|
tiny: 50,
|
|
small: 64,
|
|
medium: 72,
|
|
large: 96
|
|
}
|
|
|
|
this.lightClass = (window.XLSF_LIGHT_CLASS || 'tiny'); // kind of light to show (32px to 96px square)
|
|
if (window.location.href.match(/size=/i)) {
|
|
this.lightClass = window.location.href.substr(window.location.href.indexOf('size=') + 5);
|
|
if (this.lightClass.indexOf('#') !== -1) {
|
|
this.lightClass = this.lightClass.substr(0, this.lightClass.indexOf('#'));
|
|
}
|
|
}
|
|
|
|
this.lightXY = this.lightClasses[this.lightClass]; // shortcut to w/h
|
|
|
|
function rnd(n) {
|
|
return parseInt(Math.random() * n);
|
|
}
|
|
|
|
function plusMinus(n) {
|
|
return (parseInt(rnd(2), 10) === 1 ? n * -1 : n);
|
|
}
|
|
|
|
this.lightGroups = {
|
|
left: [],
|
|
top: [],
|
|
right: [],
|
|
bottom: []
|
|
}
|
|
this.lightSmashCounter = 0;
|
|
this.lightIndex = 0;
|
|
this.lightInterval = 500;
|
|
this.timer = null;
|
|
this.bgBaseX = 0;
|
|
this.bgBaseY = 0;
|
|
this.soundIDs = 0;
|
|
this.soundPan = {
|
|
panValue: 75,
|
|
left: 0,
|
|
mid: 481,
|
|
right: 962
|
|
}
|
|
|
|
this.initSounds = function() {
|
|
if (!soundManager.supported()) {
|
|
return false;
|
|
}
|
|
for (var i = 0; i < 6; i++) {
|
|
soundManager.createSound({
|
|
id: 'smash' + i,
|
|
url: (window.XLSF_URL_BASE || '') + 'sound/glass' + i + '.mp3',
|
|
autoLoad: true,
|
|
multiShot: true,
|
|
volume: 25
|
|
});
|
|
}
|
|
self.initSounds = function() {} // safety net
|
|
}
|
|
|
|
this.appendLights = function() {
|
|
writeDebug('xlsf.appendLights()');
|
|
self.oTarget.appendChild(self.oFrag);
|
|
// self.oFrag = document.createDocumentFragment();
|
|
}
|
|
|
|
function ExplosionFragment(nType, sClass, x, y, vX, vY) {
|
|
var self = this;
|
|
this.o = xlsf.oExplosionFrag.cloneNode(true);
|
|
this.nType = nType;
|
|
this.sClass = sClass;
|
|
this.x = x;
|
|
this.y = y;
|
|
this.w = 50;
|
|
this.h = 50;
|
|
this.bgBaseX = 0;
|
|
this.bgBaseY = this.h * this.nType;
|
|
this.vX = vX * (1.5 + Math.random());
|
|
this.vY = vY * (1.5 + Math.random());
|
|
this.oA = null;
|
|
this.oA2 = null;
|
|
this.burstPhase = 1; // starting background offset point
|
|
this.burstPhases = 4; // 1+offset (ignore large size)
|
|
this.animDuration = 1; // how long the animations run for
|
|
this.o.style.backgroundPosition = ((this.w * -this.burstPhase) + 'px ' + (this.h * -nType) + 'px');
|
|
|
|
// boundary checks
|
|
if (self.sClass == 'left') {
|
|
this.vX = Math.abs(this.vX);
|
|
} else if (self.sClass == 'right') {
|
|
this.vX = Math.abs(this.vX) * -1;
|
|
}
|
|
|
|
this.burstTween = function() {
|
|
// determine frame to show based on animation's progress vs. its total time (and don't allow overflow, in the event animation runs long.)
|
|
var phase = 1 + (Math.floor(Math.min(self.animDuration, (this.get('elapsedTime') / 1000)) * self.burstPhases));
|
|
if (phase != self.burstPhase) {
|
|
self.burstPhase = phase;
|
|
self.o.style.backgroundPosition = ((self.w * -self.burstPhase) + 'px ' + (self.h * -nType) + 'px');
|
|
}
|
|
}
|
|
|
|
|
|
this.burst = function() {
|
|
self.oA = new Y.Anim({
|
|
node: Y.one(self.o),
|
|
to: {
|
|
marginLeft: (self.vX * (5 + Math.random() * 10)),
|
|
marginTop: (self.vY * (5 + Math.random() * 10))
|
|
},
|
|
duration: animDuration,
|
|
easing: Y.Easing.easeOutStrong
|
|
});
|
|
self.oA.on('tween', self.burstTween);
|
|
self.oA.on('end', self.hide);
|
|
self.oA.run();
|
|
}
|
|
|
|
this.hide = function() {
|
|
if (!isIE) self.o.style.opacity = 0;
|
|
}
|
|
|
|
this.reset = function() {
|
|
self.o.style.left = '0px';
|
|
self.o.style.top = '0px';
|
|
self.o.style.marginLeft = '0px';
|
|
self.o.style.marginTop = '0px';
|
|
if (!isIE) self.o.style.opacity = 1;
|
|
}
|
|
|
|
this.animate = function() {
|
|
self.reset();
|
|
self.burst();
|
|
}
|
|
|
|
}
|
|
|
|
function Explosion(nType, sClass, x, y) {
|
|
var oParent = this;
|
|
var self = this;
|
|
this.o = null;
|
|
this.nType = nType;
|
|
this.sClass = sClass;
|
|
this.x = x;
|
|
this.y = y;
|
|
this.boxVX = 0;
|
|
this.boxVY = 0;
|
|
this.o = xlsf.oExplosionBox.cloneNode(true);
|
|
this.o.style.left = x + 'px';
|
|
this.o.style.top = y + 'px';
|
|
// this.oFrag = document.createDocumentFragment();
|
|
this.fragments = [];
|
|
|
|
var mX = x;
|
|
var mY = y;
|
|
var type = typeMap[nType + sClass];
|
|
var scale = 5 + Math.random() * 10;
|
|
var shift = 2;
|
|
|
|
this.fragments.push(new ExplosionFragment(type, sClass, mX, mY, -rnd(scale), -rnd(scale)));
|
|
this.fragments.push(new ExplosionFragment(type, sClass, mX, mY, plusMinus(rnd(shift)), -rnd(scale)));
|
|
this.fragments.push(new ExplosionFragment(type, sClass, mX, mY, rnd(scale), -rnd(scale)));
|
|
|
|
this.fragments.push(new ExplosionFragment(type, sClass, mX, mY, -rnd(scale), plusMinus(rnd(shift))));
|
|
this.fragments.push(new ExplosionFragment(type, sClass, mX, mY, plusMinus(rnd(shift)), plusMinus(rnd(shift))));
|
|
this.fragments.push(new ExplosionFragment(type, sClass, mX, mY, rnd(scale), plusMinus(rnd(shift))));
|
|
|
|
this.fragments.push(new ExplosionFragment(type, sClass, mX, mY, rnd(scale), -rnd(scale)));
|
|
this.fragments.push(new ExplosionFragment(type, sClass, mX, mY, rnd(scale), plusMinus(rnd(shift))));
|
|
this.fragments.push(new ExplosionFragment(type, sClass, mX, mY, rnd(scale), rnd(scale)));
|
|
|
|
this.init = function() {
|
|
for (var i = self.fragments.length; i--;) {
|
|
self.o.appendChild(self.fragments[i].o);
|
|
}
|
|
if (!IS_MOON_COMPUTER) {
|
|
// faster rendering, particles get cropped
|
|
xlsf.oExplosionTarget.appendChild(self.o);
|
|
} else {
|
|
// slower rendering, can overlay body
|
|
xlsf.oExplosionTarget.appendChild(self.o);
|
|
}
|
|
}
|
|
|
|
this.reset = function() {
|
|
// clean-up
|
|
// self.o.parentNode.removeChild(self.o);
|
|
self.o.style.display = 'none';
|
|
self.o.style.marginLeft = '0px';
|
|
self.o.style.marginTop = '0px';
|
|
self.o.style.left = self.x + 'px';
|
|
self.o.style.top = self.y + 'px';
|
|
if (!isIE) self.o.style.opacity = 1;
|
|
for (var i = self.fragments.length; i--;) {
|
|
self.fragments[i].reset();
|
|
}
|
|
}
|
|
|
|
this.trigger = function(boxVX, boxVY) {
|
|
self.o.style.display = 'block';
|
|
self.boxVX = boxVX;
|
|
self.boxVY = boxVY;
|
|
// boundary checks
|
|
if (self.sClass == 'right') {
|
|
self.boxVX = Math.abs(self.boxVX) * -1;
|
|
} else if (self.sClass == 'left') {
|
|
self.boxVX = Math.abs(self.boxVX);
|
|
}
|
|
for (var i = self.fragments.length; i--;) {
|
|
self.fragments[i].animate();
|
|
}
|
|
if (!isIE && (IS_MOON_COMPUTER)) {
|
|
var oAExplode = new Y.Anim({
|
|
node: Y.one(o),
|
|
to: {
|
|
marginLeft: 100 * self.boxVX,
|
|
marginTop: 150 * self.boxVY,
|
|
opacity: 0.01
|
|
},
|
|
duration: animDuration,
|
|
easing: Y.Easing.easeInStrong
|
|
});
|
|
} else {
|
|
// even IE 7 sucks w/alpha-transparent PNG + CSS opacity. Boourns.
|
|
var oAExplode = new Y.Anim({
|
|
node: Y.one(self.o),
|
|
to: {
|
|
marginLeft: 100 * self.boxVX,
|
|
marginTop: 150 * self.boxVY
|
|
},
|
|
duration: animDuration,
|
|
easing: Y.Easing.easeInStrong
|
|
});
|
|
}
|
|
oAExplode.on('end', self.reset);
|
|
oAExplode.run();
|
|
// setTimeout(self.reset,animDuration*1000*1.5);
|
|
}
|
|
|
|
this.init();
|
|
|
|
}
|
|
|
|
function Light(sSizeClass, sClass, nType, x, y, row, col) {
|
|
var self = this;
|
|
this.o = document.createElement('div');
|
|
this.sClass = sClass;
|
|
this.sSizeClass = sSizeClass;
|
|
this.nType = (nType || 0);
|
|
this.useY = (sClass == 'left' || sClass == 'right');
|
|
this.state = null;
|
|
this.broken = 0;
|
|
this.w = xlsf.lightClasses[sSizeClass];
|
|
this.h = xlsf.lightClasses[sSizeClass];
|
|
this.x = x;
|
|
this.y = y;
|
|
this.row = row;
|
|
this.col = col;
|
|
this.bg = (window.XLSF_URL_BASE || '') + 'image/bulbs-' + this.w + 'x' + this.h + '-' + this.sClass + '.png';
|
|
this.o.style.width = this.w + 'px';
|
|
this.o.style.height = this.h + 'px';
|
|
this.o.style.background = 'url(' + this.bg + ') no-repeat 0px 0px';
|
|
this.bgBaseX = (self.useY ? -self.w * this.nType : 0);
|
|
this.bgBaseY = (!self.useY ? -self.h * this.nType : 0);
|
|
this.glassType = parseInt(Math.random() * 6);
|
|
// this.bonusSounds = ['griffin-laugh','bblaff','bblaff2'];
|
|
// this.bonusSound = null;
|
|
this.oExplosion = null;
|
|
this.soundID = 'smash' + this.glassType;
|
|
var panValue = xlsf.soundPan.panValue; // eg. +/- 80%
|
|
this.pan = parseInt(this.x <= xlsf.soundPan.mid ? -panValue + ((this.x / xlsf.soundPan.mid) * panValue) : (this.x - xlsf.soundPan.mid) / (xlsf.soundPan.right - xlsf.soundPan.mid) * panValue);
|
|
|
|
this.setBGPos = function(x, y) {
|
|
self.o.style.backgroundPosition = ((self.bgBaseX + x) + 'px ' + (self.bgBaseY + y) + 'px');
|
|
}
|
|
|
|
this.setLight = function(bOn) {
|
|
if (self.broken || self.state == bOn) return false;
|
|
if (!self.w || !self.h) self.getDimensions();
|
|
self.state = bOn;
|
|
if (self.useY) {
|
|
self.setBGPos(0, -this.h * (bOn ? 0 : 1));
|
|
} else {
|
|
self.setBGPos(-this.w * (bOn ? 0 : 1), 0);
|
|
}
|
|
}
|
|
|
|
this.getDimensions = function() {
|
|
self.w = self.o.offsetWidth;
|
|
self.h = self.o.offsetHeight;
|
|
self.bgBaseX = (self.useY ? -self.w * self.nType : 0);
|
|
self.bgBaseY = (!self.useY ? -self.h * self.nType : 0);
|
|
}
|
|
|
|
this.on = function() {
|
|
self.setLight(1);
|
|
}
|
|
|
|
this.off = function() {
|
|
self.setLight(0);
|
|
}
|
|
|
|
this.flickr = function() {
|
|
self.setLight(Math.random() >= 0.5 ? 1 : 0);
|
|
}
|
|
|
|
this.toggle = function() {
|
|
self.setLight(!self.state ? 1 : 0);
|
|
}
|
|
|
|
this.explode = function(e) {
|
|
self.oExplosion.trigger(0, 1); // boooom!
|
|
}
|
|
|
|
this.smash = function(e) {
|
|
if (self.broken) return false;
|
|
self.broken = true;
|
|
if (soundManager && soundManager.supported()) {
|
|
soundManager.play(self.soundID, {
|
|
pan: self.pan
|
|
});
|
|
// soundManager.sounds[self.soundID].play({pan:self.pan});
|
|
// if (self.bonusSound != null) window.setTimeout(self.smashBonus,1000);
|
|
}
|
|
self.explode(e);
|
|
var rndFrame = 2; // +parseInt(Math.random()*3);
|
|
if (self.useY) {
|
|
self.setBGPos(0, self.h * -rndFrame);
|
|
} else {
|
|
self.setBGPos(self.w * -rndFrame, 0);
|
|
}
|
|
if (!useFollow && !useAngle && transforms.prop) {
|
|
self.o.style[transforms.prop] = 'rotate(' + Math.random() * plusMinus(20) + 'deg)';
|
|
}
|
|
xlsf.lightSmashCounter++;
|
|
for (var i = activeLights.length; i--;) {
|
|
// find this in the active array, and take it out
|
|
if (activeLights[i] === self) {
|
|
activeLights.splice(i, 1);
|
|
break;
|
|
}
|
|
}
|
|
// xlsf.doNukeCheck();
|
|
// window.setTimeout(self.reset,3000); // respawn
|
|
}
|
|
|
|
this.smashBonus = function() {
|
|
// soundManager.play(self.bonusSounds[self.bonusSound],urlBase+'sound/'+self.bonusSounds[self.bonusSound]+'.mp3');
|
|
}
|
|
|
|
this.reset = function() {
|
|
if (!self.broken) return false;
|
|
self.broken = false;
|
|
self.state = null;
|
|
xlsf.lightSmashCounter--;
|
|
// self.oExplosion.reset(); // may not be necessary
|
|
self.flickr();
|
|
}
|
|
|
|
this.init = function() {
|
|
self.o.className = classBase + ' ' + this.sizeClass + ' ' + this.sClass;
|
|
self.o.style.left = self.x + 'px';
|
|
self.o.style.top = self.y + 'px';
|
|
self.o.style.width = self.w + 'px';
|
|
self.o.style.height = self.h + 'px';
|
|
self.flickr();
|
|
xlsf.oFrag.appendChild(self.o);
|
|
self.oExplosion = new Explosion(self.nType, self.sClass, self.x, self.y);
|
|
}
|
|
|
|
this.init();
|
|
|
|
} // Light()
|
|
this.createLight = function(sClass, nType, x, y, row, col) {
|
|
var oLight = new Light(self.lightClass, sClass, nType, x, y, row, col);
|
|
activeLights.push(oLight);
|
|
self.lightGroups[sClass].push(oLight);
|
|
self.lights.push(oLight);
|
|
return oLight;
|
|
}
|
|
|
|
this.rotateLights = function() {
|
|
self.lights[self.lightIndex == self.lights.length ? self.lights.length - 1 : self.lightIndex].off();
|
|
self.lightIndex++;
|
|
if (self.lightIndex == self.lights.length) {
|
|
self.lightIndex = 0;
|
|
}
|
|
self.lights[self.lightIndex].on();
|
|
}
|
|
|
|
this.randomLights = function() {
|
|
self.lights[parseInt(Math.random() * self.lights.length)].toggle();
|
|
}
|
|
|
|
this.destroyLights = function() {
|
|
// reset counter
|
|
self.lightSmashCounter = 0;
|
|
self.startSequence(Math.random() > 0.75 ? self.destroyLight : self.destroyRandom, 33);
|
|
}
|
|
|
|
this.destroyRandom = function() {
|
|
for (var i = 2; i--;) {
|
|
if (activeLights.length) {
|
|
activeLights[parseInt(Math.random() * activeLights.length)].smash();
|
|
}
|
|
}
|
|
}
|
|
|
|
this.destroyLight = function() {
|
|
var groupSize = 2; // # to smash at a time
|
|
if (self.lightSmashCounter < self.lights.length) {
|
|
var limit = Math.min(self.lightSmashCounter + groupSize, self.lights.length);
|
|
var reverseLimit = Math.max(0, self.lights.length - self.lightSmashCounter - groupSize);
|
|
for (var i = self.lightSmashCounter; i < limit; i++) {
|
|
if (self.lights[self.lightSmashCounter]) {
|
|
self.lights[self.lightSmashCounter].smash();
|
|
}
|
|
self.lights[self.lights.length - self.lightSmashCounter].smash();
|
|
}
|
|
} else {
|
|
self.stopSequence();
|
|
}
|
|
}
|
|
|
|
this.uberSmash = function() {
|
|
// make everything explode - including your CPU.
|
|
self.stopSequence();
|
|
var ebCN = Y.D.getElementsByClassName;
|
|
/*
|
|
window.setTimeout(function(){self.smashGroup(self.lightGroups.left)},500);
|
|
window.setTimeout(function(){self.smashGroup(self.lightGroups.right)},2000);
|
|
window.setTimeout(function(){self.smashGroup(self.lightGroups.bottom)},4000);
|
|
window.setTimeout(function(){self.smashGroup(self.lightGroups.top)},6000);
|
|
*/
|
|
window.setTimeout(function() {
|
|
self.smashGroup(self.lightGroups.bottom)
|
|
}, 500);
|
|
window.setTimeout(function() {
|
|
self.smashGroup(self.lightGroups.top)
|
|
}, 3500);
|
|
|
|
}
|
|
|
|
this.smashGroup = function(oGroup) {
|
|
for (var i = oGroup.length; i--;) {
|
|
oGroup[i].smash();
|
|
}
|
|
}
|
|
|
|
this.startSequence = function(fSequence, nInterval) {
|
|
if (self.timer) self.stopSequence();
|
|
self.timer = window.setInterval(fSequence, (typeof nInterval != 'undefined' ? nInterval : self.lightInterval));
|
|
}
|
|
|
|
this.stopSequence = function() {
|
|
if (self.timer) {
|
|
window.clearInterval(self.timer);
|
|
self.timer = null;
|
|
}
|
|
}
|
|
|
|
var typeMaps = {
|
|
'tiny': {
|
|
'0bottom': 0,
|
|
'0top': 3,
|
|
'1bottom': 1,
|
|
'1top': 2,
|
|
'2bottom': 2,
|
|
'2top': 1,
|
|
'3bottom': 3,
|
|
'3top': 0
|
|
},
|
|
'other': {
|
|
'0bottom': 3,
|
|
'0top': 3,
|
|
'1bottom': 2,
|
|
'1top': 2,
|
|
'2bottom': 1,
|
|
'2top': 1,
|
|
'3bottom': 0,
|
|
'3top': 0
|
|
}
|
|
}
|
|
|
|
var typeMap = typeMaps[(this.lightClass === 'tiny' ? 'tiny' : 'other')];
|
|
|
|
var i = 0;
|
|
|
|
/*
|
|
for (i=0; i<6; i++) {
|
|
this.createLight('left',parseInt(Math.random()*4),-2,50+i*(self.lightXY*0.7));
|
|
this.createLight('right',parseInt(Math.random()*4),962,50+i*(self.lightXY*0.7));
|
|
}
|
|
|
|
for (i=0; i<27; i++) {
|
|
this.createLight('top',parseInt(Math.random()*4),20+i*(self.lightXY*0.7),23);
|
|
this.createLight('bottom',parseInt(Math.random()*4),20+i*(self.lightXY*0.7),253);
|
|
}
|
|
*/
|
|
|
|
var j = 0;
|
|
|
|
if (window.innerWidth || window.innerHeight) {
|
|
var screenX = window.innerWidth; // -(!isIE?24:2);
|
|
var screenY = window.innerHeight;
|
|
} else {
|
|
var screenX = (document.documentElement.clientWidth || document.body.clientWidth || document.body.scrollWidth); // -(!isIE?8:0);
|
|
var screenY = (document.documentElement.clientHeight || document.body.clientHeight || document.body.scrollHeight);
|
|
}
|
|
|
|
// hack for SM2 homepage
|
|
if (document.body && document.body.className && document.body.className.match(/home/i)) {
|
|
|
|
_id('lights').style.display = 'block';
|
|
|
|
// start lights to the right of <h1>
|
|
// offset = parseInt(document.getElementsByTagName('h1')[0].offsetWidth)+16;
|
|
var jMax = Math.floor((screenX - offset - 16) / self.lightXY);
|
|
var iMax = Math.floor((screenY - offset - 16) / self.lightXY);
|
|
|
|
for (j = 0; j < jMax; j++) {
|
|
this.createLight('top', j % 3, offset + j * self.lightXY, 0);
|
|
// this.createLight('bottom',j%3,offset+j*self.lightXY,screenY-offset-offset+1);
|
|
}
|
|
|
|
if (typeof isFun != 'undefined') {
|
|
for (i = 0; i < iMax; i++) {
|
|
this.createLight('left', i % 3, 0, offset + i * self.lightXY);
|
|
// this.createLight('right',i%3,screenX-offset-offset,offset+i*self.lightXY);
|
|
}
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
var jMax = Math.floor((screenX) / self.lightXY);
|
|
var iMax = Math.floor((screenY - 12) / self.lightXY);
|
|
|
|
for (i = 0; i < iMax; i++) {
|
|
for (j = 0; j < jMax; j++) {
|
|
this.createLight((i + 1) % 2 == 0 ? 'bottom' : 'top', i % 4, j * self.lightXY, i * self.lightXY, j, i);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
var bsCounter = 0;
|
|
for (i=0; i<8; i++) {
|
|
// plant a few random seeds.. er, sounds.
|
|
self.lights[parseInt(Math.random()*self.lights.length)].bonusSound = bsCounter++;
|
|
if (bsCounter>2) bsCounter = 0; // hack - loop through sounds
|
|
}
|
|
*/
|
|
|
|
this.appendLights();
|
|
|
|
function followMouseMove(e) {
|
|
if (!self.lights.length) {
|
|
return false;
|
|
}
|
|
var x = lastMouseX;
|
|
var y = lastMouseY;
|
|
var x2 = null;
|
|
var y2 = null;
|
|
var angle = 0;
|
|
var light = null;
|
|
for (var i = self.lights.length; i--;) {
|
|
light = self.lights[i];
|
|
if (light && !light.broken) {
|
|
x2 = light.x;
|
|
y2 = light.y;
|
|
angle = Math.atan2((y - y2), (x - x2)) * (180 / Math.PI);
|
|
if (light.col % 2 === 0) {
|
|
angle += (270 * 180 / Math.PI);
|
|
}
|
|
if (transforms.prop) {
|
|
light.o.style[transforms.prop] = 'rotate(' + angle + 'deg)';
|
|
}
|
|
}
|
|
}
|
|
mmhTimer = null;
|
|
}
|
|
|
|
function mouseOrTouchMove(e) {
|
|
// coordinate -> row/col check, smashy smash
|
|
var x, y, lightIndex;
|
|
if (e.targetTouches) {
|
|
if (e.targetTouches.length === 1) {
|
|
x = e.targetTouches[0].clientX - offset;
|
|
y = e.targetTouches[0].clientY;
|
|
}
|
|
} else {
|
|
x = e.clientX - offset;
|
|
y = e.clientY;
|
|
}
|
|
if (x < 0) {
|
|
// ignore off-screen values.
|
|
return;
|
|
}
|
|
lightCol = Math.floor((x / (self.lightClasses[self.lightClass] * jMax) * jMax)), lightRow = Math.floor((y / (self.lightClasses[self.lightClass] * iMax) * iMax))
|
|
lightIndex = (jMax * lightRow) + lightCol;
|
|
if (self.lights[lightIndex]) {
|
|
self.lights[lightIndex].smash();
|
|
}
|
|
if (useFollow) {
|
|
lastMouseX = x;
|
|
lastMouseY = y;
|
|
if (!mmhTimer) {
|
|
mmhTimer = window.setTimeout(followMouseMove, 33); // try to be nice and throttle this call, which may be expensive
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isTouchDevice) {
|
|
|
|
document.addEventListener('touchstart', function(e) {
|
|
|
|
// ignore pinch-to-zoom, links and so forth.
|
|
|
|
if (e.touches && e.touches.length === 1 && e.target && e.target.nodeName !== 'A') {
|
|
|
|
document.addEventListener('touchmove', mouseOrTouchMove, false);
|
|
document.addEventListener('touchend', function(e) {
|
|
document.removeEventListener('touchMove', mouseOrTouchMove);
|
|
});
|
|
|
|
mouseOrTouchMove(e); // initial touch might be a smashy one, too
|
|
e.preventDefault();
|
|
return false;
|
|
|
|
}
|
|
|
|
}, false);
|
|
|
|
} else {
|
|
|
|
// generic event handler
|
|
|
|
if (document.addEventListener) {
|
|
document.addEventListener('mousemove', mouseOrTouchMove, false);
|
|
} else if (document.attachEvent) {
|
|
document.attachEvent('onmousemove', mouseOrTouchMove);
|
|
}
|
|
|
|
}
|
|
|
|
this.startSequence(self.randomLights);
|
|
|
|
} // --- XLSF2007()
|
|
|
|
var xlsf = null;
|
|
|
|
function smashInit() {
|
|
var loading = document.getElementById('loading');
|
|
xlsf = new XLSF(document.getElementById('lights'));
|
|
window.xlsf = xlsf; // expose to global
|
|
xlsf.initSounds();
|
|
if (loading) {
|
|
loading.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
window.smashInit = smashInit;
|
|
|
|
// start in either case
|
|
soundManager.onready(smashInit);
|
|
soundManager.ontimeout(smashInit);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
(function() {
|
|
|
|
// script loader helper for YUI library
|
|
// http://yui.yahooapis.com/3.4.1/build/yui/yui-min.js
|
|
|
|
function loadScript(sURL, onLoad) {
|
|
try {
|
|
var loadScriptHandler = function() {
|
|
var rs = this.readyState;
|
|
if (rs == 'loaded' || rs == 'complete') {
|
|
this.onreadystatechange = null;
|
|
this.onload = null;
|
|
if (onLoad) {
|
|
window.setTimeout(onLoad, 20);
|
|
}
|
|
}
|
|
}
|
|
|
|
function scriptOnload() {
|
|
this.onreadystatechange = null;
|
|
this.onload = null;
|
|
window.setTimeout(onLoad, 20);
|
|
}
|
|
var oS = document.createElement('script');
|
|
oS.type = 'text/javascript';
|
|
oS.setAttribute('async', true);
|
|
if (onLoad) {
|
|
oS.onreadystatechange = loadScriptHandler;
|
|
oS.onload = scriptOnload;
|
|
}
|
|
oS.src = sURL;
|
|
document.getElementsByTagName('head')[0].appendChild(oS);
|
|
} catch (e) {
|
|
// oh well
|
|
}
|
|
}
|
|
|
|
if (typeof window.YUI === 'undefined') {
|
|
loadScript(YUI_SEED_URL, function() {
|
|
initChristmasLights();
|
|
});
|
|
}
|
|
|
|
}());
|
|
|
|
soundManager.setup({
|
|
url: '../../swf/',
|
|
preferFlash: true,
|
|
flashVersion: 9,
|
|
useHighPerformance: true,
|
|
wmode: 'transparent',
|
|
debugMode: false
|
|
});
|
|
|
|
}()); |