From: Vincent Vanwaelscappel Date: Wed, 24 Jul 2013 13:56:08 +0000 (+0000) Subject: (no commit message) X-Git-Url: http://git.cubedesigners.com/?a=commitdiff_plain;h=c448e123ebc625d0b8f2768d4530d9347702cc41;p=fluidbook-html5.git --- diff --git a/js/libs/fluidbook/fluidbook.bookmarks.js b/js/libs/fluidbook/fluidbook.bookmarks.js index dc35c8e0..cc121fdb 100644 --- a/js/libs/fluidbook/fluidbook.bookmarks.js +++ b/js/libs/fluidbook/fluidbook.bookmarks.js @@ -408,7 +408,7 @@ FluidbookBookmarks.prototype = { } index += '
'; - index += '
' + group.name + ''; + index += '
' + this.fluidbook.loader.getImage('data/thumbnails/p' + group.page + '.jpg') + '' + group.name + ''; if (this.fluidbook.bookmarks.enabled) { index += this.fluidbook.bookmarks.getBookmarkForPage(group.page, true, true); } @@ -426,7 +426,7 @@ FluidbookBookmarks.prototype = { for (i in pages) { var p = pages[i]; index += '
'; - index += '
' + this.fluidbook.physicalToVirtual(p) + ''; + index += '
' + this.fluidbook.loader.getImage('data/thumbnails/p' + p + '.jpg') + '' + this.fluidbook.physicalToVirtual(p) + ''; if (this.fluidbook.bookmarks.enabled) { index += this.fluidbook.bookmarks.getBookmarkForPage(p, true, true); } diff --git a/js/libs/fluidbook/fluidbook.coquillette.js b/js/libs/fluidbook/fluidbook.coquillette.js index 12b19d9c..d5ecbdc6 100644 --- a/js/libs/fluidbook/fluidbook.coquillette.js +++ b/js/libs/fluidbook/fluidbook.coquillette.js @@ -53,7 +53,7 @@ FluidbookCoquillette.prototype = { this.ctx.stroke(); }, pause: function() { - window.cancelAnimationFrame(this.raf); + TweenMax.killTweensOf(this); }, resize: function(ww, hh) { this.element.css({ diff --git a/js/libs/fluidbook/fluidbook.help.js b/js/libs/fluidbook/fluidbook.help.js index 21db77e5..07c2cc38 100644 --- a/js/libs/fluidbook/fluidbook.help.js +++ b/js/libs/fluidbook/fluidbook.help.js @@ -35,7 +35,7 @@ FluidbookHelp.prototype = { text = this.fluidbook.l10n.__('click once to zoom in, click again to zoom out') + '
' + this.fluidbook.l10n.__('roll the mouse wheel to zoom in/out'); } - help += '
'; + help += '
' + this.fluidbook.loader.getImage('data/images/help-' + name + '.' + ext, width * zoom, height * zoom); help += '

' + text + '

'; help += '
'; diff --git a/js/libs/fluidbook/fluidbook.js b/js/libs/fluidbook/fluidbook.js index 1a6b1951..a500a837 100644 --- a/js/libs/fluidbook/fluidbook.js +++ b/js/libs/fluidbook/fluidbook.js @@ -33,7 +33,7 @@ Fluidbook.prototype = { this.background = new FluidbookBackground(this); this.viewport = new FluidbookViewport(this.support) this.l10n = new FluidbookL10N(this, $_GET['lang']); - this.nav = new FluidbookNav(this); + this.video = new FluidbookVideo(this); this.bookmarks = new FluidbookBookmarks(this); this.index = new FluidbookIndex(this); @@ -48,6 +48,7 @@ Fluidbook.prototype = { this.displayOnePage = false; this.indexHTML = ''; this.transitionning = false; + this.gal = null; this.transitionAxis = 'x'; @@ -66,10 +67,8 @@ Fluidbook.prototype = { this.currentPage = -1; this.resize = new FluidbookResize(this); - this.help = new FluidbookHelp(this); this.coquillette = new FluidbookCoquillette(this); - this.stats = new FluidbookStats(this); this.stats.track(10); if (!this.support.isMobile) { @@ -83,6 +82,11 @@ Fluidbook.prototype = { this.displayLoader(); }, + reloadErrorImages: function() { + $('img').each(function() { + + }); + }, hideSplash: function() { if ($("#splash").length == 0) { return; @@ -96,12 +100,16 @@ Fluidbook.prototype = { this.ready(); $("#main").css('visibility', 'visible'); this.hideLoader(0, true); - $("#splash").css('opacity', 0).one(this.support.transitionendevents, function() { + $("#splash").css('opacity', 0).one(this.support.getTransitionEndEvent(), function() { $(this).remove(); }); }, ready: function() { + $("#main").css('display', 'block'); + this.nav = new FluidbookNav(this); + this.help = new FluidbookHelp(this); this.help.displayAtStartup(); + resize(); }, loadPlugins: function() { $.each(this.datas.plugins, function(k, plugin) { @@ -424,13 +432,16 @@ Fluidbook.prototype = { $this.beforeTransition(pageNr); // Do the transition - $(doublePage).addClass(nextFromClass + 'end').one($this.support.transitionendevents, function() { + $(doublePage).addClass(nextFromClass + 'end').one($this.support.getTransitionEndEvent(), function() { + if ($this.transitionning == false) { + return; + } if ($("#nextDoublePage").length == 0) { $("#pages").removeClass('_3dtransition'); - this.transitionning = false; + $this.transitionning = false; return; } - $(this).off($this.support.transitionendevents); + // Set the flat contents with the new page $this.loader.setContentsInDoublePage(doublePage, [pageNr, pageNr + 1], false, function() { $(doublePage).removeClass('_3d').removeClass(nextFromClass + 'start').removeClass(nextFromClass + 'end'); @@ -545,11 +556,13 @@ Fluidbook.prototype = { $this.loader.setContentsInDoublePage(doublePage, [pageNr, pageNr + 1], true, function() { $this.beforeTransition(pageNr); $("#currentDoublePage").addClass('_2d').addClass('axis_' + $this.transitionAxis).addClass(currentToClass); - $(doublePage).removeClass(nextFromClass).one($this.support.transitionendevents, function(event) { + $(doublePage).removeClass(nextFromClass).one($this.support.getTransitionEndEvent(), function(event) { + if ($this.transitionning == false) { + return; + } $("#currentDoublePage").remove(); $("#nextDoublePage").attr('id', 'currentDoublePage'); $this.afterTransition(pageNr); - $(this).off($this.support.transitionendevents); }); }); }); @@ -580,11 +593,13 @@ Fluidbook.prototype = { $this.loader.setContentsInDoublePage(doublePage, [pageNr, pageNr + 1], true, function() { $this.beforeTransition(pageNr); $("#currentDoublePage").addClass('axis_' + $this.transitionAxis).addClass('_2d').addClass(currentToClass); - $(doublePage).removeClass(nextFromClass).one($this.support.transitionendevents, function() { + $(doublePage).removeClass(nextFromClass).one($this.support.getTransitionEndEvent(), function() { + if ($this.transitionning == false) { + return; + } $("#currentDoublePage").remove(); $("#nextDoublePage").attr('id', 'currentDoublePage'); $this.afterTransition(pageNr); - $(this).off($this.support.transitionendevents); }); }); }); @@ -689,15 +704,22 @@ Fluidbook.prototype = { }, 20); }, _openView: function(view, param1, param2, callback) { + var $this = this; + if (this.gal != null && ['index', 'search', 'bookmark'].indexOf(view) >= 0) { + $(window).on('GALBundleLoaded', function(e, info) { + if (info.bundleName == 'thumbnails') { + $this.__openView(view, param1, param2, callback); + } + }); + this.gal.download('thumbnails'); + } else { + this.__openView(view, param1, param2, callback); + } + }, + __openView: function(view, param1, param2, callback) { var $this = this; var camelView = view.charAt(0).toUpperCase() + view.substr(1); - /*if ($('.mview:visible').length > 0) { - this.closeView(function() { - $this._openView(view, param1, param2, callback); - }); - return; - }*/ var cb = function() { $this.openingView(callback); }; @@ -755,7 +777,7 @@ Fluidbook.prototype = { $(mview).show().removeClass('animate').transform(from); setTimeout(function() { - $(mview).one($this.support.transitionendevents, function() { + $(mview).one($this.support.getTransitionEndEvent(), function() { $("#main").hide(); $('body').addClass('view'); $(mview).removeClass('animate'); @@ -844,7 +866,7 @@ Fluidbook.prototype = { view += '
'; view += markup; view += '
'; - + $("#view").append('
' + view + '
'); if (callback != undefined) { @@ -1036,7 +1058,7 @@ Fluidbook.prototype = { if (animate && this.support.transitions2d) { setTimeout(function() { - $(mview).one($this.support.transitionendevents, function() { + $(mview).one($this.support.getTransitionEndEvent(), function() { $(this).remove(); callback(); }).addClass('animate').transform(to); diff --git a/js/libs/fluidbook/fluidbook.loader.js b/js/libs/fluidbook/fluidbook.loader.js index 3859afb5..3b2be5e3 100644 --- a/js/libs/fluidbook/fluidbook.loader.js +++ b/js/libs/fluidbook/fluidbook.loader.js @@ -5,6 +5,7 @@ function FluidbookLoader(fluidbook) { this.links = []; this.toPreload = []; this.numPreload = 6; + this.imagesErrors = []; if (this.fluidbook.imagesVersion) { this.numPreload += 6; } @@ -47,8 +48,7 @@ FluidbookLoader.prototype = { return; } - var imgback = new Image(); - $(imgback).one('load', function() { + this.backgrounds[preloadingPage] = this.loadImage(this.getBackgroundURL(preloadingPage), null, null, null, function() { if ($this.fluidbook.vectorTexts) { $this._loadTexts(preloadingPage, function() { $this.preloadPages(); @@ -57,8 +57,6 @@ FluidbookLoader.prototype = { $this.preloadPages(); } }); - imgback.src = this.getBackgroundURL(preloadingPage); - this.backgrounds[preloadingPage] = imgback; }, preloadAround: function(page) { var min = Math.max(1, page - 1); @@ -137,7 +135,7 @@ FluidbookLoader.prototype = { } shade += '.png'; - $(page).children(".shade").html(''); + $(page).children(".shade").html(this.loadImage('images/' + shade, this.fluidbook.datas.width / 4, this.fluidbook.datas.height)); $(page).children('.clinks').html(this.fluidbook.datas.clinks[pageNr]); this.fluidbook.highlightSearchTerms(pageNr); callback(); @@ -159,8 +157,8 @@ FluidbookLoader.prototype = { } shade += '.png'; $(page).children('.clinks').html(this.fluidbook.datas.clinks[pageNr]); - $(page).children(".shade").html(''); -}, + $(page).children(".shade").html(this.loadImage('images/' + shade, this.fluidbook.datas.width / 4, this.fluidbook.datas.height)); + }, loadLeftPage: function(page, doublePage, callback) { if (page > 0) { this.loadPage(page, doublePage, 'left', callback); @@ -176,7 +174,7 @@ FluidbookLoader.prototype = { $(doublePage).find('.right').remove(); callback(); } -}, + }, getBackgroundURL: function(page) { var prefix = 'p'; if (this.fluidbook.imagesVersion) { @@ -200,12 +198,7 @@ FluidbookLoader.prototype = { if (this.backgrounds[page] != undefined) { callback(); } else { - var img = new Image(); - $(img).one('load', function() { - callback(); - }); - img.src = this.getBackgroundURL(page); - this.backgrounds[page] = img; + this.backgrounds[page] = this.loadImage(this.getBackgroundURL(page), null, null, null, callback); } }, loadTexts: function(pageNr, callback) { @@ -230,18 +223,47 @@ FluidbookLoader.prototype = { var w = this.fluidbook.datas.width / 0.75; var h = this.fluidbook.datas.height / 0.75; - var img = new Image(); - img.width = w * 2; - img.height = h * 2; - img.type = 'image/svg+xml'; - $(img).one('load', callback); - img.src = this.getTextsURL(pageNr); - this.texts[pageNr] = img; + this.texts[pageNr] = this.loadImage(this.getTextsURL(pageNr), w * 2, h * 2, 'image/svg+xml', callback); }, loadDatas: function(pageNr, callback) { var $this = this; this.loadTexts(pageNr, function() { $this.setBackground(pageNr, callback); }); + }, + getImage: function(src, width, height, type, callback) { + var img = this.loadImage(src, width, height, type, callback); + return $(img).get(0).outerHTML; + }, + loadImage: function(src, width, height, type, callback) { + var img = new Image(); + var $this = this; + if (callback && typeof callback == 'function') { + $(img).one('load', callback); + } + $(img).on('error', function() { + $this.imagesErrors.push(this); + }); + img.src = src; + if (width != undefined && width != null) { + img.width = width; + } + if (height != undefined && height != null) { + img.height = height; + } + if (type != undefined && type != null) { + img.type = type; + } + if (callback && typeof callback == 'function' && (img.complete || img.readyState == 'complete' || img.readyState == 4)) { + callback(); + } + + return $(img); + }, + retryErrorImages: function() { + $(this.imagesErrors).each(function() { + $(this).attr('src', $(this).attr('src')); + }); + this.imagesErrors = []; } }; \ No newline at end of file diff --git a/js/libs/fluidbook/fluidbook.nav.js b/js/libs/fluidbook/fluidbook.nav.js index d3120560..cec57c51 100644 --- a/js/libs/fluidbook/fluidbook.nav.js +++ b/js/libs/fluidbook/fluidbook.nav.js @@ -16,8 +16,7 @@ FluidbookNav.prototype = { if (this._dimensions[name] == undefined) { return ''; } - - return ''; + return this.fluidbook.loader.getImage(src, this._dimensions[name][0], this._dimensions[name][1]); }, addLink: function(name, href, id, help, before, c) { if ($("#nav").find('#' + id).length > 0) { @@ -60,17 +59,12 @@ FluidbookNav.prototype = { if (icon == 'home') { var homeURL = this.fluidbook.datas.home; if (this.fluidbook.datas.home == '%apphome%') { - homeURL = decodeURIComponent($_GET.home); + homeURL = decodeURIComponent(); } if (homeURL != '') { - this.addLink('nav-home', homeURL, 'home', 'home'); + this.addLink('nav-home', window.sessionStorage.getItem('apphome'), 'home', 'home'); } - $("#home").click(function() { - console.log('home click'); - window.history.go(-(window.history.length - 1)); - return false; - }); } else if (icon == 'index') { this.addLink('nav-index', '#/index', 'index', 'overview'); } else if (icon == 'chapters') { @@ -181,7 +175,7 @@ FluidbookNav.prototype = { $("#nav").append($("#search")); }, setAfterSearch: function() { - $("#nav").append('
'); + $("#nav").append('
' + this.fluidbook.loader.getImage('data/images/' + this.fluidbook.datas.afterSearch) + '
'); }, setInterface: function() { diff --git a/js/libs/fluidbook/fluidbook.resize.js b/js/libs/fluidbook/fluidbook.resize.js index 026bc9ae..6bf23440 100644 --- a/js/libs/fluidbook/fluidbook.resize.js +++ b/js/libs/fluidbook/fluidbook.resize.js @@ -133,7 +133,9 @@ FluidbookResize.prototype = { this.refw = fw; this.refh = fh; - this.fluidbook.help.resize(this.ww, this.hh, interfaceScale, navScale); + if (this.fluidbook.help) { + this.fluidbook.help.resize(this.ww, this.hh, interfaceScale, navScale); + } this.fluidbook.coquillette.resize(this.ww, this.hh); this.fluidbook.background.resize(this.ww, this.hh); diff --git a/js/libs/fluidbook/fluidbook.support.js b/js/libs/fluidbook/fluidbook.support.js index cb4189a5..d1ba7eab 100644 --- a/js/libs/fluidbook/fluidbook.support.js +++ b/js/libs/fluidbook/fluidbook.support.js @@ -7,10 +7,9 @@ function FluidbookSupport(fluidbook) { this.transitions3d = Modernizr.csstransforms3d && Modernizr.csstransitions && Modernizr.csstransformspreserve3d; this.transitions2d = Modernizr.csstransforms && Modernizr.csstransitions; - this.transitionendevents = ['transitionEnd', 'transitionend', 'mozTransitionEnd', 'webkitTransitionEnd', 'oTransitionEnd', 'msTransitionEnd'].join(' '); - + this.transitionendevent = null; this.initialResolution = 150; - + this.isMobile = isMobile(); this.SVG = Modernizr.svg && this.fluidbook.datas.mobileIconVector; @@ -27,6 +26,19 @@ function FluidbookSupport(fluidbook) { } FluidbookSupport.prototype = { + getTransitionEndEvent: function() { + if (this.transitionendevent == null) { + var transEndEventNames = { + 'WebkitTransition': 'webkitTransitionEnd', + 'MozTransition': 'transitionend', + 'OTransition': 'oTransitionEnd', + 'msTransition': 'MSTransitionEnd', + 'transition': 'transitionend' + }; + this.transitionendevent = transEndEventNames[ Modernizr.prefixed('transition') ]; + } + return this.transitionendevent; + }, hasNetwork: function() { if (navigator.onLine != undefined) { return navigator.onLine; @@ -115,14 +127,14 @@ FluidbookSupport.prototype = { var tzoom = DetectZoom.zoom(); var iz; if (this._orientation == 0) { - iz=this.initialZoomPortrait; - if(iz==0){ - iz=this.initialZoomPortrait=tzoom; + iz = this.initialZoomPortrait; + if (iz == 0) { + iz = this.initialZoomPortrait = tzoom; } - }else{ - iz=this.initialZoomLandscape; - if(iz==0){ - iz=this.initialZoomLandscape=tzoom; + } else { + iz = this.initialZoomLandscape; + if (iz == 0) { + iz = this.initialZoomLandscape = tzoom; } } return tzoom / iz; diff --git a/js/libs/fluidbook/views/fluidbook.index.js b/js/libs/fluidbook/views/fluidbook.index.js index 8255d3fd..1cdbb569 100644 --- a/js/libs/fluidbook/views/fluidbook.index.js +++ b/js/libs/fluidbook/views/fluidbook.index.js @@ -32,7 +32,7 @@ FluidbookIndex.prototype = { ix = ''; c = ''; if (i > 0) { - ix += '
' + this.fluidbook.physicalToVirtual(i) + ''; + ix += '
' + this.fluidbook.loader.getImage('data/thumbnails/p' + i + '.jpg') + '' + this.fluidbook.physicalToVirtual(i) + ''; if (this.fluidbook.bookmarks.enabled) { ix += this.fluidbook.bookmarks.getBookmarkForPage(i, true); } @@ -43,7 +43,7 @@ FluidbookIndex.prototype = { c = ' simple right'; } if (j < this.fluidbook.datas.pages) { - ix += '
' + this.fluidbook.physicalToVirtual(j) + ''; + ix += '
' + this.fluidbook.loader.getImage('data/thumbnails/p' + j + '.jpg') + '' + this.fluidbook.physicalToVirtual(j) + ''; if (this.fluidbook.bookmarks.enabled) { ix += this.fluidbook.bookmarks.getBookmarkForPage(j, true); } diff --git a/js/libs/gal/gal.filesystem.js b/js/libs/gal/gal.filesystem.js new file mode 100644 index 00000000..b5d3a290 --- /dev/null +++ b/js/libs/gal/gal.filesystem.js @@ -0,0 +1,262 @@ +/* + * Copyright 2011 Google Inc. All Rights Reserved. + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +/** + * @fileoverview The filesystem adapter used by Game Asset Loader. + * @author smus@google.com (Boris Smus) + */ + +(function(gal) { + var ROOT_DIR = 'gal'; + var DEFAULT_QUOTA = 1024 * 1024 * 100; + + function onError(error) { + var message; + switch (error.code) { + case FileError.NOT_FOUND_ERR: + message = 'not found'; + break; + case FileError.SECURITY_ERR: + message = 'security'; + break; + case FileError.ABORT_ERR: + message = 'abort'; + break; + case FileError.NOT_READABLE_ERR: + message = 'not readable'; + break; + case FileError.ENCODING_ERR: + message = 'encoding'; + break; + case FileError.NO_MODIFICATION_ALLOWED_ERR: + message = 'no modification allowed'; + break; + case FileError.INVALID_STATE_ERR: + message = 'invalid state'; + break; + case FileError.SYNTAX_ERR: + message = 'syntax'; + break; + case FileError.INVALID_MODIFICATION_ERR: + message = 'invalid modification'; + break; + case FileError.QUOTA_EXCEEDED_ERR: + message = 'quota exceeded'; + break; + case FileError.TYPE_MISMATCH_ERR: + message = 'type mismatch'; + break; + case FileError.PATH_EXISTS_ERR: + message = 'path exists'; + break; + + } + + + console.error('Filesystem error:', error.code + ' :: ' + message); + } + ; + + + + /** + * @private + * Helper to create file at path, as well as intermediate directories in the + * path. Behaves roughly like `mkdir -p` + * @param {DirectoryEntry} root Directory at the root of the gal. + * @param {array} folders Folder heirarchy to create. + * @param {function} callback Called when the directory structure is created + * @return DirectoryEntry to the directory that was just created. + */ + function createDir_(root, folders, callback) { + // Throw out './' or '/' and move on to prevent something like '/foo/.//bar'. + if (folders.length && (folders[0] === '.' || folders[0] === '')) { + folders = folders.slice(1); + } + + if (!folders.length) { + callback(root); + } + + + var f = folders.shift(); + + + root.getDirectory(f, {create: true}, function(dirEntry) { + if (folders.length > 0) { + createDir_(dirEntry, folders, callback); + } else { + callback(dirEntry); + } + }, onError); + } + ; + + /** + * @private + * Utility tools to emulate UNIX dirname. + * @param {string} path The path whose basename to get. + * @return {string} The contents of the path before the file name. + */ + function dirname_(path) { + var match = path.match(/(.*)\//); + return match && match[1] || ''; + } + ; + + /** + * @private + * Utility tools to emulate UNIX basename. + * @param {string} path The path whose basename to get. + * @return {string} The contents of the path after the file name. + */ + function basename_(path) { + return path.replace(/.*\//, ''); + } + ; + + + /** + * Class for serializing game assets (for GAL) using the filesystem API. + * @constructor + */ + function GALFS() { + // Table to store lookups from file path fragment to filesystem URL + this.lookupTable = {}; + } + ; + + /** + * Initializes the adapter. + * @param {function} callback The callback to call once the adapter has been + * initialized. + * @param {string} opt_quota The quota (in bytes) to request (optional). + */ + GALFS.prototype.init = function(callback, opt_quota) { + // requestFileSystem and storageInfo shims + var requestFileSystem = window.requestFileSystem || + window.webkitRequestFileSystem; + var storageInfo = window.storageInfo || window.webkitStorageInfo; + + var quota = opt_quota || DEFAULT_QUOTA; + + var that = this; + // Callback when the filesystem has been initialized + var onInitFs = function(fs) { + that.fs = fs; + + // Create a directory for the root of the GAL + fs.root.getDirectory(ROOT_DIR, {create: true}, function(dirEntry) { + that.root = dirEntry; + callback(); + }, onError); + }; + + // Callback when the filesystem API has granted quota + var quotaCallback = function(grantedBytes) { + var persistent = LocalFileSystem.PERSISTENT; + // Save grantedBytes in the adapter + that.grantedBytes = grantedBytes; + // Once quota is grantedBytes, initialize a filesystem + requestFileSystem(persistent, 0, onInitFs, onError); + }; + + if (storageInfo != undefined) { + // Get quota + storageInfo.requestQuota(window.PERSISTENT, quota, + quotaCallback, onError); + } else { + quotaCallback(0); + } + + }; + + /** + * Saves an asset at the given URL to the filesystem API callback when + * successfully saved. + * @param {string} key The key path to use for storing the asset. + * @param {string} url The URL to the asset. + * @param {function} callback The function to call when the asset was saved. + * @param {function} failCallback The function to call when an error occurred. + */ + GALFS.prototype.saveAsset = function(key, url, callback, failCallback) { + // BlobBuilder shim + var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder; + + var root = this.root; + var lookupTable = this.lookupTable; + + createDir_(root, dirname_(key).split('/'), function(dir) { + var file = basename_(key); + dir.getFile(file, {create: true}, function(fileEntry) { + var fileTransfer = new FileTransfer(); + fileTransfer.download(url, fileEntry.fullPath, function(entry) { + lookupTable[key] = entry.toURL(); + callback(); + }, failCallback); + }, failCallback); + }); + + }; + + /** + * Gets the filesystem path for the asset stored at the given URL. + * @param {string} key The key path to the asset. + * @return {string} URL to the filesystem. + */ + GALFS.prototype.getAssetUrl = function(key) { + return this.lookupTable[key]; + }; + + /** + * Checks if a file with the specified key exists in the filesystem. + * @param {string} key The key path to the asset. + * @param {function} callback The callback to call if the file exists. + * @param {function} failCallback The callback to call if the file + * doesn't exist. + */ + GALFS.prototype.checkAsset = function(key, callback, failCallback) { + var lookupTable = this.lookupTable; + this.root.getFile(key, {}, function(fileEntry) { + // Save the file in the lookup table. + lookupTable[key] = fileEntry.toURL(); + callback(); + }, failCallback); + }; + + /** + * Clears everything out of the root directory. Mostly for unit testing. + */ + GALFS.prototype.clear = function() { + // Remove the root directory + this.root.removeRecursively(function() { + }, onError); + + var that = this; + // And then recreate it + this.fs.root.getDirectory(ROOT_DIR, {create: true}, function(dirEntry) { + that.root = dirEntry; + }, onError); + }; + + if (!gal) { + throw 'Game asset loader needs to be loaded before loading the fs adapter'; + } + + gal.adapterClass = GALFS; + +}(GameAssetLoader)); diff --git a/js/libs/gal/gal.js b/js/libs/gal/gal.js new file mode 100644 index 00000000..8835c773 --- /dev/null +++ b/js/libs/gal/gal.js @@ -0,0 +1,321 @@ +/* + * Copyright 2011 Google Inc. All Rights Reserved. + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +/** + * @fileoverview Asset loader library. + * @author smus@google.com (Boris Smus) + */ +(function(exports) { + + /** + * @constructor + * @param {Object} manifest URL to manifest file. + */ + var GAL = function(manifest) { + this._manifest = manifest; + // Dictionary of arrays of all of the bundles contained in the manifest. + this.bundles = {}; + // Array of bundle names in the order that they appear in the manifest. + this.bundleOrder = []; + // Table of callbacks, per bundle. + this.loaded = {}; + this.progress = {}; + this.error = {}; + }; + + /** + * Initializes loader. + * @param {Function} callback called when the library finishes loading the + * manifest. + */ + GAL.prototype.init = function(callback) { + var that = this; + finishInit_.call(that, this._manifest, callback) + }; + + /** + * Downloads assets contained in the named bundle. + * @param {string} bundleName name of single bundle to download. + */ + GAL.prototype.download = function(bundleName) { + var bundle = this.bundles[bundleName]; + + if (!bundle) { + // Attempting to download invalid bundle. + throw "Invalid bundle specified"; + } + var that = this; + + + // If offline, check for downloaded resources, and if they exist, callback. + this.check(bundleName, function(result) { + if (result.success) { + // Already downloaded. Success! + fireCallback_(that.loaded, bundleName, { + success: true, + cached: true, + bundleName: bundleName + }); + } else { + if (!that.online()) { + // Otherwise, since we're offline, error out. + fireCallback_(that.error, bundleName, { + error: 'Missing resources cant be downloaded while offline' + }); + } else { + // Setup a loop via callback chaining. + (function loop(index) { + // If we've finished loading all of the assets in the bundle. + if (index == bundle.length) { + fireCallback_(that.loaded, bundleName, { + bundleName: bundleName, + success: true + }); + return; + } + + var key = bundle[index]; + // Get the full url to the asset. + var url = that.manifest.assetRoot + key; + // Fetch full url and store it locally. + that.adapter.saveAsset(key, url, function() { + fireCallback_(that.progress, bundleName, { + current: index + 1, + total: bundle.length + }); + // Iterate to the next file. + loop(index + 1); + }); + + })(0); + } + } + }); + }; + + + + + /** + * Adds a callback to fire when a bundle has been loaded. + * @param {string} opt_bundleName Name of bundle to monitor (if none specified, + * monitor all bundles). + * @param {function} callback Called after bundle was downloaded. + */ + GAL.prototype.onLoaded = function(opt_bundleName, callback) { + addCallback_(this.loaded, opt_bundleName, callback); + }; + + /** + * Adds a callback to fire when a bundle's downloading has progressed. + * @param {string} opt_bundleName Name of bundle to monitor (if none specified, + * monitor all bundles). + * @param {function} callback Called after bundle download progressed. + */ + GAL.prototype.onProgress = function(opt_bundleName, callback) { + addCallback_(this.progress, opt_bundleName, callback); + }; + + /** + * Adds a callback to fire when a bundle's downloading has failed + * @param {string} opt_bundleName Name of bundle to monitor (if none specified, + * monitor all bundles). + * @param {function} callback Called after bundle download failed. + */ + GAL.prototype.onError = function(opt_bundleName, callback) { + addCallback_(this.error, opt_bundleName, callback); + }; + + /** + * Checks if a bundle is already downloaded. + * @param {string} bundleName Name of bundle to check. + * @param {function} callback Called with the result. + */ + GAL.prototype.check = function(bundleName, callback) { + var bundle = this.bundles[bundleName]; + if (!bundle) { + callback({success: false}); + return; + } + + var adapter = this.adapter; + (function loop(index) { + // If we've finished loading all of the assets in the bundle. + if (index == bundle.length) { + callback({success: true}); + return; + } + var key = bundle[index]; + adapter.checkAsset(key, function() { + // Iterate to the next file. + loop(index + 1); + }, function() { + // Failure. + callback({success: false}); + }); + + })(0); + }; + + /** + * Gets URL to loaded asset. + * @param {string} assetPath path of the asset relative to the manifest + * root. + * @return {string} url to the asset in the local filesystem. + * @throws {exception} if the asset doesn't actually exist. + */ + GAL.prototype.get = function(assetPath) { + return this.adapter.getAssetUrl(assetPath) || null; + }; + + /** + * Gets the last cached time for an asset at a given path. + * @param {string} assetPath relative path of asset. + * @return {number} UNIX time of the last time the asset was cached. + */ + GAL.prototype.cacheTime = function(assetPath) { + // TODO(smus): implement me! + return Math.random(); + }; + + /** + * @return {Boolean} true iff the browser is online. + */ + GAL.prototype.online = function() { + return navigator.onLine; + }; + + GAL.prototype.getRootURL = function() { + return this.adapter.root.toURL(); + } + + + /** + * @private + * Sets the manifest and parses out bundles and bundle order. + * @param {function} callback Called when the adapter has initialized. + */ + function initAdapter_(callback) { + this.adapter = new GAL.adapterClass(); + this.adapter.init(function() { + callback(); + }); + } + + /** + * @private + * Fetches JSON at a URL and calls the callback with the parsed object. + * @param {object} manifest The manifest object. + */ + function setManifest_(manifest) { + this.manifest = manifest; + // Set this.bundles object and this.bundleOrder array + for (var i = 0, bundle; bundle = manifest.bundles[i]; ++i) { + this.bundles[bundle.name] = bundle.contents; + this.bundleOrder.push(bundle.name); + } + } + + /** + * @private + * Initializes the adapter and assigns the manifest. + * Starts downloading assets if the manifest is set to autoDownload. + * @param {object} manifest The manifest object. + * @param {function} callback Called when the initialization is finished. + */ + function finishInit_(manifest, callback) { + var context = this; + initAdapter_.call(context, function() { + setManifest_.call(context, manifest); + // Optionally, start auto-download. + if (manifest.autoDownload && context.online()) { + downloadAll_.call(context); + } + callback(); + }); + } + + /** + * @private + * Adds a callback associated with a bundle name. + * @param {object} callbacks an object associated with an event type + * (ex. bundle loaded, bundle load progress updated, bundle failed). + * @param {string} bundleName the name of the bundle to monitor. If set + * to "*", all bundles will be monitored. + * @param {function} callback the function to call. + */ + function addCallback_(callbacks, bundleName, callback) { + if (typeof bundleName == "function") { + // bundleName is optional, and may be a callback instead. + callback = bundleName; + bundleName = '*'; + } + if (!callbacks[bundleName]) { + // Add an empty array. + callbacks[bundleName] = []; + } + + callbacks[bundleName].push(callback); + } + + /** + * @private + * Fires callbacks of a given type for a certain bundle. + * @param {object} object dictionary of callbacks. + * @param {string} bundleName string with the name of the bundle. + * @param {object} params to call the callback with. + */ + function fireCallback_(callbacks, bundleName, params) { + // Fire the principle callbacks, indexed by given bundleName. + fireCallbackHelper_(callbacks, bundleName, params); + // Also fire all * callbacks. + fireCallbackHelper_(callbacks, '*', params); + } + function fireCallbackHelper_(object, bundleName, params) { + var callbacks = object[bundleName]; + if (callbacks) { + for (var i = 0, callback; callback = callbacks[i]; ++i) { + callbacks[i](params); + } + } + } + + /** + * @private + * Starts downloading all of the assets in the manifest, in order. + */ + function downloadAll_() { + var that = this; + // Start by downloading the first bundle, then download subsequent ones. + (function loop(bundleIndex) { + if (bundleIndex == that.bundleOrder.length) { + // We're done downloading stuff! + return; + } + var bundleName = that.bundleOrder[bundleIndex]; + that.onLoaded(bundleName, function() { + // Once bundle is loaded, load the next bundle. + loop(bundleIndex + 1); + }); + that.download(bundleName); + })(0); + } + + exports.GameAssetLoader = GAL; + +})(window); + diff --git a/js/libs/gsap/TimelineLite.js b/js/libs/gsap/TimelineLite.js index 1128f444..b56cf5f2 100644 --- a/js/libs/gsap/TimelineLite.js +++ b/js/libs/gsap/TimelineLite.js @@ -1,6 +1,6 @@ /*! - * VERSION: beta 1.9.8 - * DATE: 2013-06-05 + * VERSION: beta 1.10.1 + * DATE: 2013-07-10 * UPDATES AND DOCS AT: http://www.greensock.com * * @license Copyright (c) 2008-2013, GreenSock. All rights reserved. @@ -24,25 +24,17 @@ this._sortChildren = true; this._onUpdate = this.vars.onUpdate; var v = this.vars, - i = _paramProps.length, - j, a; - while (--i > -1) { - a = v[_paramProps[i]]; - if (a) { - j = a.length; - while (--j > -1) { - if (a[j] === "{self}") { - a = v[_paramProps[i]] = a.concat(); //copy the array in case the user referenced the same array in multiple timelines/tweens (each {self} should be unique) - a[j] = this; - } - } + val, p; + for (p in v) { + val = v[p]; + if (val instanceof Array) if (val.join("").indexOf("{self}") !== -1) { + v[p] = this._swapSelfInParams(val); } } if (v.tweens instanceof Array) { this.add(v.tweens, 0, v.align, v.stagger); } }, - _paramProps = ["onStartParams","onUpdateParams","onCompleteParams","onReverseCompleteParams","onRepeatParams"], _blankArray = [], _copy = function(vars) { var copy = {}, p; @@ -51,10 +43,16 @@ } return copy; }, + _pauseCallback = function(tween, callback, params, scope) { + tween._timeline.pause(tween._startTime); + if (callback) { + callback.apply(scope || tween._timeline, params || _blankArray); + } + }, _slice = _blankArray.slice, p = TimelineLite.prototype = new SimpleTimeline(); - TimelineLite.version = "1.9.8"; + TimelineLite.version = "1.10.1"; p.constructor = TimelineLite; p.kill()._gc = false; @@ -76,7 +74,7 @@ if (typeof(targets) === "string") { targets = TweenLite.selector(targets) || targets; } - if (!(targets instanceof Array) && targets.length && targets[0] && targets[0].nodeType && targets[0].style) { //senses if the targets object is a selector. If it is, we should translate it into an array. + if (!(targets instanceof Array) && targets.length && targets !== window && targets[0] && (targets[0] === window || (targets[0].nodeType && targets[0].style && !targets.nodeType))) { //senses if the targets object is a selector. If it is, we should translate it into an array. targets = _slice.call(targets, 0); } stagger = stagger || 0; @@ -235,6 +233,10 @@ this._labels[label] = this._parseTimeOrLabel(position); return this; }; + + p.addPause = function(position, callback, params, scope) { + return this.call(_pauseCallback, ["{self}", callback, params, scope], this, position); + }; p.removeLabel = function(label) { delete this._labels[label]; @@ -298,8 +300,7 @@ if (this._gc) { this._enabled(true, false); } - this._active = !this._paused; - var totalDur = (!this._dirty) ? this._totalDuration : this.totalDuration(), + var totalDur = (!this._dirty) ? this._totalDuration : this.totalDuration(), prevTime = this._time, prevStart = this._startTime, prevTimeScale = this._timeScale, @@ -345,10 +346,15 @@ } else if (!this._initted) { this._initted = true; } + + if (!this._active) if (!this._paused && this._time !== prevTime && time > 0) { + this._active = true; //so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example. + } + if (prevTime === 0) if (this.vars.onStart) if (this._time !== 0) if (!suppressEvents) { this.vars.onStart.apply(this.vars.onStartScope || this, this.vars.onStartParams || _blankArray); } - + if (this._time >= prevTime) { tween = this._first; while (tween) { @@ -356,7 +362,7 @@ if (this._paused && !prevPaused) { //in case a tween pauses the timeline when rendering break; } else if (tween._active || (tween._startTime <= this._time && !tween._paused && !tween._gc)) { - + if (!tween._reversed) { tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force); } else { diff --git a/js/libs/gsap/TimelineMax.js b/js/libs/gsap/TimelineMax.js index 9c20e673..e42d34a9 100644 --- a/js/libs/gsap/TimelineMax.js +++ b/js/libs/gsap/TimelineMax.js @@ -1,6 +1,6 @@ /*! - * VERSION: beta 1.9.8 - * DATE: 2013-06-05 + * VERSION: beta 1.10.1 + * DATE: 2013-07-10 * UPDATES AND DOCS AT: http://www.greensock.com * * @license Copyright (c) 2008-2013, GreenSock. All rights reserved. @@ -12,6 +12,8 @@ (window._gsQueue || (window._gsQueue = [])).push( function() { + "use strict"; + window._gsDefine("TimelineMax", ["TimelineLite","TweenLite","easing.Ease"], function(TimelineLite, TweenLite, Ease) { var TimelineMax = function(vars) { @@ -37,7 +39,7 @@ p.constructor = TimelineMax; p.kill()._gc = false; - TimelineMax.version = "1.9.8"; + TimelineMax.version = "1.10.1"; p.invalidate = function() { this._yoyo = (this.vars.yoyo === true); @@ -102,7 +104,6 @@ if (this._gc) { this._enabled(true, false); } - this._active = !this._paused; var totalDur = (!this._dirty) ? this._totalDuration : this.totalDuration(), dur = this._duration, prevTime = this._time, @@ -238,6 +239,10 @@ } else if (!this._initted) { this._initted = true; } + + if (!this._active) if (!this._paused && this._totalTime !== prevTotalTime && time > 0) { + this._active = true; //so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example. + } if (prevTotalTime === 0) if (this.vars.onStart) if (this._totalTime !== 0) if (!suppressEvents) { this.vars.onStart.apply(this.vars.onStartScope || this, this.vars.onStartParams || _blankArray); @@ -459,25 +464,17 @@ this._sortChildren = true; this._onUpdate = this.vars.onUpdate; var v = this.vars, - i = _paramProps.length, - j, a; - while (--i > -1) { - a = v[_paramProps[i]]; - if (a) { - j = a.length; - while (--j > -1) { - if (a[j] === "{self}") { - a = v[_paramProps[i]] = a.concat(); //copy the array in case the user referenced the same array in multiple timelines/tweens (each {self} should be unique) - a[j] = this; - } - } + val, p; + for (p in v) { + val = v[p]; + if (val instanceof Array) if (val.join("").indexOf("{self}") !== -1) { + v[p] = this._swapSelfInParams(val); } } if (v.tweens instanceof Array) { this.add(v.tweens, 0, v.align, v.stagger); } }, - _paramProps = ["onStartParams","onUpdateParams","onCompleteParams","onReverseCompleteParams","onRepeatParams"], _blankArray = [], _copy = function(vars) { var copy = {}, p; @@ -486,10 +483,16 @@ } return copy; }, + _pauseCallback = function(tween, callback, params, scope) { + tween._timeline.pause(tween._startTime); + if (callback) { + callback.apply(scope || tween._timeline, params || _blankArray); + } + }, _slice = _blankArray.slice, p = TimelineLite.prototype = new SimpleTimeline(); - TimelineLite.version = "1.9.8"; + TimelineLite.version = "1.10.1"; p.constructor = TimelineLite; p.kill()._gc = false; @@ -511,7 +514,7 @@ if (typeof(targets) === "string") { targets = TweenLite.selector(targets) || targets; } - if (!(targets instanceof Array) && targets.length && targets[0] && targets[0].nodeType && targets[0].style) { //senses if the targets object is a selector. If it is, we should translate it into an array. + if (!(targets instanceof Array) && targets.length && targets !== window && targets[0] && (targets[0] === window || (targets[0].nodeType && targets[0].style && !targets.nodeType))) { //senses if the targets object is a selector. If it is, we should translate it into an array. targets = _slice.call(targets, 0); } stagger = stagger || 0; @@ -671,6 +674,10 @@ return this; }; + p.addPause = function(position, callback, params, scope) { + return this.call(_pauseCallback, ["{self}", callback, params, scope], this, position); + }; + p.removeLabel = function(label) { delete this._labels[label]; return this; @@ -733,7 +740,6 @@ if (this._gc) { this._enabled(true, false); } - this._active = !this._paused; var totalDur = (!this._dirty) ? this._totalDuration : this.totalDuration(), prevTime = this._time, prevStart = this._startTime, @@ -780,6 +786,11 @@ } else if (!this._initted) { this._initted = true; } + + if (!this._active) if (!this._paused && this._time !== prevTime && time > 0) { + this._active = true; //so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example. + } + if (prevTime === 0) if (this.vars.onStart) if (this._time !== 0) if (!suppressEvents) { this.vars.onStart.apply(this.vars.onStartScope || this, this.vars.onStartParams || _blankArray); } diff --git a/js/libs/gsap/TweenLite.js b/js/libs/gsap/TweenLite.js index cbab8978..6d902410 100644 --- a/js/libs/gsap/TweenLite.js +++ b/js/libs/gsap/TweenLite.js @@ -1,6 +1,6 @@ /*! - * VERSION: beta 1.9.8 - * DATE: 2013-06-05 + * VERSION: beta 1.10.1 + * DATE: 2013-07-10 * UPDATES AND DOCS AT: http://www.greensock.com * * @license Copyright (c) 2008-2013, GreenSock. All rights reserved. @@ -462,15 +462,23 @@ } return this; }; + + p._swapSelfInParams = function(params) { + var i = params.length, + copy = params.concat(); + while (--i > -1) { + if (params[i] === "{self}") { + copy[i] = this; + } + } + return copy; + }; //----Animation getters/setters -------------------------------------------------------- p.eventCallback = function(type, callback, params, scope) { - if (type == null) { - return null; - } else if (type.substr(0,2) === "on") { - var v = this.vars, - i; + if ((type || "").substr(0,2) === "on") { + var v = this.vars; if (arguments.length === 1) { return v[type]; } @@ -478,17 +486,8 @@ delete v[type]; } else { v[type] = callback; - v[type + "Params"] = params; + v[type + "Params"] = ((params instanceof Array) && params.join("").indexOf("{self}") !== -1) ? this._swapSelfInParams(params) : params; v[type + "Scope"] = scope; - if (params) { - i = params.length; - while (--i > -1) { - if (params[i] === "{self}") { - params = v[type + "Params"] = params.concat(); //copying the array avoids situations where the same array is passed to multiple tweens/timelines and {self} doesn't correctly point to each individual instance. - params[i] = this; - } - } - } } if (type === "onUpdate") { this._onUpdate = callback; @@ -557,13 +556,15 @@ time = totalDuration; } this._startTime = (this._paused ? this._pauseTime : tl._time) - ((!this._reversed ? time : totalDuration - time) / this._timeScale); - if (!tl._dirty) { //for performance improvement. If the parent's cache is already dirty, it already took care of marking the anscestors as dirty too, so skip the function call here. + if (!tl._dirty) { //for performance improvement. If the parent's cache is already dirty, it already took care of marking the ancestors as dirty too, so skip the function call here. this._uncache(false); } - if (!tl._active) { - //in case any of the anscestors had completed but should now be enabled... + //in case any of the ancestor timelines had completed but should now be enabled, we should reset their totalTime() which will also ensure that they're lined up properly and enabled. Skip for animations that are on the root (wasteful). Example: a TimelineLite.exportRoot() is performed when there's a paused tween on the root, the export will not complete until that tween is unpaused, but imagine a child gets restarted later, after all [unpaused] tweens have completed. The startTime of that child would get pushed out, but one of the ancestors may have completed. + if (tl._timeline) { while (tl._timeline) { - tl.totalTime(tl._totalTime, true); + if (tl._timeline._time !== (tl._startTime + tl._totalTime) / tl._timeScale) { + tl.totalTime(tl._totalTime, true); + } tl = tl._timeline; } } @@ -624,9 +625,10 @@ if (!_tickerActive && !value) { _ticker.wake(); } - var raw = this._timeline.rawTime(), + var tl = this._timeline, + raw = tl.rawTime(), elapsed = raw - this._pauseTime; - if (!value && this._timeline.smoothChildTiming) { + if (!value && tl.smoothChildTiming) { this._startTime += elapsed; this._uncache(false); } @@ -634,7 +636,7 @@ this._paused = value; this._active = (!value && this._totalTime > 0 && this._totalTime < this._totalDuration); if (!value && elapsed !== 0 && this._duration !== 0) { - this.render(this._totalTime, true, true); + this.render((tl.smoothChildTiming ? this._totalTime : (raw - this._startTime) / this._timeScale), true, true); //in case the target's properties changed via some other tween or manual update by the user, we should force a render. } } if (this._gc && !value) { @@ -756,14 +758,14 @@ */ var TweenLite = _class("TweenLite", function(target, duration, vars) { Animation.call(this, duration, vars); - + if (target == null) { throw "Cannot tween a null target."; } this.target = target = (typeof(target) !== "string") ? target : TweenLite.selector(target) || target; - var isSelector = (target.jquery || (target.length && target[0] && target[0].nodeType && target[0].style && !target.nodeType)), + var isSelector = (target.jquery || (target.length && target !== window && target[0] && (target[0] === window || (target[0].nodeType && target[0].style && !target.nodeType)))), overwrite = this.vars.overwrite, i, targ, targets; @@ -784,7 +786,7 @@ targets.splice(i+1, 1); //to avoid an endless loop (can't imagine why the selector would return a string, but just in case) } continue; - } else if (targ.length && targ[0] && targ[0].nodeType && targ[0].style && !targ.nodeType) { //in case the user is passing in an array of selector objects (like jQuery objects), we need to check one more level and pull things out if necessary. Also note that elements pass all the criteria regarding length and the first child having style, so we must also check to ensure the target isn't an HTML node itself. targets.splice(i--, 1); this._targets = targets = targets.concat(_slice.call(targ, 0)); continue; @@ -794,7 +796,7 @@ _applyOverwrite(targ, this, null, 1, this._siblings[i]); } } - + } else { this._propLookup = {}; this._siblings = _register(target, this, false); @@ -807,13 +809,13 @@ } }, true), _isSelector = function(v) { - return (v.length && v[0] && v[0].nodeType && v[0].style && !v.nodeType); + return (v.length && v !== window && v[0] && (v[0] === window || (v[0].nodeType && v[0].style && !v.nodeType))); //we cannot check "nodeType" if the target is window from within an iframe, otherwise it will trigger a security error in some browsers like Firefox. }, _autoCSS = function(vars, target) { var css = {}, p; for (p in vars) { - if (!_reservedProps[p] && (!(p in target) || p === "x" || p === "y" || p === "width" || p === "height" || p === "className") && (!_plugins[p] || (_plugins[p] && _plugins[p]._autoCSS))) { //note: elements contain read-only "x" and "y" properties. We should also prioritize editing css width/height rather than the element's properties. + if (!_reservedProps[p] && (!(p in target) || p === "x" || p === "y" || p === "width" || p === "height" || p === "className" || p === "border") && (!_plugins[p] || (_plugins[p] && _plugins[p]._autoCSS))) { //note: elements contain read-only "x" and "y" properties. We should also prioritize editing css width/height rather than the element's properties. css[p] = vars[p]; delete vars[p]; } @@ -831,7 +833,7 @@ p._firstPT = p._targets = p._overwrittenProps = p._startAt = null; p._notifyPluginsOfEnabled = false; - TweenLite.version = "1.9.8"; + TweenLite.version = "1.10.1"; TweenLite.defaultEase = p._ease = new Ease(null, null, 1, 1); TweenLite.defaultOverwrite = "auto"; TweenLite.ticker = _ticker; @@ -1050,19 +1052,14 @@ if (target == null) { return false; } - if (!this.vars.css) if (target.style) if (target.nodeType) if (_plugins.css) if (this.vars.autoCSS !== false) { //it's so common to use TweenLite/Max to animate the css of DOM elements, we assume that if the target is a DOM element, that's what is intended (a convenience so that users don't have to wrap things in css:{}, although we still recommend it for a slight performance boost and better specificity) + if (!this.vars.css) if (target.style) if (target !== window && target.nodeType) if (_plugins.css) if (this.vars.autoCSS !== false) { //it's so common to use TweenLite/Max to animate the css of DOM elements, we assume that if the target is a DOM element, that's what is intended (a convenience so that users don't have to wrap things in css:{}, although we still recommend it for a slight performance boost and better specificity). Note: we cannot check "nodeType" on the window inside an iframe. _autoCSS(this.vars, target); } for (p in this.vars) { - if (_reservedProps[p]) { - if (p === "onStartParams" || p === "onUpdateParams" || p === "onCompleteParams" || p === "onReverseCompleteParams" || p === "onRepeatParams") if ((a = this.vars[p])) { - i = a.length; - while (--i > -1) { - if (a[i] === "{self}") { - a = this.vars[p] = a.concat(); //copy the array in case the user referenced the same array in multiple tweens/timelines (each {self} should be unique) - a[i] = this; - } - } + v = this.vars[p]; + if (_reservedProps[p]) { + if (v instanceof Array) if (v.join("").indexOf("{self}") !== -1) { + this.vars[p] = v = this._swapSelfInParams(v, this); } } else if (_plugins[p] && (plugin = new _plugins[p]())._onInitTween(target, this.vars[p], this)) { @@ -1090,7 +1087,6 @@ } else { this._firstPT = propLookup[p] = pt = {_next:this._firstPT, t:target, p:p, f:(typeof(target[p]) === "function"), n:p, pg:false, pr:0}; pt.s = (!pt.f) ? parseFloat(target[p]) : target[ ((p.indexOf("set") || typeof(target["get" + p.substr(3)]) !== "function") ? p : "get" + p.substr(3)) ](); - v = this.vars[p]; pt.c = (typeof(v) === "string" && v.charAt(1) === "=") ? parseInt(v.charAt(0) + "1", 10) * Number(v.substr(2)) : (Number(v) - pt.s) || 0; } if (pt) if (pt._next) { @@ -1202,9 +1198,10 @@ } } - if (!this._active) if (!this._paused) { + if (!this._active) if (!this._paused && this._time !== prevTime && time >= 0) { this._active = true; //so that if the user renders a tween (as opposed to the timeline rendering it), the timeline is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the tween already finished but the user manually re-renders it as halfway done. } + if (prevTime === 0) { if (this._startAt) { if (time >= 0) { @@ -1440,17 +1437,18 @@ }, true); p = TweenPlugin.prototype; - TweenPlugin.version = "1.9.1"; + TweenPlugin.version = "1.10.1"; TweenPlugin.API = 2; p._firstPT = null; p._addTween = function(target, prop, start, end, overwriteProp, round) { var c, pt; - if (end != null && (c = (typeof(end) === "number" || end.charAt(1) !== "=") ? Number(end) - start : parseInt(end.charAt(0)+"1", 10) * Number(end.substr(2)))) { + if (end != null && (c = (typeof(end) === "number" || end.charAt(1) !== "=") ? Number(end) - start : parseInt(end.charAt(0) + "1", 10) * Number(end.substr(2)))) { this._firstPT = pt = {_next:this._firstPT, t:target, p:prop, s:start, c:c, f:(typeof(target[prop]) === "function"), n:overwriteProp || prop, r:round}; if (pt._next) { pt._next._prev = pt; } + return pt; } }; @@ -1461,7 +1459,7 @@ while (pt) { val = pt.c * v + pt.s; if (pt.r) { - val = (val + ((val > 0) ? 0.5 : -0.5)) >> 0; //about 4x faster than Math.round() + val = (val + ((val > 0) ? 0.5 : -0.5)) | 0; //about 4x faster than Math.round() } else if (val < min) if (val > -min) { //prevents issues with converting very small numbers to strings in the browser val = 0; } diff --git a/js/libs/gsap/TweenMax.js b/js/libs/gsap/TweenMax.js index 1579b079..68f55768 100644 --- a/js/libs/gsap/TweenMax.js +++ b/js/libs/gsap/TweenMax.js @@ -1,6 +1,6 @@ /*! - * VERSION: beta 1.9.8 - * DATE: 2013-06-05 + * VERSION: beta 1.10.1 + * DATE: 2013-07-10 * UPDATES AND DOCS AT: http://www.greensock.com * * Includes all of the following: TweenLite, TweenMax, TimelineLite, TimelineMax, EasePack, CSSPlugin, RoundPropsPlugin, BezierPlugin, AttrPlugin, DirectionalRotationPlugin @@ -28,12 +28,12 @@ this._dirty = true; //ensures that if there is any repeat, the totalDuration will get recalculated to accurately report it. }, _isSelector = function(v) { - return (v.jquery || (v.length && v[0] && v[0].nodeType && v[0].style && !v.nodeType)); + return (v.jquery || (v.length && v !== window && v[0] && (v[0] === window || (v[0].nodeType && v[0].style && !v.nodeType)))); //note: we cannot check "nodeType" on window from inside an iframe (some browsers throw a security error) }, p = TweenMax.prototype = TweenLite.to({}, 0.1, {}), _blankArray = []; - TweenMax.version = "1.9.8"; + TweenMax.version = "1.10.1"; p.constructor = TweenMax; p.kill()._gc = false; TweenMax.killTweensOf = TweenMax.killDelayedCallsTo = TweenLite.killTweensOf; @@ -216,7 +216,7 @@ } } - if (!this._active) if (!this._paused) { + if (!this._active) if (!this._paused && this._time !== prevTime && time >= 0) { this._active = true; //so that if the user renders a tween (as opposed to the timeline rendering it), the timeline is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the tween already finished but the user manually re-renders it as halfway done. } if (prevTotalTime === 0) { @@ -293,7 +293,7 @@ a = [], finalComplete = function() { if (vars.onComplete) { - vars.onComplete.apply(vars.onCompleteScope || this, vars.onCompleteParams || _blankArray); + vars.onComplete.apply(vars.onCompleteScope || this, arguments); } onCompleteAll.apply(onCompleteAllScope || this, onCompleteAllParams || _blankArray); }, @@ -439,12 +439,9 @@ }; var _changePause = function(pause, tweens, delayedCalls, timelines) { - if (tweens === undefined) { - tweens = true; - } - if (delayedCalls === undefined) { - delayedCalls = true; - } + tweens = (tweens !== false); + delayedCalls = (delayedCalls !== false); + timelines = (timelines !== false); var a = getAllTweens(timelines), allTrue = (tweens && delayedCalls && timelines), i = a.length, @@ -564,25 +561,17 @@ this._sortChildren = true; this._onUpdate = this.vars.onUpdate; var v = this.vars, - i = _paramProps.length, - j, a; - while (--i > -1) { - a = v[_paramProps[i]]; - if (a) { - j = a.length; - while (--j > -1) { - if (a[j] === "{self}") { - a = v[_paramProps[i]] = a.concat(); //copy the array in case the user referenced the same array in multiple timelines/tweens (each {self} should be unique) - a[j] = this; - } - } + val, p; + for (p in v) { + val = v[p]; + if (val instanceof Array) if (val.join("").indexOf("{self}") !== -1) { + v[p] = this._swapSelfInParams(val); } } if (v.tweens instanceof Array) { this.add(v.tweens, 0, v.align, v.stagger); } }, - _paramProps = ["onStartParams","onUpdateParams","onCompleteParams","onReverseCompleteParams","onRepeatParams"], _blankArray = [], _copy = function(vars) { var copy = {}, p; @@ -591,10 +580,16 @@ } return copy; }, + _pauseCallback = function(tween, callback, params, scope) { + tween._timeline.pause(tween._startTime); + if (callback) { + callback.apply(scope || tween._timeline, params || _blankArray); + } + }, _slice = _blankArray.slice, p = TimelineLite.prototype = new SimpleTimeline(); - TimelineLite.version = "1.9.8"; + TimelineLite.version = "1.10.1"; p.constructor = TimelineLite; p.kill()._gc = false; @@ -616,7 +611,7 @@ if (typeof(targets) === "string") { targets = TweenLite.selector(targets) || targets; } - if (!(targets instanceof Array) && targets.length && targets[0] && targets[0].nodeType && targets[0].style) { //senses if the targets object is a selector. If it is, we should translate it into an array. + if (!(targets instanceof Array) && targets.length && targets !== window && targets[0] && (targets[0] === window || (targets[0].nodeType && targets[0].style && !targets.nodeType))) { //senses if the targets object is a selector. If it is, we should translate it into an array. targets = _slice.call(targets, 0); } stagger = stagger || 0; @@ -776,6 +771,10 @@ return this; }; + p.addPause = function(position, callback, params, scope) { + return this.call(_pauseCallback, ["{self}", callback, params, scope], this, position); + }; + p.removeLabel = function(label) { delete this._labels[label]; return this; @@ -838,7 +837,6 @@ if (this._gc) { this._enabled(true, false); } - this._active = !this._paused; var totalDur = (!this._dirty) ? this._totalDuration : this.totalDuration(), prevTime = this._time, prevStart = this._startTime, @@ -885,6 +883,11 @@ } else if (!this._initted) { this._initted = true; } + + if (!this._active) if (!this._paused && this._time !== prevTime && time > 0) { + this._active = true; //so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example. + } + if (prevTime === 0) if (this.vars.onStart) if (this._time !== 0) if (!suppressEvents) { this.vars.onStart.apply(this.vars.onStartScope || this, this.vars.onStartParams || _blankArray); } @@ -1189,7 +1192,7 @@ p.constructor = TimelineMax; p.kill()._gc = false; - TimelineMax.version = "1.9.8"; + TimelineMax.version = "1.10.1"; p.invalidate = function() { this._yoyo = (this.vars.yoyo === true); @@ -1254,7 +1257,6 @@ if (this._gc) { this._enabled(true, false); } - this._active = !this._paused; var totalDur = (!this._dirty) ? this._totalDuration : this.totalDuration(), dur = this._duration, prevTime = this._time, @@ -1391,6 +1393,10 @@ this._initted = true; } + if (!this._active) if (!this._paused && this._totalTime !== prevTotalTime && time > 0) { + this._active = true; //so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example. + } + if (prevTotalTime === 0) if (this.vars.onStart) if (this._totalTime !== 0) if (!suppressEvents) { this.vars.onStart.apply(this.vars.onStartScope || this, this.vars.onStartParams || _blankArray); } @@ -2201,7 +2207,7 @@ p = CSSPlugin.prototype = new TweenPlugin("css"); p.constructor = CSSPlugin; - CSSPlugin.version = "1.9.8"; + CSSPlugin.version = "1.10.1"; CSSPlugin.API = 2; CSSPlugin.defaultTransformPerspective = 0; p = "px"; //we'll reuse the "p" variable to keep file size down @@ -2312,8 +2318,7 @@ t = cs.getPropertyValue(p.replace(_capsExp, "-$1").toLowerCase()); rv = (t || cs.length) ? t : cs[p]; //Opera behaves VERY strangely - length is usually 0 and cs[p] is the only way to get accurate results EXCEPT when checking for -o-transform which only works with cs.getPropertyValue()! } else if (t.currentStyle) { - cs = t.currentStyle; - rv = cs[p]; + rv = t.currentStyle[p]; } return (dflt != null && (!rv || rv === "none" || rv === "auto" || rv === "auto auto")) ? dflt : rv; }, @@ -3263,7 +3268,7 @@ a34 = a33*a34+tm.zOrigin-m[14]; } - //only parse from the matrix if we MUST because not only is it usually unnecessary due to the fact that we store the values in the _gsTransform object, but also because it's impossible to accurately interpret rotationX, rotationY, and rotationZ if all are applied, so it's much better to rely on what we store. However, we must parse the first time that an object is tweened. We also assume that if the position has changed, the user must have done some styling changes outside of CSSPlugin, thus we force a parse in that scenario. + //only parse from the matrix if we MUST because not only is it usually unnecessary due to the fact that we store the values in the _gsTransform object, but also because it's impossible to accurately interpret rotationX, rotationY, rotationZ, scaleX, and scaleY if all are applied, so it's much better to rely on what we store. However, we must parse the first time that an object is tweened. We also assume that if the position has changed, the user must have done some styling changes outside of CSSPlugin, thus we force a parse in that scenario. if (!rec || parse || tm.rotationX == null) { var a11 = m[0], a21 = m[1], a31 = m[2], a41 = m[3], a12 = m[4], a22 = m[5], a32 = m[6], a42 = m[7], @@ -3278,7 +3283,6 @@ t1 = a12*cos+a13*sin; t2 = a22*cos+a23*sin; t3 = a32*cos+a33*sin; - //t4 = a42*cos+a43*sin; a13 = a12*-sin+a13*cos; a23 = a22*-sin+a23*cos; a33 = a32*-sin+a33*cos; @@ -3286,7 +3290,6 @@ a12 = t1; a22 = t2; a32 = t3; - //a42 = t4; } //rotationY angle = tm.rotationY = Math.atan2(a13, a11); @@ -3297,15 +3300,12 @@ t1 = a11*cos-a13*sin; t2 = a21*cos-a23*sin; t3 = a31*cos-a33*sin; - //t4 = a41*cos-a43*sin; - //a13 = a11*sin+a13*cos; a23 = a21*sin+a23*cos; a33 = a31*sin+a33*cos; a43 = a41*sin+a43*cos; a11 = t1; a21 = t2; a31 = t3; - //a41 = t4; } //rotationZ angle = tm.rotation = Math.atan2(a21, a22); @@ -3465,19 +3465,16 @@ style.removeAttribute("filter"); } }, + _set3DTransformRatio = function(v) { var t = this.data, //refers to the element's _gsTransform object style = this.t.style, - perspective = t.perspective, - a11 = t.scaleX, a12 = 0, a13 = 0, a14 = 0, - a21 = 0, a22 = t.scaleY, a23 = 0, a24 = 0, - a31 = 0, a32 = 0, a33 = t.scaleZ, a34 = 0, - a41 = 0, a42 = 0, a43 = (perspective) ? -1 / perspective : 0, angle = t.rotation, - zOrigin = t.zOrigin, - rnd = 100000, - cos, sin, t1, t2, t3, t4, ffProp, n, sfx; - + sx = t.scaleX, + sy = t.scaleY, + sz = t.scaleZ, + a11, a12, a13, a14, a21, a22, a23, a24, a31, a32, a33, a34, a41, a42, a43, + perspective, zOrigin, rnd, cos, sin, t1, t2, t3, t4, ffProp, n, sfx; if (_isFirefox) { //Firefox has a bug that causes 3D elements to randomly disappear during animation unless a repaint is forced. One way to do this is change "top" or "bottom" by 0.05 which is imperceptible, so we go back and forth. Another way is to change the display to "none", read the clientTop, and then revert the display but that is much slower. ffProp = style.top ? "top" : style.bottom ? "bottom" : parseFloat(_getStyle(this.t, "top", null, false)) ? "bottom" : "top"; t1 = _getStyle(this.t, ffProp, null, false); @@ -3486,35 +3483,43 @@ t._ffFix = !t._ffFix; style[ffProp] = (t._ffFix ? n + 0.05 : n - 0.05) + sfx; } - if (angle || t.skewX) { - t1 = a11*Math.cos(angle); - t2 = a22*Math.sin(angle); - angle -= t.skewX; - a12 = a11*-Math.sin(angle); - a22 = a22*Math.cos(angle); - a11 = t1; - a21 = t2; - } else if (!t.rotationY && !t.rotationX && a33 === 1) { //if we're only translating and/or 2D scaling, this is faster... - style[_transformProp] = "translate3d(" + t.x + "px," + t.y + "px," + t.z +"px)" + ((a11 !== 1 || a22 !== 1) ? " scale(" + a11 + "," + a22 + ")" : ""); + cos = Math.cos(angle); + sin = Math.sin(angle); + a11 = cos; + a21 = sin; + if (t.skewX) { + angle -= t.skewX; + cos = Math.cos(angle); + sin = Math.sin(angle); + } + a12 = -sin; + a22 = cos; + } else if (!t.rotationY && !t.rotationX && sz === 1) { //if we're only translating and/or 2D scaling, this is faster... + style[_transformProp] = "translate3d(" + t.x + "px," + t.y + "px," + t.z +"px)" + ((sx !== 1 || sy !== 1) ? " scale(" + sx + "," + sy + ")" : ""); return; - } + } else { + a11 = a22 = 1; + a12 = a21 = 0; + } + a33 = 1; + a13 = a14 = a23 = a24 = a31 = a32 = a34 = a41 = a42 = 0; + perspective = t.perspective; + a43 = (perspective) ? -1 / perspective : 0; + zOrigin = t.zOrigin; + rnd = 100000; angle = t.rotationY; if (angle) { cos = Math.cos(angle); sin = Math.sin(angle); - t1 = a11*cos; - t2 = a21*cos; - t3 = a33*-sin; - t4 = a43*-sin; + a31 = a33*-sin; + a41 = a43*-sin; a13 = a11*sin; a23 = a21*sin; - a33 = a33*cos; + a33 *= cos; a43 *= cos; - a11 = t1; - a21 = t2; - a31 = t3; - a41 = t4; + a11 *= cos; + a21 *= cos; } angle = t.rotationX; if (angle) { @@ -3533,6 +3538,24 @@ a32 = t3; a42 = t4; } + if (sz !== 1) { + a13*=sz; + a23*=sz; + a33*=sz; + a43*=sz; + } + if (sy !== 1) { + a12*=sy; + a22*=sy; + a32*=sy; + a42*=sy; + } + if (sx !== 1) { + a11*=sx; + a21*=sx; + a31*=sx; + a41*=sx; + } if (zOrigin) { a34 -= zOrigin; a14 = a13*a34; @@ -3545,6 +3568,7 @@ a34 = (t1 = (a34 += t.z) - (a34 |= 0)) ? ((t1 * rnd + (t1 < 0 ? -0.5 : 0.5)) | 0) / rnd + a34 : a34; style[_transformProp] = "matrix3d(" + [ (((a11 * rnd) | 0) / rnd), (((a21 * rnd) | 0) / rnd), (((a31 * rnd) | 0) / rnd), (((a41 * rnd) | 0) / rnd), (((a12 * rnd) | 0) / rnd), (((a22 * rnd) | 0) / rnd), (((a32 * rnd) | 0) / rnd), (((a42 * rnd) | 0) / rnd), (((a13 * rnd) | 0) / rnd), (((a23 * rnd) | 0) / rnd), (((a33 * rnd) | 0) / rnd), (((a43 * rnd) | 0) / rnd), a14, a24, a34, (perspective ? (1 + (-a34 / perspective)) : 1) ].join(",") + ")"; }, + _set2DTransformRatio = function(v) { var t = this.data, //refers to the element's _gsTransform object targ = this.t, @@ -3571,7 +3595,7 @@ } }; - _registerComplexSpecialProp("transform,scale,scaleX,scaleY,scaleZ,x,y,z,rotation,rotationX,rotationY,rotationZ,skewX,skewY,shortRotation,shortRotationX,shortRotationY,shortRotationZ,transformOrigin,transformPerspective,directionalRotation,parseTransform", {parser:function(t, e, p, cssp, pt, plugin, vars) { + _registerComplexSpecialProp("transform,scale,scaleX,scaleY,scaleZ,x,y,z,rotation,rotationX,rotationY,rotationZ,skewX,skewY,shortRotation,shortRotationX,shortRotationY,shortRotationZ,transformOrigin,transformPerspective,directionalRotation,parseTransform,force3D", {parser:function(t, e, p, cssp, pt, plugin, vars) { if (cssp._transform) { return pt; } //only need to parse the transform once, and only if the browser supports it. var m1 = cssp._transform = _getTransform(t, _cs, true, vars.parseTransform), style = t.style, @@ -3620,7 +3644,12 @@ } } - has3D = (m1.z || m1.rotationX || m1.rotationY || m2.z || m2.rotationX || m2.rotationY || m2.perspective); + if (v.force3D != null) { + m1.force3D = v.force3D; + hasChange = true; + } + + has3D = (m1.force3D || m1.z || m1.rotationX || m1.rotationY || m2.z || m2.rotationX || m2.rotationY || m2.perspective); if (!has3D && v.scale != null) { m2.scaleZ = 1; //no need to tween scaleZ. } @@ -3644,15 +3673,15 @@ if (orig || (_supports3D && has3D && m1.zOrigin)) { //if anything 3D is happening and there's a transformOrigin with a z component that's non-zero, we must ensure that the transformOrigin's z-component is set to 0 so that we can manually do those calculations to get around Safari bugs. Even if the user didn't specifically define a "transformOrigin" in this particular tween (maybe they did it via css directly). if (_transformProp) { hasChange = true; - orig = (orig || _getStyle(t, p, _cs, false, "50% 50%")) + ""; //cast as string to avoid errors p = _transformOriginProp; + orig = (orig || _getStyle(t, p, _cs, false, "50% 50%")) + ""; //cast as string to avoid errors pt = new CSSPropTween(style, p, 0, 0, pt, -1, "transformOrigin"); pt.b = style[p]; pt.plugin = plugin; if (_supports3D) { copy = m1.zOrigin; orig = orig.split(" "); - m1.zOrigin = ((orig.length > 2) ? parseFloat(orig[2]) : copy) || 0; //Safari doesn't handle the z part of transformOrigin correctly, so we'll manually handle it in the _set3DTransformRatio() method. + m1.zOrigin = ((orig.length > 2 && !(copy !== 0 && orig[2] === "0px")) ? parseFloat(orig[2]) : copy) || 0; //Safari doesn't handle the z part of transformOrigin correctly, so we'll manually handle it in the _set3DTransformRatio() method. pt.xs0 = pt.e = style[p] = orig[0] + " " + (orig[1] || "50%") + " 0px"; //we must define a z value of 0px specifically otherwise iOS 5 Safari will stick with the old one (if one was defined)! pt = new CSSPropTween(m1, "zOrigin", 0, 0, pt, -1, pt.n); //we must create a CSSPropTween for the _gsTransform.zOrigin so that it gets reset properly at the beginning if the tween runs backward (as opposed to just setting m1.zOrigin here) pt.b = copy; @@ -3795,7 +3824,7 @@ //opacity-related var _setIEOpacityRatio = function(v) { var t = this.t, //refers to the element's style property - filters = t.filter, + filters = t.filter || _getStyle(this.data, "filter"), val = (this.s + this.c * v) | 0, skip; if (val === 100) { //for older versions of IE that need to use a filter to apply opacity, we should remove the filter if opacity hits 1 in order to improve performance, but make sure there isn't a transform (matrix) or gradient in the filters. @@ -3809,10 +3838,12 @@ } if (!skip) { if (this.xn1) { - t.filter = filters = filters || "alpha(opacity=100)"; //works around bug in IE7/8 that prevents changes to "visibility" from being applied properly if the filter is changed to a different alpha on the same frame. + t.filter = filters = filters || ("alpha(opacity=" + val + ")"); //works around bug in IE7/8 that prevents changes to "visibility" from being applied properly if the filter is changed to a different alpha on the same frame. } if (filters.indexOf("opacity") === -1) { //only used if browser doesn't support the standard opacity style property (IE 7 and 8) - t.filter += " alpha(opacity=" + val + ")"; //we round the value because otherwise, bugs in IE7/8 can prevent "visibility" changes from being applied properly. + if (val !== 0 || !this.xn1) { //bugs in IE7/8 won't render the filter properly if opacity is ADDED on the same frame/render as "visibility" changes (this.xn1 is 1 if this tween is an "autoAlpha" tween) + t.filter += " alpha(opacity=" + val + ")"; //we round the value because otherwise, bugs in IE7/8 can prevent "visibility" changes from being applied properly. + } } else { t.filter = filters.replace(_opacityExp, "opacity=" + val); } @@ -3821,22 +3852,16 @@ _registerComplexSpecialProp("opacity,alpha,autoAlpha", {defaultValue:"1", parser:function(t, e, p, cssp, pt, plugin) { var b = parseFloat(_getStyle(t, "opacity", _cs, false, "1")), style = t.style, - vb; + isAutoAlpha = (p === "autoAlpha"); e = parseFloat(e); - if (p === "autoAlpha") { - vb = _getStyle(t, "visibility", _cs); - if (b === 1 && vb === "hidden" && e !== 0) { //if visibility is initially set to "hidden", we should interpret that as intent to make opacity 0 (a convenience) - b = 0; - } - pt = new CSSPropTween(style, "visibility", 0, 0, pt, -1, null, false, 0, ((b !== 0) ? "visible" : "hidden"), ((e === 0) ? "hidden" : "visible")); - pt.xs0 = "visible"; - cssp._overwriteProps.push(pt.n); + if (isAutoAlpha && b === 1 && _getStyle(t, "visibility", _cs) === "hidden" && e !== 0) { //if visibility is initially set to "hidden", we should interpret that as intent to make opacity 0 (a convenience) + b = 0; } if (_supportsOpacity) { pt = new CSSPropTween(style, "opacity", b, e - b, pt); } else { pt = new CSSPropTween(style, "opacity", b * 100, (e - b) * 100, pt); - pt.xn1 = (p === "autoAlpha") ? 1 : 0; //we need to record whether or not this is an autoAlpha so that in the setRatio(), we know to duplicate the setting of the alpha in order to work around a bug in IE7 and IE8 that prevents changes to "visibility" from taking effect if the filter is changed to a different alpha(opacity) at the same time. Setting it to the SAME value first, then the new value works around the IE7/8 bug. + pt.xn1 = isAutoAlpha ? 1 : 0; //we need to record whether or not this is an autoAlpha so that in the setRatio(), we know to duplicate the setting of the alpha in order to work around a bug in IE7 and IE8 that prevents changes to "visibility" from taking effect if the filter is changed to a different alpha(opacity) at the same time. Setting it to the SAME value first, then the new value works around the IE7/8 bug. style.zoom = 1; //helps correct an IE issue. pt.type = 2; pt.b = "alpha(opacity=" + pt.s + ")"; @@ -3845,6 +3870,11 @@ pt.plugin = plugin; pt.setRatio = _setIEOpacityRatio; } + if (isAutoAlpha) { //we have to create the "visibility" PropTween after the opacity one in the linked list so that they run in the order that works properly in IE8 and earlier + pt = new CSSPropTween(style, "visibility", 0, 0, pt, -1, null, false, 0, ((b !== 0) ? "visible" : "hidden"), ((e === 0) ? "hidden" : "visible")); + pt.xs0 = "visible"; + cssp._overwriteProps.push(pt.n); + } return pt; }}); @@ -3916,17 +3946,20 @@ var _setClearPropsRatio = function(v) { if (v === 1 || v === 0) if (this.data._totalTime === this.data._totalDuration) { //this.data refers to the tween. Only clear at the END of the tween (remember, from() tweens make the ratio go from 1 to 0, so we can't just check that). - var all = (this.e === "all"), - s = this.t.style, - a = all ? s.cssText.split(";") : this.e.split(","), + if (this.e === "all") { + this.t.style.cssText = ""; + if (this.t._gsTransform) { + delete this.t._gsTransform; + } + return; + } + var s = this.t.style, + a = this.e.split(","), i = a.length, transformParse = _specialProps.transform.parse, p; while (--i > -1) { p = a[i]; - if (all) { - p = p.substr(0, p.indexOf(":")).split(" ").join(""); - } if (_specialProps[p]) { p = (_specialProps[p].parse === transformParse) ? _transformProp : _specialProps[p].p; //ensures that special properties use the proper browser-specific property name, like "scaleX" might be "-webkit-transform" or "boxShadow" might be "-moz-box-shadow" } @@ -3975,7 +4008,6 @@ _overwriteProps = this._overwriteProps; var style = target.style, v, pt, pt2, first, last, next, zIndex, tpt, threeD; - if (_reqSafariFix) if (style.zIndex === "") { v = _getStyle(target, "zIndex", _cs); if (v === "auto" || v === "") { @@ -4377,7 +4409,6 @@ return results; }; - TweenPlugin.activate([CSSPlugin]); return CSSPlugin; @@ -4486,8 +4517,9 @@ this._target = target; this._proxy = {}; for (p in value) { - this._addTween(this._proxy, p, parseFloat(target.getAttribute(p)), value[p], p); - this._overwriteProps.push(p); + if ( this._addTween(this._proxy, p, parseFloat(target.getAttribute(p)), value[p], p) ) { + this._overwriteProps.push(p); + } } return true; }, @@ -5397,14 +5429,22 @@ return this; }; + p._swapSelfInParams = function(params) { + var i = params.length, + copy = params.concat(); + while (--i > -1) { + if (params[i] === "{self}") { + copy[i] = this; + } + } + return copy; + }; + //----Animation getters/setters -------------------------------------------------------- p.eventCallback = function(type, callback, params, scope) { - if (type == null) { - return null; - } else if (type.substr(0,2) === "on") { - var v = this.vars, - i; + if ((type || "").substr(0,2) === "on") { + var v = this.vars; if (arguments.length === 1) { return v[type]; } @@ -5412,17 +5452,8 @@ delete v[type]; } else { v[type] = callback; - v[type + "Params"] = params; + v[type + "Params"] = ((params instanceof Array) && params.join("").indexOf("{self}") !== -1) ? this._swapSelfInParams(params) : params; v[type + "Scope"] = scope; - if (params) { - i = params.length; - while (--i > -1) { - if (params[i] === "{self}") { - params = v[type + "Params"] = params.concat(); //copying the array avoids situations where the same array is passed to multiple tweens/timelines and {self} doesn't correctly point to each individual instance. - params[i] = this; - } - } - } } if (type === "onUpdate") { this._onUpdate = callback; @@ -5491,13 +5522,15 @@ time = totalDuration; } this._startTime = (this._paused ? this._pauseTime : tl._time) - ((!this._reversed ? time : totalDuration - time) / this._timeScale); - if (!tl._dirty) { //for performance improvement. If the parent's cache is already dirty, it already took care of marking the anscestors as dirty too, so skip the function call here. + if (!tl._dirty) { //for performance improvement. If the parent's cache is already dirty, it already took care of marking the ancestors as dirty too, so skip the function call here. this._uncache(false); } - if (!tl._active) { - //in case any of the anscestors had completed but should now be enabled... + //in case any of the ancestor timelines had completed but should now be enabled, we should reset their totalTime() which will also ensure that they're lined up properly and enabled. Skip for animations that are on the root (wasteful). Example: a TimelineLite.exportRoot() is performed when there's a paused tween on the root, the export will not complete until that tween is unpaused, but imagine a child gets restarted later, after all [unpaused] tweens have completed. The startTime of that child would get pushed out, but one of the ancestors may have completed. + if (tl._timeline) { while (tl._timeline) { - tl.totalTime(tl._totalTime, true); + if (tl._timeline._time !== (tl._startTime + tl._totalTime) / tl._timeScale) { + tl.totalTime(tl._totalTime, true); + } tl = tl._timeline; } } @@ -5558,9 +5591,10 @@ if (!_tickerActive && !value) { _ticker.wake(); } - var raw = this._timeline.rawTime(), + var tl = this._timeline, + raw = tl.rawTime(), elapsed = raw - this._pauseTime; - if (!value && this._timeline.smoothChildTiming) { + if (!value && tl.smoothChildTiming) { this._startTime += elapsed; this._uncache(false); } @@ -5568,7 +5602,7 @@ this._paused = value; this._active = (!value && this._totalTime > 0 && this._totalTime < this._totalDuration); if (!value && elapsed !== 0 && this._duration !== 0) { - this.render(this._totalTime, true, true); + this.render((tl.smoothChildTiming ? this._totalTime : (raw - this._startTime) / this._timeScale), true, true); //in case the target's properties changed via some other tween or manual update by the user, we should force a render. } } if (this._gc && !value) { @@ -5697,7 +5731,7 @@ this.target = target = (typeof(target) !== "string") ? target : TweenLite.selector(target) || target; - var isSelector = (target.jquery || (target.length && target[0] && target[0].nodeType && target[0].style && !target.nodeType)), + var isSelector = (target.jquery || (target.length && target !== window && target[0] && (target[0] === window || (target[0].nodeType && target[0].style && !target.nodeType)))), overwrite = this.vars.overwrite, i, targ, targets; @@ -5718,7 +5752,7 @@ targets.splice(i+1, 1); //to avoid an endless loop (can't imagine why the selector would return a string, but just in case) } continue; - } else if (targ.length && targ[0] && targ[0].nodeType && targ[0].style && !targ.nodeType) { //in case the user is passing in an array of selector objects (like jQuery objects), we need to check one more level and pull things out if necessary. Also note that elements pass all the criteria regarding length and the first child having style, so we must also check to ensure the target isn't an HTML node itself. targets.splice(i--, 1); this._targets = targets = targets.concat(_slice.call(targ, 0)); continue; @@ -5741,13 +5775,13 @@ } }, true), _isSelector = function(v) { - return (v.length && v[0] && v[0].nodeType && v[0].style && !v.nodeType); + return (v.length && v !== window && v[0] && (v[0] === window || (v[0].nodeType && v[0].style && !v.nodeType))); //we cannot check "nodeType" if the target is window from within an iframe, otherwise it will trigger a security error in some browsers like Firefox. }, _autoCSS = function(vars, target) { var css = {}, p; for (p in vars) { - if (!_reservedProps[p] && (!(p in target) || p === "x" || p === "y" || p === "width" || p === "height" || p === "className") && (!_plugins[p] || (_plugins[p] && _plugins[p]._autoCSS))) { //note: elements contain read-only "x" and "y" properties. We should also prioritize editing css width/height rather than the element's properties. + if (!_reservedProps[p] && (!(p in target) || p === "x" || p === "y" || p === "width" || p === "height" || p === "className" || p === "border") && (!_plugins[p] || (_plugins[p] && _plugins[p]._autoCSS))) { //note: elements contain read-only "x" and "y" properties. We should also prioritize editing css width/height rather than the element's properties. css[p] = vars[p]; delete vars[p]; } @@ -5765,7 +5799,7 @@ p._firstPT = p._targets = p._overwrittenProps = p._startAt = null; p._notifyPluginsOfEnabled = false; - TweenLite.version = "1.9.8"; + TweenLite.version = "1.10.1"; TweenLite.defaultEase = p._ease = new Ease(null, null, 1, 1); TweenLite.defaultOverwrite = "auto"; TweenLite.ticker = _ticker; @@ -5984,19 +6018,14 @@ if (target == null) { return false; } - if (!this.vars.css) if (target.style) if (target.nodeType) if (_plugins.css) if (this.vars.autoCSS !== false) { //it's so common to use TweenLite/Max to animate the css of DOM elements, we assume that if the target is a DOM element, that's what is intended (a convenience so that users don't have to wrap things in css:{}, although we still recommend it for a slight performance boost and better specificity) + if (!this.vars.css) if (target.style) if (target !== window && target.nodeType) if (_plugins.css) if (this.vars.autoCSS !== false) { //it's so common to use TweenLite/Max to animate the css of DOM elements, we assume that if the target is a DOM element, that's what is intended (a convenience so that users don't have to wrap things in css:{}, although we still recommend it for a slight performance boost and better specificity). Note: we cannot check "nodeType" on the window inside an iframe. _autoCSS(this.vars, target); } for (p in this.vars) { + v = this.vars[p]; if (_reservedProps[p]) { - if (p === "onStartParams" || p === "onUpdateParams" || p === "onCompleteParams" || p === "onReverseCompleteParams" || p === "onRepeatParams") if ((a = this.vars[p])) { - i = a.length; - while (--i > -1) { - if (a[i] === "{self}") { - a = this.vars[p] = a.concat(); //copy the array in case the user referenced the same array in multiple tweens/timelines (each {self} should be unique) - a[i] = this; - } - } + if (v instanceof Array) if (v.join("").indexOf("{self}") !== -1) { + this.vars[p] = v = this._swapSelfInParams(v, this); } } else if (_plugins[p] && (plugin = new _plugins[p]())._onInitTween(target, this.vars[p], this)) { @@ -6024,7 +6053,6 @@ } else { this._firstPT = propLookup[p] = pt = {_next:this._firstPT, t:target, p:p, f:(typeof(target[p]) === "function"), n:p, pg:false, pr:0}; pt.s = (!pt.f) ? parseFloat(target[p]) : target[ ((p.indexOf("set") || typeof(target["get" + p.substr(3)]) !== "function") ? p : "get" + p.substr(3)) ](); - v = this.vars[p]; pt.c = (typeof(v) === "string" && v.charAt(1) === "=") ? parseInt(v.charAt(0) + "1", 10) * Number(v.substr(2)) : (Number(v) - pt.s) || 0; } if (pt) if (pt._next) { @@ -6136,9 +6164,10 @@ } } - if (!this._active) if (!this._paused) { + if (!this._active) if (!this._paused && this._time !== prevTime && time >= 0) { this._active = true; //so that if the user renders a tween (as opposed to the timeline rendering it), the timeline is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the tween already finished but the user manually re-renders it as halfway done. } + if (prevTime === 0) { if (this._startAt) { if (time >= 0) { @@ -6374,17 +6403,18 @@ }, true); p = TweenPlugin.prototype; - TweenPlugin.version = "1.9.1"; + TweenPlugin.version = "1.10.1"; TweenPlugin.API = 2; p._firstPT = null; p._addTween = function(target, prop, start, end, overwriteProp, round) { var c, pt; - if (end != null && (c = (typeof(end) === "number" || end.charAt(1) !== "=") ? Number(end) - start : parseInt(end.charAt(0)+"1", 10) * Number(end.substr(2)))) { + if (end != null && (c = (typeof(end) === "number" || end.charAt(1) !== "=") ? Number(end) - start : parseInt(end.charAt(0) + "1", 10) * Number(end.substr(2)))) { this._firstPT = pt = {_next:this._firstPT, t:target, p:prop, s:start, c:c, f:(typeof(target[prop]) === "function"), n:overwriteProp || prop, r:round}; if (pt._next) { pt._next._prev = pt; } + return pt; } }; @@ -6395,7 +6425,7 @@ while (pt) { val = pt.c * v + pt.s; if (pt.r) { - val = (val + ((val > 0) ? 0.5 : -0.5)) >> 0; //about 4x faster than Math.round() + val = (val + ((val > 0) ? 0.5 : -0.5)) | 0; //about 4x faster than Math.round() } else if (val < min) if (val > -min) { //prevents issues with converting very small numbers to strings in the browser val = 0; } diff --git a/js/libs/gsap/plugins/AttrPlugin.js b/js/libs/gsap/plugins/AttrPlugin.js index 2b8c8f49..e31e66bb 100644 --- a/js/libs/gsap/plugins/AttrPlugin.js +++ b/js/libs/gsap/plugins/AttrPlugin.js @@ -1,6 +1,6 @@ /*! - * VERSION: 0.1.0 - * DATE: 2013-02-22 + * VERSION: 0.2.0 + * DATE: 2013-07-10 * UPDATES AND DOCS AT: http://www.greensock.com * * @license Copyright (c) 2008-2013, GreenSock. All rights reserved. @@ -26,8 +26,9 @@ this._target = target; this._proxy = {}; for (p in value) { - this._addTween(this._proxy, p, parseFloat(target.getAttribute(p)), value[p], p); - this._overwriteProps.push(p); + if ( this._addTween(this._proxy, p, parseFloat(target.getAttribute(p)), value[p], p) ) { + this._overwriteProps.push(p); + } } return true; }, diff --git a/js/libs/gsap/plugins/CSSPlugin.js b/js/libs/gsap/plugins/CSSPlugin.js index a1a27833..83857b8c 100644 --- a/js/libs/gsap/plugins/CSSPlugin.js +++ b/js/libs/gsap/plugins/CSSPlugin.js @@ -1,6 +1,6 @@ /*! - * VERSION: beta 1.9.8 - * DATE: 2013-06-05 + * VERSION: beta 1.10.1 + * DATE: 2013-07-03 * UPDATES AND DOCS AT: http://www.greensock.com * * @license Copyright (c) 2008-2013, GreenSock. All rights reserved. @@ -28,7 +28,7 @@ p = CSSPlugin.prototype = new TweenPlugin("css"); p.constructor = CSSPlugin; - CSSPlugin.version = "1.9.8"; + CSSPlugin.version = "1.10.1"; CSSPlugin.API = 2; CSSPlugin.defaultTransformPerspective = 0; p = "px"; //we'll reuse the "p" variable to keep file size down @@ -139,8 +139,7 @@ t = cs.getPropertyValue(p.replace(_capsExp, "-$1").toLowerCase()); rv = (t || cs.length) ? t : cs[p]; //Opera behaves VERY strangely - length is usually 0 and cs[p] is the only way to get accurate results EXCEPT when checking for -o-transform which only works with cs.getPropertyValue()! } else if (t.currentStyle) { - cs = t.currentStyle; - rv = cs[p]; + rv = t.currentStyle[p]; } return (dflt != null && (!rv || rv === "none" || rv === "auto" || rv === "auto auto")) ? dflt : rv; }, @@ -1027,8 +1026,8 @@ return rv; }, priority:priority}); }; - - + + @@ -1090,7 +1089,7 @@ a34 = a33*a34+tm.zOrigin-m[14]; } - //only parse from the matrix if we MUST because not only is it usually unnecessary due to the fact that we store the values in the _gsTransform object, but also because it's impossible to accurately interpret rotationX, rotationY, and rotationZ if all are applied, so it's much better to rely on what we store. However, we must parse the first time that an object is tweened. We also assume that if the position has changed, the user must have done some styling changes outside of CSSPlugin, thus we force a parse in that scenario. + //only parse from the matrix if we MUST because not only is it usually unnecessary due to the fact that we store the values in the _gsTransform object, but also because it's impossible to accurately interpret rotationX, rotationY, rotationZ, scaleX, and scaleY if all are applied, so it's much better to rely on what we store. However, we must parse the first time that an object is tweened. We also assume that if the position has changed, the user must have done some styling changes outside of CSSPlugin, thus we force a parse in that scenario. if (!rec || parse || tm.rotationX == null) { var a11 = m[0], a21 = m[1], a31 = m[2], a41 = m[3], a12 = m[4], a22 = m[5], a32 = m[6], a42 = m[7], @@ -1105,7 +1104,6 @@ t1 = a12*cos+a13*sin; t2 = a22*cos+a23*sin; t3 = a32*cos+a33*sin; - //t4 = a42*cos+a43*sin; a13 = a12*-sin+a13*cos; a23 = a22*-sin+a23*cos; a33 = a32*-sin+a33*cos; @@ -1113,7 +1111,6 @@ a12 = t1; a22 = t2; a32 = t3; - //a42 = t4; } //rotationY angle = tm.rotationY = Math.atan2(a13, a11); @@ -1124,15 +1121,12 @@ t1 = a11*cos-a13*sin; t2 = a21*cos-a23*sin; t3 = a31*cos-a33*sin; - //t4 = a41*cos-a43*sin; - //a13 = a11*sin+a13*cos; a23 = a21*sin+a23*cos; a33 = a31*sin+a33*cos; a43 = a41*sin+a43*cos; a11 = t1; a21 = t2; a31 = t3; - //a41 = t4; } //rotationZ angle = tm.rotation = Math.atan2(a21, a22); @@ -1292,19 +1286,16 @@ style.removeAttribute("filter"); } }, + _set3DTransformRatio = function(v) { var t = this.data, //refers to the element's _gsTransform object style = this.t.style, - perspective = t.perspective, - a11 = t.scaleX, a12 = 0, a13 = 0, a14 = 0, - a21 = 0, a22 = t.scaleY, a23 = 0, a24 = 0, - a31 = 0, a32 = 0, a33 = t.scaleZ, a34 = 0, - a41 = 0, a42 = 0, a43 = (perspective) ? -1 / perspective : 0, angle = t.rotation, - zOrigin = t.zOrigin, - rnd = 100000, - cos, sin, t1, t2, t3, t4, ffProp, n, sfx; - + sx = t.scaleX, + sy = t.scaleY, + sz = t.scaleZ, + a11, a12, a13, a14, a21, a22, a23, a24, a31, a32, a33, a34, a41, a42, a43, + perspective, zOrigin, rnd, cos, sin, t1, t2, t3, t4, ffProp, n, sfx; if (_isFirefox) { //Firefox has a bug that causes 3D elements to randomly disappear during animation unless a repaint is forced. One way to do this is change "top" or "bottom" by 0.05 which is imperceptible, so we go back and forth. Another way is to change the display to "none", read the clientTop, and then revert the display but that is much slower. ffProp = style.top ? "top" : style.bottom ? "bottom" : parseFloat(_getStyle(this.t, "top", null, false)) ? "bottom" : "top"; t1 = _getStyle(this.t, ffProp, null, false); @@ -1313,35 +1304,43 @@ t._ffFix = !t._ffFix; style[ffProp] = (t._ffFix ? n + 0.05 : n - 0.05) + sfx; } - if (angle || t.skewX) { - t1 = a11*Math.cos(angle); - t2 = a22*Math.sin(angle); - angle -= t.skewX; - a12 = a11*-Math.sin(angle); - a22 = a22*Math.cos(angle); - a11 = t1; - a21 = t2; - } else if (!t.rotationY && !t.rotationX && a33 === 1) { //if we're only translating and/or 2D scaling, this is faster... - style[_transformProp] = "translate3d(" + t.x + "px," + t.y + "px," + t.z +"px)" + ((a11 !== 1 || a22 !== 1) ? " scale(" + a11 + "," + a22 + ")" : ""); + cos = Math.cos(angle); + sin = Math.sin(angle); + a11 = cos; + a21 = sin; + if (t.skewX) { + angle -= t.skewX; + cos = Math.cos(angle); + sin = Math.sin(angle); + } + a12 = -sin; + a22 = cos; + } else if (!t.rotationY && !t.rotationX && sz === 1) { //if we're only translating and/or 2D scaling, this is faster... + style[_transformProp] = "translate3d(" + t.x + "px," + t.y + "px," + t.z +"px)" + ((sx !== 1 || sy !== 1) ? " scale(" + sx + "," + sy + ")" : ""); return; - } + } else { + a11 = a22 = 1; + a12 = a21 = 0; + } + a33 = 1; + a13 = a14 = a23 = a24 = a31 = a32 = a34 = a41 = a42 = 0; + perspective = t.perspective; + a43 = (perspective) ? -1 / perspective : 0; + zOrigin = t.zOrigin; + rnd = 100000; angle = t.rotationY; if (angle) { cos = Math.cos(angle); sin = Math.sin(angle); - t1 = a11*cos; - t2 = a21*cos; - t3 = a33*-sin; - t4 = a43*-sin; + a31 = a33*-sin; + a41 = a43*-sin; a13 = a11*sin; a23 = a21*sin; - a33 = a33*cos; + a33 *= cos; a43 *= cos; - a11 = t1; - a21 = t2; - a31 = t3; - a41 = t4; + a11 *= cos; + a21 *= cos; } angle = t.rotationX; if (angle) { @@ -1360,6 +1359,24 @@ a32 = t3; a42 = t4; } + if (sz !== 1) { + a13*=sz; + a23*=sz; + a33*=sz; + a43*=sz; + } + if (sy !== 1) { + a12*=sy; + a22*=sy; + a32*=sy; + a42*=sy; + } + if (sx !== 1) { + a11*=sx; + a21*=sx; + a31*=sx; + a41*=sx; + } if (zOrigin) { a34 -= zOrigin; a14 = a13*a34; @@ -1372,6 +1389,7 @@ a34 = (t1 = (a34 += t.z) - (a34 |= 0)) ? ((t1 * rnd + (t1 < 0 ? -0.5 : 0.5)) | 0) / rnd + a34 : a34; style[_transformProp] = "matrix3d(" + [ (((a11 * rnd) | 0) / rnd), (((a21 * rnd) | 0) / rnd), (((a31 * rnd) | 0) / rnd), (((a41 * rnd) | 0) / rnd), (((a12 * rnd) | 0) / rnd), (((a22 * rnd) | 0) / rnd), (((a32 * rnd) | 0) / rnd), (((a42 * rnd) | 0) / rnd), (((a13 * rnd) | 0) / rnd), (((a23 * rnd) | 0) / rnd), (((a33 * rnd) | 0) / rnd), (((a43 * rnd) | 0) / rnd), a14, a24, a34, (perspective ? (1 + (-a34 / perspective)) : 1) ].join(",") + ")"; }, + _set2DTransformRatio = function(v) { var t = this.data, //refers to the element's _gsTransform object targ = this.t, @@ -1398,7 +1416,7 @@ } }; - _registerComplexSpecialProp("transform,scale,scaleX,scaleY,scaleZ,x,y,z,rotation,rotationX,rotationY,rotationZ,skewX,skewY,shortRotation,shortRotationX,shortRotationY,shortRotationZ,transformOrigin,transformPerspective,directionalRotation,parseTransform", {parser:function(t, e, p, cssp, pt, plugin, vars) { + _registerComplexSpecialProp("transform,scale,scaleX,scaleY,scaleZ,x,y,z,rotation,rotationX,rotationY,rotationZ,skewX,skewY,shortRotation,shortRotationX,shortRotationY,shortRotationZ,transformOrigin,transformPerspective,directionalRotation,parseTransform,force3D", {parser:function(t, e, p, cssp, pt, plugin, vars) { if (cssp._transform) { return pt; } //only need to parse the transform once, and only if the browser supports it. var m1 = cssp._transform = _getTransform(t, _cs, true, vars.parseTransform), style = t.style, @@ -1447,7 +1465,12 @@ } } - has3D = (m1.z || m1.rotationX || m1.rotationY || m2.z || m2.rotationX || m2.rotationY || m2.perspective); + if (v.force3D != null) { + m1.force3D = v.force3D; + hasChange = true; + } + + has3D = (m1.force3D || m1.z || m1.rotationX || m1.rotationY || m2.z || m2.rotationX || m2.rotationY || m2.perspective); if (!has3D && v.scale != null) { m2.scaleZ = 1; //no need to tween scaleZ. } @@ -1471,15 +1494,15 @@ if (orig || (_supports3D && has3D && m1.zOrigin)) { //if anything 3D is happening and there's a transformOrigin with a z component that's non-zero, we must ensure that the transformOrigin's z-component is set to 0 so that we can manually do those calculations to get around Safari bugs. Even if the user didn't specifically define a "transformOrigin" in this particular tween (maybe they did it via css directly). if (_transformProp) { hasChange = true; - orig = (orig || _getStyle(t, p, _cs, false, "50% 50%")) + ""; //cast as string to avoid errors p = _transformOriginProp; + orig = (orig || _getStyle(t, p, _cs, false, "50% 50%")) + ""; //cast as string to avoid errors pt = new CSSPropTween(style, p, 0, 0, pt, -1, "transformOrigin"); pt.b = style[p]; pt.plugin = plugin; if (_supports3D) { copy = m1.zOrigin; orig = orig.split(" "); - m1.zOrigin = ((orig.length > 2) ? parseFloat(orig[2]) : copy) || 0; //Safari doesn't handle the z part of transformOrigin correctly, so we'll manually handle it in the _set3DTransformRatio() method. + m1.zOrigin = ((orig.length > 2 && !(copy !== 0 && orig[2] === "0px")) ? parseFloat(orig[2]) : copy) || 0; //Safari doesn't handle the z part of transformOrigin correctly, so we'll manually handle it in the _set3DTransformRatio() method. pt.xs0 = pt.e = style[p] = orig[0] + " " + (orig[1] || "50%") + " 0px"; //we must define a z value of 0px specifically otherwise iOS 5 Safari will stick with the old one (if one was defined)! pt = new CSSPropTween(m1, "zOrigin", 0, 0, pt, -1, pt.n); //we must create a CSSPropTween for the _gsTransform.zOrigin so that it gets reset properly at the beginning if the tween runs backward (as opposed to just setting m1.zOrigin here) pt.b = copy; @@ -1622,7 +1645,7 @@ //opacity-related var _setIEOpacityRatio = function(v) { var t = this.t, //refers to the element's style property - filters = t.filter, + filters = t.filter || _getStyle(this.data, "filter"), val = (this.s + this.c * v) | 0, skip; if (val === 100) { //for older versions of IE that need to use a filter to apply opacity, we should remove the filter if opacity hits 1 in order to improve performance, but make sure there isn't a transform (matrix) or gradient in the filters. @@ -1636,10 +1659,12 @@ } if (!skip) { if (this.xn1) { - t.filter = filters = filters || "alpha(opacity=100)"; //works around bug in IE7/8 that prevents changes to "visibility" from being applied properly if the filter is changed to a different alpha on the same frame. + t.filter = filters = filters || ("alpha(opacity=" + val + ")"); //works around bug in IE7/8 that prevents changes to "visibility" from being applied properly if the filter is changed to a different alpha on the same frame. } if (filters.indexOf("opacity") === -1) { //only used if browser doesn't support the standard opacity style property (IE 7 and 8) - t.filter += " alpha(opacity=" + val + ")"; //we round the value because otherwise, bugs in IE7/8 can prevent "visibility" changes from being applied properly. + if (val !== 0 || !this.xn1) { //bugs in IE7/8 won't render the filter properly if opacity is ADDED on the same frame/render as "visibility" changes (this.xn1 is 1 if this tween is an "autoAlpha" tween) + t.filter += " alpha(opacity=" + val + ")"; //we round the value because otherwise, bugs in IE7/8 can prevent "visibility" changes from being applied properly. + } } else { t.filter = filters.replace(_opacityExp, "opacity=" + val); } @@ -1648,22 +1673,16 @@ _registerComplexSpecialProp("opacity,alpha,autoAlpha", {defaultValue:"1", parser:function(t, e, p, cssp, pt, plugin) { var b = parseFloat(_getStyle(t, "opacity", _cs, false, "1")), style = t.style, - vb; + isAutoAlpha = (p === "autoAlpha"); e = parseFloat(e); - if (p === "autoAlpha") { - vb = _getStyle(t, "visibility", _cs); - if (b === 1 && vb === "hidden" && e !== 0) { //if visibility is initially set to "hidden", we should interpret that as intent to make opacity 0 (a convenience) - b = 0; - } - pt = new CSSPropTween(style, "visibility", 0, 0, pt, -1, null, false, 0, ((b !== 0) ? "visible" : "hidden"), ((e === 0) ? "hidden" : "visible")); - pt.xs0 = "visible"; - cssp._overwriteProps.push(pt.n); + if (isAutoAlpha && b === 1 && _getStyle(t, "visibility", _cs) === "hidden" && e !== 0) { //if visibility is initially set to "hidden", we should interpret that as intent to make opacity 0 (a convenience) + b = 0; } if (_supportsOpacity) { pt = new CSSPropTween(style, "opacity", b, e - b, pt); } else { pt = new CSSPropTween(style, "opacity", b * 100, (e - b) * 100, pt); - pt.xn1 = (p === "autoAlpha") ? 1 : 0; //we need to record whether or not this is an autoAlpha so that in the setRatio(), we know to duplicate the setting of the alpha in order to work around a bug in IE7 and IE8 that prevents changes to "visibility" from taking effect if the filter is changed to a different alpha(opacity) at the same time. Setting it to the SAME value first, then the new value works around the IE7/8 bug. + pt.xn1 = isAutoAlpha ? 1 : 0; //we need to record whether or not this is an autoAlpha so that in the setRatio(), we know to duplicate the setting of the alpha in order to work around a bug in IE7 and IE8 that prevents changes to "visibility" from taking effect if the filter is changed to a different alpha(opacity) at the same time. Setting it to the SAME value first, then the new value works around the IE7/8 bug. style.zoom = 1; //helps correct an IE issue. pt.type = 2; pt.b = "alpha(opacity=" + pt.s + ")"; @@ -1672,6 +1691,11 @@ pt.plugin = plugin; pt.setRatio = _setIEOpacityRatio; } + if (isAutoAlpha) { //we have to create the "visibility" PropTween after the opacity one in the linked list so that they run in the order that works properly in IE8 and earlier + pt = new CSSPropTween(style, "visibility", 0, 0, pt, -1, null, false, 0, ((b !== 0) ? "visible" : "hidden"), ((e === 0) ? "hidden" : "visible")); + pt.xs0 = "visible"; + cssp._overwriteProps.push(pt.n); + } return pt; }}); @@ -1743,17 +1767,20 @@ var _setClearPropsRatio = function(v) { if (v === 1 || v === 0) if (this.data._totalTime === this.data._totalDuration) { //this.data refers to the tween. Only clear at the END of the tween (remember, from() tweens make the ratio go from 1 to 0, so we can't just check that). - var all = (this.e === "all"), - s = this.t.style, - a = all ? s.cssText.split(";") : this.e.split(","), + if (this.e === "all") { + this.t.style.cssText = ""; + if (this.t._gsTransform) { + delete this.t._gsTransform; + } + return; + } + var s = this.t.style, + a = this.e.split(","), i = a.length, transformParse = _specialProps.transform.parse, p; while (--i > -1) { p = a[i]; - if (all) { - p = p.substr(0, p.indexOf(":")).split(" ").join(""); - } if (_specialProps[p]) { p = (_specialProps[p].parse === transformParse) ? _transformProp : _specialProps[p].p; //ensures that special properties use the proper browser-specific property name, like "scaleX" might be "-webkit-transform" or "boxShadow" might be "-moz-box-shadow" } @@ -1786,8 +1813,8 @@ p = CSSPlugin.prototype; p._firstPT = null; - - //gets called when the tween renders for the first time. This kicks everything off, recording start/end values, etc. + + //gets called when the tween renders for the first time. This kicks everything off, recording start/end values, etc. p._onInitTween = function(target, vars, tween) { if (!target.nodeType) { //css is only for dom elements return false; @@ -1802,7 +1829,6 @@ _overwriteProps = this._overwriteProps; var style = target.style, v, pt, pt2, first, last, next, zIndex, tpt, threeD; - if (_reqSafariFix) if (style.zIndex === "") { v = _getStyle(target, "zIndex", _cs); if (v === "auto" || v === "") { @@ -1810,7 +1836,7 @@ style.zIndex = 0; } } - + if (typeof(vars) === "string") { first = style.cssText; v = _getAllStyles(target, _cs); @@ -1987,8 +2013,8 @@ } return pt; }; - - + + //gets called every time the tween updates, passing the new ratio (typically a value between 0 and 1, but not always (for example, if an Elastic.easeOut is used, the value can jump above 1 mid-tween). It will always start and 0 and end at 1. p.setRatio = function(v) { var pt = this._firstPT, @@ -2096,7 +2122,7 @@ } return pt; }; - + //we need to make sure that if alpha or autoAlpha is killed, opacity is too. And autoAlpha affects the "visibility" property. p._kill = function(lookup) { var copy = lookup, @@ -2204,10 +2230,9 @@ return results; }; - TweenPlugin.activate([CSSPlugin]); return CSSPlugin; - + }, true); }); if (window._gsDefine) { window._gsQueue.pop()(); } \ No newline at end of file diff --git a/js/libs/gsap/plugins/CSSRulePlugin.js b/js/libs/gsap/plugins/CSSRulePlugin.js index 36dfe9a8..49126f1d 100644 --- a/js/libs/gsap/plugins/CSSRulePlugin.js +++ b/js/libs/gsap/plugins/CSSRulePlugin.js @@ -1,6 +1,6 @@ /*! - * VERSION: beta 0.5 - * DATE: 2012-12-20 + * VERSION: beta 0.6.0 + * DATE: 2013-07-03 * UPDATES AND DOCS AT: http://www.greensock.com * * @license Copyright (c) 2008-2013, GreenSock. All rights reserved. @@ -47,7 +47,13 @@ a = []; } while (--i > -1) { - curSS = ss[i][ruleProp]; + //Firefox may throw insecure operation errors when css is loaded from other domains, so try/catch. + try { + curSS = ss[i][ruleProp]; + } catch (e) { + console.log(e); + continue; + } j = curSS.length; while (--j > -1) { cs = curSS[j]; diff --git a/js/libs/gsap/plugins/KineticPlugin.js b/js/libs/gsap/plugins/KineticPlugin.js index 2b14f80f..a3bd9390 100644 --- a/js/libs/gsap/plugins/KineticPlugin.js +++ b/js/libs/gsap/plugins/KineticPlugin.js @@ -1,6 +1,6 @@ /*! - * VERSION: 0.4.0 - * DATE: 2013-05-16 + * VERSION: 0.4.1 + * DATE: 2013-07-10 * UPDATES AND DOCS AT: http://www.greensock.com * * @license Copyright (c) 2008-2013, GreenSock. All rights reserved. @@ -18,7 +18,7 @@ _getterFuncs = {}, _setterFuncs = {}, _numExp = /(\d|\.)+/g, - _directionalRotationExp = /(?:_cw|_ccw|_short)/g, + _directionalRotationExp = /(?:_cw|_ccw|_short)/, _plugins = window._gsDefine.globals.com.greensock.plugins, _colorLookup = {aqua:[0,255,255], lime:[0,255,0], diff --git a/js/libs/gsap/plugins/TextPlugin.js b/js/libs/gsap/plugins/TextPlugin.js index b1aa7b82..e738b7e1 100644 --- a/js/libs/gsap/plugins/TextPlugin.js +++ b/js/libs/gsap/plugins/TextPlugin.js @@ -1,6 +1,6 @@ /*! - * VERSION: 0.4.0 - * DATE: 2013-05-16 + * VERSION: 0.5.0 + * DATE: 2013-07-10 * UPDATES AND DOCS AT: http://www.greensock.com * * @license Copyright (c) 2008-2013, GreenSock. All rights reserved. @@ -35,6 +35,7 @@ //called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run. init: function(target, value, tween) { + var i, shrt; if (!("innerHTML" in target)) { return false; } @@ -49,6 +50,12 @@ this._delimiter = value.delimiter || ""; this._original = _getText(target).replace(/\s+/g, " ").split(this._delimiter); this._text = value.value.replace(/\s+/g, " ").split(this._delimiter); + this._runBackwards = (tween.vars.runBackwards === true); + if (this._runBackwards) { + i = this._original; + this._original = this._text; + this._text = i; + } if (typeof(value.newClass) === "string") { this._newClass = value.newClass; this._hasClass = true; @@ -57,8 +64,8 @@ this._oldClass = value.oldClass; this._hasClass = true; } - var i = this._original.length - this._text.length, - shrt = (i < 0) ? this._original : this._text; + i = this._original.length - this._text.length, + shrt = (i < 0) ? this._original : this._text; this._fillChar = value.fillChar || (value.padSpace ? " " : ""); if (i < 0) { i = -i; @@ -76,6 +83,9 @@ } else if (ratio < 0) { ratio = 0; } + if (this._runBackwards) { + ratio = 1 - ratio; + } var l = this._text.length, i = (ratio * l + 0.5) | 0, applyNew, applyOld, str; diff --git a/js/libs/gsap/utils/Draggable.js b/js/libs/gsap/utils/Draggable.js new file mode 100644 index 00000000..7e5cc1a5 --- /dev/null +++ b/js/libs/gsap/utils/Draggable.js @@ -0,0 +1,747 @@ +/*! + * VERSION: 0.6.0 + * DATE: 2013-07-19 + * UPDATES AND DOCS AT: http://www.greensock.com + * + * @license Copyright (c) 2008-2013, GreenSock. All rights reserved. + * This work is subject to the terms at http://www.greensock.com/terms_of_use.html or for + * Club GreenSock members, the software agreement that was issued with your membership. + * + * @author: Jack Doyle, jack@greensock.com + */ +(window._gsQueue || (window._gsQueue = [])).push( function() { + + "use strict"; + + window._gsDefine("utils.Draggable", ["events.EventDispatcher","TweenLite"], function(EventDispatcher, TweenLite) { + + var tempVarsXY = {css:{}}, //speed optimization - we reuse the same vars object for x/y TweenLite.set() calls to minimize garbage collection tasks and improve performance. + tempVarsX = {css:{}}, + tempVarsY = {css:{}}, + tempVarsRotation = {css:{}}, + tempEvent = {}, //for populating with pageX/pageY in old versions of IE + doc = document, + docElement = doc.documentElement, + emptyArray = [], + emptyFunc = function() { return false; }, + RAD2DEG = 180 / Math.PI, + DEG2RAD = Math.PI / 180, + isOldIE = (doc.all && !doc.addEventListener), + prefix, + ThrowPropsPlugin, + + //just used for IE8 and earlier to normalize events and populate pageX/pageY + populateIEEvent = function(e, preventDefault) { + e = e || window.event; + tempEvent.pageX = e.clientX + doc.body.scrollLeft + docElement.scrollLeft; + tempEvent.pageY = e.clientY + doc.body.scrollTop + docElement.scrollTop; + if (preventDefault) { + e.returnValue = false; + } + return tempEvent; + }, + + checkPrefix = function(e, p) { + var s = e.style, + capped, i, a; + if (s[p] === undefined) { + a = ["O","Moz","ms","Ms","Webkit"]; + i = 5; + capped = p.charAt(0).toUpperCase() + p.substr(1); + while (--i > -1 && s[a[i]+capped] === undefined) { } + if (i < 0) { + return ""; + } + prefix = (i === 3) ? "ms" : a[i]; + p = prefix + capped; + } + return p; + }, + setStyle = function(e, p, value) { + var s = e.style; + if (s[p] === undefined) { + p = checkPrefix(e, p); + } + if (value == null) { + if (s.removeProperty) { + s.removeProperty(p.replace(/([A-Z])/g, "-$1").toLowerCase()); + } else { //note: old versions of IE use "removeAttribute()" instead of "removeProperty()" + s.removeAttribute(p); + } + } else if (s[p] !== undefined) { + s[p] = value; + } + }, + getComputedStyle = doc.defaultView ? doc.defaultView.getComputedStyle : emptyFunc, + getStyle = function(element, prop, keepUnits) { + var rv = (element._gsTransform || {})[prop], + cs; + if (rv || rv === 0) { + return rv; + } else if (element.style[prop]) { + rv = element.style[prop]; + } else if ((cs = getComputedStyle(element))) { + element = cs.getPropertyValue(prop.replace(/([A-Z])/g, "-$1").toLowerCase()); + rv = (element || cs.length) ? element : cs[prop]; //Opera behaves VERY strangely - length is usually 0 and cs[prop] is the only way to get accurate results EXCEPT when checking for -o-transform which only works with cs.getPropertyValue()! + } else if (element.currentStyle) { + rv = element.currentStyle[prop]; + } + return keepUnits ? rv : parseFloat(rv) || 0; + }, + addListener = function(element, type, func) { + if (element.addEventListener) { + element.addEventListener(type, func, false); + } else if (element.attachEvent) { + element.attachEvent("on" + type, func); + } + }, + removeListener = function(element, type, func) { + if (element.removeEventListener) { + element.removeEventListener(type, func); + } else if (element.detachEvent) { + element.detachEvent("on" + type, func); + } + }, + dispatchEvent = function(instance, type, callbackName) { + var vars = instance.vars, + callback = vars[callbackName], + listeners = instance._listeners[type]; + if (typeof(callback) === "function") { + callback.apply(vars[callbackName + "Scope"] || instance, vars[callbackName + "Params"] || emptyArray); + } + if (listeners) { + instance.dispatchEvent(type); + } + }, + getBounds = function(e) { + if (e === window) { + return { + top:(e.pageYOffset != null) ? e.pageYOffset : (doc.scrollTop != null) ? doc.scrollTop : doc.body.scrollTop || docElement.scrollTop || 0, + left:(e.pageXOffset != null) ? e.pageXOffset : (doc.scrollLeft != null) ? doc.scrollLeft : doc.body.scrollLeft || docElement.scrollLeft || 0, + width:(docElement ? docElement.clientWidth : e.innerWidth), + height:(docElement ? docElement.clientHeight : e.innerHeight) + }; + } + var width = e.offsetWidth, + height = e.offsetHeight, + top = e.offsetTop, + left = e.offsetLeft; + if (isOldIE && e._gsTransform) { + top -= e._gsTransform.y; + left -= e._gsTransform.x; + } + while ((e = e.offsetParent)) { + top += e.offsetTop; + left += e.offsetLeft; + } + return {top:top, left:left, width:width, height:height}; + }, + originProp = checkPrefix(doc.body, "transformOrigin").replace(/([A-Z])/g, "-$1").toLowerCase(), + transformProp = checkPrefix(doc.body, "transform"), + supports3D = (checkPrefix(doc.body, "perspective") !== ""), + use3DTransform = (transformProp && supports3D), + getTransformOriginOffset = function(e) { + var bounds = getBounds(e), + cs = getComputedStyle(e), + v = (originProp && cs) ? cs.getPropertyValue(originProp) : "50% 50%", + a = v.split(" "), + x = (v.indexOf("left") !== -1) ? "0%" : (v.indexOf("right") !== -1) ? "100%" : a[0], + y = (v.indexOf("top") !== -1) ? "0%" : (v.indexOf("bottom") !== -1) ? "100%" : a[1]; + if (y == null) { + y = "0"; + } else if (y === "center") { + y = "50%"; + } + if (x === "center" || isNaN(parseFloat(x))) { //remember, the user could flip-flop the values and say "bottom center" or "center bottom", etc. "center" is ambiguous because it could be used to describe horizontal or vertical, hence the isNaN(). If there's an "=" sign in the value, it's relative. + x = "50%"; + } + bounds.left += (x.indexOf("%") !== -1) ? bounds.width * parseFloat(x) / 100 : parseFloat(x); + bounds.top += (y.indexOf("%") !== -1) ? bounds.height * parseFloat(y) / 100 : parseFloat(y); + return bounds; + }, + isArrayLike = function(e) { + return (e.length && e[0] && ((e[0].nodeType && e[0].style && !e.nodeType) || (e[0].length && e[0][0]))) ? true : false; //could be an array of jQuery objects too, so accommodate that. + }, + flattenArray = function(a) { + var result = [], + l = a.length, + i, e, j; + for (i = 0; i < l; i++) { + e = a[i]; + if (isArrayLike(e)) { + j = e.length; + for (j = 0; j < e.length; j++) { + result.push(e[j]); + } + } else { + result.push(e); + } + } + return result; + }, + parseThrowProps = function(draggable, snap, max, min, factor) { + var vars = {}, + a, i, l; + if (snap) { + if (factor && snap instanceof Array) { //some data must be altered to make sense, like if the user passes in an array of rotational values in degrees, we must convert it to radians. Or for scrollLeft and scrollTop, we invert the values. + vars.end = a = []; + l = snap.length; + for (i = 0; i < l; i++) { + a[i] = snap[i] * factor; + } + } else if (typeof(snap) === "function") { + vars.end = function(value) { + return snap.call(draggable, value); //we need to ensure that we can scope the function call to the Draggable instance itself so that users can access important values like xMax, xMin, yMax, yMin, x, and y from within that function. + }; + } else { + vars.end = snap; + } + } + if (max || max === 0) { + vars.max = max; + } + if (min || min === 0) { + vars.min = min; + } + return vars; + }, + + addPaddingBR, + addPaddingLeft = (function() { //this function is in charge of analyzing browser behavior related to padding. It sets the addPaddingBR to true if the browser doesn't normally factor in the bottom or right padding on the element inside the scrolling area, and it sets addPaddingLeft to true if it's a browser that requires the extra offset (offsetLeft) to be added to the paddingRight (like Opera). + var div = doc.createElement("div"), + child = doc.createElement("div"), + childStyle = child.style, + val; + childStyle.display = "inline-block"; + childStyle.position = "relative"; + div.style.cssText = child.innerHTML = "width:90px; height:40px; padding:10px; overflow:auto; visibility: hidden"; + div.appendChild(child); + doc.body.appendChild(div); + addPaddingBR = (child.offsetHeight + 18 > div.scrollHeight); //div.scrollHeight should be child.offsetHeight + 20 because of the 10px of padding on each side, but some browsers ignore one side. We allow a 2px margin of error. + childStyle.width = "100%"; + if (!use3DTransform) { + childStyle.paddingRight = "500px"; + val = div.scrollLeft = div.scrollWidth - div.clientWidth; + childStyle.left = "-90px"; + val = (val !== div.scrollLeft); + } + doc.body.removeChild(div); + return val; + }()), + + //The ScrollProxy class wraps an element's contents into another div (we call it "content") that we either add padding when necessary or apply a translate3d() transform in order to overscroll (scroll past the boundaries). This allows us to simply set the scrollTop/scrollLeft (or top/left for easier reverse-axis orientation, which is what we do in Draggable) and it'll do all the work for us. For example, if we tried setting scrollTop to -100 on a normal DOM element, it wouldn't work - it'd look the same as setting it to 0, but if we set scrollTop of a ScrollProxy to -100, it'll give the correct appearance by either setting paddingTop of the wrapper to 100 or applying a 100-pixel translateY. + ScrollProxy = function(element) { + if (element.length && element[0]) { + element = element[0]; + } + var content = doc.createElement("div"), + style = content.style, + node = element.firstChild, + offsetTop = 0, + offsetLeft = 0, + prevTop = element.scrollTop, + prevLeft = element.scrollLeft, + extraPadRight = 0, + maxLeft = 0, + maxTop = 0, + elementWidth, elementHeight, contentHeight, nextNode; + + this.scrollTop = function(value, force) { + if (!arguments.length) { + return -this.top(); + } + this.top(-value, force); + }; + + this.scrollLeft = function(value, force) { + if (!arguments.length) { + return -this.left(); + } + this.left(-value, force); + }; + + this.left = function(value, force) { + if (!arguments.length) { + return -(element.scrollLeft + offsetLeft); + } + var dif = element.scrollLeft - prevLeft, + oldOffset = offsetLeft; + if ((dif > 2 || dif < -2) && !force) { //if the user interacts with the scrollbar (or something else scrolls it, like the mouse wheel), we should kill any tweens of the ScrollProxy. + prevLeft = element.scrollLeft; + TweenLite.killTweensOf(this, {left:1, scrollLeft:1}); + this.left(-prevLeft); + return; + } + value = -value; //invert because scrolling works in the opposite direction + if (value < 0) { + offsetLeft = (value - 0.5) | 0; + value = 0; + } else if (value > maxLeft) { + offsetLeft = (value - maxLeft) | 0; + value = maxLeft; + } else { + offsetLeft = 0; + } + if (offsetLeft || oldOffset) { + if (use3DTransform) { + style[transformProp] = "translate3d(" + -offsetLeft + "px," + -offsetTop + "px,0px)"; + } else { + style.left = -offsetLeft + "px"; + } + if (addPaddingLeft && offsetLeft + extraPadRight >= 0) { + style.paddingRight = offsetLeft + extraPadRight + "px"; + } + } + element.scrollLeft = value | 0; + prevLeft = element.scrollLeft; //don't merge this with the line above because some browsers adjsut the scrollLeft after it's set, so in order to be 100% accurate in tracking it, we need to ask the browser to report it. + }; + + this.top = function(value, force) { + if (!arguments.length) { + return -(element.scrollTop + offsetTop); + } + var dif = element.scrollTop - prevTop, + oldOffset = offsetTop; + if ((dif > 2 || dif < -2) && !force) { //if the user interacts with the scrollbar (or something else scrolls it, like the mouse wheel), we should kill any tweens of the ScrollProxy. + prevTop = element.scrollTop; + TweenLite.killTweensOf(this, {top:1, scrollTop:1}); + this.top(-prevTop); + return; + } + value = -value; //invert because scrolling works in the opposite direction + if (value < 0) { + offsetTop = (value - 0.5) | 0; + value = 0; + } else if (value > maxTop) { + offsetTop = (value - maxTop) | 0; + value = maxTop; + } else { + offsetTop = 0; + } + if (offsetTop || oldOffset) { + if (use3DTransform) { + style[transformProp] = "translate3d(" + -offsetLeft + "px," + -offsetTop + "px,0px)"; + } else { + style.top = -offsetTop + "px"; + } + } + element.scrollTop = value | 0; + prevTop = element.scrollTop; + }; + + this.maxScrollTop = function() { + return maxTop; + }; + + this.maxScrollLeft = function() { + return maxLeft; + }; + + this.disable = function() { + node = content.firstChild; + while (node) { + nextNode = node.nextSibling; + element.appendChild(node); + node = nextNode; + } + element.removeChild(content); + }; + + this.enable = function() { + node = element.firstChild; + if (node === content) { + return; + } + while (node) { + nextNode = node.nextSibling; + content.appendChild(node); + node = nextNode; + } + element.appendChild(content); + this.calibrate(); + }; + + this.calibrate = function(force) { + var widthMatches = (element.clientWidth === elementWidth), + x, y; + if (widthMatches && element.clientHeight === elementHeight && content.offsetHeight === contentHeight && !force) { + return; //no need to recalculate things if the width and height haven't changed. + } + if (offsetTop || offsetLeft) { + x = this.left(); + y = this.top(); + this.left(-element.scrollLeft); + this.top(-element.scrollTop); + } + //first, we need to remove any width constraints to see how the content naturally flows so that we can see if it's wider than the containing element. If so, we've got to record the amount of overage so that we can apply that as padding in order for browsers to correctly handle things. Then we switch back to a width of 100% (without that, some browsers don't flow the content correctly) + if (!widthMatches || force) { + style.display = "block"; + style.width = "auto"; + style.paddingRight = "0px"; + extraPadRight = Math.max(0, element.scrollWidth - element.clientWidth); + //if the content is wider than the container, we need to add the paddingLeft and paddingRight in order for things to behave correctly. + if (extraPadRight) { + extraPadRight += getStyle(element, "paddingLeft") + (addPaddingBR ? getStyle(element, "paddingRight") : 0); + } + } + style.display = "inline-block"; + style.position = "relative"; + style.overflow = "visible"; + style.width = "100%"; + style.paddingRight = extraPadRight + "px"; + //some browsers neglect to factor in the bottom padding when calculating the scrollHeight, so we need to add that padding to the content when that happens. Allow a 2px margin for error + if (addPaddingBR) { + style.paddingBottom = getStyle(element, "paddingBottom", true); + } + if (isOldIE) { + style.zoom = "1"; + } + elementWidth = element.clientWidth; + elementHeight = element.clientHeight; + maxLeft = element.scrollWidth - elementWidth; + maxTop = element.scrollHeight - elementHeight; + contentHeight = content.offsetHeight; + if (x || y) { + this.left(x); + this.top(y); + } + }; + + this.content = content; + this.element = element; + this.enable(); + }, + + + + + + Draggable = function(target, vars) { + EventDispatcher.call(this, target); + if (target.length && target[0]) { //in case the target is a selector object. + target = target[0]; + } + if (!ThrowPropsPlugin) { + ThrowPropsPlugin = (window.GreenSockGlobals || window).com.greensock.plugins.ThrowPropsPlugin; + } + this.vars = vars = vars || {}; + this.target = target; + this.x = this.y = 0; + var type = (vars.type || (isOldIE ? "top,left" : "x,y")).toLowerCase(), + xyMode = (type.indexOf("x") !== -1 || type.indexOf("y") !== -1), + rotationMode = (type.indexOf("rotation") !== -1), + xProp = xyMode ? "x" : "left", + yProp = xyMode ? "y" : "top", + allowX = (type.indexOf("x") !== -1 || type.indexOf("left") !== -1 || type === "scroll"), + allowY = (type.indexOf("y") !== -1 || type.indexOf("top") !== -1 || type === "scroll"), + self = this, + killProps = {}, + edgeTolerance = parseFloat(vars.edgeTolerance) || (1 - (parseFloat(vars.edgeResistance) || 0)), //legacy support for edgeTolerance (new, more intuitive name is edgeResistance which works the opposite) + scrollProxy, startMouseX, startMouseY, startElementX, startElementY, hasBounds, hasDragCallback, xMax, xMin, yMax, yMin, tempVars, cssVars, touch, touchID, rotationOffset, + onPress = function(e) { + if (isOldIE) { + e = populateIEEvent(e, true); + } else { + e.preventDefault(); + } + if (e.changedTouches) { //touch events store the data slightly differently + e = touch = e.changedTouches[0]; + touchID = e.identifier; + } else { + touch = null; + } + TweenLite.killTweensOf(scrollProxy || target, killProps); //in case the user tries to drag it before the last tween is done. + startMouseY = e.pageY; //record the starting x and y so that we can calculate the movement from the original in _onMouseMove + startMouseX = e.pageX; + if (rotationMode) { + rotationOffset = getTransformOriginOffset(target); + startElementX = rotationOffset.left; + startElementY = rotationOffset.top; + rotationOffset = Math.atan2(startElementY - startMouseY, startMouseX - startElementX); + } else if (scrollProxy) { + startElementY = scrollProxy.top(); + startElementX = scrollProxy.left(); + } else { + startElementY = getStyle(target, yProp); //record the starting top and left values so that we can just add the mouse's movement to them later. + startElementX = getStyle(target, xProp); + } + if (!rotationMode && !scrollProxy && vars.zIndexBoost !== false) { + target.style.zIndex = Draggable.zIndex++; + } + if (touch) { //note: on iOS, BOTH touchmove and mousemove are dispatched, but the mousemove has pageY and pageX of 0 which would mess up the calculations and needlessly hurt performance. + addListener(doc, "touchmove", onMove); //don't forget touch events + addListener(doc, "touchend", onRelease); + } else { + addListener(doc, "mousemove", onMove); //attach these to the document instead of the box itself so that if the user's mouse moves too quickly (and off of the box), things still work. + addListener(doc, "mouseup", onRelease); + } + self.isDragging = true; + hasDragCallback = !!(vars.onDrag || self._listeners.drag); + hasBounds = false; + if (scrollProxy) { + scrollProxy.calibrate(); + self.xMin = xMin = -scrollProxy.maxScrollLeft(); + self.yMin = yMin = -scrollProxy.maxScrollTop(); + self.xMax = xMax = self.yMax = yMax = 0; + hasBounds = true; + + } else if (!!vars.bounds && !rotationMode) { + var targetBounds = getBounds(target), + bounds = (vars.bounds.length && vars.bounds !== window && vars.bounds[0] && !vars.bounds.nodeType) ? getBounds(vars.bounds[0]) : (vars.bounds === window || vars.bounds.style) ? getBounds(vars.bounds) : vars.bounds; //could be a selector/jQuery object or a DOM element or a generic object like {top:0, left:100, width:1000, height:800} + self.xMin = xMin = (xyMode ? 0 : getStyle(target, "left")) + bounds.left - targetBounds.left; + self.yMin = yMin = (xyMode ? 0 : getStyle(target, "top")) + bounds.top - targetBounds.top; + self.xMax = xMax = xMin + (bounds.width - target.offsetWidth); + self.yMax = yMax = yMin + (bounds.height - target.offsetHeight); + if (xMin > xMax) { + self.xMin = xMax; + self.xMax = xMax = xMin; + xMin = self.xMin; + } + if (yMin > yMax) { + self.yMin = yMax; + self.yMax = yMax = yMin; + yMin = self.yMin; + } + hasBounds = true; + } + if (hasBounds) { + if (startElementX > xMax) { + startElementX = xMax + (startElementX - xMax) / edgeTolerance; + } else if (startElementX < xMin) { + startElementX = xMin - (xMin - startElementX) / edgeTolerance; + } + if (startElementY > yMax) { + startElementY = yMax + (startElementY - yMax) / edgeTolerance; + } else if (startElementY < yMin) { + startElementY = yMin - (yMin - startElementY) / edgeTolerance; + } + } + + if (!rotationMode) { + setStyle(target, "cursor", vars.cursor || "move"); + } + dispatchEvent(self, "dragstart", "onDragStart"); + return false; + }, + onMove = function(e) { + if (isOldIE) { + e = populateIEEvent(e, true); + } else { + e.preventDefault(); + } + var touches = e.changedTouches, + xChange, yChange, x, y, i; + if (touches) { //touch events store the data slightly differently + e = touches[0]; + if (e !== touch && e.identifier !== touchID) { //Usually changedTouches[0] will be what we're looking for, but in case it's not, look through the rest of the array...(and Android browsers don't reuse the event like iOS) + i = touches.length; + while (--i > -1 && (e = touches[i]).identifier !== touchID) {} + if (i < 0) { + return; + } + } + } + if (rotationMode) { + x = Math.atan2(startElementY - e.pageY, e.pageX - startElementX); + cssVars.rotation = "+=" + ((rotationOffset - x) * RAD2DEG); + TweenLite.set(target, tempVars); + rotationOffset = x; + } else { + yChange = (e.pageY - startMouseY), + xChange = (e.pageX - startMouseX), + x = (xChange > 2 || xChange < -2) ? startElementX + xChange : startElementX, + y = (yChange > 2 || yChange < -2) ? startElementY + yChange : startElementY; + if (hasBounds) { + if (x > xMax) { + x = xMax + (x - xMax) * edgeTolerance; + } else if (x < xMin) { + x = xMin + (x - xMin) * edgeTolerance; + } + if (y > yMax) { + y = yMax + (y - yMax) * edgeTolerance; + } else if (y < yMin) { + y = yMin + (y - yMin) * edgeTolerance; + } + } + self.x = x; + self.y = y; + if (scrollProxy) { + if (allowY) { + scrollProxy.top(y); + } + if (allowX) { + scrollProxy.left(x); + } + } else if (xyMode) { + if (allowY) { + cssVars.y = y; + } + if (allowX) { + cssVars.x = x; + } + TweenLite.set(target, tempVars); + } else { + if (allowY) { + target.style.top = y + "px"; + } + if (allowX) { + target.style.left = x + "px"; + } + } + } + if (hasDragCallback) { + dispatchEvent(self, "drag", "onDrag"); + } + return true; + }, + onRelease = function(e) { + if (isOldIE) { + e = populateIEEvent(e, false); + } + var touches = e.changedTouches, + throwProps = vars.throwProps, + xChange, yChange, i, snap, snapIsRaw; + if (touches) { //touch events store the data slightly differently + e = touches[0]; + if (e !== touch && e.identifier !== touchID) { //Usually changedTouches[0] will be what we're looking for, but in case it's not, look through the rest of the array...(and Android browsers don't reuse the event like iOS) + i = touches.length; + while (--i > -1 && (e = touches[i]).identifier !== touchID) {} + if (i < 0) { + return; + } + } + } + yChange = (e.pageY - startMouseY); + xChange = (e.pageX - startMouseX); + self.isDragging = false; + removeListener(doc, "mouseup", onRelease); + removeListener(doc, "touchend", onRelease); + removeListener(doc, "mousemove", onMove); + removeListener(doc, "touchmove", onMove); + if (throwProps && ThrowPropsPlugin) { + if (throwProps === true) { + snap = vars.snap || {}; + snapIsRaw = (snap instanceof Array || typeof(snap) === "function"); + throwProps = {resistance:(vars.resistance || 1000) / (rotationMode ? 100 : 1)}; + if (rotationMode) { + throwProps.rotation = parseThrowProps(self, snapIsRaw ? snap : snap.rotation, xMax, xMin, vars.useRadians ? null : DEG2RAD); + } else { + if (allowX) { + throwProps[xProp] = parseThrowProps(self, snapIsRaw ? snap : snap.x || snap.left || snap.scrollLeft, xMax, xMin, scrollProxy ? -1 : null); + } + if (allowY) { + throwProps[yProp] = parseThrowProps(self, snapIsRaw ? snap : snap.y || snap.top || snap.scrollTop, yMax, yMin, scrollProxy ? -1 : null); + } + } + } + ThrowPropsPlugin.to(scrollProxy || target, {throwProps:throwProps, ease:(vars.ease || Power3.easeOut), onComplete:vars.onComplete, onUpdate:vars.onUpdate}, vars.maxDuration || 2, vars.minDuration || 0.5, (vars.overshootTolerance === undefined) ? edgeTolerance + 0.2 : vars.overshootTolerance); + } + if (!rotationMode) { + setStyle(target, "cursor", vars.cursor || "move"); + } + if (xChange < 2 && xChange > -2 && yChange < 2 && yChange > -2) { + dispatchEvent(self, "click", "onClick"); + } + dispatchEvent(self, "dragend", "onDragEnd"); + }; + + this.enable = function() { + addListener(target, "mousedown", onPress); + addListener(target, "touchstart", onPress); + if (!rotationMode) { + setStyle(target, "cursor", vars.cursor || "move"); + } + setStyle(target, "userSelect", "none"); + setStyle(target, "touchCallout", "none"); + if (ThrowPropsPlugin) { + ThrowPropsPlugin.track(scrollProxy || target, (xyMode ? "x,y" : rotationMode ? "rotation" : "top,left")); + } + if (scrollProxy) { + scrollProxy.enable(); + } + }; + + this.disable = function() { + var dragging = this.isDragging; + if (!rotationMode) { + setStyle(target, "cursor", null); + } + TweenLite.killTweensOf(scrollProxy || target, killProps); //in case the user tries to drag it before the last tween is done. + setStyle(target, "userSelect", "text"); + setStyle(target, "touchCallout", "default"); + removeListener(target, "mousedown", onPress); + removeListener(target, "touchstart", onPress); + removeListener(doc, "mouseup", onRelease); + removeListener(doc, "touchend", onRelease); + removeListener(doc, "mousemove", onMove); + removeListener(doc, "touchmove", onMove); + if (ThrowPropsPlugin) { + ThrowPropsPlugin.untrack(scrollProxy || target, (xyMode ? "x,y" : rotationMode ? "rotation" : "top,left")); + } + if (scrollProxy) { + scrollProxy.disable(); + } + this.isDragging = false; + if (dragging) { + dispatchEvent(this, "dragend", "onDragEnd"); + } + }; + + if (type.indexOf("scroll") !== -1) { + scrollProxy = this.scrollProxy = new ScrollProxy(target); + if (target._gsTransform && target._gsTransform.z === 0.01) { + TweenLite.set(target, {z:0}); //if the element and the ScrollProxy's content share the same z transform, some Webkit browsers ignore mouse clicks on it. + TweenLite.set(target, {z:0}); + } + target.style.overflowY = allowY ? "auto" : "hidden"; + target.style.overflowX = allowX ? "auto" : "hidden"; + target = scrollProxy.content; + } + + // prevent IE from trying to drag an image and prevent text selection in IE + target.ondragstart = doc.onselectstart = target.onselectstart = emptyFunc; + TweenLite.set(target, {z:"+=0.01"}); //improve performance by forcing a GPU layer when possible + if (rotationMode) { + killProps.rotation = 1; + } else { + if (allowX) { + killProps.x = killProps.left = 1; + } + if (allowY) { + killProps.y = killProps.top = 1; + } + } + if (rotationMode) { + tempVars = tempVarsRotation; + cssVars = tempVars.css; + } else if (xyMode) { + tempVars = (allowX && allowY) ? tempVarsXY : allowX ? tempVarsX : tempVarsY; + cssVars = tempVars.css; + } + this.isDragging = false; + this.enable(); + }, + p = Draggable.prototype = new EventDispatcher(); + + p.constructor = Draggable; + Draggable.version = "0.6.0"; + Draggable.zIndex = 1000; + + Draggable.create = function(targets, vars) { + if (typeof(targets) === "string") { + targets = TweenLite.selector(targets); + } + var a = isArrayLike(targets) ? flattenArray(targets) : [targets], + i = a.length; + while (--i > -1) { + a[i] = new Draggable(a[i], vars); + } + return a; + }; + + return Draggable; + + }, true); + + +}); if (window._gsDefine) { window._gsQueue.pop()(); } \ No newline at end of file diff --git a/js/main.js b/js/main.js index 59aa1b1c..d1a958f1 100644 --- a/js/main.js +++ b/js/main.js @@ -6,6 +6,8 @@ var $_GET; var maskHashChange = false; var jsLibraries = []; var longpresstime = undefined; +var startAfterLoading = false; +var gal=null; $(function() { $_GET = parseGet(); @@ -48,7 +50,27 @@ function onAppResume() { } function onDeviceReady() { - init(); + var manifest = window.sessionStorage.getItem('manifest.' + DATAS.id); + if (manifest) { + gal = new GameAssetLoader(JSON.parse(manifest)); + gal.init(function() { + startAfterLoading = true; + init(); + }); + + gal.onLoaded(function(info) { + $(window).trigger('GALBundleLoaded', [info]); + }); + + $(window).on('GALBundleLoaded', function(e, info) { + if (info.bundleName === 'content_4') { + fluidbook.changeAddress(); + } + fluidbook.loader.retryErrorImages(); + }); + } else { + init(); + } } function loadJSLibrary(url, callback) { @@ -97,14 +119,18 @@ function init() { INITED = true; fluidbook = new Fluidbook(DATAS); + if (null != gal) { + fluidbook.gal = gal; + } fluidbook.loadPlugins(); fluidbook.loader.preloadPages(); desktopScale = 1; desktopScaleAmount = 1.5; - $("#main").css('display', 'block'); + if ($_GET.s == '1') { + $("#main").css('display', 'block'); $('html').addClass('screenshot'); } @@ -190,7 +216,9 @@ function initEvents() { fluidbook.pollZoom(); }, 250); - fluidbook.changeAddress(); + if (!startAfterLoading) { + fluidbook.changeAddress(); + } } function checkScroll() { diff --git a/style/fluidbook.css b/style/fluidbook.css index f0d53679..f677cd1b 100644 --- a/style/fluidbook.css +++ b/style/fluidbook.css @@ -1279,8 +1279,7 @@ a.button{ /* Webfonts*/ @font-face { font-family: 'Silkscreen'; - src: url('fonts/slkscr-webfont.woff') format('woff'), - url('fonts/slkscr-webfont.ttf') format('truetype'); + src: url('fonts/slkscr-webfont.ttf') format('truetype'); font-weight: normal; font-style: normal; @@ -1288,48 +1287,42 @@ a.button{ @font-face { font-family: 'Ubuntu'; - src: url('fonts/Ubuntu-R-webfont.woff') format('woff'), - url('fonts/Ubuntu-R-webfont.ttf') format('truetype'); + src: url('fonts/Ubuntu-R-webfont.ttf') format('truetype'); font-weight: 400; font-style: normal; } @font-face { font-family: 'Ubuntu'; - src: url('fonts/Ubuntu-RI-webfont.woff') format('woff'), - url('fonts/Ubuntu-RI-webfont.ttf') format('truetype'); + src: url('fonts/Ubuntu-RI-webfont.ttf') format('truetype'); font-weight: 400; font-style: italic; } @font-face { font-family: 'Ubuntu'; - src: url('fonts/Ubuntu-L-webfont.woff') format('woff'), - url('fonts/Ubuntu-L-webfont.ttf') format('truetype'); + src: url('fonts/Ubuntu-L-webfont.ttf') format('truetype'); font-weight:300; font-style: normal; } @font-face { font-family: 'Ubuntu'; - src: url('fonts/Ubuntu-LI-webfont.woff') format('woff'), - url('fonts/Ubuntu-LI-webfont.ttf') format('truetype'); + src: url('fonts/Ubuntu-LI-webfont.ttf') format('truetype'); font-weight: 300; font-style: italic; } @font-face { font-family: 'Ubuntu'; - src: url('fonts/Ubuntu-M-webfont.woff') format('woff'), - url('fonts/Ubuntu-M-webfont.ttf') format('truetype'); + src:url('fonts/Ubuntu-M-webfont.ttf') format('truetype'); font-weight: 600; font-style: normal; } @font-face { font-family: 'Ubuntu'; - src: url('fonts/Ubuntu-MI-webfont.woff') format('woff'), - url('fonts/Ubuntu-MI-webfont.ttf') format('truetype'); + src:url('fonts/Ubuntu-MI-webfont.ttf') format('truetype'); font-weight: 600; font-style: italic; } diff --git a/style/fonts/Ubuntu-B-webfont.woff b/style/fonts/Ubuntu-B-webfont.woff deleted file mode 100644 index d2752865..00000000 Binary files a/style/fonts/Ubuntu-B-webfont.woff and /dev/null differ diff --git a/style/fonts/Ubuntu-BI-webfont.woff b/style/fonts/Ubuntu-BI-webfont.woff deleted file mode 100644 index 171b64fa..00000000 Binary files a/style/fonts/Ubuntu-BI-webfont.woff and /dev/null differ diff --git a/style/fonts/Ubuntu-L-webfont.woff b/style/fonts/Ubuntu-L-webfont.woff deleted file mode 100644 index 7c2af3b7..00000000 Binary files a/style/fonts/Ubuntu-L-webfont.woff and /dev/null differ diff --git a/style/fonts/Ubuntu-LI-webfont.woff b/style/fonts/Ubuntu-LI-webfont.woff deleted file mode 100644 index 70ee056f..00000000 Binary files a/style/fonts/Ubuntu-LI-webfont.woff and /dev/null differ diff --git a/style/fonts/Ubuntu-M-webfont.woff b/style/fonts/Ubuntu-M-webfont.woff deleted file mode 100644 index 72ce7ad4..00000000 Binary files a/style/fonts/Ubuntu-M-webfont.woff and /dev/null differ diff --git a/style/fonts/Ubuntu-MI-webfont.woff b/style/fonts/Ubuntu-MI-webfont.woff deleted file mode 100644 index c1f6294d..00000000 Binary files a/style/fonts/Ubuntu-MI-webfont.woff and /dev/null differ diff --git a/style/fonts/Ubuntu-R-webfont.woff b/style/fonts/Ubuntu-R-webfont.woff deleted file mode 100644 index cb3dc6f1..00000000 Binary files a/style/fonts/Ubuntu-R-webfont.woff and /dev/null differ diff --git a/style/fonts/Ubuntu-RI-webfont.woff b/style/fonts/Ubuntu-RI-webfont.woff deleted file mode 100644 index 4f09e67b..00000000 Binary files a/style/fonts/Ubuntu-RI-webfont.woff and /dev/null differ diff --git a/style/fonts/slkscr-webfont.woff b/style/fonts/slkscr-webfont.woff deleted file mode 100644 index 6f18403a..00000000 Binary files a/style/fonts/slkscr-webfont.woff and /dev/null differ