From f0bbcfb65421db436d9cb164c9da1cef448bc8d2 Mon Sep 17 00:00:00 2001 From: samuel-p Date: Tue, 22 Nov 2016 23:53:50 +0100 Subject: [PATCH] flip added --- bower_components/flip/.bower.json | 25 ++ bower_components/flip/.bowerrc | 3 + bower_components/flip/.gitignore | 4 + bower_components/flip/.jshintrc | 25 ++ bower_components/flip/.travis.yml | 8 + bower_components/flip/CONTRIBUTING.md | 15 + bower_components/flip/Gruntfile.js | 61 +++ bower_components/flip/LICENSE | 21 + bower_components/flip/README.md | 65 +++ bower_components/flip/bower.json | 15 + .../flip/demo/flip-with-swipebox/index.html | 56 +++ .../flip/demo/flip-with-swipebox/style.css | 36 ++ bower_components/flip/demo/index.html | 68 ++++ bower_components/flip/demo/index2.html | 157 ++++++++ bower_components/flip/dist/jquery.flip.js | 369 ++++++++++++++++++ bower_components/flip/dist/jquery.flip.min.js | 6 + .../flip/dist/jquery.flip.min.js.map | 1 + bower_components/flip/package.json | 64 +++ bower_components/flip/src/flip.js | 366 +++++++++++++++++ 19 files changed, 1365 insertions(+) create mode 100644 bower_components/flip/.bower.json create mode 100644 bower_components/flip/.bowerrc create mode 100644 bower_components/flip/.gitignore create mode 100644 bower_components/flip/.jshintrc create mode 100644 bower_components/flip/.travis.yml create mode 100644 bower_components/flip/CONTRIBUTING.md create mode 100644 bower_components/flip/Gruntfile.js create mode 100644 bower_components/flip/LICENSE create mode 100644 bower_components/flip/README.md create mode 100644 bower_components/flip/bower.json create mode 100644 bower_components/flip/demo/flip-with-swipebox/index.html create mode 100644 bower_components/flip/demo/flip-with-swipebox/style.css create mode 100644 bower_components/flip/demo/index.html create mode 100644 bower_components/flip/demo/index2.html create mode 100644 bower_components/flip/dist/jquery.flip.js create mode 100644 bower_components/flip/dist/jquery.flip.min.js create mode 100644 bower_components/flip/dist/jquery.flip.min.js.map create mode 100644 bower_components/flip/package.json create mode 100644 bower_components/flip/src/flip.js diff --git a/bower_components/flip/.bower.json b/bower_components/flip/.bower.json new file mode 100644 index 0000000..ed1b336 --- /dev/null +++ b/bower_components/flip/.bower.json @@ -0,0 +1,25 @@ +{ + "name": "flip", + "version": "1.1.2", + "license": "MIT", + "dependencies": { + "jquery": "~2.0" + }, + "devDependencies": { + "jquery": "~2.0" + }, + "main": [ + "dist/jquery.flip.js" + ], + "ignore": [], + "homepage": "https://github.com/nnattawat/flip", + "_release": "1.1.2", + "_resolution": { + "type": "version", + "tag": "v1.1.2", + "commit": "e5155d6e29b349205216846822eac8fe9b6426d0" + }, + "_source": "https://github.com/nnattawat/flip.git", + "_target": "*", + "_originalSource": "flip" +} \ No newline at end of file diff --git a/bower_components/flip/.bowerrc b/bower_components/flip/.bowerrc new file mode 100644 index 0000000..44491d3 --- /dev/null +++ b/bower_components/flip/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory": "bower_components" +} diff --git a/bower_components/flip/.gitignore b/bower_components/flip/.gitignore new file mode 100644 index 0000000..ae9f6df --- /dev/null +++ b/bower_components/flip/.gitignore @@ -0,0 +1,4 @@ +/node_modules/ +/bower_components/ +npm-debug.log +*.swp diff --git a/bower_components/flip/.jshintrc b/bower_components/flip/.jshintrc new file mode 100644 index 0000000..2896f35 --- /dev/null +++ b/bower_components/flip/.jshintrc @@ -0,0 +1,25 @@ +{ + "boss": true, + "browser": true, + "curly": true, + "devel": true, + "eqeqeq": true, + "eqnull": true, + "esversion": 5, + "expr": true, + "immed": true, + "newcap": false, + "noarg": true, + "onevar": true, + "quotmark": false, + "shadow": true, + "trailing": true, + "undef": true, + "unused": true, + "freeze": true, + "maxstatements": 30, + + "globals": { + "jQuery": false + } +} diff --git a/bower_components/flip/.travis.yml b/bower_components/flip/.travis.yml new file mode 100644 index 0000000..f6009b6 --- /dev/null +++ b/bower_components/flip/.travis.yml @@ -0,0 +1,8 @@ +language: node_js +node_js: + - '0.10' +before_install: + - npm install -g grunt-cli bower +install: + - npm install + - bower install \ No newline at end of file diff --git a/bower_components/flip/CONTRIBUTING.md b/bower_components/flip/CONTRIBUTING.md new file mode 100644 index 0000000..73d2cc7 --- /dev/null +++ b/bower_components/flip/CONTRIBUTING.md @@ -0,0 +1,15 @@ +# Issue and Pull Request Guidlines + +## + +##### Be clear + * Just because you have an understanding of what you would like to address, doesnt mean its obvious. Please be clear and consise. + +##### Examples are your friend + * Probably the best way for us to get a handle on what's going on is you providing us with a short example using something like a [JSFiddle](http://jsfiddle.net/). + +##### Stick around + * If you're interested in getting your changes in and/or issue resolved, it's extremely likely you're going to have to have some discussion about it before that happens. So don't just drop something on us and leave and expect that something will come of it. + +##### Discussion before code + * If you don't want to waste your time writing code that might not be used, it's probably best to make an issue and discuss it with us first before you start writing. diff --git a/bower_components/flip/Gruntfile.js b/bower_components/flip/Gruntfile.js new file mode 100644 index 0000000..f51a543 --- /dev/null +++ b/bower_components/flip/Gruntfile.js @@ -0,0 +1,61 @@ +'use strict'; + +module.exports = function (grunt) { + // Load all grunt tasks + require('load-grunt-tasks')(grunt); + // Show elapsed time at the end + require('time-grunt')(grunt); + + // Project configuration. + grunt.initConfig({ + // Metadata. + pkg: grunt.file.readJSON('package.json'), + banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' + + '<%= grunt.template.today("yyyy-mm-dd") %>\n' + + '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' + + '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' + + ' Licensed MIT */\n', + // Task configuration. + clean: { + files: ['dist'] + }, + jshint: { + options : { + jshintrc : '.jshintrc' + }, + all: [ 'src/<%= pkg.name %>.js' ] + }, + concat: { + options: { + banner: '<%= banner %>', + stripBanners: true + }, + dist: { + src: ['src/<%= pkg.name %>.js'], + dest: 'dist/jquery.<%= pkg.name %>.js' + } + }, + uglify: { + options: { + sourceMap: 'dist/jquery.<%= pkg.name %>.min.js.map', + sourceMappingURL : 'jquery.<%= pkg.name %>.min.js.map', + banner: '<%= banner %>' + }, + dist: { + src: '<%= concat.dist.src %>', + dest: 'dist/jquery.<%= pkg.name %>.min.js' + } + }, + connect: { + server: { + options: { + hostname: '*', + port: 9000 + } + } + } + }); + + // Default task. + grunt.registerTask('default', ['connect', 'clean', 'jshint', 'concat', 'uglify']); +}; diff --git a/bower_components/flip/LICENSE b/bower_components/flip/LICENSE new file mode 100644 index 0000000..0cc25d9 --- /dev/null +++ b/bower_components/flip/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Nattawat Nonsung (author) and Carlos Fagiani Junior + 2015 Jemar Jones, Nattawat Nonsung, Razvan Popa and Stijn de Witt + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/bower_components/flip/README.md b/bower_components/flip/README.md new file mode 100644 index 0000000..9ffe189 --- /dev/null +++ b/bower_components/flip/README.md @@ -0,0 +1,65 @@ +[![Build Status](https://travis-ci.org/nnattawat/flip.svg?branch=master)](https://travis-ci.org/nnattawat/flip) +# jQuery Flip + +**A lightweight jQuery plugin to create 3d flip animation.** +See the [project page](http://nnattawat.github.io/flip/) + +## Getting Started + +### CDN + https://cdn.rawgit.com/nnattawat/flip/master/dist/jquery.flip.min.js + +### Download +* [jquery.flip.js][max] (development version, commented ~9kB) +* [jquery.flip.min.js][min] (production version, minified ~4kB, gzipped ~2kB) +* [jquery.flip.min.js.map][map] (source map, ~5kB) +[max]: https://cdn.rawgit.com/nnattawat/flip/master/dist/jquery.flip.js +[min]: https://cdn.rawgit.com/nnattawat/flip/master/dist/jquery.flip.min.js +[map]: https://cdn.rawgit.com/nnattawat/flip/master/dist/jquery.flip.min.js.map + +### Bower +
bower install flip
+ +### Usage +In your web page: + +```html + +
+
+ Front content +
+
+ Back content +
+
+ + + + +``` + +## Documentation and Example + +Please refer to [the project website](http://nnattawat.github.io/flip/) + +## Development +Ensure that you have the latest [Node.js](http://nodejs.org/) and [npm](http://npmjs.org/) installed. + +Test that Grunt's CLI and Bower are installed by running `grunt --version` and `bower --version`. If the commands aren't found, run `npm install -g grunt-cli bower`. For more information about installing the tools, see the [getting started with Grunt guide](http://gruntjs.com/getting-started) or [bower.io](http://bower.io/) respectively. + +To run the demo locally, do the following. +
+npm install
+bower install
+
+ +And run grunt command to create files in /dist folder. +
grunt
+ +## What's new +Please refer to [the release page](https://github.com/nnattawat/flip/releases) diff --git a/bower_components/flip/bower.json b/bower_components/flip/bower.json new file mode 100644 index 0000000..0271ee9 --- /dev/null +++ b/bower_components/flip/bower.json @@ -0,0 +1,15 @@ +{ + "name": "flip", + "version": "1.1.2", + "license": "MIT", + "dependencies": { + "jquery": "~2.0" + }, + "devDependencies": { + "jquery": "~2.0" + }, + "main": [ + "dist/jquery.flip.js" + ], + "ignore": [] +} diff --git a/bower_components/flip/demo/flip-with-swipebox/index.html b/bower_components/flip/demo/flip-with-swipebox/index.html new file mode 100644 index 0000000..7ec8ac2 --- /dev/null +++ b/bower_components/flip/demo/flip-with-swipebox/index.html @@ -0,0 +1,56 @@ + + + + + + + + + +
+
+

Flip with Swipebox

+
+ + image + + + image + + + image + + + image + +
+

When a Swipebox is used on + a card animated with Flip, the Swipebox fails, as can be seen in this demo when + we use version 1.0.1 of Flip. If we apply the patch the issue is fixed.

+

Click on the thumbnails. A Swipebox should open.

+ +
+
+

Flip with Swipebox

+

The problem is caused by Flip disabling the bubbling of click + events on any links that are contained inside the element to be flipped, + as can be seen in lines 80-82 of the + source code.

+

This code was written to prevent the card from flipping when buttons and + links on the card are pressed. However, preventing event bubling is + dangerous.

+

The better solution is to ignore those events that you are not interested in.

+
+
+ + + + + + + \ No newline at end of file diff --git a/bower_components/flip/demo/flip-with-swipebox/style.css b/bower_components/flip/demo/flip-with-swipebox/style.css new file mode 100644 index 0000000..3c6d855 --- /dev/null +++ b/bower_components/flip/demo/flip-with-swipebox/style.css @@ -0,0 +1,36 @@ +html, body, div, ul { + box-sizing: border-box; +} + +html, body { + margin: 0; + padding: 0; +} + +.card { + width: 320px; + height: 460px; + padding: 30px; + margin: 0 auto; +} + +.card a.thumb { + float: left; + width: 100px; + height: 60px; + margin: 0 5px 10px 0; +} + +.card a.thumb img { + max-width: 100%; + max-height: 100%; +} + +.front, .back { + width: 100%; + height: 80%; + padding: 15px; + background-color: white; + border-radius: 5px; + box-shadow: 0px 1px 6px rgba(0,0,0, 0.4); +} \ No newline at end of file diff --git a/bower_components/flip/demo/index.html b/bower_components/flip/demo/index.html new file mode 100644 index 0000000..0521abf --- /dev/null +++ b/bower_components/flip/demo/index.html @@ -0,0 +1,68 @@ + + + + + + + jQuery plugin + + + +
+
+ Front: Cursus aliquet mus et sociis, placerat adipiscing a placerat magnis integer nisi lacus in, turpis porttitor? Lectus nunc dis in porta, montes lacus. Tortor. Pid sit nisi eu nec aenean. +
+
+ link + Back: Dolor scelerisque ridiculus! Mus? Augue, montes, montes proin rhoncus vel a parturient dapibus eros? Penatibus nascetur. In turpis nisi elementum nascetur habitasse augue egestas, in ac rhoncus odio porttitor turpis. + Back: Dolor scelerisque ridiculus! Mus? Augue, montes, montes proin rhoncus vel a parturient dapibus eros? Penatibus nascetur. In turpis nisi elementum nascetur habitasse augue egestas, in ac rhoncus odio porttitor turpis. +
+
+ +
+
+ Front: Cursus aliquet mus et sociis, placerat adipiscing a placerat magnis integer nisi lacus in, turpis porttitor? Lectus nunc dis in porta, montes lacus. Tortor. Pid sit nisi eu nec aenean. +
+
+ link + Back: Dolor scelerisque ridiculus! Mus? Augue, montes, montes proin rhoncus vel a parturient dapibus eros? Penatibus nascetur. In turpis nisi elementum nascetur habitasse augue egestas, in ac rhoncus odio porttitor turpis. + +
+
+ + + + diff --git a/bower_components/flip/demo/index2.html b/bower_components/flip/demo/index2.html new file mode 100644 index 0000000..4740a32 --- /dev/null +++ b/bower_components/flip/demo/index2.html @@ -0,0 +1,157 @@ + + + + + + + + jQuery plugin + + + +
+
+ Front +
+
+ Back +
+
+ +
+
+ Front +
+
+ Back +
+
+ +
+
+ Front +
+
+ Back +
+
+ +
+
+ Front +
+
+ Back +
+
+ +
+
+ Front +
+
+ Back +
+
+ +
+
+ Front +
+
+ Back +
+
+ +
+
+ Front +
+
+ Back +
+
+ +
+
+ Front +
+
+ Back +
+
+ +
+
+ Front +
+
+ Back +
+
+ +
+
+ Front +
+
+ Back +
+
+ +
+
+ Front +
+
+ Back +
+
+ +
+
+ Front +
+
+ Back +
+
+ +
+
+ Front +
+
+ Back +
+
+ + + diff --git a/bower_components/flip/dist/jquery.flip.js b/bower_components/flip/dist/jquery.flip.js new file mode 100644 index 0000000..bc5d328 --- /dev/null +++ b/bower_components/flip/dist/jquery.flip.js @@ -0,0 +1,369 @@ +/*! flip - v1.1.2 - 2016-10-20 +* https://github.com/nnattawat/flip +* Copyright (c) 2016 Nattawat Nonsung; Licensed MIT */ +(function( $ ) { + /* + * Private attributes and method + */ + + // Function from David Walsh: http://davidwalsh.name/css-animation-callback licensed with http://opensource.org/licenses/MIT + var whichTransitionEvent = function() { + var t, el = document.createElement("fakeelement"), + transitions = { + "transition" : "transitionend", + "OTransition" : "oTransitionEnd", + "MozTransition" : "transitionend", + "WebkitTransition": "webkitTransitionEnd" + }; + + for (t in transitions) { + if (el.style[t] !== undefined) { + return transitions[t]; + } + } + }; + + /* + * Model declaration + */ + var Flip = function($el, options, callback) { + // Define default setting + this.setting = { + axis: "y", + reverse: false, + trigger: "click", + speed: 500, + forceHeight: false, + forceWidth: false, + autoSize: true, + front: '.front', + back: '.back' + }; + + this.setting = $.extend(this.setting, options); + + if (typeof options.axis === 'string' && (options.axis.toLowerCase() === 'x' || options.axis.toLowerCase() === 'y')) { + this.setting.axis = options.axis.toLowerCase(); + } + + if (typeof options.reverse === "boolean") { + this.setting.reverse = options.reverse; + } + + if (typeof options.trigger === 'string') { + this.setting.trigger = options.trigger.toLowerCase(); + } + + var speed = parseInt(options.speed); + if (!isNaN(speed)) { + this.setting.speed = speed; + } + + if (typeof options.forceHeight === "boolean") { + this.setting.forceHeight = options.forceHeight; + } + + if (typeof options.forceWidth === "boolean") { + this.setting.forceWidth = options.forceWidth; + } + + if (typeof options.autoSize === "boolean") { + this.setting.autoSize = options.autoSize; + } + + if (typeof options.front === 'string' || options.front instanceof $) { + this.setting.front = options.front; + } + + if (typeof options.back === 'string' || options.back instanceof $) { + this.setting.back = options.back; + } + + // Other attributes + this.element = $el; + this.frontElement = this.getFrontElement(); + this.backElement = this.getBackElement(); + this.isFlipped = false; + + this.init(callback); + }; + + /* + * Public methods + */ + $.extend(Flip.prototype, { + + flipDone: function(callback) { + var self = this; + // Providing a nicely wrapped up callback because transform is essentially async + self.element.one(whichTransitionEvent(), function() { + self.element.trigger('flip:done'); + if (typeof callback === 'function') { + callback.call(self.element); + } + }); + }, + + flip: function(callback) { + if (this.isFlipped) { + return; + } + + this.isFlipped = true; + + var rotateAxis = "rotate" + this.setting.axis; + this.frontElement.css({ + transform: rotateAxis + (this.setting.reverse ? "(-180deg)" : "(180deg)"), + "z-index": "0" + }); + + this.backElement.css({ + transform: rotateAxis + "(0deg)", + "z-index": "1" + }); + this.flipDone(callback); + }, + + unflip: function(callback) { + if (!this.isFlipped) { + return; + } + + this.isFlipped = false; + + var rotateAxis = "rotate" + this.setting.axis; + this.frontElement.css({ + transform: rotateAxis + "(0deg)", + "z-index": "1" + }); + + this.backElement.css({ + transform: rotateAxis + (this.setting.reverse ? "(180deg)" : "(-180deg)"), + "z-index": "0" + }); + this.flipDone(callback); + }, + + getFrontElement: function() { + if (this.setting.front instanceof $) { + return this.setting.front; + } else { + return this.element.find(this.setting.front); + } + }, + + getBackElement: function() { + if (this.setting.back instanceof $) { + return this.setting.back; + } else { + return this.element.find(this.setting.back); + } + }, + + init: function(callback) { + var self = this; + + var faces = self.frontElement.add(self.backElement); + var rotateAxis = "rotate" + self.setting.axis; + var perspective = self.element["outer" + (rotateAxis === "rotatex" ? "Height" : "Width")]() * 2; + var elementCss = { + 'perspective': perspective, + 'position': 'relative' + }; + var backElementCss = { + "transform": rotateAxis + "(" + (self.setting.reverse ? "180deg" : "-180deg") + ")", + "z-index": "0", + "position": "relative" + }; + var faceElementCss = { + "backface-visibility": "hidden", + "transform-style": "preserve-3d", + "position": "absolute", + "z-index": "1" + }; + + if (self.setting.forceHeight) { + faces.outerHeight(self.element.height()); + } else if (self.setting.autoSize) { + faceElementCss.height = '100%'; + } + + if (self.setting.forceWidth) { + faces.outerWidth(self.element.width()); + } else if (self.setting.autoSize) { + faceElementCss.width = '100%'; + } + + // Back face always visible on Chrome #39 + if ((window.chrome || (window.Intl && Intl.v8BreakIterator)) && 'CSS' in window) { + //Blink Engine, add preserve-3d to self.element + elementCss["-webkit-transform-style"] = "preserve-3d"; + } + + + faces.css(faceElementCss).find('*').css({ + "backface-visibility": "hidden" + }); + + self.element.css(elementCss); + self.backElement.css(backElementCss); + + // #39 + // not forcing width/height may cause an initial flip to show up on + // page load when we apply the style to reverse the backface... + // To prevent self we first apply the basic styles and then give the + // browser a moment to apply them. Only afterwards do we add the transition. + setTimeout(function() { + // By now the browser should have applied the styles, so the transition + // will only affect subsequent flips. + var speedInSec = self.setting.speed / 1000 || 0.5; + faces.css({ + "transition": "all " + speedInSec + "s ease-out" + }); + + // This allows flip to be called for setup with only a callback (default settings) + if (typeof callback === 'function') { + callback.call(self.element); + } + + // While this used to work with a setTimeout of zero, at some point that became + // unstable and the initial flip returned. The reason for this is unknown but we + // will temporarily use a short delay of 20 to mitigate this issue. + }, 20); + + self.attachEvents(); + }, + + clickHandler: function(event) { + if (!event) { event = window.event; } + if (this.element.find($(event.target).closest('button, a, input[type="submit"]')).length) { + return; + } + + if (this.isFlipped) { + this.unflip(); + } else { + this.flip(); + } + }, + + hoverHandler: function() { + var self = this; + self.element.off('mouseleave.flip'); + + self.flip(); + + setTimeout(function() { + self.element.on('mouseleave.flip', $.proxy(self.unflip, self)); + if (!self.element.is(":hover")) { + self.unflip(); + } + }, (self.setting.speed + 150)); + }, + + attachEvents: function() { + var self = this; + if (self.setting.trigger === "click") { + self.element.on($.fn.tap ? "tap.flip" : "click.flip", $.proxy(self.clickHandler, self)); + } else if (self.setting.trigger === "hover") { + self.element.on('mouseenter.flip', $.proxy(self.hoverHandler, self)); + self.element.on('mouseleave.flip', $.proxy(self.unflip, self)); + } + }, + + flipChanged: function(callback) { + this.element.trigger('flip:change'); + if (typeof callback === 'function') { + callback.call(this.element); + } + }, + + changeSettings: function(options, callback) { + var self = this; + var changeNeeded = false; + + if (options.axis !== undefined && self.setting.axis !== options.axis.toLowerCase()) { + self.setting.axis = options.axis.toLowerCase(); + changeNeeded = true; + } + + if (options.reverse !== undefined && self.setting.reverse !== options.reverse) { + self.setting.reverse = options.reverse; + changeNeeded = true; + } + + if (changeNeeded) { + var faces = self.frontElement.add(self.backElement); + var savedTrans = faces.css(["transition-property", "transition-timing-function", "transition-duration", "transition-delay"]); + + faces.css({ + transition: "none" + }); + + // This sets up the first flip in the new direction automatically + var rotateAxis = "rotate" + self.setting.axis; + + if (self.isFlipped) { + self.frontElement.css({ + transform: rotateAxis + (self.setting.reverse ? "(-180deg)" : "(180deg)"), + "z-index": "0" + }); + } else { + self.backElement.css({ + transform: rotateAxis + (self.setting.reverse ? "(180deg)" : "(-180deg)"), + "z-index": "0" + }); + } + // Providing a nicely wrapped up callback because transform is essentially async + setTimeout(function() { + faces.css(savedTrans); + self.flipChanged(callback); + }, 0); + } else { + // If we didnt have to set the axis we can just call back. + self.flipChanged(callback); + } + } + + }); + + /* + * jQuery collection methods + */ + $.fn.flip = function (options, callback) { + if (typeof options === 'function') { + callback = options; + } + + if (typeof options === "string" || typeof options === "boolean") { + this.each(function() { + var flip = $(this).data('flip-model'); + + if (options === "toggle") { + options = !flip.isFlipped; + } + + if (options) { + flip.flip(callback); + } else { + flip.unflip(callback); + } + }); + } else { + this.each(function() { + if ($(this).data('flip-model')) { // The element has been initiated, all we have to do is change applicable settings + var flip = $(this).data('flip-model'); + + if (options && (options.axis !== undefined || options.reverse !== undefined)) { + flip.changeSettings(options, callback); + } + } else { // Init + $(this).data('flip-model', new Flip($(this), (options || {}), callback)); + } + }); + } + + return this; + }; + +}( jQuery )); diff --git a/bower_components/flip/dist/jquery.flip.min.js b/bower_components/flip/dist/jquery.flip.min.js new file mode 100644 index 0000000..53cfe2b --- /dev/null +++ b/bower_components/flip/dist/jquery.flip.min.js @@ -0,0 +1,6 @@ +/*! flip - v1.1.2 - 2016-10-20 +* https://github.com/nnattawat/flip +* Copyright (c) 2016 Nattawat Nonsung; Licensed MIT */ + +!function(a){var b=function(){var a,b=document.createElement("fakeelement"),c={transition:"transitionend",OTransition:"oTransitionEnd",MozTransition:"transitionend",WebkitTransition:"webkitTransitionEnd"};for(a in c)if(void 0!==b.style[a])return c[a]},c=function(b,c,d){this.setting={axis:"y",reverse:!1,trigger:"click",speed:500,forceHeight:!1,forceWidth:!1,autoSize:!0,front:".front",back:".back"},this.setting=a.extend(this.setting,c),"string"!=typeof c.axis||"x"!==c.axis.toLowerCase()&&"y"!==c.axis.toLowerCase()||(this.setting.axis=c.axis.toLowerCase()),"boolean"==typeof c.reverse&&(this.setting.reverse=c.reverse),"string"==typeof c.trigger&&(this.setting.trigger=c.trigger.toLowerCase());var e=parseInt(c.speed);isNaN(e)||(this.setting.speed=e),"boolean"==typeof c.forceHeight&&(this.setting.forceHeight=c.forceHeight),"boolean"==typeof c.forceWidth&&(this.setting.forceWidth=c.forceWidth),"boolean"==typeof c.autoSize&&(this.setting.autoSize=c.autoSize),("string"==typeof c.front||c.front instanceof a)&&(this.setting.front=c.front),("string"==typeof c.back||c.back instanceof a)&&(this.setting.back=c.back),this.element=b,this.frontElement=this.getFrontElement(),this.backElement=this.getBackElement(),this.isFlipped=!1,this.init(d)};a.extend(c.prototype,{flipDone:function(a){var c=this;c.element.one(b(),function(){c.element.trigger("flip:done"),"function"==typeof a&&a.call(c.element)})},flip:function(a){if(!this.isFlipped){this.isFlipped=!0;var b="rotate"+this.setting.axis;this.frontElement.css({transform:b+(this.setting.reverse?"(-180deg)":"(180deg)"),"z-index":"0"}),this.backElement.css({transform:b+"(0deg)","z-index":"1"}),this.flipDone(a)}},unflip:function(a){if(this.isFlipped){this.isFlipped=!1;var b="rotate"+this.setting.axis;this.frontElement.css({transform:b+"(0deg)","z-index":"1"}),this.backElement.css({transform:b+(this.setting.reverse?"(180deg)":"(-180deg)"),"z-index":"0"}),this.flipDone(a)}},getFrontElement:function(){return this.setting.front instanceof a?this.setting.front:this.element.find(this.setting.front)},getBackElement:function(){return this.setting.back instanceof a?this.setting.back:this.element.find(this.setting.back)},init:function(a){var b=this,c=b.frontElement.add(b.backElement),d="rotate"+b.setting.axis,e=2*b.element["outer"+("rotatex"===d?"Height":"Width")](),f={perspective:e,position:"relative"},g={transform:d+"("+(b.setting.reverse?"180deg":"-180deg")+")","z-index":"0",position:"relative"},h={"backface-visibility":"hidden","transform-style":"preserve-3d",position:"absolute","z-index":"1"};b.setting.forceHeight?c.outerHeight(b.element.height()):b.setting.autoSize&&(h.height="100%"),b.setting.forceWidth?c.outerWidth(b.element.width()):b.setting.autoSize&&(h.width="100%"),(window.chrome||window.Intl&&Intl.v8BreakIterator)&&"CSS"in window&&(f["-webkit-transform-style"]="preserve-3d"),c.css(h).find("*").css({"backface-visibility":"hidden"}),b.element.css(f),b.backElement.css(g),setTimeout(function(){var d=b.setting.speed/1e3||.5;c.css({transition:"all "+d+"s ease-out"}),"function"==typeof a&&a.call(b.element)},20),b.attachEvents()},clickHandler:function(b){b||(b=window.event),this.element.find(a(b.target).closest('button, a, input[type="submit"]')).length||(this.isFlipped?this.unflip():this.flip())},hoverHandler:function(){var b=this;b.element.off("mouseleave.flip"),b.flip(),setTimeout(function(){b.element.on("mouseleave.flip",a.proxy(b.unflip,b)),b.element.is(":hover")||b.unflip()},b.setting.speed+150)},attachEvents:function(){var b=this;"click"===b.setting.trigger?b.element.on(a.fn.tap?"tap.flip":"click.flip",a.proxy(b.clickHandler,b)):"hover"===b.setting.trigger&&(b.element.on("mouseenter.flip",a.proxy(b.hoverHandler,b)),b.element.on("mouseleave.flip",a.proxy(b.unflip,b)))},flipChanged:function(a){this.element.trigger("flip:change"),"function"==typeof a&&a.call(this.element)},changeSettings:function(a,b){var c=this,d=!1;if(void 0!==a.axis&&c.setting.axis!==a.axis.toLowerCase()&&(c.setting.axis=a.axis.toLowerCase(),d=!0),void 0!==a.reverse&&c.setting.reverse!==a.reverse&&(c.setting.reverse=a.reverse,d=!0),d){var e=c.frontElement.add(c.backElement),f=e.css(["transition-property","transition-timing-function","transition-duration","transition-delay"]);e.css({transition:"none"});var g="rotate"+c.setting.axis;c.isFlipped?c.frontElement.css({transform:g+(c.setting.reverse?"(-180deg)":"(180deg)"),"z-index":"0"}):c.backElement.css({transform:g+(c.setting.reverse?"(180deg)":"(-180deg)"),"z-index":"0"}),setTimeout(function(){e.css(f),c.flipChanged(b)},0)}else c.flipChanged(b)}}),a.fn.flip=function(b,d){return"function"==typeof b&&(d=b),"string"==typeof b||"boolean"==typeof b?this.each(function(){var c=a(this).data("flip-model");"toggle"===b&&(b=!c.isFlipped),b?c.flip(d):c.unflip(d)}):this.each(function(){if(a(this).data("flip-model")){var e=a(this).data("flip-model");!b||void 0===b.axis&&void 0===b.reverse||e.changeSettings(b,d)}else a(this).data("flip-model",new c(a(this),b||{},d))}),this}}(jQuery); +//# sourceMappingURL=jquery.flip.min.js.map \ No newline at end of file diff --git a/bower_components/flip/dist/jquery.flip.min.js.map b/bower_components/flip/dist/jquery.flip.min.js.map new file mode 100644 index 0000000..fde9dee --- /dev/null +++ b/bower_components/flip/dist/jquery.flip.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dist/jquery.flip.min.js","sources":["src/flip.js"],"names":["$","whichTransitionEvent","t","el","document","createElement","transitions","transition","OTransition","MozTransition","WebkitTransition","undefined","style","Flip","$el","options","callback","this","setting","axis","reverse","trigger","speed","forceHeight","forceWidth","autoSize","front","back","extend","toLowerCase","parseInt","isNaN","element","frontElement","getFrontElement","backElement","getBackElement","isFlipped","init","prototype","flipDone","self","one","call","flip","rotateAxis","css","transform","z-index","unflip","find","faces","add","perspective","elementCss","position","backElementCss","faceElementCss","backface-visibility","transform-style","outerHeight","height","outerWidth","width","window","chrome","Intl","v8BreakIterator","setTimeout","speedInSec","attachEvents","clickHandler","event","target","closest","length","hoverHandler","off","on","proxy","is","fn","tap","flipChanged","changeSettings","changeNeeded","savedTrans","each","data","jQuery"],"mappings":";;;;CAAC,SAAUA,GAMT,GAAIC,GAAuB,WACzB,GAAIC,GAAGC,EAAKC,SAASC,cAAc,eACnCC,GACEC,WAAoB,gBACpBC,YAAoB,iBACpBC,cAAoB,gBACpBC,iBAAoB,sBAGtB,KAAKR,IAAKI,GACR,GAAoBK,SAAhBR,EAAGS,MAAMV,GACX,MAAOI,GAAYJ,IAQrBW,EAAO,SAASC,EAAKC,EAASC,GAEhCC,KAAKC,SACHC,KAAM,IACNC,SAAS,EACTC,QAAS,QACTC,MAAO,IACPC,aAAa,EACbC,YAAY,EACZC,UAAU,EACVC,MAAO,SACPC,KAAM,SAGRV,KAAKC,QAAUlB,EAAE4B,OAAOX,KAAKC,QAASH,GAEV,gBAAjBA,GAAQI,MAAqD,MAA/BJ,EAAQI,KAAKU,eAAwD,MAA/Bd,EAAQI,KAAKU,gBAC1FZ,KAAKC,QAAQC,KAAOJ,EAAQI,KAAKU,eAGJ,iBAApBd,GAAQK,UACjBH,KAAKC,QAAQE,QAAUL,EAAQK,SAGF,gBAApBL,GAAQM,UACjBJ,KAAKC,QAAQG,QAAUN,EAAQM,QAAQQ,cAGzC,IAAIP,GAAQQ,SAASf,EAAQO,MACxBS,OAAMT,KACTL,KAAKC,QAAQI,MAAQA,GAGY,iBAAxBP,GAAQQ,cACjBN,KAAKC,QAAQK,YAAcR,EAAQQ,aAGH,iBAAvBR,GAAQS,aACjBP,KAAKC,QAAQM,WAAaT,EAAQS,YAGJ,iBAArBT,GAAQU,WACjBR,KAAKC,QAAQO,SAAWV,EAAQU,WAGL,gBAAlBV,GAAQW,OAAsBX,EAAQW,gBAAiB1B,MAChEiB,KAAKC,QAAQQ,MAAQX,EAAQW,QAGH,gBAAjBX,GAAQY,MAAqBZ,EAAQY,eAAgB3B,MAC9DiB,KAAKC,QAAQS,KAAOZ,EAAQY,MAI9BV,KAAKe,QAAUlB,EACfG,KAAKgB,aAAehB,KAAKiB,kBACzBjB,KAAKkB,YAAclB,KAAKmB,iBACxBnB,KAAKoB,WAAY,EAEjBpB,KAAKqB,KAAKtB,GAMZhB,GAAE4B,OAAOf,EAAK0B,WAEZC,SAAU,SAASxB,GACjB,GAAIyB,GAAOxB,IAEXwB,GAAKT,QAAQU,IAAIzC,IAAwB,WACvCwC,EAAKT,QAAQX,QAAQ,aACG,kBAAbL,IACTA,EAAS2B,KAAKF,EAAKT,YAKzBY,KAAM,SAAS5B,GACb,IAAIC,KAAKoB,UAAT,CAIApB,KAAKoB,WAAY,CAEjB,IAAIQ,GAAa,SAAW5B,KAAKC,QAAQC,IACzCF,MAAKgB,aAAaa,KAChBC,UAAWF,GAAc5B,KAAKC,QAAQE,QAAU,YAAc,YAC9D4B,UAAW,MAGb/B,KAAKkB,YAAYW,KACfC,UAAWF,EAAa,SACxBG,UAAW,MAEb/B,KAAKuB,SAASxB,KAGhBiC,OAAQ,SAASjC,GACf,GAAKC,KAAKoB,UAAV,CAIApB,KAAKoB,WAAY,CAEjB,IAAIQ,GAAa,SAAW5B,KAAKC,QAAQC,IACzCF,MAAKgB,aAAaa,KAChBC,UAAWF,EAAa,SACxBG,UAAW,MAGb/B,KAAKkB,YAAYW,KACfC,UAAWF,GAAc5B,KAAKC,QAAQE,QAAU,WAAa,aAC7D4B,UAAW,MAEb/B,KAAKuB,SAASxB,KAGhBkB,gBAAiB,WACf,MAAIjB,MAAKC,QAAQQ,gBAAiB1B,GACzBiB,KAAKC,QAAQQ,MAEbT,KAAKe,QAAQkB,KAAKjC,KAAKC,QAAQQ,QAI1CU,eAAgB,WACd,MAAInB,MAAKC,QAAQS,eAAgB3B,GACxBiB,KAAKC,QAAQS,KAEbV,KAAKe,QAAQkB,KAAKjC,KAAKC,QAAQS,OAI1CW,KAAM,SAAStB,GACb,GAAIyB,GAAOxB,KAEPkC,EAAQV,EAAKR,aAAamB,IAAIX,EAAKN,aACnCU,EAAa,SAAWJ,EAAKvB,QAAQC,KACrCkC,EAA0F,EAA5EZ,EAAKT,QAAQ,SAA0B,YAAfa,EAA2B,SAAW,YAC5ES,GACFD,YAAeA,EACfE,SAAY,YAEVC,GACFT,UAAaF,EAAa,KAAOJ,EAAKvB,QAAQE,QAAU,SAAW,WAAa,IAChF4B,UAAW,IACXO,SAAY,YAEVE,GACFC,sBAAuB,SACvBC,kBAAmB,cACnBJ,SAAY,WACZP,UAAW,IAGTP,GAAKvB,QAAQK,YACf4B,EAAMS,YAAYnB,EAAKT,QAAQ6B,UACtBpB,EAAKvB,QAAQO,WACtBgC,EAAeI,OAAS,QAGtBpB,EAAKvB,QAAQM,WACf2B,EAAMW,WAAWrB,EAAKT,QAAQ+B,SACrBtB,EAAKvB,QAAQO,WACtBgC,EAAeM,MAAQ,SAIpBC,OAAOC,QAAWD,OAAOE,MAAQA,KAAKC,kBAAqB,OAASH,UAEvEV,EAAW,2BAA6B,eAI1CH,EAAML,IAAIW,GAAgBP,KAAK,KAAKJ,KAClCY,sBAAuB,WAGzBjB,EAAKT,QAAQc,IAAIQ,GACjBb,EAAKN,YAAYW,IAAIU,GAOrBY,WAAW,WAGT,GAAIC,GAAa5B,EAAKvB,QAAQI,MAAQ,KAAQ,EAC9C6B,GAAML,KACJvC,WAAc,OAAS8D,EAAa,eAId,kBAAbrD,IACTA,EAAS2B,KAAKF,EAAKT,UAMpB,IAEHS,EAAK6B,gBAGPC,aAAc,SAASC,GAChBA,IAASA,EAAQR,OAAOQ,OACzBvD,KAAKe,QAAQkB,KAAKlD,EAAEwE,EAAMC,QAAQC,QAAQ,oCAAoCC,SAI9E1D,KAAKoB,UACPpB,KAAKgC,SAELhC,KAAK2B,SAITgC,aAAc,WACZ,GAAInC,GAAOxB,IACXwB,GAAKT,QAAQ6C,IAAI,mBAEjBpC,EAAKG,OAELwB,WAAW,WACT3B,EAAKT,QAAQ8C,GAAG,kBAAmB9E,EAAE+E,MAAMtC,EAAKQ,OAAQR,IACnDA,EAAKT,QAAQgD,GAAG,WACnBvC,EAAKQ,UAELR,EAAKvB,QAAQI,MAAQ,MAG3BgD,aAAc,WACZ,GAAI7B,GAAOxB,IACkB,WAAzBwB,EAAKvB,QAAQG,QACfoB,EAAKT,QAAQ8C,GAAG9E,EAAEiF,GAAGC,IAAM,WAAa,aAAclF,EAAE+E,MAAMtC,EAAK8B,aAAc9B,IAC/C,UAAzBA,EAAKvB,QAAQG,UACtBoB,EAAKT,QAAQ8C,GAAG,kBAAmB9E,EAAE+E,MAAMtC,EAAKmC,aAAcnC,IAC9DA,EAAKT,QAAQ8C,GAAG,kBAAmB9E,EAAE+E,MAAMtC,EAAKQ,OAAQR,MAI5D0C,YAAa,SAASnE,GACpBC,KAAKe,QAAQX,QAAQ,eACG,kBAAbL,IACTA,EAAS2B,KAAK1B,KAAKe,UAIvBoD,eAAgB,SAASrE,EAASC,GAChC,GAAIyB,GAAOxB,KACPoE,GAAe,CAYnB,IAVqB1E,SAAjBI,EAAQI,MAAsBsB,EAAKvB,QAAQC,OAASJ,EAAQI,KAAKU,gBACnEY,EAAKvB,QAAQC,KAAOJ,EAAQI,KAAKU,cACjCwD,GAAe,GAGO1E,SAApBI,EAAQK,SAAyBqB,EAAKvB,QAAQE,UAAYL,EAAQK,UACpEqB,EAAKvB,QAAQE,QAAUL,EAAQK,QAC/BiE,GAAe,GAGbA,EAAc,CAChB,GAAIlC,GAAQV,EAAKR,aAAamB,IAAIX,EAAKN,aACnCmD,EAAanC,EAAML,KAAK,sBAAuB,6BAA8B,sBAAuB,oBAExGK,GAAML,KACJvC,WAAY,QAId,IAAIsC,GAAa,SAAWJ,EAAKvB,QAAQC,IAErCsB,GAAKJ,UACPI,EAAKR,aAAaa,KAChBC,UAAWF,GAAcJ,EAAKvB,QAAQE,QAAU,YAAc,YAC9D4B,UAAW,MAGbP,EAAKN,YAAYW,KACfC,UAAWF,GAAcJ,EAAKvB,QAAQE,QAAU,WAAa,aAC7D4B,UAAW,MAIfoB,WAAW,WACTjB,EAAML,IAAIwC,GACV7C,EAAK0C,YAAYnE,IAChB,OAGHyB,GAAK0C,YAAYnE,MASvBhB,EAAEiF,GAAGrC,KAAO,SAAU7B,EAASC,GAiC7B,MAhCuB,kBAAZD,KACTC,EAAWD,GAGU,gBAAZA,IAA2C,iBAAZA,GACxCE,KAAKsE,KAAK,WACR,GAAI3C,GAAO5C,EAAEiB,MAAMuE,KAAK,aAER,YAAZzE,IACFA,GAAW6B,EAAKP,WAGdtB,EACF6B,EAAKA,KAAK5B,GAEV4B,EAAKK,OAAOjC,KAIhBC,KAAKsE,KAAK,WACR,GAAIvF,EAAEiB,MAAMuE,KAAK,cAAe,CAC9B,GAAI5C,GAAO5C,EAAEiB,MAAMuE,KAAK,eAEpBzE,GAA6BJ,SAAjBI,EAAQI,MAA0CR,SAApBI,EAAQK,SACpDwB,EAAKwC,eAAerE,EAASC,OAG/BhB,GAAEiB,MAAMuE,KAAK,aAAc,GAAI3E,GAAKb,EAAEiB,MAAQF,MAAgBC,MAK7DC,OAGRwE"} \ No newline at end of file diff --git a/bower_components/flip/package.json b/bower_components/flip/package.json new file mode 100644 index 0000000..42d1c76 --- /dev/null +++ b/bower_components/flip/package.json @@ -0,0 +1,64 @@ +{ + "name": "flip", + "version": "1.1.2", + "description": "jQuery Plugin - 3d Flip Content", + "keywords": [ + "jquery-plugin" + ], + "main": "dist/jquery.flip.js", + "homepage": "https://github.com/nnattawat/flip", + "bugs": "https://github.com/nnattawat/flip/issues", + "author": { + "name": "Nattawat Nonsung", + "email": "armmer1@gmail.com", + "url": "https://github.com/nnattawat" + }, + "contributors": [ + { + "name": "Carlos Fagiani Junior", + "email": "fagianijunior@gmail.com", + "url": "https://github.com/fagianijunior" + }, + { + "name": "Zlatko Fedor", + "email": "zfedor@gmail.com", + "url": "https://github.com/seeden" + }, + { + "name": "Jemar Jones", + "email": "jemarkjones@gmail.com", + "url": "http://JKJones.me/" + }, + { + "name": "Razvan Popa", + "url": "https://github.com/VholtWCP" + }, + { + "name": "Stijn de Witt", + "email": "StijnDeWitt@hotmail.com", + "url": "http://StijnDeWitt.com" + } + ], + "repository": { + "type": "git", + "url": "https://github.com/nnattawat/flip.git" + }, + "license": "MIT", + "devDependencies": { + "grunt-contrib-concat": "~0.3.0", + "grunt-contrib-uglify": "~0.2.7", + "grunt-contrib-watch": "~0.5.3", + "grunt-contrib-clean": "~0.5.0", + "grunt-contrib-connect": "~0.5.0", + "time-grunt": "~0.2.3", + "load-grunt-tasks": "~0.2.0", + "grunt": "~0.4.2", + "grunt-contrib-jshint": "~1.0.0", + "grunt-cli": "~0.1.13", + "bower": "~1.7.6" + }, + "scripts": { + "test": "grunt jshint", + "grunt": "grunt" + } +} diff --git a/bower_components/flip/src/flip.js b/bower_components/flip/src/flip.js new file mode 100644 index 0000000..dfe07b9 --- /dev/null +++ b/bower_components/flip/src/flip.js @@ -0,0 +1,366 @@ +(function( $ ) { + /* + * Private attributes and method + */ + + // Function from David Walsh: http://davidwalsh.name/css-animation-callback licensed with http://opensource.org/licenses/MIT + var whichTransitionEvent = function() { + var t, el = document.createElement("fakeelement"), + transitions = { + "transition" : "transitionend", + "OTransition" : "oTransitionEnd", + "MozTransition" : "transitionend", + "WebkitTransition": "webkitTransitionEnd" + }; + + for (t in transitions) { + if (el.style[t] !== undefined) { + return transitions[t]; + } + } + }; + + /* + * Model declaration + */ + var Flip = function($el, options, callback) { + // Define default setting + this.setting = { + axis: "y", + reverse: false, + trigger: "click", + speed: 500, + forceHeight: false, + forceWidth: false, + autoSize: true, + front: '.front', + back: '.back' + }; + + this.setting = $.extend(this.setting, options); + + if (typeof options.axis === 'string' && (options.axis.toLowerCase() === 'x' || options.axis.toLowerCase() === 'y')) { + this.setting.axis = options.axis.toLowerCase(); + } + + if (typeof options.reverse === "boolean") { + this.setting.reverse = options.reverse; + } + + if (typeof options.trigger === 'string') { + this.setting.trigger = options.trigger.toLowerCase(); + } + + var speed = parseInt(options.speed); + if (!isNaN(speed)) { + this.setting.speed = speed; + } + + if (typeof options.forceHeight === "boolean") { + this.setting.forceHeight = options.forceHeight; + } + + if (typeof options.forceWidth === "boolean") { + this.setting.forceWidth = options.forceWidth; + } + + if (typeof options.autoSize === "boolean") { + this.setting.autoSize = options.autoSize; + } + + if (typeof options.front === 'string' || options.front instanceof $) { + this.setting.front = options.front; + } + + if (typeof options.back === 'string' || options.back instanceof $) { + this.setting.back = options.back; + } + + // Other attributes + this.element = $el; + this.frontElement = this.getFrontElement(); + this.backElement = this.getBackElement(); + this.isFlipped = false; + + this.init(callback); + }; + + /* + * Public methods + */ + $.extend(Flip.prototype, { + + flipDone: function(callback) { + var self = this; + // Providing a nicely wrapped up callback because transform is essentially async + self.element.one(whichTransitionEvent(), function() { + self.element.trigger('flip:done'); + if (typeof callback === 'function') { + callback.call(self.element); + } + }); + }, + + flip: function(callback) { + if (this.isFlipped) { + return; + } + + this.isFlipped = true; + + var rotateAxis = "rotate" + this.setting.axis; + this.frontElement.css({ + transform: rotateAxis + (this.setting.reverse ? "(-180deg)" : "(180deg)"), + "z-index": "0" + }); + + this.backElement.css({ + transform: rotateAxis + "(0deg)", + "z-index": "1" + }); + this.flipDone(callback); + }, + + unflip: function(callback) { + if (!this.isFlipped) { + return; + } + + this.isFlipped = false; + + var rotateAxis = "rotate" + this.setting.axis; + this.frontElement.css({ + transform: rotateAxis + "(0deg)", + "z-index": "1" + }); + + this.backElement.css({ + transform: rotateAxis + (this.setting.reverse ? "(180deg)" : "(-180deg)"), + "z-index": "0" + }); + this.flipDone(callback); + }, + + getFrontElement: function() { + if (this.setting.front instanceof $) { + return this.setting.front; + } else { + return this.element.find(this.setting.front); + } + }, + + getBackElement: function() { + if (this.setting.back instanceof $) { + return this.setting.back; + } else { + return this.element.find(this.setting.back); + } + }, + + init: function(callback) { + var self = this; + + var faces = self.frontElement.add(self.backElement); + var rotateAxis = "rotate" + self.setting.axis; + var perspective = self.element["outer" + (rotateAxis === "rotatex" ? "Height" : "Width")]() * 2; + var elementCss = { + 'perspective': perspective, + 'position': 'relative' + }; + var backElementCss = { + "transform": rotateAxis + "(" + (self.setting.reverse ? "180deg" : "-180deg") + ")", + "z-index": "0", + "position": "relative" + }; + var faceElementCss = { + "backface-visibility": "hidden", + "transform-style": "preserve-3d", + "position": "absolute", + "z-index": "1" + }; + + if (self.setting.forceHeight) { + faces.outerHeight(self.element.height()); + } else if (self.setting.autoSize) { + faceElementCss.height = '100%'; + } + + if (self.setting.forceWidth) { + faces.outerWidth(self.element.width()); + } else if (self.setting.autoSize) { + faceElementCss.width = '100%'; + } + + // Back face always visible on Chrome #39 + if ((window.chrome || (window.Intl && Intl.v8BreakIterator)) && 'CSS' in window) { + //Blink Engine, add preserve-3d to self.element + elementCss["-webkit-transform-style"] = "preserve-3d"; + } + + + faces.css(faceElementCss).find('*').css({ + "backface-visibility": "hidden" + }); + + self.element.css(elementCss); + self.backElement.css(backElementCss); + + // #39 + // not forcing width/height may cause an initial flip to show up on + // page load when we apply the style to reverse the backface... + // To prevent self we first apply the basic styles and then give the + // browser a moment to apply them. Only afterwards do we add the transition. + setTimeout(function() { + // By now the browser should have applied the styles, so the transition + // will only affect subsequent flips. + var speedInSec = self.setting.speed / 1000 || 0.5; + faces.css({ + "transition": "all " + speedInSec + "s ease-out" + }); + + // This allows flip to be called for setup with only a callback (default settings) + if (typeof callback === 'function') { + callback.call(self.element); + } + + // While this used to work with a setTimeout of zero, at some point that became + // unstable and the initial flip returned. The reason for this is unknown but we + // will temporarily use a short delay of 20 to mitigate this issue. + }, 20); + + self.attachEvents(); + }, + + clickHandler: function(event) { + if (!event) { event = window.event; } + if (this.element.find($(event.target).closest('button, a, input[type="submit"]')).length) { + return; + } + + if (this.isFlipped) { + this.unflip(); + } else { + this.flip(); + } + }, + + hoverHandler: function() { + var self = this; + self.element.off('mouseleave.flip'); + + self.flip(); + + setTimeout(function() { + self.element.on('mouseleave.flip', $.proxy(self.unflip, self)); + if (!self.element.is(":hover")) { + self.unflip(); + } + }, (self.setting.speed + 150)); + }, + + attachEvents: function() { + var self = this; + if (self.setting.trigger === "click") { + self.element.on($.fn.tap ? "tap.flip" : "click.flip", $.proxy(self.clickHandler, self)); + } else if (self.setting.trigger === "hover") { + self.element.on('mouseenter.flip', $.proxy(self.hoverHandler, self)); + self.element.on('mouseleave.flip', $.proxy(self.unflip, self)); + } + }, + + flipChanged: function(callback) { + this.element.trigger('flip:change'); + if (typeof callback === 'function') { + callback.call(this.element); + } + }, + + changeSettings: function(options, callback) { + var self = this; + var changeNeeded = false; + + if (options.axis !== undefined && self.setting.axis !== options.axis.toLowerCase()) { + self.setting.axis = options.axis.toLowerCase(); + changeNeeded = true; + } + + if (options.reverse !== undefined && self.setting.reverse !== options.reverse) { + self.setting.reverse = options.reverse; + changeNeeded = true; + } + + if (changeNeeded) { + var faces = self.frontElement.add(self.backElement); + var savedTrans = faces.css(["transition-property", "transition-timing-function", "transition-duration", "transition-delay"]); + + faces.css({ + transition: "none" + }); + + // This sets up the first flip in the new direction automatically + var rotateAxis = "rotate" + self.setting.axis; + + if (self.isFlipped) { + self.frontElement.css({ + transform: rotateAxis + (self.setting.reverse ? "(-180deg)" : "(180deg)"), + "z-index": "0" + }); + } else { + self.backElement.css({ + transform: rotateAxis + (self.setting.reverse ? "(180deg)" : "(-180deg)"), + "z-index": "0" + }); + } + // Providing a nicely wrapped up callback because transform is essentially async + setTimeout(function() { + faces.css(savedTrans); + self.flipChanged(callback); + }, 0); + } else { + // If we didnt have to set the axis we can just call back. + self.flipChanged(callback); + } + } + + }); + + /* + * jQuery collection methods + */ + $.fn.flip = function (options, callback) { + if (typeof options === 'function') { + callback = options; + } + + if (typeof options === "string" || typeof options === "boolean") { + this.each(function() { + var flip = $(this).data('flip-model'); + + if (options === "toggle") { + options = !flip.isFlipped; + } + + if (options) { + flip.flip(callback); + } else { + flip.unflip(callback); + } + }); + } else { + this.each(function() { + if ($(this).data('flip-model')) { // The element has been initiated, all we have to do is change applicable settings + var flip = $(this).data('flip-model'); + + if (options && (options.axis !== undefined || options.reverse !== undefined)) { + flip.changeSettings(options, callback); + } + } else { // Init + $(this).data('flip-model', new Flip($(this), (options || {}), callback)); + } + }); + } + + return this; + }; + +}( jQuery ));