├── AnimationCollections.framer ├── .gitignore ├── app.coffee ├── app.js ├── framer │ ├── coffee-script.js │ ├── config.json │ ├── framer.generated.js │ ├── framer.init.js │ ├── framer.js │ ├── framer.js.map │ ├── framer.modules.js │ ├── images │ │ ├── background.png │ │ ├── cursor.png │ │ ├── cursor@2x.png │ │ ├── icon-120.png │ │ ├── icon-152.png │ │ ├── icon-180.png │ │ ├── icon-192.png │ │ ├── icon-76.png │ │ ├── icon-arrow.png │ │ ├── icon-arrow@2x.png │ │ ├── icon-close.png │ │ ├── icon-close@2x.png │ │ ├── icon-framer.png │ │ ├── icon-framer@2x.png │ │ ├── icon-share.png │ │ └── icon-share@2x.png │ ├── mirror.css │ ├── style.css │ └── version ├── images │ ├── .gitkeep │ └── framer-icon.png ├── index.html └── modules │ ├── AnimationSequence.coffee │ └── AnimationSet.coffee ├── LICENSE ├── README.md └── examples ├── basic-sequence.framer ├── .gitignore ├── app.coffee ├── app.js ├── framer │ ├── coffee-script.js │ ├── config.json │ ├── framer.generated.js │ ├── framer.init.js │ ├── framer.js │ ├── framer.js.map │ ├── framer.modules.js │ ├── images │ │ ├── background.png │ │ ├── cursor.png │ │ ├── cursor@2x.png │ │ ├── icon-120.png │ │ ├── icon-152.png │ │ ├── icon-180.png │ │ ├── icon-192.png │ │ ├── icon-76.png │ │ ├── icon-arrow.png │ │ ├── icon-arrow@2x.png │ │ ├── icon-close.png │ │ ├── icon-close@2x.png │ │ ├── icon-framer.png │ │ ├── icon-framer@2x.png │ │ ├── icon-share.png │ │ └── icon-share@2x.png │ ├── mirror.css │ ├── style.css │ └── version ├── images │ └── .gitkeep ├── index.html └── modules │ ├── AnimationSequence.coffee │ └── AnimationSet.coffee ├── basic-set.framer ├── .gitignore ├── app.coffee ├── app.js ├── framer │ ├── coffee-script.js │ ├── config.json │ ├── framer.generated.js │ ├── framer.init.js │ ├── framer.js │ ├── framer.js.map │ ├── framer.modules.js │ ├── images │ │ ├── background.png │ │ ├── cursor.png │ │ ├── cursor@2x.png │ │ ├── icon-120.png │ │ ├── icon-152.png │ │ ├── icon-180.png │ │ ├── icon-192.png │ │ ├── icon-76.png │ │ ├── icon-arrow.png │ │ ├── icon-arrow@2x.png │ │ ├── icon-close.png │ │ ├── icon-close@2x.png │ │ ├── icon-framer.png │ │ ├── icon-framer@2x.png │ │ ├── icon-share.png │ │ └── icon-share@2x.png │ ├── mirror.css │ ├── style.css │ └── version ├── images │ └── .gitkeep ├── index.html └── modules │ ├── AnimationSequence.coffee │ └── AnimationSet.coffee ├── dynamic-sequence.framer ├── .gitignore ├── app.coffee ├── app.js ├── framer │ ├── coffee-script.js │ ├── config.json │ ├── framer.generated.js │ ├── framer.init.js │ ├── framer.js │ ├── framer.js.map │ ├── framer.modules.js │ ├── images │ │ ├── background.png │ │ ├── cursor.png │ │ ├── cursor@2x.png │ │ ├── icon-120.png │ │ ├── icon-152.png │ │ ├── icon-180.png │ │ ├── icon-192.png │ │ ├── icon-76.png │ │ ├── icon-arrow.png │ │ ├── icon-arrow@2x.png │ │ ├── icon-close.png │ │ ├── icon-close@2x.png │ │ ├── icon-framer.png │ │ ├── icon-framer@2x.png │ │ ├── icon-share.png │ │ └── icon-share@2x.png │ ├── mirror.css │ ├── style.css │ └── version ├── images │ └── .gitkeep ├── index.html └── modules │ ├── AnimationSequence.coffee │ └── AnimationSet.coffee └── mixed-collections.framer ├── .gitignore ├── app.coffee ├── app.js ├── framer ├── coffee-script.js ├── config.json ├── framer.generated.js ├── framer.init.js ├── framer.js ├── framer.js.map ├── framer.modules.js ├── images │ ├── background.png │ ├── cursor.png │ ├── cursor@2x.png │ ├── icon-120.png │ ├── icon-152.png │ ├── icon-180.png │ ├── icon-192.png │ ├── icon-76.png │ ├── icon-arrow.png │ ├── icon-arrow@2x.png │ ├── icon-close.png │ ├── icon-close@2x.png │ ├── icon-framer.png │ ├── icon-framer@2x.png │ ├── icon-share.png │ └── icon-share@2x.png ├── mirror.css ├── style.css └── version ├── images └── .gitkeep ├── index.html └── modules ├── AnimationSequence.coffee └── AnimationSet.coffee /AnimationCollections.framer/.gitignore: -------------------------------------------------------------------------------- 1 | # Framer Git Ignore 2 | 3 | # General OSX 4 | 5 | .DS_Store 6 | .AppleDouble 7 | .LSOverride 8 | 9 | # Icon must end with two \r 10 | Icon 11 | 12 | # Thumbnails 13 | ._* 14 | 15 | # Files that might appear in the root of a volume 16 | .DocumentRevisions-V100 17 | .fseventsd 18 | .Spotlight-V100 19 | .TemporaryItems 20 | .Trashes 21 | .VolumeIcon.icns 22 | 23 | # Directories potentially created on remote AFP share 24 | .AppleDB 25 | .AppleDesktop 26 | Network Trash Folder 27 | Temporary Items 28 | .apdisk 29 | 30 | 31 | # Framer Specific 32 | .temp.html 33 | framer/*.old.* 34 | framer/backup.coffee 35 | framer/backups/* 36 | framer/.*.hash 37 | -------------------------------------------------------------------------------- /AnimationCollections.framer/app.coffee: -------------------------------------------------------------------------------- 1 | # Animation Collections 2 | # by Isaac Weinhausen 3 | # http://isaacw.com 4 | 5 | 6 | 7 | 8 | # Import modules 9 | # ------------------------------------- 10 | 11 | {AnimationSequence} = require "AnimationSequence" 12 | {AnimationSet} = require "AnimationSet" 13 | 14 | 15 | 16 | 17 | # App 18 | # ------------------------------------- 19 | 20 | 21 | # Override defaults 22 | Framer.Defaults.Layer.backgroundColor = "#877DD7" 23 | Framer.Defaults.Animation.time = 0.75 24 | 25 | 26 | # Set canvas props 27 | bg1 = new BackgroundLayer 28 | backgroundColor: "#292929" 29 | 30 | bg2 = new BackgroundLayer 31 | backgroundColor: "white" 32 | 33 | # Render shape 34 | square = new Layer 35 | width: 80 36 | height: 80 37 | borderRadius: 8 38 | square.center() 39 | 40 | # Define animations 41 | rotateAnimation = new Animation 42 | layer: square 43 | properties: 44 | rotation: 360 45 | 46 | moveAnimation = new Animation 47 | layer: square 48 | properties: 49 | scale: 2 50 | 51 | tweenAnimation = new Animation 52 | layer: square 53 | properties: 54 | borderRadius: 40 55 | 56 | fadeBgAnimation = new Animation 57 | layer: bg1 58 | properties: 59 | opacity: 0 60 | 61 | # Create an animation sequence and add animations 62 | squaresAnimation = new AnimationSequence 63 | animations: 64 | first: rotateAnimation 65 | second: moveAnimation 66 | third: fadeBgAnimation 67 | fourth: tweenAnimation 68 | 69 | # Call the start() method to see it in action 70 | squaresAnimation.start() 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /AnimationCollections.framer/app.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.9.3 2 | 3 | -------------------------------------------------------------------------------- /AnimationCollections.framer/framer/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "device" : "iPhone 5S Space Gray", 3 | "sharedPrototype" : 0, 4 | "deviceOrientation" : 0, 5 | "contentScale" : 1, 6 | "deviceType" : "fullscreen", 7 | "updateDelay" : 0.736559139784946, 8 | "deviceScale" : 0.25, 9 | "delay" : 0.3, 10 | "orientation" : 0, 11 | "fullScreen" : false 12 | } -------------------------------------------------------------------------------- /AnimationCollections.framer/framer/framer.init.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | function isFileLoadingAllowed() { 4 | return (window.location.protocol.indexOf("file") == -1) 5 | } 6 | 7 | function isHomeScreened() { 8 | return ("standalone" in window.navigator) && window.navigator.standalone == true 9 | } 10 | 11 | function isCompatibleBrowser() { 12 | return Utils.isWebKit() 13 | } 14 | 15 | var alertNode; 16 | 17 | function dismissAlert() { 18 | alertNode.parentElement.removeChild(alertNode) 19 | loadProject() 20 | } 21 | 22 | function showAlert(html) { 23 | 24 | alertNode = document.createElement("div") 25 | 26 | alertNode.classList.add("framerAlertBackground") 27 | alertNode.innerHTML = html 28 | 29 | document.addEventListener("DOMContentLoaded", function(event) { 30 | document.body.appendChild(alertNode) 31 | }) 32 | 33 | window.dismissAlert = dismissAlert; 34 | } 35 | 36 | function showBrowserAlert() { 37 | var html = "" 38 | html += "
" 39 | html += "Error: Not A WebKit Browser" 40 | html += "Your browser is not supported.
Please use Safari or Chrome.
" 41 | html += "Try anyway" 42 | html += "
" 43 | 44 | showAlert(html) 45 | } 46 | 47 | function showFileLoadingAlert() { 48 | var html = "" 49 | html += "
" 50 | html += "Error: Local File Restrictions" 51 | html += "Preview this prototype with Framer Mirror or learn more about " 52 | html += "file restrictions.
" 53 | html += "Try anyway" 54 | html += "
" 55 | 56 | showAlert(html) 57 | } 58 | 59 | function showHomeScreenAlert() { 60 | 61 | link = document.createElement("link"); 62 | link.href = "framer/mirror.css" 63 | link.type = "text/css" 64 | link.rel = "stylesheet" 65 | link.media = "screen" 66 | 67 | document.addEventListener("DOMContentLoaded", function(event) { 68 | document.getElementsByTagName("head")[0].appendChild(link) 69 | }) 70 | 71 | var html = "" 72 | html += "
" 73 | html += "
" 74 | html += "

Install Prototype

" 75 | html += "

Tap

Share
, then choose 'Add to Home Screen'

" 76 | html += "
" 77 | html += "
" 78 | 79 | showAlert(html) 80 | } 81 | 82 | function loadProject() { 83 | CoffeeScript.load("app.coffee") 84 | } 85 | 86 | function setDefaultPageTitle() { 87 | // If no title was set we set it to the project folder name so 88 | // you get a nice name on iOS if you bookmark to desktop. 89 | document.addEventListener("DOMContentLoaded", function() { 90 | if (document.title == "") { 91 | if (window.FramerStudioInfo && window.FramerStudioInfo.documentTitle) { 92 | document.title = window.FramerStudioInfo.documentTitle 93 | } else { 94 | document.title = window.location.pathname.replace(/\//g, "") 95 | } 96 | } 97 | }) 98 | } 99 | 100 | function init() { 101 | 102 | if (Utils.isFramerStudio()) { 103 | return 104 | } 105 | 106 | setDefaultPageTitle() 107 | 108 | if (!isCompatibleBrowser()) { 109 | return showBrowserAlert() 110 | } 111 | 112 | if (!isFileLoadingAllowed()) { 113 | return showFileLoadingAlert() 114 | } 115 | 116 | // if (Utils.isMobile() && !isHomeScreened()) { 117 | // return showHomeScreenAlert() 118 | // } 119 | 120 | loadProject() 121 | 122 | } 123 | 124 | init() 125 | 126 | })() 127 | -------------------------------------------------------------------------------- /AnimationCollections.framer/framer/framer.modules.js: -------------------------------------------------------------------------------- 1 | require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0) { 79 | if (this._currentAnimation == null) { 80 | this._currentAnimation = this._animationsArray[0]; 81 | } 82 | this._currentAnimation.start(); 83 | return this.emit(Events.AnimationStart); 84 | } 85 | }; 86 | 87 | AnimationSequence.prototype.stop = function() { 88 | this._currentAnimation.stop(); 89 | return this.emit(Events.AnimationStop); 90 | }; 91 | 92 | return AnimationSequence; 93 | 94 | })(Framer.EventEmitter); 95 | 96 | 97 | 98 | },{}],"AnimationSet":[function(require,module,exports){ 99 | var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, 100 | extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, 101 | hasProp = {}.hasOwnProperty; 102 | 103 | exports.AnimationSet = (function(superClass) { 104 | extend(AnimationSet, superClass); 105 | 106 | function AnimationSet(options) { 107 | var animation, k, ref, ref1; 108 | if (options == null) { 109 | options = {}; 110 | } 111 | this.stop = bind(this.stop, this); 112 | this.start = bind(this.start, this); 113 | this.isAnimating = bind(this.isAnimating, this); 114 | this._update = bind(this._update, this); 115 | this.add = bind(this.add, this); 116 | this._animationsArray = []; 117 | ref = options.animations; 118 | for (k in ref) { 119 | animation = ref[k]; 120 | this.add(animation); 121 | } 122 | this.repeat = (ref1 = options.repeat) != null ? ref1 : false; 123 | } 124 | 125 | AnimationSet.prototype.add = function(animation) { 126 | animation.stop(); 127 | animation.isAnimating = false; 128 | animation.on(Events.AnimationEnd, (function(_this) { 129 | return function() { 130 | animation.isAnimating = false; 131 | return _this._update(); 132 | }; 133 | })(this)); 134 | return this._animationsArray.push(animation); 135 | }; 136 | 137 | AnimationSet.prototype._update = function() { 138 | if (!this.isAnimating()) { 139 | if (this.repeat) { 140 | return this.start(); 141 | } else { 142 | return this.emit(Events.AnimationEnd); 143 | } 144 | } 145 | }; 146 | 147 | AnimationSet.prototype.isAnimating = function() { 148 | return _.any(this._animationsArray, "isAnimating", true); 149 | }; 150 | 151 | AnimationSet.prototype.start = function() { 152 | var animation, i, len, ref; 153 | ref = this._animationsArray; 154 | for (i = 0, len = ref.length; i < len; i++) { 155 | animation = ref[i]; 156 | animation.start(); 157 | animation.isAnimating = true; 158 | } 159 | return this.emit(Events.AnimationStart); 160 | }; 161 | 162 | AnimationSet.prototype.stop = function() { 163 | var animation, i, len, ref; 164 | ref = this._animationsArray; 165 | for (i = 0, len = ref.length; i < len; i++) { 166 | animation = ref[i]; 167 | animation.stop(); 168 | animation.isAnimating = false; 169 | } 170 | return this.emit(Events.AnimationStop); 171 | }; 172 | 173 | return AnimationSet; 174 | 175 | })(Framer.EventEmitter); 176 | 177 | 178 | 179 | },{}]},{},[]) 180 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvVXNlcnMvaXNhYWN3L3NyYy9mcmFtZXItYW5pbWF0aW9uLWNvbGxlY3Rpb25zL0FuaW1hdGlvbkNvbGxlY3Rpb25zLmZyYW1lci9tb2R1bGVzL0FuaW1hdGlvblNlcXVlbmNlLmNvZmZlZSIsIi9Vc2Vycy9pc2FhY3cvc3JjL2ZyYW1lci1hbmltYXRpb24tY29sbGVjdGlvbnMvQW5pbWF0aW9uQ29sbGVjdGlvbnMuZnJhbWVyL21vZHVsZXMvQW5pbWF0aW9uU2V0LmNvZmZlZSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ09BLElBQUE7OzZCQUFBOztBQUFBLE9BQWEsQ0FBQztBQUViLHVDQUFBLENBQUE7O0FBQWEsRUFBQSwyQkFBQyxPQUFELEdBQUE7QUFDWixRQUFBLHVCQUFBOztNQURhLFVBQVU7S0FDdkI7QUFBQSxxQ0FBQSxDQUFBO0FBQUEsdUNBQUEsQ0FBQTtBQUFBLHVDQUFBLENBQUE7QUFBQSw2REFBQSxDQUFBO0FBQUEsMkNBQUEsQ0FBQTtBQUFBLHVDQUFBLENBQUE7QUFBQSxtQ0FBQSxDQUFBO0FBQUEsSUFBQSxJQUFDLENBQUEsZ0JBQUQsR0FBb0IsRUFBcEIsQ0FBQTtBQUFBLElBQ0EsSUFBQyxDQUFBLGlCQUFELEdBQXFCLElBRHJCLENBQUE7QUFFQTtBQUFBLFNBQUEsUUFBQTt5QkFBQTtBQUFBLE1BQUEsSUFBQyxDQUFBLEdBQUQsQ0FBSyxTQUFMLENBQUEsQ0FBQTtBQUFBLEtBRkE7QUFBQSxJQUdBLElBQUMsQ0FBQSxNQUFELDRDQUEyQixLQUgzQixDQURZO0VBQUEsQ0FBYjs7QUFBQSw4QkFNQSxHQUFBLEdBQUssU0FBQyxTQUFELEVBQVksS0FBWixHQUFBO0FBR0osUUFBQSx1QkFBQTtBQUFBLElBQUEsU0FBUyxDQUFDLElBQVYsQ0FBQSxDQUFBLENBQUE7QUFBQSxJQUdBLFNBQVMsQ0FBQyxFQUFW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Q0E1QmIsQ0FBQTs7QUFBQSx5QkErQkEsS0FBQSxHQUFPLFNBQUEsR0FBQTtBQUNOLFFBQUEsc0JBQUE7QUFBQTtBQUFBLFNBQUEscUNBQUE7eUJBQUE7QUFDQyxNQUFBLFNBQVMsQ0FBQyxLQUFWLENBQUEsQ0FBQSxDQUFBO0FBQUEsTUFDQSxTQUFTLENBQUMsV0FBVixHQUF3QixJQUR4QixDQUREO0FBQUEsS0FBQTtXQUdBLElBQUMsQ0FBQSxJQUFELENBQU0sTUFBTSxDQUFDLGNBQWIsRUFKTTtFQUFBLENBL0JQLENBQUE7O0FBQUEseUJBcUNBLElBQUEsR0FBTSxTQUFBLEdBQUE7QUFDTCxRQUFBLHNCQUFBO0FBQUE7QUFBQSxTQUFBLHFDQUFBO3lCQUFBO0FBQ0MsTUFBQSxTQUFTLENBQUMsSUFBVixDQUFBLENBQUEsQ0FBQTtBQUFBLE1BQ0EsU0FBUyxDQUFDLFdBQVYsR0FBd0IsS0FEeEIsQ0FERDtBQUFBLEtBQUE7V0FHQSxJQUFDLENBQUEsSUFBRCxDQUFNLE1BQU0sQ0FBQyxhQUFiLEVBSks7RUFBQSxDQXJDTixDQUFBOztzQkFBQTs7R0FGa0MsTUFBTSxDQUFDLGFBQTFDLENBQUEiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiIyBBbmltYXRpb24gU2VxdWVuY2VcbiMgTWFuYWdlcyBhIHNlcXVlbmNlIG9mIEFuaW1hdGlvbnNcbiMgXG4jIGJ5IElzYWFjIFdlaW5oYXVzZW5cbiMgaHR0cDovL2lzYWFjdy5jb21cblxuXG5jbGFzcyBleHBvcnRzLkFuaW1hdGlvblNlcXVlbmNlIGV4dGVuZHMgRnJhbWVyLkV2ZW50RW1pdHRlclxuXHRcblx0Y29uc3RydWN0b3I6IChvcHRpb25zID0ge30pIC0+XG5cdFx0QF9hbmltYXRpb25zQXJyYXkgPSBbXVxuXHRcdEBfY3VycmVudEFuaW1hdGlvbiA9IG51bGxcblx0XHRAYWRkKGFuaW1hdGlvbikgZm9yIGssIGFuaW1hdGlvbiBvZiBvcHRpb25zLmFuaW1hdGlvbnNcblx0XHRAcmVwZWF0ID0gb3B0aW9ucy5yZXBlYXQgPyBmYWxzZVxuXHRcblx0YWRkOiAoYW5pbWF0aW9uLCBpbmRleCkgPT5cblxuXHRcdCMgRW5zdXJlIHRoZSBhbmltYXRpb24gaXMgc3RvcHBlZCAobmVlZGVkIGZvciB3aGVuIHBhc3NlZCB2aWEgdGhlIGxheWVyLmFuaW1hdGUgbWV0aG9kKVxuXHRcdGFuaW1hdGlvbi5zdG9wKClcblx0XHRcblx0XHQjIFNldCBhbmltYXRpb24gY2FsbGJhY2tcblx0XHRhbmltYXRpb24ub24gRXZlbnRzLkFuaW1hdGlvbkVuZCwgPT5cblx0XHRcdEBfdXBkYXRlKClcblx0XHRcblx0XHQjIE5vIHZhbGlkIGluZGV4IHdhcyBwYXNzZWQ/XG5cdFx0dW5sZXNzIGluZGV4PyBhbmQgaW5kZXggPD0gQF9hbmltYXRpb25zQXJyYXkubGVuZ3RoXG5cdFx0XHRpbmRleCA9IEBfYW5pbWF0aW9uc0FycmF5Lmxlbmd0aFxuXHRcdFxuXHRcdCMgSW5zZXJ0IGFuaW1hdGlvbiBpbnRvIGl0cyBwb3NpdGlvblxuXHRcdEBfYW5pbWF0aW9uc0FycmF5LnNwbGljZSBpbmRleCwgMCwgYW5pbWF0aW9uXG5cdFx0XG5cdFx0IyBVcGRhdGUgSW5kaWNlcyAoYW5pbWF0aW9ucyBuZWVkIHRvIHRyYWNrIHRoZWlyIG93biBwb3NpdGlvbilcblx0XHRhbmltYXRpb24uaW5kZXggPSBpIGZvciBhbmltYXRpb24sIGkgaW4gQF9hbmltYXRpb25zQXJyYXlcblx0XHRcblx0XG5cdGZyb250OiAoYW5pbWF0aW9uKSA9PlxuXHRcdEBhZGQgYW5pbWF0aW9uLCAwXG5cdFx0IyBAX3Vuc2hpZnQgYW5pbWF0aW9uXG5cdFx0XG5cdF91cGRhdGU6ID0+XG5cdFx0XG5cdFx0IyBFbmQgb2Ygc2VxdWVuY2U/IERvIG5vdCByZXN0YXJ0P1xuXHRcdGlmIEBfaXNFbmRPZlNlcXVlbmNlKCkgYW5kIEByZXBlYXQgaXMgZmFsc2Vcblx0XHRcdEBlbWl0IEV2ZW50cy5BbmltYXRpb25FbmRcblx0XHRcdFxuXHRcdCMgTmV2ZXJtaW5kLCBtb3ZlIGFsb25nLi4uXG5cdFx0ZWxzZVxuXHRcdFx0IyBTdGFydCBuZXh0IGFuaW1hdGlvbiAob3IgcmVzdGFydCBzZXF1ZW5jZSlcblx0XHRcdEBfbmV4dCgpLnN0YXJ0KClcblx0XHRcdFxuXHRcdCMgKFJlKVNldCBjdXJyZW50IEFuaW1hdGlvblxuXHRcdEBfY3VycmVudEFuaW1hdGlvbiA9IEBfbmV4dCgpXG5cblxuXHRfaXNFbmRPZlNlcXVlbmNlOiAoYW5pbWF0aW9uID0gQF9jdXJyZW50QW5pbWF0aW9uKSA9PlxuXHRcdGFuaW1hdGlvbi5pbmRleCBpcyBAX2FuaW1hdGlvbnNBcnJheS5sZW5ndGggLSAxXG5cdFx0XG5cdF9uZXh0OiA9PlxuXHRcdEBfYW5pbWF0aW9uc0FycmF5W0BfY3VycmVudEFuaW1hdGlvbi5pbmRleCArIDFdID8gQF9hbmltYXRpb25zQXJyYXlbMF1cblx0XG5cdHN0YXJ0OiA9PlxuXHRcdGlmIEBfYW5pbWF0aW9uc0FycmF5Lmxlbmd0aCA+IDBcblx0XHRcdCMgU2V0IF9jdXJyZW50QW5pbWF0aW9uIGlmIG5vdCBzZXRcblx0XHRcdHVubGVzcyBAX2N1cnJlbnRBbmltYXRpb24/XG5cdFx0XHRcdEBfY3VycmVudEFuaW1hdGlvbiA9IEBfYW5pbWF0aW9uc0FycmF5WzBdXG5cdFx0XHRAX2N1cnJlbnRBbmltYXRpb24uc3RhcnQoKVxuXHRcdFx0QGVtaXQgRXZlbnRzLkFuaW1hdGlvblN0YXJ0XG5cdFx0XG5cdHN0b3A6ID0+XG5cdFx0QF9jdXJyZW50QW5pbWF0aW9uLnN0b3AoKVxuXHRcdEBlbWl0IEV2ZW50cy5BbmltYXRpb25TdG9wXG5cblxuXG4iLCIjIEFuaW1hdGlvbiBTZXRcbiMgTWFuYWdlcyBhIHNldCBvZiBBbmltYXRpb25zXG4jIFxuIyBieSBJc2FhYyBXZWluaGF1c2VuXG4jIGh0dHA6Ly9pc2FhY3cuY29tXG5cblxuY2xhc3MgZXhwb3J0cy5BbmltYXRpb25TZXQgZXh0ZW5kcyBGcmFtZXIuRXZlbnRFbWl0dGVyXG5cdFxuXHRjb25zdHJ1Y3RvcjogKG9wdGlvbnMgPSB7fSkgLT5cblx0XHRAX2FuaW1hdGlvbnNBcnJheSA9IFtdXG5cdFx0QGFkZChhbmltYXRpb24pIGZvciBrLCBhbmltYXRpb24gb2Ygb3B0aW9ucy5hbmltYXRpb25zXG5cdFx0QHJlcGVhdCA9IG9wdGlvbnMucmVwZWF0ID8gZmFsc2Vcblx0XHRcdFxuXHRhZGQ6IChhbmltYXRpb24pID0+XG5cdFx0XG5cdFx0IyBFbnN1cmUgdGhlIGFuaW1hdGlvbiBpcyBzdG9wcGVkIChuZWVkZWQgd2hlbiBwYXNzZWQgdmlhIHRoZSBsYXllci5hbmltYXRlIG1ldGhvZClcblx0XHRhbmltYXRpb24uc3RvcCgpXG5cdFx0XG5cdFx0IyBIYXZlIHRoZSBhbmltYXRpb24gdHJhY2sgaXRzIGFuaW1hdGluZyBzdGF0ZVxuXHRcdGFuaW1hdGlvbi5pc0FuaW1hdGluZyA9IGZhbHNlXG5cdFx0XG5cdFx0YW5pbWF0aW9uLm9uIEV2ZW50cy5BbmltYXRpb25FbmQsID0+XG5cdFx0XHRhbmltYXRpb24uaXNBbmltYXRpbmcgPSBmYWxzZVxuXHRcdFx0QF91cGRhdGUoKVxuXHRcdFx0XG5cdFx0QF9hbmltYXRpb25zQXJyYXkucHVzaCBhbmltYXRpb25cblx0XG5cdFxuXHRfdXBkYXRlOiAoKSA9PlxuXHRcdCMgSGF2ZSBhbGwgYW5pbWF0aW9ucyBzdG9wcGVkP1xuXHRcdGlmIG5vdCBAaXNBbmltYXRpbmcoKVxuXHRcdFx0aWYgQHJlcGVhdFxuXHRcdFx0XHRAc3RhcnQoKVxuXHRcdFx0ZWxzZVxuXHRcdFx0XHRAZW1pdCBFdmVudHMuQW5pbWF0aW9uRW5kXG5cdFx0XG5cdGlzQW5pbWF0aW5nOiA9PlxuXHRcdF8uYW55KEBfYW5pbWF0aW9uc0FycmF5LCBcImlzQW5pbWF0aW5nXCIsIHRydWUpXG5cdFxuXHRzdGFydDogPT5cblx0XHRmb3IgYW5pbWF0aW9uIGluIEBfYW5pbWF0aW9uc0FycmF5XG5cdFx0XHRhbmltYXRpb24uc3RhcnQoKVxuXHRcdFx0YW5pbWF0aW9uLmlzQW5pbWF0aW5nID0gdHJ1ZVxuXHRcdEBlbWl0IEV2ZW50cy5BbmltYXRpb25TdGFydFxuXHRcdFxuXHRzdG9wOiA9PlxuXHRcdGZvciBhbmltYXRpb24gaW4gQF9hbmltYXRpb25zQXJyYXlcblx0XHRcdGFuaW1hdGlvbi5zdG9wKClcblx0XHRcdGFuaW1hdGlvbi5pc0FuaW1hdGluZyA9IGZhbHNlXG5cdFx0QGVtaXQgRXZlbnRzLkFuaW1hdGlvblN0b3AiXX0= 181 | -------------------------------------------------------------------------------- /AnimationCollections.framer/framer/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/AnimationCollections.framer/framer/images/background.png -------------------------------------------------------------------------------- /AnimationCollections.framer/framer/images/cursor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/AnimationCollections.framer/framer/images/cursor.png -------------------------------------------------------------------------------- /AnimationCollections.framer/framer/images/cursor@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/AnimationCollections.framer/framer/images/cursor@2x.png -------------------------------------------------------------------------------- /AnimationCollections.framer/framer/images/icon-120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/AnimationCollections.framer/framer/images/icon-120.png -------------------------------------------------------------------------------- /AnimationCollections.framer/framer/images/icon-152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/AnimationCollections.framer/framer/images/icon-152.png -------------------------------------------------------------------------------- /AnimationCollections.framer/framer/images/icon-180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/AnimationCollections.framer/framer/images/icon-180.png -------------------------------------------------------------------------------- /AnimationCollections.framer/framer/images/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/AnimationCollections.framer/framer/images/icon-192.png -------------------------------------------------------------------------------- /AnimationCollections.framer/framer/images/icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/AnimationCollections.framer/framer/images/icon-76.png -------------------------------------------------------------------------------- /AnimationCollections.framer/framer/images/icon-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/AnimationCollections.framer/framer/images/icon-arrow.png -------------------------------------------------------------------------------- /AnimationCollections.framer/framer/images/icon-arrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/AnimationCollections.framer/framer/images/icon-arrow@2x.png -------------------------------------------------------------------------------- /AnimationCollections.framer/framer/images/icon-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/AnimationCollections.framer/framer/images/icon-close.png -------------------------------------------------------------------------------- /AnimationCollections.framer/framer/images/icon-close@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/AnimationCollections.framer/framer/images/icon-close@2x.png -------------------------------------------------------------------------------- /AnimationCollections.framer/framer/images/icon-framer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/AnimationCollections.framer/framer/images/icon-framer.png -------------------------------------------------------------------------------- /AnimationCollections.framer/framer/images/icon-framer@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/AnimationCollections.framer/framer/images/icon-framer@2x.png -------------------------------------------------------------------------------- /AnimationCollections.framer/framer/images/icon-share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/AnimationCollections.framer/framer/images/icon-share.png -------------------------------------------------------------------------------- /AnimationCollections.framer/framer/images/icon-share@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/AnimationCollections.framer/framer/images/icon-share@2x.png -------------------------------------------------------------------------------- /AnimationCollections.framer/framer/mirror.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | border: none; 5 | -webkit-user-select: none; 6 | -webkit-tap-highlight-color: rgba(0,0,0,0); 7 | } 8 | html, body, .wrapper { 9 | height: 100%; 10 | } 11 | body { 12 | background: #fff; 13 | font: 300 20px "Helvetica Neue", Helvetica, sans-serif; 14 | overflow: hidden; 15 | cursor: url('images/cursor.png') 39 39, auto; 16 | text-align: center; 17 | position: relative; 18 | -webkit-font-smoothing: antialiased; 19 | text-rendering: optimizeLegibility; 20 | color: #333740; 21 | } 22 | a { 23 | color: gray; 24 | } 25 | .framerAlert { 26 | font: 12px/1.6em Menlo; 27 | margin: 10px; 28 | color: gray; 29 | } 30 | ::-webkit-scrollbar { 31 | display: none; 32 | } 33 | .wrapper { 34 | width:100%; 35 | max-width: 240px; 36 | margin: 0 auto; 37 | padding-top: 38%; 38 | position: relative; 39 | } 40 | /* Text */ 41 | h1 { 42 | font-size: 22px; 43 | font-weight: 400; 44 | margin-top: 0px; 45 | line-height: 1.5; 46 | color: black; 47 | 48 | margin-bottom: 8px; 49 | margin-top: 16px; 50 | } 51 | h2 { 52 | font-size: 14px; 53 | font-weight: 400; 54 | color: #788594; 55 | } 56 | hr { 57 | border: none; width: 100%; 58 | border-bottom: 1px solid #EFF1F3; 59 | display: block; 60 | margin: 40px auto 32px auto; 61 | } 62 | p { 63 | display: inline-block; 64 | line-height: 1.5; 65 | } 66 | figure { 67 | display: inline-block; 68 | } 69 | .share { 70 | color: #007AFF; 71 | display: inline-block; 72 | margin-left: 8px; 73 | } 74 | .icon-share { 75 | margin-right: 0px; 76 | position: relative; 77 | top:0.5px; 78 | } 79 | .arrow { 80 | position: absolute; 81 | max-width: 240px; 82 | width: 100%; 83 | left:50%; margin-left:-120px; 84 | bottom: 24%; 85 | } 86 | .arrow figure { 87 | -webkit-animation: bounce 1.25s ease infinite; 88 | -moz-animation: bounce 1.25s ease infinite; 89 | -o-animation: bounce 1.25s ease infinite; 90 | animation: bounce 1.25s ease infinite; 91 | -webkit-transform-origin: center bottom; 92 | -ms-transform-origin: center bottom; 93 | transform-origin: center bottom; 94 | } 95 | /* Arrow animation */ 96 | @-webkit-keyframes bounce { 97 | 0%, 100% { 98 | -webkit-transform: translate3d(0,0,0); 99 | transform: translate3d(0,0,0); 100 | } 101 | 50% { 102 | -webkit-transform: translate3d(0, -16px, 0); 103 | transform: translate3d(0, -16px, 0); 104 | } 105 | } 106 | @keyframes bounce { 107 | 0%, 100% { 108 | -webkit-transform: translate3d(0,0,0); 109 | transform: translate3d(0,0,0); 110 | } 111 | 50% { 112 | -webkit-transform: translate3d(0, -16px, 0); 113 | transform: translate3d(0, -16px, 0); 114 | } 115 | } 116 | /* Icons */ 117 | .icon-close, 118 | .icon-framer, 119 | .icon-share, 120 | .icon-arrow { 121 | background-size: cover; 122 | } 123 | .icon-close { 124 | background-image: url("images/icon-close.png"); 125 | position: absolute; 126 | top:16px; 127 | right:16px; 128 | cursor: pointer; 129 | cursor: hand; 130 | width: 18px; 131 | height: 18px; 132 | } 133 | .icon-framer { 134 | background-image: url("images/icon-framer.png"); 135 | width: 60px; 136 | height: 60px; 137 | } 138 | .icon-share { 139 | background-image: url("images/icon-share.png"); 140 | width: 11px; 141 | height: 18px; 142 | } 143 | .icon-arrow { 144 | background-image: url("images/icon-arrow.png"); 145 | width: 18px; 146 | height: 30px; 147 | } 148 | /* Retina Icons */ 149 | @media screen and (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { 150 | .icon-close { 151 | background-image: url("images/icon-close@2x.png"); 152 | } 153 | .icon-framer { 154 | background-image: url("images/icon-framer@2x.png"); 155 | } 156 | .icon-share { 157 | background-image: url("images/icon-share@2x.png"); 158 | } 159 | .icon-arrow { 160 | background-image: url("images/icon-arrow@2x.png"); 161 | } 162 | } 163 | /* Avoid overflow scrolling when viewing in Portrait */ 164 | @media screen and (orientation:portrait) { 165 | html, body, .wrapper { 166 | overflow: hidden; 167 | } 168 | } 169 | /* iPad share icon is positioned in the navigation bar */ 170 | @media screen and (min-width: 576px){ 171 | .arrow { 172 | display: none; 173 | } 174 | .wrapper { 175 | padding-bottom: 25%; 176 | } 177 | } 178 | /* When it landscape, hide arrow and adjust spacing */ 179 | @media screen and (orientation:landscape) { 180 | .arrow { 181 | display: none; 182 | } 183 | .wrapper { 184 | padding-top: 10%; 185 | padding-bottom: 0; 186 | } 187 | } 188 | /* iPhone 6 Portrait */ 189 | @media screen and (min-device-width:375px) and (max-device-width:667px) and (-webkit-min-device-pixel-ratio:2) and (orientation:portrait) { 190 | .wrapper { 191 | padding-top: 48%; 192 | } 193 | .arrow { 194 | bottom: 27%; 195 | } 196 | } -------------------------------------------------------------------------------- /AnimationCollections.framer/framer/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | border: none; 5 | -webkit-user-select: none; 6 | -webkit-tap-highlight-color: rgba(0,0,0,0); 7 | } 8 | 9 | body { 10 | background-color: #fff; 11 | font: 28px/1em "Helvetica"; 12 | color: #FFF; 13 | overflow: hidden; 14 | cursor: url('images/cursor.png') 39 39, auto; 15 | } 16 | 17 | a { 18 | color: gray; 19 | } 20 | 21 | .framerAlertBackground { 22 | position: absolute; top:0px; left:0px; right:0px; bottom:0px; 23 | z-index: 1000; 24 | background-color: #fff; 25 | } 26 | 27 | .framerAlert { 28 | font:400 14px/1.4 "Helvetica Neue", Helvetica, Arial, sans-serif; 29 | -webkit-font-smoothing:antialiased; 30 | color:#616367; text-align:center; 31 | position: absolute; top:40%; left:50%; width:260px; margin-left:-130px; 32 | } 33 | .framerAlert strong { font-weight:500; color:#000; margin-bottom:8px; display:block; } 34 | .framerAlert a { color:#28AFFA; } 35 | .framerAlert .btn { 36 | font-weight:500; text-decoration:none; line-height:1; 37 | display:inline-block; padding:6px 12px 7px 12px; 38 | border-radius:3px; margin-top:12px; 39 | background:#28AFFA; color:#fff; 40 | } 41 | 42 | ::-webkit-scrollbar { 43 | display: none; 44 | } -------------------------------------------------------------------------------- /AnimationCollections.framer/framer/version: -------------------------------------------------------------------------------- 1 | 1 -------------------------------------------------------------------------------- /AnimationCollections.framer/images/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/AnimationCollections.framer/images/.gitkeep -------------------------------------------------------------------------------- /AnimationCollections.framer/images/framer-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/AnimationCollections.framer/images/framer-icon.png -------------------------------------------------------------------------------- /AnimationCollections.framer/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /AnimationCollections.framer/modules/AnimationSequence.coffee: -------------------------------------------------------------------------------- 1 | # Animation Sequence 2 | # Manages a sequence of Animations 3 | # 4 | # by Isaac Weinhausen 5 | # http://isaacw.com 6 | 7 | 8 | class exports.AnimationSequence extends Framer.EventEmitter 9 | 10 | constructor: (options = {}) -> 11 | @_animationsArray = [] 12 | @_currentAnimation = null 13 | @add(animation) for k, animation of options.animations 14 | @repeat = options.repeat ? false 15 | 16 | add: (animation, index) => 17 | 18 | # Ensure the animation is stopped (needed for when passed via the layer.animate method) 19 | animation.stop() 20 | 21 | # Set animation callback 22 | animation.on Events.AnimationEnd, => 23 | @_update() 24 | 25 | # No valid index was passed? 26 | unless index? and index <= @_animationsArray.length 27 | index = @_animationsArray.length 28 | 29 | # Insert animation into its position 30 | @_animationsArray.splice index, 0, animation 31 | 32 | # Update Indices (animations need to track their own position) 33 | animation.index = i for animation, i in @_animationsArray 34 | 35 | 36 | front: (animation) => 37 | @add animation, 0 38 | # @_unshift animation 39 | 40 | _update: => 41 | 42 | # End of sequence? Do not restart? 43 | if @_isEndOfSequence() and @repeat is false 44 | @emit Events.AnimationEnd 45 | 46 | # Nevermind, move along... 47 | else 48 | # Start next animation (or restart sequence) 49 | @_next().start() 50 | 51 | # (Re)Set current Animation 52 | @_currentAnimation = @_next() 53 | 54 | 55 | _isEndOfSequence: (animation = @_currentAnimation) => 56 | animation.index is @_animationsArray.length - 1 57 | 58 | _next: => 59 | @_animationsArray[@_currentAnimation.index + 1] ? @_animationsArray[0] 60 | 61 | start: => 62 | if @_animationsArray.length > 0 63 | # Set _currentAnimation if not set 64 | unless @_currentAnimation? 65 | @_currentAnimation = @_animationsArray[0] 66 | @_currentAnimation.start() 67 | @emit Events.AnimationStart 68 | 69 | stop: => 70 | @_currentAnimation.stop() 71 | @emit Events.AnimationStop 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /AnimationCollections.framer/modules/AnimationSet.coffee: -------------------------------------------------------------------------------- 1 | # Animation Set 2 | # Manages a set of Animations 3 | # 4 | # by Isaac Weinhausen 5 | # http://isaacw.com 6 | 7 | 8 | class exports.AnimationSet extends Framer.EventEmitter 9 | 10 | constructor: (options = {}) -> 11 | @_animationsArray = [] 12 | @add(animation) for k, animation of options.animations 13 | @repeat = options.repeat ? false 14 | 15 | add: (animation) => 16 | 17 | # Ensure the animation is stopped (needed when passed via the layer.animate method) 18 | animation.stop() 19 | 20 | # Have the animation track its animating state 21 | animation.isAnimating = false 22 | 23 | animation.on Events.AnimationEnd, => 24 | animation.isAnimating = false 25 | @_update() 26 | 27 | @_animationsArray.push animation 28 | 29 | 30 | _update: () => 31 | # Have all animations stopped? 32 | if not @isAnimating() 33 | if @repeat 34 | @start() 35 | else 36 | @emit Events.AnimationEnd 37 | 38 | isAnimating: => 39 | _.any(@_animationsArray, "isAnimating", true) 40 | 41 | start: => 42 | for animation in @_animationsArray 43 | animation.start() 44 | animation.isAnimating = true 45 | @emit Events.AnimationStart 46 | 47 | stop: => 48 | for animation in @_animationsArray 49 | animation.stop() 50 | animation.isAnimating = false 51 | @emit Events.AnimationStop -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Isaac Weinhausen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Animation Collections for Framer.js 2 | 3 | Classes for managing large sets of animations in [Framer.js](https://github.com/koenbok/Framer). Objects are simple and flexible, and can be used interchangeably with `Animation` objects. 4 | 5 | ## Get Started 6 | 7 | - [Download] (https://github.com/isaacw/framer-animation-collections/archive/master.zip) (Framer Studio project and examples) 8 | - Unzip and go to `AnimationCollections.framer/modules/` 9 | - Copy `AnimationSequence.coffee` and `AnimationSet.coffee` into your Framer Studio project modules folder 10 | - Open your Framer Studio project and, at the top, paste: 11 | ```coffeescript 12 | {AnimationSequence} = require "AnimationSequence" 13 | {AnimationSet} = require "AnimationSet" 14 | ``` 15 | 16 | ## Example 17 | ###### Create a new layer 18 | ```coffeescript 19 | square = new Layer 20 | width: 80 21 | height: 80 22 | borderRadius: 8 23 | square.center() 24 | ``` 25 | 26 | ###### Define some animations 27 | ```coffeescript 28 | rotateAnimation = new Animation 29 | layer: square 30 | properties: 31 | rotation: 360 32 | 33 | moveAnimation = new Animation 34 | layer: square 35 | properties: 36 | scale: 2 37 | 38 | tweenAnimation = new Animation 39 | layer: square 40 | properties: 41 | borderRadius: 40 42 | ``` 43 | 44 | ###### Create an animation sequence 45 | Pass the animations in in the desired order 46 | ```coffeescript 47 | squaresAnimation = new AnimationSequence 48 | animations: 49 | first: rotateAnimation 50 | second: moveAnimation 51 | third: fadeBgAnimation 52 | fourth: tweenAnimation 53 | ``` 54 | 55 | ## Documentation 56 | AnimationSequence and AnimationSet look very similar, but serve different functions. Both classes inherit from `Framer.EventEmitter` and emit events `Events.AnimationStart` and `Events.AnimationEnd`. 57 | 58 | #### AnimationSequence 59 | Inherits from: `Framer.EventEmitter`. 60 | 61 | Manages a sequence of animations. Animations play in the order specified. 62 | 63 | ##### new AnimationSequence(options *\*) 64 | Instantiates a new AnimationSequence. 65 | 66 | Example 67 | ```coffeescript 68 | mySequence = new AnimationSequence 69 | animations: 70 | a: myAnimation 71 | b: myOtherAnimation 72 | c: myOtherSequence 73 | repeat: false 74 | ``` 75 | 76 | ##### AnimationSequence.repeat *\* 77 | If set `true`, the sequence will repeat after the final animation has completed; `Events.AnimationEnd` will not emit. 78 | 79 | ##### AnimationSequence.add(animation *\*) 80 | Adds an animation to the end of the sequence. 81 | 82 | ##### AnimationSequence.front(animation *\*) 83 | Adds an animation to the beginning of the sequence. 84 | 85 | ##### AnimationSequence.start() 86 | Starts/resumes the sequence. 87 | 88 | ##### AnimationSequence.stop() 89 | Stops the sequence. 90 | 91 | #### AnimationSet 92 | Inherits from: `Framer.EventEmitter`. 93 | 94 | Manages a set of animations. Animations play simultaneously. 95 | 96 | ##### new AnimationSet(options *\*) 97 | Instantiates a new AnimationSet. 98 | 99 | Example 100 | ```coffeescript 101 | mySet = new AnimationSet 102 | animations: 103 | a: myAnimation 104 | b: myOtherAnimation 105 | c: myOtherOtherAnimation 106 | repeat: false 107 | ``` 108 | 109 | ##### AnimationSet.repeat *\* 110 | If set `true`, the set will repeat after all the animations have completed; `Events.AnimationEnd` will not emit. 111 | 112 | ##### AnimationSet.add(animation *\*) 113 | Adds an animation to the collection. 114 | 115 | ##### AnimationSet.start() 116 | Starts/resumes the set. 117 | 118 | ##### AnimationSet.stop() 119 | Stops the set. 120 | 121 | ##### AnimationSet.isAnimating() 122 | Returns: boolean 123 | Returns `true` if an animation in the set is currently playing 124 | 125 | ## Changelog 126 | 127 | ##### **v0.3** 2015-08-15 128 | ###### New 129 | - Initial release! 130 | 131 | ## Misc Stuff 132 | 133 | ###### Community & Help 134 | If you haven't already, join the [Framer JS](https://www.facebook.com/groups/framerjs/) Facebook group and post examples and questions. If I get a chance, I'll try to personally answer any questions. 135 | 136 | Also, please, feel free to contribute! Right now I mostly need help with bugs and robustness. 137 | 138 | ###### Backlog 139 | - [x] AnimationSequence.front method 140 | - [ ] Remove methods 141 | - [ ] Reset methods 142 | -------------------------------------------------------------------------------- /examples/basic-sequence.framer/.gitignore: -------------------------------------------------------------------------------- 1 | # Framer Git Ignore 2 | 3 | # General OSX 4 | 5 | .DS_Store 6 | .AppleDouble 7 | .LSOverride 8 | 9 | # Icon must end with two \r 10 | Icon 11 | 12 | # Thumbnails 13 | ._* 14 | 15 | # Files that might appear in the root of a volume 16 | .DocumentRevisions-V100 17 | .fseventsd 18 | .Spotlight-V100 19 | .TemporaryItems 20 | .Trashes 21 | .VolumeIcon.icns 22 | 23 | # Directories potentially created on remote AFP share 24 | .AppleDB 25 | .AppleDesktop 26 | Network Trash Folder 27 | Temporary Items 28 | .apdisk 29 | 30 | 31 | # Framer Specific 32 | .temp.html 33 | framer/*.old.* 34 | framer/backup.coffee 35 | framer/backups/* 36 | framer/.*.hash 37 | -------------------------------------------------------------------------------- /examples/basic-sequence.framer/app.coffee: -------------------------------------------------------------------------------- 1 | # Basic Sequence 2 | # by Isaac Weinhausen 3 | # http://isaacw.com 4 | 5 | 6 | 7 | 8 | # Import classes 9 | # ------------------------------------- 10 | 11 | {AnimationSequence} = require "AnimationSequence" 12 | {AnimationSet} = require "AnimationSet" 13 | 14 | 15 | 16 | 17 | # Setup 18 | # ------------------------------------- 19 | 20 | # Remember these nice colors 21 | colors = 22 | "purple" : "#877DD7" 23 | "blue" : "#28affa" 24 | "teal" : "#2DD7AA" 25 | "green" : "#7DDD11" 26 | "darkGray" : "#292929" 27 | 28 | 29 | # Override defaults 30 | Framer.Defaults.Layer.borderRadius = 8 31 | Framer.Defaults.Layer.backgroundColor = "white" 32 | Framer.Defaults.Animation.time = 1 33 | 34 | 35 | # Set canvas props 36 | bg = new BackgroundLayer 37 | backgroundColor: colors["blue"] 38 | borderRadius: 0 39 | 40 | 41 | 42 | 43 | # App 44 | # ------------------------------------- 45 | 46 | 47 | rect1 = new Layer 48 | width: 162 49 | height: 100 50 | rect1.center() 51 | rect1.y -= 125 52 | 53 | rect2 = new Layer 54 | width: 162 55 | height: 100 56 | rect2.center() 57 | 58 | rect3 = new Layer 59 | width: 162 60 | height: 100 61 | rect3.center() 62 | rect3.y += 125 63 | 64 | growAnimation = new AnimationSequence 65 | animations: 66 | moveTop: rect1.animate 67 | properties: 68 | y: rect1.y - 100 69 | moveBottom: rect3.animate 70 | properties: 71 | y: rect3.y + 100 72 | moveMiddle: rect2.animate 73 | properties: 74 | scale: rect2.scale * 1.618 75 | # repeat: true 76 | 77 | 78 | 79 | 80 | # Execute 81 | # ------------------------------------- 82 | 83 | growAnimation.start() 84 | 85 | -------------------------------------------------------------------------------- /examples/basic-sequence.framer/app.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.9.3 2 | 3 | -------------------------------------------------------------------------------- /examples/basic-sequence.framer/framer/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "sharedPrototype" : 0, 3 | "deviceOrientation" : 0, 4 | "contentScale" : 1, 5 | "deviceType" : "fullscreen", 6 | "updateDelay" : 0.3, 7 | "deviceScale" : 1, 8 | "orientation" : 0 9 | } -------------------------------------------------------------------------------- /examples/basic-sequence.framer/framer/framer.init.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | function isFileLoadingAllowed() { 4 | return (window.location.protocol.indexOf("file") == -1) 5 | } 6 | 7 | function isHomeScreened() { 8 | return ("standalone" in window.navigator) && window.navigator.standalone == true 9 | } 10 | 11 | function isCompatibleBrowser() { 12 | return Utils.isWebKit() 13 | } 14 | 15 | var alertNode; 16 | 17 | function dismissAlert() { 18 | alertNode.parentElement.removeChild(alertNode) 19 | loadProject() 20 | } 21 | 22 | function showAlert(html) { 23 | 24 | alertNode = document.createElement("div") 25 | 26 | alertNode.classList.add("framerAlertBackground") 27 | alertNode.innerHTML = html 28 | 29 | document.addEventListener("DOMContentLoaded", function(event) { 30 | document.body.appendChild(alertNode) 31 | }) 32 | 33 | window.dismissAlert = dismissAlert; 34 | } 35 | 36 | function showBrowserAlert() { 37 | var html = "" 38 | html += "
" 39 | html += "Error: Not A WebKit Browser" 40 | html += "Your browser is not supported.
Please use Safari or Chrome.
" 41 | html += "Try anyway" 42 | html += "
" 43 | 44 | showAlert(html) 45 | } 46 | 47 | function showFileLoadingAlert() { 48 | var html = "" 49 | html += "
" 50 | html += "Error: Local File Restrictions" 51 | html += "Preview this prototype with Framer Mirror or learn more about " 52 | html += "file restrictions.
" 53 | html += "Try anyway" 54 | html += "
" 55 | 56 | showAlert(html) 57 | } 58 | 59 | function showHomeScreenAlert() { 60 | 61 | link = document.createElement("link"); 62 | link.href = "framer/mirror.css" 63 | link.type = "text/css" 64 | link.rel = "stylesheet" 65 | link.media = "screen" 66 | 67 | document.addEventListener("DOMContentLoaded", function(event) { 68 | document.getElementsByTagName("head")[0].appendChild(link) 69 | }) 70 | 71 | var html = "" 72 | html += "
" 73 | html += "
" 74 | html += "

Install Prototype

" 75 | html += "

Tap

, then choose 'Add to Home Screen'

" 76 | html += "
" 77 | html += "
" 78 | 79 | showAlert(html) 80 | } 81 | 82 | function loadProject() { 83 | CoffeeScript.load("app.coffee") 84 | } 85 | 86 | function setDefaultPageTitle() { 87 | // If no title was set we set it to the project folder name so 88 | // you get a nice name on iOS if you bookmark to desktop. 89 | document.addEventListener("DOMContentLoaded", function() { 90 | if (document.title == "") { 91 | if (window.FramerStudioInfo && window.FramerStudioInfo.documentTitle) { 92 | document.title = window.FramerStudioInfo.documentTitle 93 | } else { 94 | document.title = window.location.pathname.replace(/\//g, "") 95 | } 96 | } 97 | }) 98 | } 99 | 100 | function init() { 101 | 102 | if (Utils.isFramerStudio()) { 103 | return 104 | } 105 | 106 | setDefaultPageTitle() 107 | 108 | if (!isCompatibleBrowser()) { 109 | return showBrowserAlert() 110 | } 111 | 112 | if (!isFileLoadingAllowed()) { 113 | return showFileLoadingAlert() 114 | } 115 | 116 | // if (Utils.isMobile() && !isHomeScreened()) { 117 | // return showHomeScreenAlert() 118 | // } 119 | 120 | loadProject() 121 | 122 | } 123 | 124 | init() 125 | 126 | })() 127 | -------------------------------------------------------------------------------- /examples/basic-sequence.framer/framer/framer.modules.js: -------------------------------------------------------------------------------- 1 | require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0) { 79 | if (this._currentAnimation == null) { 80 | this._currentAnimation = this._animationsArray[0]; 81 | } 82 | this._currentAnimation.start(); 83 | return this.emit(Events.AnimationStart); 84 | } 85 | }; 86 | 87 | AnimationSequence.prototype.stop = function() { 88 | this._currentAnimation.stop(); 89 | return this.emit(Events.AnimationStop); 90 | }; 91 | 92 | return AnimationSequence; 93 | 94 | })(Framer.EventEmitter); 95 | 96 | 97 | 98 | },{}],"AnimationSet":[function(require,module,exports){ 99 | var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, 100 | extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, 101 | hasProp = {}.hasOwnProperty; 102 | 103 | exports.AnimationSet = (function(superClass) { 104 | extend(AnimationSet, superClass); 105 | 106 | function AnimationSet(options) { 107 | var animation, k, ref, ref1; 108 | if (options == null) { 109 | options = {}; 110 | } 111 | this.stop = bind(this.stop, this); 112 | this.start = bind(this.start, this); 113 | this.isAnimating = bind(this.isAnimating, this); 114 | this._update = bind(this._update, this); 115 | this.add = bind(this.add, this); 116 | this._animationsArray = []; 117 | ref = options.animations; 118 | for (k in ref) { 119 | animation = ref[k]; 120 | this.add(animation); 121 | } 122 | this.repeat = (ref1 = options.repeat) != null ? ref1 : false; 123 | } 124 | 125 | AnimationSet.prototype.add = function(animation) { 126 | animation.stop(); 127 | animation.isAnimating = false; 128 | animation.on(Events.AnimationEnd, (function(_this) { 129 | return function() { 130 | animation.isAnimating = false; 131 | return _this._update(); 132 | }; 133 | })(this)); 134 | return this._animationsArray.push(animation); 135 | }; 136 | 137 | AnimationSet.prototype._update = function() { 138 | if (!this.isAnimating()) { 139 | if (this.repeat) { 140 | return this.start(); 141 | } else { 142 | return this.emit(Events.AnimationEnd); 143 | } 144 | } 145 | }; 146 | 147 | AnimationSet.prototype.isAnimating = function() { 148 | return _.any(this._animationsArray, "isAnimating", true); 149 | }; 150 | 151 | AnimationSet.prototype.start = function() { 152 | var animation, i, len, ref; 153 | ref = this._animationsArray; 154 | for (i = 0, len = ref.length; i < len; i++) { 155 | animation = ref[i]; 156 | animation.start(); 157 | animation.isAnimating = true; 158 | } 159 | return this.emit(Events.AnimationStart); 160 | }; 161 | 162 | AnimationSet.prototype.stop = function() { 163 | var animation, i, len, ref; 164 | ref = this._animationsArray; 165 | for (i = 0, len = ref.length; i < len; i++) { 166 | animation = ref[i]; 167 | animation.stop(); 168 | animation.isAnimating = false; 169 | } 170 | return this.emit(Events.AnimationStop); 171 | }; 172 | 173 | return AnimationSet; 174 | 175 | })(Framer.EventEmitter); 176 | 177 | 178 | 179 | },{}]},{},[]) 180 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvVXNlcnMvd2VpbmhhdXMvc3JjL2ZyYW1lci1hbmltYXRpb24tY29sbGVjdGlvbnMvZXhhbXBsZXMvYmFzaWMtc2VxdWVuY2UuZnJhbWVyL21vZHVsZXMvQW5pbWF0aW9uU2VxdWVuY2UuY29mZmVlIiwiL1VzZXJzL3dlaW5oYXVzL3NyYy9mcmFtZXItYW5pbWF0aW9uLWNvbGxlY3Rpb25zL2V4YW1wbGVzL2Jhc2ljLXNlcXVlbmNlLmZyYW1lci9tb2R1bGVzL0FuaW1hdGlvblNldC5jb2ZmZWUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNPQSxJQUFBOzs2QkFBQTs7QUFBQSxPQUFhLENBQUM7QUFFYix1Q0FBQSxDQUFBOztBQUFhLEVBQUEsMkJBQUMsT0FBRCxHQUFBO0FBQ1osUUFBQSx1QkFBQTs7TUFEYSxVQUFVO0tBQ3ZCO0FBQUEscUNBQUEsQ0FBQTtBQUFBLHVDQUFBLENBQUE7QUFBQSx1Q0FBQSxDQUFBO0FBQUEsNkRBQUEsQ0FBQTtBQUFBLDJDQUFBLENBQUE7QUFBQSx1Q0FBQSxDQUFBO0FBQUEsbUNBQUEsQ0FBQTtBQUFBLElBQUEsSUFBQyxDQUFBLGdCQUFELEdBQW9CLEVBQXBCLENBQUE7QUFBQSxJQUNBLElBQUMsQ0FBQSxpQkFBRCxHQUFxQixJQURyQixDQUFBO0FBRUE7QUFBQSxTQUFBLFFBQUE7eUJBQUE7QUFBQSxNQUFBLElBQUMsQ0FBQSxHQUFELENBQUssU0FBTCxDQUFBLENBQUE7QUFBQSxLQUZBO0FBQUEsSUFHQSxJQUFDLENBQUEsTUFBRCw0Q0FBMkIsS0FIM0IsQ0FEWTtFQUFBLENBQWI7O0FBQUEsOEJBTUEsR0FBQSxHQUFLLFNBQUMsU0FBRCxFQUFZLEtBQVosR0FBQTtBQUdKLFFBQUEsdUJBQUE7QUFBQSxJQUFBLFNBQVMsQ0FBQyxJQUFWLENBQUEsQ0FBQSxDQUFBO0FBQUEsSUFHQSxTQUFT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RUFEWTtFQUFBLENBNUJiLENBQUE7O0FBQUEseUJBK0JBLEtBQUEsR0FBTyxTQUFBLEdBQUE7QUFDTixRQUFBLHNCQUFBO0FBQUE7QUFBQSxTQUFBLHFDQUFBO3lCQUFBO0FBQ0MsTUFBQSxTQUFTLENBQUMsS0FBVixDQUFBLENBQUEsQ0FBQTtBQUFBLE1BQ0EsU0FBUyxDQUFDLFdBQVYsR0FBd0IsSUFEeEIsQ0FERDtBQUFBLEtBQUE7V0FHQSxJQUFDLENBQUEsSUFBRCxDQUFNLE1BQU0sQ0FBQyxjQUFiLEVBSk07RUFBQSxDQS9CUCxDQUFBOztBQUFBLHlCQXFDQSxJQUFBLEdBQU0sU0FBQSxHQUFBO0FBQ0wsUUFBQSxzQkFBQTtBQUFBO0FBQUEsU0FBQSxxQ0FBQTt5QkFBQTtBQUNDLE1BQUEsU0FBUyxDQUFDLElBQVYsQ0FBQSxDQUFBLENBQUE7QUFBQSxNQUNBLFNBQVMsQ0FBQyxXQUFWLEdBQXdCLEtBRHhCLENBREQ7QUFBQSxLQUFBO1dBR0EsSUFBQyxDQUFBLElBQUQsQ0FBTSxNQUFNLENBQUMsYUFBYixFQUpLO0VBQUEsQ0FyQ04sQ0FBQTs7c0JBQUE7O0dBRmtDLE1BQU0sQ0FBQyxhQUExQyxDQUFBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIiMgQW5pbWF0aW9uIFNlcXVlbmNlXG4jIE1hbmFnZXMgYSBzZXF1ZW5jZSBvZiBBbmltYXRpb25zXG4jIFxuIyBieSBJc2FhYyBXZWluaGF1c2VuXG4jIGh0dHA6Ly9pc2FhY3cuY29tXG5cblxuY2xhc3MgZXhwb3J0cy5BbmltYXRpb25TZXF1ZW5jZSBleHRlbmRzIEZyYW1lci5FdmVudEVtaXR0ZXJcblx0XG5cdGNvbnN0cnVjdG9yOiAob3B0aW9ucyA9IHt9KSAtPlxuXHRcdEBfYW5pbWF0aW9uc0FycmF5ID0gW11cblx0XHRAX2N1cnJlbnRBbmltYXRpb24gPSBudWxsXG5cdFx0QGFkZChhbmltYXRpb24pIGZvciBrLCBhbmltYXRpb24gb2Ygb3B0aW9ucy5hbmltYXRpb25zXG5cdFx0QHJlcGVhdCA9IG9wdGlvbnMucmVwZWF0ID8gZmFsc2Vcblx0XG5cdGFkZDogKGFuaW1hdGlvbiwgaW5kZXgpID0+XG5cblx0XHQjIEVuc3VyZSB0aGUgYW5pbWF0aW9uIGlzIHN0b3BwZWQgKG5lZWRlZCBmb3Igd2hlbiBwYXNzZWQgdmlhIHRoZSBsYXllci5hbmltYXRlIG1ldGhvZClcblx0XHRhbmltYXRpb24uc3RvcCgpXG5cdFx0XG5cdFx0IyBTZXQgYW5pbWF0aW9uIGNhbGxiYWNrXG5cdFx0YW5pbWF0aW9uLm9uIEV2ZW50cy5BbmltYXRpb25FbmQsID0+XG5cdFx0XHRAX3VwZGF0ZSgpXG5cdFx0XG5cdFx0IyBObyB2YWxpZCBpbmRleCB3YXMgcGFzc2VkP1xuXHRcdHVubGVzcyBpbmRleD8gYW5kIGluZGV4IDw9IEBfYW5pbWF0aW9uc0FycmF5Lmxlbmd0aFxuXHRcdFx0aW5kZXggPSBAX2FuaW1hdGlvbnNBcnJheS5sZW5ndGhcblx0XHRcblx0XHQjIEluc2VydCBhbmltYXRpb24gaW50byBpdHMgcG9zaXRpb25cblx0XHRAX2FuaW1hdGlvbnNBcnJheS5zcGxpY2UgaW5kZXgsIDAsIGFuaW1hdGlvblxuXHRcdFxuXHRcdCMgVXBkYXRlIEluZGljZXMgKGFuaW1hdGlvbnMgbmVlZCB0byB0cmFjayB0aGVpciBvd24gcG9zaXRpb24pXG5cdFx0YW5pbWF0aW9uLmluZGV4ID0gaSBmb3IgYW5pbWF0aW9uLCBpIGluIEBfYW5pbWF0aW9uc0FycmF5XG5cdFx0XG5cdFxuXHRmcm9udDogKGFuaW1hdGlvbikgPT5cblx0XHRAYWRkIGFuaW1hdGlvbiwgMFxuXHRcdCMgQF91bnNoaWZ0IGFuaW1hdGlvblxuXHRcdFxuXHRfdXBkYXRlOiA9PlxuXHRcdFxuXHRcdCMgRW5kIG9mIHNlcXVlbmNlPyBEbyBub3QgcmVzdGFydD9cblx0XHRpZiBAX2lzRW5kT2ZTZXF1ZW5jZSgpIGFuZCBAcmVwZWF0IGlzIGZhbHNlXG5cdFx0XHRAZW1pdCBFdmVudHMuQW5pbWF0aW9uRW5kXG5cdFx0XHRcblx0XHQjIE5ldmVybWluZCwgbW92ZSBhbG9uZy4uLlxuXHRcdGVsc2Vcblx0XHRcdCMgU3RhcnQgbmV4dCBhbmltYXRpb24gKG9yIHJlc3RhcnQgc2VxdWVuY2UpXG5cdFx0XHRAX25leHQoKS5zdGFydCgpXG5cdFx0XHRcblx0XHQjIChSZSlTZXQgY3VycmVudCBBbmltYXRpb25cblx0XHRAX2N1cnJlbnRBbmltYXRpb24gPSBAX25leHQoKVxuXG5cblx0X2lzRW5kT2ZTZXF1ZW5jZTogKGFuaW1hdGlvbiA9IEBfY3VycmVudEFuaW1hdGlvbikgPT5cblx0XHRhbmltYXRpb24uaW5kZXggaXMgQF9hbmltYXRpb25zQXJyYXkubGVuZ3RoIC0gMVxuXHRcdFxuXHRfbmV4dDogPT5cblx0XHRAX2FuaW1hdGlvbnNBcnJheVtAX2N1cnJlbnRBbmltYXRpb24uaW5kZXggKyAxXSA/IEBfYW5pbWF0aW9uc0FycmF5WzBdXG5cdFxuXHRzdGFydDogPT5cblx0XHRpZiBAX2FuaW1hdGlvbnNBcnJheS5sZW5ndGggPiAwXG5cdFx0XHQjIFNldCBfY3VycmVudEFuaW1hdGlvbiBpZiBub3Qgc2V0XG5cdFx0XHR1bmxlc3MgQF9jdXJyZW50QW5pbWF0aW9uP1xuXHRcdFx0XHRAX2N1cnJlbnRBbmltYXRpb24gPSBAX2FuaW1hdGlvbnNBcnJheVswXVxuXHRcdFx0QF9jdXJyZW50QW5pbWF0aW9uLnN0YXJ0KClcblx0XHRcdEBlbWl0IEV2ZW50cy5BbmltYXRpb25TdGFydFxuXHRcdFxuXHRzdG9wOiA9PlxuXHRcdEBfY3VycmVudEFuaW1hdGlvbi5zdG9wKClcblx0XHRAZW1pdCBFdmVudHMuQW5pbWF0aW9uU3RvcFxuXG5cblxuIiwiIyBBbmltYXRpb24gU2V0XG4jIE1hbmFnZXMgYSBzZXQgb2YgQW5pbWF0aW9uc1xuIyBcbiMgYnkgSXNhYWMgV2VpbmhhdXNlblxuIyBodHRwOi8vaXNhYWN3LmNvbVxuXG5cbmNsYXNzIGV4cG9ydHMuQW5pbWF0aW9uU2V0IGV4dGVuZHMgRnJhbWVyLkV2ZW50RW1pdHRlclxuXHRcblx0Y29uc3RydWN0b3I6IChvcHRpb25zID0ge30pIC0+XG5cdFx0QF9hbmltYXRpb25zQXJyYXkgPSBbXVxuXHRcdEBhZGQoYW5pbWF0aW9uKSBmb3IgaywgYW5pbWF0aW9uIG9mIG9wdGlvbnMuYW5pbWF0aW9uc1xuXHRcdEByZXBlYXQgPSBvcHRpb25zLnJlcGVhdCA/IGZhbHNlXG5cdFx0XHRcblx0YWRkOiAoYW5pbWF0aW9uKSA9PlxuXHRcdFxuXHRcdCMgRW5zdXJlIHRoZSBhbmltYXRpb24gaXMgc3RvcHBlZCAobmVlZGVkIHdoZW4gcGFzc2VkIHZpYSB0aGUgbGF5ZXIuYW5pbWF0ZSBtZXRob2QpXG5cdFx0YW5pbWF0aW9uLnN0b3AoKVxuXHRcdFxuXHRcdCMgSGF2ZSB0aGUgYW5pbWF0aW9uIHRyYWNrIGl0cyBhbmltYXRpbmcgc3RhdGVcblx0XHRhbmltYXRpb24uaXNBbmltYXRpbmcgPSBmYWxzZVxuXHRcdFxuXHRcdGFuaW1hdGlvbi5vbiBFdmVudHMuQW5pbWF0aW9uRW5kLCA9PlxuXHRcdFx0YW5pbWF0aW9uLmlzQW5pbWF0aW5nID0gZmFsc2Vcblx0XHRcdEBfdXBkYXRlKClcblx0XHRcdFxuXHRcdEBfYW5pbWF0aW9uc0FycmF5LnB1c2ggYW5pbWF0aW9uXG5cdFxuXHRcblx0X3VwZGF0ZTogKCkgPT5cblx0XHQjIEhhdmUgYWxsIGFuaW1hdGlvbnMgc3RvcHBlZD9cblx0XHRpZiBub3QgQGlzQW5pbWF0aW5nKClcblx0XHRcdGlmIEByZXBlYXRcblx0XHRcdFx0QHN0YXJ0KClcblx0XHRcdGVsc2Vcblx0XHRcdFx0QGVtaXQgRXZlbnRzLkFuaW1hdGlvbkVuZFxuXHRcdFxuXHRpc0FuaW1hdGluZzogPT5cblx0XHRfLmFueShAX2FuaW1hdGlvbnNBcnJheSwgXCJpc0FuaW1hdGluZ1wiLCB0cnVlKVxuXHRcblx0c3RhcnQ6ID0+XG5cdFx0Zm9yIGFuaW1hdGlvbiBpbiBAX2FuaW1hdGlvbnNBcnJheVxuXHRcdFx0YW5pbWF0aW9uLnN0YXJ0KClcblx0XHRcdGFuaW1hdGlvbi5pc0FuaW1hdGluZyA9IHRydWVcblx0XHRAZW1pdCBFdmVudHMuQW5pbWF0aW9uU3RhcnRcblx0XHRcblx0c3RvcDogPT5cblx0XHRmb3IgYW5pbWF0aW9uIGluIEBfYW5pbWF0aW9uc0FycmF5XG5cdFx0XHRhbmltYXRpb24uc3RvcCgpXG5cdFx0XHRhbmltYXRpb24uaXNBbmltYXRpbmcgPSBmYWxzZVxuXHRcdEBlbWl0IEV2ZW50cy5BbmltYXRpb25TdG9wIl19 181 | -------------------------------------------------------------------------------- /examples/basic-sequence.framer/framer/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-sequence.framer/framer/images/background.png -------------------------------------------------------------------------------- /examples/basic-sequence.framer/framer/images/cursor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-sequence.framer/framer/images/cursor.png -------------------------------------------------------------------------------- /examples/basic-sequence.framer/framer/images/cursor@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-sequence.framer/framer/images/cursor@2x.png -------------------------------------------------------------------------------- /examples/basic-sequence.framer/framer/images/icon-120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-sequence.framer/framer/images/icon-120.png -------------------------------------------------------------------------------- /examples/basic-sequence.framer/framer/images/icon-152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-sequence.framer/framer/images/icon-152.png -------------------------------------------------------------------------------- /examples/basic-sequence.framer/framer/images/icon-180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-sequence.framer/framer/images/icon-180.png -------------------------------------------------------------------------------- /examples/basic-sequence.framer/framer/images/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-sequence.framer/framer/images/icon-192.png -------------------------------------------------------------------------------- /examples/basic-sequence.framer/framer/images/icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-sequence.framer/framer/images/icon-76.png -------------------------------------------------------------------------------- /examples/basic-sequence.framer/framer/images/icon-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-sequence.framer/framer/images/icon-arrow.png -------------------------------------------------------------------------------- /examples/basic-sequence.framer/framer/images/icon-arrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-sequence.framer/framer/images/icon-arrow@2x.png -------------------------------------------------------------------------------- /examples/basic-sequence.framer/framer/images/icon-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-sequence.framer/framer/images/icon-close.png -------------------------------------------------------------------------------- /examples/basic-sequence.framer/framer/images/icon-close@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-sequence.framer/framer/images/icon-close@2x.png -------------------------------------------------------------------------------- /examples/basic-sequence.framer/framer/images/icon-framer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-sequence.framer/framer/images/icon-framer.png -------------------------------------------------------------------------------- /examples/basic-sequence.framer/framer/images/icon-framer@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-sequence.framer/framer/images/icon-framer@2x.png -------------------------------------------------------------------------------- /examples/basic-sequence.framer/framer/images/icon-share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-sequence.framer/framer/images/icon-share.png -------------------------------------------------------------------------------- /examples/basic-sequence.framer/framer/images/icon-share@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-sequence.framer/framer/images/icon-share@2x.png -------------------------------------------------------------------------------- /examples/basic-sequence.framer/framer/mirror.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | border: none; 5 | -webkit-user-select: none; 6 | -webkit-tap-highlight-color: rgba(0,0,0,0); 7 | } 8 | html, body, .wrapper { 9 | height: 100%; 10 | } 11 | body { 12 | background: #fff; 13 | font: 300 20px "Helvetica Neue", Helvetica, sans-serif; 14 | overflow: hidden; 15 | cursor: url('images/cursor.png') 39 39, auto; 16 | text-align: center; 17 | position: relative; 18 | -webkit-font-smoothing: antialiased; 19 | text-rendering: optimizeLegibility; 20 | color: #333740; 21 | } 22 | a { 23 | color: gray; 24 | } 25 | .framerAlert { 26 | font: 12px/1.6em Menlo; 27 | margin: 10px; 28 | color: gray; 29 | } 30 | ::-webkit-scrollbar { 31 | display: none; 32 | } 33 | .wrapper { 34 | width:100%; 35 | max-width: 240px; 36 | margin: 0 auto; 37 | padding-top: 38%; 38 | position: relative; 39 | } 40 | /* Text */ 41 | h1 { 42 | font-size: 22px; 43 | font-weight: 400; 44 | margin-top: 0px; 45 | line-height: 1.5; 46 | color: black; 47 | 48 | margin-bottom: 8px; 49 | margin-top: 16px; 50 | } 51 | h2 { 52 | font-size: 14px; 53 | font-weight: 400; 54 | color: #788594; 55 | } 56 | hr { 57 | border: none; width: 100%; 58 | border-bottom: 1px solid #EFF1F3; 59 | display: block; 60 | margin: 40px auto 32px auto; 61 | } 62 | p { 63 | display: inline-block; 64 | line-height: 1.5; 65 | } 66 | figure { 67 | display: inline-block; 68 | } 69 | .share { 70 | color: #007AFF; 71 | display: inline-block; 72 | margin-left: 8px; 73 | } 74 | .icon-share { 75 | margin-right: 0px; 76 | position: relative; 77 | top:0.5px; 78 | } 79 | .arrow { 80 | position: absolute; 81 | max-width: 240px; 82 | width: 100%; 83 | left:50%; margin-left:-120px; 84 | bottom: 24%; 85 | } 86 | .arrow figure { 87 | -webkit-animation: bounce 1.25s ease infinite; 88 | -moz-animation: bounce 1.25s ease infinite; 89 | -o-animation: bounce 1.25s ease infinite; 90 | animation: bounce 1.25s ease infinite; 91 | -webkit-transform-origin: center bottom; 92 | -ms-transform-origin: center bottom; 93 | transform-origin: center bottom; 94 | } 95 | /* Arrow animation */ 96 | @-webkit-keyframes bounce { 97 | 0%, 100% { 98 | -webkit-transform: translate3d(0,0,0); 99 | transform: translate3d(0,0,0); 100 | } 101 | 50% { 102 | -webkit-transform: translate3d(0, -16px, 0); 103 | transform: translate3d(0, -16px, 0); 104 | } 105 | } 106 | @keyframes bounce { 107 | 0%, 100% { 108 | -webkit-transform: translate3d(0,0,0); 109 | transform: translate3d(0,0,0); 110 | } 111 | 50% { 112 | -webkit-transform: translate3d(0, -16px, 0); 113 | transform: translate3d(0, -16px, 0); 114 | } 115 | } 116 | /* Icons */ 117 | .icon-close, 118 | .icon-framer, 119 | .icon-share, 120 | .icon-arrow { 121 | background-size: cover; 122 | } 123 | .icon-close { 124 | background-image: url("images/icon-close.png"); 125 | position: absolute; 126 | top:16px; 127 | right:16px; 128 | cursor: pointer; 129 | cursor: hand; 130 | width: 18px; 131 | height: 18px; 132 | } 133 | .icon-framer { 134 | background-image: url("images/icon-framer.png"); 135 | width: 60px; 136 | height: 60px; 137 | } 138 | .icon-share { 139 | background-image: url("images/icon-share.png"); 140 | width: 11px; 141 | height: 18px; 142 | } 143 | .icon-arrow { 144 | background-image: url("images/icon-arrow.png"); 145 | width: 18px; 146 | height: 30px; 147 | } 148 | /* Retina Icons */ 149 | @media screen and (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { 150 | .icon-close { 151 | background-image: url("images/icon-close@2x.png"); 152 | } 153 | .icon-framer { 154 | background-image: url("images/icon-framer@2x.png"); 155 | } 156 | .icon-share { 157 | background-image: url("images/icon-share@2x.png"); 158 | } 159 | .icon-arrow { 160 | background-image: url("images/icon-arrow@2x.png"); 161 | } 162 | } 163 | /* Avoid overflow scrolling when viewing in Portrait */ 164 | @media screen and (orientation:portrait) { 165 | html, body, .wrapper { 166 | overflow: hidden; 167 | } 168 | } 169 | /* iPad share icon is positioned in the navigation bar */ 170 | @media screen and (min-width: 576px){ 171 | .arrow { 172 | display: none; 173 | } 174 | .wrapper { 175 | padding-bottom: 25%; 176 | } 177 | } 178 | /* When it landscape, hide arrow and adjust spacing */ 179 | @media screen and (orientation:landscape) { 180 | .arrow { 181 | display: none; 182 | } 183 | .wrapper { 184 | padding-top: 10%; 185 | padding-bottom: 0; 186 | } 187 | } 188 | /* iPhone 6 Portrait */ 189 | @media screen and (min-device-width:375px) and (max-device-width:667px) and (-webkit-min-device-pixel-ratio:2) and (orientation:portrait) { 190 | .wrapper { 191 | padding-top: 48%; 192 | } 193 | .arrow { 194 | bottom: 27%; 195 | } 196 | } -------------------------------------------------------------------------------- /examples/basic-sequence.framer/framer/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | border: none; 5 | -webkit-user-select: none; 6 | -webkit-tap-highlight-color: rgba(0,0,0,0); 7 | } 8 | 9 | body { 10 | background-color: #fff; 11 | font: 28px/1em "Helvetica"; 12 | color: #FFF; 13 | overflow: hidden; 14 | cursor: url('images/cursor.png') 39 39, auto; 15 | } 16 | 17 | a { 18 | color: gray; 19 | } 20 | 21 | .framerAlertBackground { 22 | position: absolute; top:0px; left:0px; right:0px; bottom:0px; 23 | z-index: 1000; 24 | background-color: #fff; 25 | } 26 | 27 | .framerAlert { 28 | font:400 14px/1.4 "Helvetica Neue", Helvetica, Arial, sans-serif; 29 | -webkit-font-smoothing:antialiased; 30 | color:#616367; text-align:center; 31 | position: absolute; top:40%; left:50%; width:260px; margin-left:-130px; 32 | } 33 | .framerAlert strong { font-weight:500; color:#000; margin-bottom:8px; display:block; } 34 | .framerAlert a { color:#28AFFA; } 35 | .framerAlert .btn { 36 | font-weight:500; text-decoration:none; line-height:1; 37 | display:inline-block; padding:6px 12px 7px 12px; 38 | border-radius:3px; margin-top:12px; 39 | background:#28AFFA; color:#fff; 40 | } 41 | 42 | ::-webkit-scrollbar { 43 | display: none; 44 | } -------------------------------------------------------------------------------- /examples/basic-sequence.framer/framer/version: -------------------------------------------------------------------------------- 1 | 1 -------------------------------------------------------------------------------- /examples/basic-sequence.framer/images/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-sequence.framer/images/.gitkeep -------------------------------------------------------------------------------- /examples/basic-sequence.framer/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /examples/basic-sequence.framer/modules/AnimationSequence.coffee: -------------------------------------------------------------------------------- 1 | # Animation Sequence 2 | # Manages a sequence of Animations 3 | # 4 | # by Isaac Weinhausen 5 | # http://isaacw.com 6 | 7 | 8 | class exports.AnimationSequence extends Framer.EventEmitter 9 | 10 | constructor: (options = {}) -> 11 | @_animationsArray = [] 12 | @_currentAnimation = null 13 | @add(animation) for k, animation of options.animations 14 | @repeat = options.repeat ? false 15 | 16 | add: (animation, index) => 17 | 18 | # Ensure the animation is stopped (needed for when passed via the layer.animate method) 19 | animation.stop() 20 | 21 | # Set animation callback 22 | animation.on Events.AnimationEnd, => 23 | @_update() 24 | 25 | # No valid index was passed? 26 | unless index? and index <= @_animationsArray.length 27 | index = @_animationsArray.length 28 | 29 | # Insert animation into its position 30 | @_animationsArray.splice index, 0, animation 31 | 32 | # Update Indices (animations need to track their own position) 33 | animation.index = i for animation, i in @_animationsArray 34 | 35 | 36 | front: (animation) => 37 | @add animation, 0 38 | # @_unshift animation 39 | 40 | _update: => 41 | 42 | # End of sequence? Do not restart? 43 | if @_isEndOfSequence() and @repeat is false 44 | @emit Events.AnimationEnd 45 | 46 | # Nevermind, move along... 47 | else 48 | # Start next animation (or restart sequence) 49 | @_next().start() 50 | 51 | # (Re)Set current Animation 52 | @_currentAnimation = @_next() 53 | 54 | 55 | _isEndOfSequence: (animation = @_currentAnimation) => 56 | animation.index is @_animationsArray.length - 1 57 | 58 | _next: => 59 | @_animationsArray[@_currentAnimation.index + 1] ? @_animationsArray[0] 60 | 61 | start: => 62 | if @_animationsArray.length > 0 63 | # Set _currentAnimation if not set 64 | unless @_currentAnimation? 65 | @_currentAnimation = @_animationsArray[0] 66 | @_currentAnimation.start() 67 | @emit Events.AnimationStart 68 | 69 | stop: => 70 | @_currentAnimation.stop() 71 | @emit Events.AnimationStop 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /examples/basic-sequence.framer/modules/AnimationSet.coffee: -------------------------------------------------------------------------------- 1 | # Animation Set 2 | # Manages a set of Animations 3 | # 4 | # by Isaac Weinhausen 5 | # http://isaacw.com 6 | 7 | 8 | class exports.AnimationSet extends Framer.EventEmitter 9 | 10 | constructor: (options = {}) -> 11 | @_animationsArray = [] 12 | @add(animation) for k, animation of options.animations 13 | @repeat = options.repeat ? false 14 | 15 | add: (animation) => 16 | 17 | # Ensure the animation is stopped (needed when passed via the layer.animate method) 18 | animation.stop() 19 | 20 | # Have the animation track its animating state 21 | animation.isAnimating = false 22 | 23 | animation.on Events.AnimationEnd, => 24 | animation.isAnimating = false 25 | @_update() 26 | 27 | @_animationsArray.push animation 28 | 29 | 30 | _update: () => 31 | # Have all animations stopped? 32 | if not @isAnimating() 33 | if @repeat 34 | @start() 35 | else 36 | @emit Events.AnimationEnd 37 | 38 | isAnimating: => 39 | _.any(@_animationsArray, "isAnimating", true) 40 | 41 | start: => 42 | for animation in @_animationsArray 43 | animation.start() 44 | animation.isAnimating = true 45 | @emit Events.AnimationStart 46 | 47 | stop: => 48 | for animation in @_animationsArray 49 | animation.stop() 50 | animation.isAnimating = false 51 | @emit Events.AnimationStop -------------------------------------------------------------------------------- /examples/basic-set.framer/.gitignore: -------------------------------------------------------------------------------- 1 | # Framer Git Ignore 2 | 3 | # General OSX 4 | 5 | .DS_Store 6 | .AppleDouble 7 | .LSOverride 8 | 9 | # Icon must end with two \r 10 | Icon 11 | 12 | # Thumbnails 13 | ._* 14 | 15 | # Files that might appear in the root of a volume 16 | .DocumentRevisions-V100 17 | .fseventsd 18 | .Spotlight-V100 19 | .TemporaryItems 20 | .Trashes 21 | .VolumeIcon.icns 22 | 23 | # Directories potentially created on remote AFP share 24 | .AppleDB 25 | .AppleDesktop 26 | Network Trash Folder 27 | Temporary Items 28 | .apdisk 29 | 30 | 31 | # Framer Specific 32 | .temp.html 33 | framer/*.old.* 34 | framer/backup.coffee 35 | framer/backups/* 36 | framer/.*.hash 37 | -------------------------------------------------------------------------------- /examples/basic-set.framer/app.coffee: -------------------------------------------------------------------------------- 1 | # Basic Set 2 | # by Isaac Weinhausen 3 | # http://isaacw.com 4 | 5 | 6 | 7 | 8 | # Import classes 9 | # ------------------------------------- 10 | 11 | {AnimationSequence} = require "AnimationSequence" 12 | {AnimationSet} = require "AnimationSet" 13 | 14 | 15 | 16 | 17 | # Setup 18 | # ------------------------------------- 19 | 20 | # Remember these nice colors 21 | colors = 22 | "purple" : "#877DD7" 23 | "blue" : "#28affa" 24 | "teal" : "#2DD7AA" 25 | "green" : "#7DDD11" 26 | "darkGray" : "#292929" 27 | 28 | 29 | # Override defaults 30 | Framer.Defaults.Layer.backgroundColor = "white" 31 | Framer.Defaults.Animation.time = 2 32 | 33 | 34 | # Set canvas props 35 | bg = new BackgroundLayer 36 | backgroundColor: colors["purple"] 37 | 38 | 39 | 40 | 41 | # App 42 | # ------------------------------------- 43 | 44 | 45 | circle1 = new Layer 46 | width: 100 47 | height: 100 48 | borderRadius: 50 49 | circle1.center() 50 | circle1.x -= 125 51 | 52 | circle2 = new Layer 53 | width: 100 54 | height: 100 55 | borderRadius: 50 56 | circle2.center() 57 | 58 | circle3 = new Layer 59 | width: 100 60 | height: 100 61 | borderRadius: 50 62 | circle3.center() 63 | circle3.x += 125 64 | 65 | moveAnimation = new AnimationSet 66 | animations: 67 | 1: circle1.animate 68 | properties: 69 | scale: .5 70 | 2: circle2.animate 71 | properties: 72 | rotationX: 180 73 | 3: circle3.animate 74 | properties: 75 | borderRadius: 8 76 | repeat: true 77 | 78 | 79 | 80 | 81 | # Execute 82 | # ------------------------------------- 83 | 84 | moveAnimation.start() 85 | 86 | -------------------------------------------------------------------------------- /examples/basic-set.framer/app.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.9.3 2 | 3 | -------------------------------------------------------------------------------- /examples/basic-set.framer/framer/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "sharedPrototype" : 0, 3 | "deviceOrientation" : 0, 4 | "contentScale" : 1, 5 | "deviceType" : "fullscreen", 6 | "updateDelay" : 0.3, 7 | "deviceScale" : 1, 8 | "orientation" : 0 9 | } -------------------------------------------------------------------------------- /examples/basic-set.framer/framer/framer.init.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | function isFileLoadingAllowed() { 4 | return (window.location.protocol.indexOf("file") == -1) 5 | } 6 | 7 | function isHomeScreened() { 8 | return ("standalone" in window.navigator) && window.navigator.standalone == true 9 | } 10 | 11 | function isCompatibleBrowser() { 12 | return Utils.isWebKit() 13 | } 14 | 15 | var alertNode; 16 | 17 | function dismissAlert() { 18 | alertNode.parentElement.removeChild(alertNode) 19 | loadProject() 20 | } 21 | 22 | function showAlert(html) { 23 | 24 | alertNode = document.createElement("div") 25 | 26 | alertNode.classList.add("framerAlertBackground") 27 | alertNode.innerHTML = html 28 | 29 | document.addEventListener("DOMContentLoaded", function(event) { 30 | document.body.appendChild(alertNode) 31 | }) 32 | 33 | window.dismissAlert = dismissAlert; 34 | } 35 | 36 | function showBrowserAlert() { 37 | var html = "" 38 | html += "
" 39 | html += "Error: Not A WebKit Browser" 40 | html += "Your browser is not supported.
Please use Safari or Chrome.
" 41 | html += "Try anyway" 42 | html += "
" 43 | 44 | showAlert(html) 45 | } 46 | 47 | function showFileLoadingAlert() { 48 | var html = "" 49 | html += "
" 50 | html += "Error: Local File Restrictions" 51 | html += "Preview this prototype with Framer Mirror or learn more about " 52 | html += "file restrictions.
" 53 | html += "Try anyway" 54 | html += "
" 55 | 56 | showAlert(html) 57 | } 58 | 59 | function showHomeScreenAlert() { 60 | 61 | link = document.createElement("link"); 62 | link.href = "framer/mirror.css" 63 | link.type = "text/css" 64 | link.rel = "stylesheet" 65 | link.media = "screen" 66 | 67 | document.addEventListener("DOMContentLoaded", function(event) { 68 | document.getElementsByTagName("head")[0].appendChild(link) 69 | }) 70 | 71 | var html = "" 72 | html += "
" 73 | html += "
" 74 | html += "

Install Prototype

" 75 | html += "

Tap

, then choose 'Add to Home Screen'

" 76 | html += "
" 77 | html += "
" 78 | 79 | showAlert(html) 80 | } 81 | 82 | function loadProject() { 83 | CoffeeScript.load("app.coffee") 84 | } 85 | 86 | function setDefaultPageTitle() { 87 | // If no title was set we set it to the project folder name so 88 | // you get a nice name on iOS if you bookmark to desktop. 89 | document.addEventListener("DOMContentLoaded", function() { 90 | if (document.title == "") { 91 | if (window.FramerStudioInfo && window.FramerStudioInfo.documentTitle) { 92 | document.title = window.FramerStudioInfo.documentTitle 93 | } else { 94 | document.title = window.location.pathname.replace(/\//g, "") 95 | } 96 | } 97 | }) 98 | } 99 | 100 | function init() { 101 | 102 | if (Utils.isFramerStudio()) { 103 | return 104 | } 105 | 106 | setDefaultPageTitle() 107 | 108 | if (!isCompatibleBrowser()) { 109 | return showBrowserAlert() 110 | } 111 | 112 | if (!isFileLoadingAllowed()) { 113 | return showFileLoadingAlert() 114 | } 115 | 116 | // if (Utils.isMobile() && !isHomeScreened()) { 117 | // return showHomeScreenAlert() 118 | // } 119 | 120 | loadProject() 121 | 122 | } 123 | 124 | init() 125 | 126 | })() 127 | -------------------------------------------------------------------------------- /examples/basic-set.framer/framer/framer.modules.js: -------------------------------------------------------------------------------- 1 | require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0) { 79 | if (this._currentAnimation == null) { 80 | this._currentAnimation = this._animationsArray[0]; 81 | } 82 | this._currentAnimation.start(); 83 | return this.emit(Events.AnimationStart); 84 | } 85 | }; 86 | 87 | AnimationSequence.prototype.stop = function() { 88 | this._currentAnimation.stop(); 89 | return this.emit(Events.AnimationStop); 90 | }; 91 | 92 | return AnimationSequence; 93 | 94 | })(Framer.EventEmitter); 95 | 96 | 97 | 98 | },{}],"AnimationSet":[function(require,module,exports){ 99 | var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, 100 | extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, 101 | hasProp = {}.hasOwnProperty; 102 | 103 | exports.AnimationSet = (function(superClass) { 104 | extend(AnimationSet, superClass); 105 | 106 | function AnimationSet(options) { 107 | var animation, k, ref, ref1; 108 | if (options == null) { 109 | options = {}; 110 | } 111 | this.stop = bind(this.stop, this); 112 | this.start = bind(this.start, this); 113 | this.isAnimating = bind(this.isAnimating, this); 114 | this._update = bind(this._update, this); 115 | this.add = bind(this.add, this); 116 | this._animationsArray = []; 117 | ref = options.animations; 118 | for (k in ref) { 119 | animation = ref[k]; 120 | this.add(animation); 121 | } 122 | this.repeat = (ref1 = options.repeat) != null ? ref1 : false; 123 | } 124 | 125 | AnimationSet.prototype.add = function(animation) { 126 | animation.stop(); 127 | animation.isAnimating = false; 128 | animation.on(Events.AnimationEnd, (function(_this) { 129 | return function() { 130 | animation.isAnimating = false; 131 | return _this._update(); 132 | }; 133 | })(this)); 134 | return this._animationsArray.push(animation); 135 | }; 136 | 137 | AnimationSet.prototype._update = function() { 138 | if (!this.isAnimating()) { 139 | if (this.repeat) { 140 | return this.start(); 141 | } else { 142 | return this.emit(Events.AnimationEnd); 143 | } 144 | } 145 | }; 146 | 147 | AnimationSet.prototype.isAnimating = function() { 148 | return _.any(this._animationsArray, "isAnimating", true); 149 | }; 150 | 151 | AnimationSet.prototype.start = function() { 152 | var animation, i, len, ref; 153 | ref = this._animationsArray; 154 | for (i = 0, len = ref.length; i < len; i++) { 155 | animation = ref[i]; 156 | animation.start(); 157 | animation.isAnimating = true; 158 | } 159 | return this.emit(Events.AnimationStart); 160 | }; 161 | 162 | AnimationSet.prototype.stop = function() { 163 | var animation, i, len, ref; 164 | ref = this._animationsArray; 165 | for (i = 0, len = ref.length; i < len; i++) { 166 | animation = ref[i]; 167 | animation.stop(); 168 | animation.isAnimating = false; 169 | } 170 | return this.emit(Events.AnimationStop); 171 | }; 172 | 173 | return AnimationSet; 174 | 175 | })(Framer.EventEmitter); 176 | 177 | 178 | 179 | },{}]},{},[]) 180 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvVXNlcnMvd2VpbmhhdXMvc3JjL2ZyYW1lci1hbmltYXRpb24tY29sbGVjdGlvbnMvZXhhbXBsZXMvYmFzaWMtc2V0LmZyYW1lci9tb2R1bGVzL0FuaW1hdGlvblNlcXVlbmNlLmNvZmZlZSIsIi9Vc2Vycy93ZWluaGF1cy9zcmMvZnJhbWVyLWFuaW1hdGlvbi1jb2xsZWN0aW9ucy9leGFtcGxlcy9iYXNpYy1zZXQuZnJhbWVyL21vZHVsZXMvQW5pbWF0aW9uU2V0LmNvZmZlZSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ09BLElBQUE7OzZCQUFBOztBQUFBLE9BQWEsQ0FBQztBQUViLHVDQUFBLENBQUE7O0FBQWEsRUFBQSwyQkFBQyxPQUFELEdBQUE7QUFDWixRQUFBLHVCQUFBOztNQURhLFVBQVU7S0FDdkI7QUFBQSxxQ0FBQSxDQUFBO0FBQUEsdUNBQUEsQ0FBQTtBQUFBLHVDQUFBLENBQUE7QUFBQSw2REFBQSxDQUFBO0FBQUEsMkNBQUEsQ0FBQTtBQUFBLHVDQUFBLENBQUE7QUFBQSxtQ0FBQSxDQUFBO0FBQUEsSUFBQSxJQUFDLENBQUEsZ0JBQUQsR0FBb0IsRUFBcEIsQ0FBQTtBQUFBLElBQ0EsSUFBQyxDQUFBLGlCQUFELEdBQXFCLElBRHJCLENBQUE7QUFFQTtBQUFBLFNBQUEsUUFBQTt5QkFBQTtBQUFBLE1BQUEsSUFBQyxDQUFBLEdBQUQsQ0FBSyxTQUFMLENBQUEsQ0FBQTtBQUFBLEtBRkE7QUFBQSxJQUdBLElBQUMsQ0FBQSxNQUFELDRDQUEyQixLQUgzQixDQURZO0VBQUEsQ0FBYjs7QUFBQSw4QkFNQSxHQUFBLEdBQUssU0FBQyxTQUFELEVBQVksS0FBWixHQUFBO0FBR0osUUFBQSx1QkFBQTtBQUFBLElBQUEsU0FBUyxDQUFDLElBQVYsQ0FBQSxDQUFBLENBQUE7QUFBQSxJQUdBLFNBQVMsQ0FBQyxFQUFW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Q0E1QmIsQ0FBQTs7QUFBQSx5QkErQkEsS0FBQSxHQUFPLFNBQUEsR0FBQTtBQUNOLFFBQUEsc0JBQUE7QUFBQTtBQUFBLFNBQUEscUNBQUE7eUJBQUE7QUFDQyxNQUFBLFNBQVMsQ0FBQyxLQUFWLENBQUEsQ0FBQSxDQUFBO0FBQUEsTUFDQSxTQUFTLENBQUMsV0FBVixHQUF3QixJQUR4QixDQUREO0FBQUEsS0FBQTtXQUdBLElBQUMsQ0FBQSxJQUFELENBQU0sTUFBTSxDQUFDLGNBQWIsRUFKTTtFQUFBLENBL0JQLENBQUE7O0FBQUEseUJBcUNBLElBQUEsR0FBTSxTQUFBLEdBQUE7QUFDTCxRQUFBLHNCQUFBO0FBQUE7QUFBQSxTQUFBLHFDQUFBO3lCQUFBO0FBQ0MsTUFBQSxTQUFTLENBQUMsSUFBVixDQUFBLENBQUEsQ0FBQTtBQUFBLE1BQ0EsU0FBUyxDQUFDLFdBQVYsR0FBd0IsS0FEeEIsQ0FERDtBQUFBLEtBQUE7V0FHQSxJQUFDLENBQUEsSUFBRCxDQUFNLE1BQU0sQ0FBQyxhQUFiLEVBSks7RUFBQSxDQXJDTixDQUFBOztzQkFBQTs7R0FGa0MsTUFBTSxDQUFDLGFBQTFDLENBQUEiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiIyBBbmltYXRpb24gU2VxdWVuY2VcbiMgTWFuYWdlcyBhIHNlcXVlbmNlIG9mIEFuaW1hdGlvbnNcbiMgXG4jIGJ5IElzYWFjIFdlaW5oYXVzZW5cbiMgaHR0cDovL2lzYWFjdy5jb21cblxuXG5jbGFzcyBleHBvcnRzLkFuaW1hdGlvblNlcXVlbmNlIGV4dGVuZHMgRnJhbWVyLkV2ZW50RW1pdHRlclxuXHRcblx0Y29uc3RydWN0b3I6IChvcHRpb25zID0ge30pIC0+XG5cdFx0QF9hbmltYXRpb25zQXJyYXkgPSBbXVxuXHRcdEBfY3VycmVudEFuaW1hdGlvbiA9IG51bGxcblx0XHRAYWRkKGFuaW1hdGlvbikgZm9yIGssIGFuaW1hdGlvbiBvZiBvcHRpb25zLmFuaW1hdGlvbnNcblx0XHRAcmVwZWF0ID0gb3B0aW9ucy5yZXBlYXQgPyBmYWxzZVxuXHRcblx0YWRkOiAoYW5pbWF0aW9uLCBpbmRleCkgPT5cblxuXHRcdCMgRW5zdXJlIHRoZSBhbmltYXRpb24gaXMgc3RvcHBlZCAobmVlZGVkIGZvciB3aGVuIHBhc3NlZCB2aWEgdGhlIGxheWVyLmFuaW1hdGUgbWV0aG9kKVxuXHRcdGFuaW1hdGlvbi5zdG9wKClcblx0XHRcblx0XHQjIFNldCBhbmltYXRpb24gY2FsbGJhY2tcblx0XHRhbmltYXRpb24ub24gRXZlbnRzLkFuaW1hdGlvbkVuZCwgPT5cblx0XHRcdEBfdXBkYXRlKClcblx0XHRcblx0XHQjIE5vIHZhbGlkIGluZGV4IHdhcyBwYXNzZWQ/XG5cdFx0dW5sZXNzIGluZGV4PyBhbmQgaW5kZXggPD0gQF9hbmltYXRpb25zQXJyYXkubGVuZ3RoXG5cdFx0XHRpbmRleCA9IEBfYW5pbWF0aW9uc0FycmF5Lmxlbmd0aFxuXHRcdFxuXHRcdCMgSW5zZXJ0IGFuaW1hdGlvbiBpbnRvIGl0cyBwb3NpdGlvblxuXHRcdEBfYW5pbWF0aW9uc0FycmF5LnNwbGljZSBpbmRleCwgMCwgYW5pbWF0aW9uXG5cdFx0XG5cdFx0IyBVcGRhdGUgSW5kaWNlcyAoYW5pbWF0aW9ucyBuZWVkIHRvIHRyYWNrIHRoZWlyIG93biBwb3NpdGlvbilcblx0XHRhbmltYXRpb24uaW5kZXggPSBpIGZvciBhbmltYXRpb24sIGkgaW4gQF9hbmltYXRpb25zQXJyYXlcblx0XHRcblx0XG5cdGZyb250OiAoYW5pbWF0aW9uKSA9PlxuXHRcdEBhZGQgYW5pbWF0aW9uLCAwXG5cdFx0IyBAX3Vuc2hpZnQgYW5pbWF0aW9uXG5cdFx0XG5cdF91cGRhdGU6ID0+XG5cdFx0XG5cdFx0IyBFbmQgb2Ygc2VxdWVuY2U/IERvIG5vdCByZXN0YXJ0P1xuXHRcdGlmIEBfaXNFbmRPZlNlcXVlbmNlKCkgYW5kIEByZXBlYXQgaXMgZmFsc2Vcblx0XHRcdEBlbWl0IEV2ZW50cy5BbmltYXRpb25FbmRcblx0XHRcdFxuXHRcdCMgTmV2ZXJtaW5kLCBtb3ZlIGFsb25nLi4uXG5cdFx0ZWxzZVxuXHRcdFx0IyBTdGFydCBuZXh0IGFuaW1hdGlvbiAob3IgcmVzdGFydCBzZXF1ZW5jZSlcblx0XHRcdEBfbmV4dCgpLnN0YXJ0KClcblx0XHRcdFxuXHRcdCMgKFJlKVNldCBjdXJyZW50IEFuaW1hdGlvblxuXHRcdEBfY3VycmVudEFuaW1hdGlvbiA9IEBfbmV4dCgpXG5cblxuXHRfaXNFbmRPZlNlcXVlbmNlOiAoYW5pbWF0aW9uID0gQF9jdXJyZW50QW5pbWF0aW9uKSA9PlxuXHRcdGFuaW1hdGlvbi5pbmRleCBpcyBAX2FuaW1hdGlvbnNBcnJheS5sZW5ndGggLSAxXG5cdFx0XG5cdF9uZXh0OiA9PlxuXHRcdEBfYW5pbWF0aW9uc0FycmF5W0BfY3VycmVudEFuaW1hdGlvbi5pbmRleCArIDFdID8gQF9hbmltYXRpb25zQXJyYXlbMF1cblx0XG5cdHN0YXJ0OiA9PlxuXHRcdGlmIEBfYW5pbWF0aW9uc0FycmF5Lmxlbmd0aCA+IDBcblx0XHRcdCMgU2V0IF9jdXJyZW50QW5pbWF0aW9uIGlmIG5vdCBzZXRcblx0XHRcdHVubGVzcyBAX2N1cnJlbnRBbmltYXRpb24/XG5cdFx0XHRcdEBfY3VycmVudEFuaW1hdGlvbiA9IEBfYW5pbWF0aW9uc0FycmF5WzBdXG5cdFx0XHRAX2N1cnJlbnRBbmltYXRpb24uc3RhcnQoKVxuXHRcdFx0QGVtaXQgRXZlbnRzLkFuaW1hdGlvblN0YXJ0XG5cdFx0XG5cdHN0b3A6ID0+XG5cdFx0QF9jdXJyZW50QW5pbWF0aW9uLnN0b3AoKVxuXHRcdEBlbWl0IEV2ZW50cy5BbmltYXRpb25TdG9wXG5cblxuXG4iLCIjIEFuaW1hdGlvbiBTZXRcbiMgTWFuYWdlcyBhIHNldCBvZiBBbmltYXRpb25zXG4jIFxuIyBieSBJc2FhYyBXZWluaGF1c2VuXG4jIGh0dHA6Ly9pc2FhY3cuY29tXG5cblxuY2xhc3MgZXhwb3J0cy5BbmltYXRpb25TZXQgZXh0ZW5kcyBGcmFtZXIuRXZlbnRFbWl0dGVyXG5cdFxuXHRjb25zdHJ1Y3RvcjogKG9wdGlvbnMgPSB7fSkgLT5cblx0XHRAX2FuaW1hdGlvbnNBcnJheSA9IFtdXG5cdFx0QGFkZChhbmltYXRpb24pIGZvciBrLCBhbmltYXRpb24gb2Ygb3B0aW9ucy5hbmltYXRpb25zXG5cdFx0QHJlcGVhdCA9IG9wdGlvbnMucmVwZWF0ID8gZmFsc2Vcblx0XHRcdFxuXHRhZGQ6IChhbmltYXRpb24pID0+XG5cdFx0XG5cdFx0IyBFbnN1cmUgdGhlIGFuaW1hdGlvbiBpcyBzdG9wcGVkIChuZWVkZWQgd2hlbiBwYXNzZWQgdmlhIHRoZSBsYXllci5hbmltYXRlIG1ldGhvZClcblx0XHRhbmltYXRpb24uc3RvcCgpXG5cdFx0XG5cdFx0IyBIYXZlIHRoZSBhbmltYXRpb24gdHJhY2sgaXRzIGFuaW1hdGluZyBzdGF0ZVxuXHRcdGFuaW1hdGlvbi5pc0FuaW1hdGluZyA9IGZhbHNlXG5cdFx0XG5cdFx0YW5pbWF0aW9uLm9uIEV2ZW50cy5BbmltYXRpb25FbmQsID0+XG5cdFx0XHRhbmltYXRpb24uaXNBbmltYXRpbmcgPSBmYWxzZVxuXHRcdFx0QF91cGRhdGUoKVxuXHRcdFx0XG5cdFx0QF9hbmltYXRpb25zQXJyYXkucHVzaCBhbmltYXRpb25cblx0XG5cdFxuXHRfdXBkYXRlOiAoKSA9PlxuXHRcdCMgSGF2ZSBhbGwgYW5pbWF0aW9ucyBzdG9wcGVkP1xuXHRcdGlmIG5vdCBAaXNBbmltYXRpbmcoKVxuXHRcdFx0aWYgQHJlcGVhdFxuXHRcdFx0XHRAc3RhcnQoKVxuXHRcdFx0ZWxzZVxuXHRcdFx0XHRAZW1pdCBFdmVudHMuQW5pbWF0aW9uRW5kXG5cdFx0XG5cdGlzQW5pbWF0aW5nOiA9PlxuXHRcdF8uYW55KEBfYW5pbWF0aW9uc0FycmF5LCBcImlzQW5pbWF0aW5nXCIsIHRydWUpXG5cdFxuXHRzdGFydDogPT5cblx0XHRmb3IgYW5pbWF0aW9uIGluIEBfYW5pbWF0aW9uc0FycmF5XG5cdFx0XHRhbmltYXRpb24uc3RhcnQoKVxuXHRcdFx0YW5pbWF0aW9uLmlzQW5pbWF0aW5nID0gdHJ1ZVxuXHRcdEBlbWl0IEV2ZW50cy5BbmltYXRpb25TdGFydFxuXHRcdFxuXHRzdG9wOiA9PlxuXHRcdGZvciBhbmltYXRpb24gaW4gQF9hbmltYXRpb25zQXJyYXlcblx0XHRcdGFuaW1hdGlvbi5zdG9wKClcblx0XHRcdGFuaW1hdGlvbi5pc0FuaW1hdGluZyA9IGZhbHNlXG5cdFx0QGVtaXQgRXZlbnRzLkFuaW1hdGlvblN0b3AiXX0= 181 | -------------------------------------------------------------------------------- /examples/basic-set.framer/framer/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-set.framer/framer/images/background.png -------------------------------------------------------------------------------- /examples/basic-set.framer/framer/images/cursor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-set.framer/framer/images/cursor.png -------------------------------------------------------------------------------- /examples/basic-set.framer/framer/images/cursor@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-set.framer/framer/images/cursor@2x.png -------------------------------------------------------------------------------- /examples/basic-set.framer/framer/images/icon-120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-set.framer/framer/images/icon-120.png -------------------------------------------------------------------------------- /examples/basic-set.framer/framer/images/icon-152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-set.framer/framer/images/icon-152.png -------------------------------------------------------------------------------- /examples/basic-set.framer/framer/images/icon-180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-set.framer/framer/images/icon-180.png -------------------------------------------------------------------------------- /examples/basic-set.framer/framer/images/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-set.framer/framer/images/icon-192.png -------------------------------------------------------------------------------- /examples/basic-set.framer/framer/images/icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-set.framer/framer/images/icon-76.png -------------------------------------------------------------------------------- /examples/basic-set.framer/framer/images/icon-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-set.framer/framer/images/icon-arrow.png -------------------------------------------------------------------------------- /examples/basic-set.framer/framer/images/icon-arrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-set.framer/framer/images/icon-arrow@2x.png -------------------------------------------------------------------------------- /examples/basic-set.framer/framer/images/icon-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-set.framer/framer/images/icon-close.png -------------------------------------------------------------------------------- /examples/basic-set.framer/framer/images/icon-close@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-set.framer/framer/images/icon-close@2x.png -------------------------------------------------------------------------------- /examples/basic-set.framer/framer/images/icon-framer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-set.framer/framer/images/icon-framer.png -------------------------------------------------------------------------------- /examples/basic-set.framer/framer/images/icon-framer@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-set.framer/framer/images/icon-framer@2x.png -------------------------------------------------------------------------------- /examples/basic-set.framer/framer/images/icon-share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-set.framer/framer/images/icon-share.png -------------------------------------------------------------------------------- /examples/basic-set.framer/framer/images/icon-share@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-set.framer/framer/images/icon-share@2x.png -------------------------------------------------------------------------------- /examples/basic-set.framer/framer/mirror.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | border: none; 5 | -webkit-user-select: none; 6 | -webkit-tap-highlight-color: rgba(0,0,0,0); 7 | } 8 | html, body, .wrapper { 9 | height: 100%; 10 | } 11 | body { 12 | background: #fff; 13 | font: 300 20px "Helvetica Neue", Helvetica, sans-serif; 14 | overflow: hidden; 15 | cursor: url('images/cursor.png') 39 39, auto; 16 | text-align: center; 17 | position: relative; 18 | -webkit-font-smoothing: antialiased; 19 | text-rendering: optimizeLegibility; 20 | color: #333740; 21 | } 22 | a { 23 | color: gray; 24 | } 25 | .framerAlert { 26 | font: 12px/1.6em Menlo; 27 | margin: 10px; 28 | color: gray; 29 | } 30 | ::-webkit-scrollbar { 31 | display: none; 32 | } 33 | .wrapper { 34 | width:100%; 35 | max-width: 240px; 36 | margin: 0 auto; 37 | padding-top: 38%; 38 | position: relative; 39 | } 40 | /* Text */ 41 | h1 { 42 | font-size: 22px; 43 | font-weight: 400; 44 | margin-top: 0px; 45 | line-height: 1.5; 46 | color: black; 47 | 48 | margin-bottom: 8px; 49 | margin-top: 16px; 50 | } 51 | h2 { 52 | font-size: 14px; 53 | font-weight: 400; 54 | color: #788594; 55 | } 56 | hr { 57 | border: none; width: 100%; 58 | border-bottom: 1px solid #EFF1F3; 59 | display: block; 60 | margin: 40px auto 32px auto; 61 | } 62 | p { 63 | display: inline-block; 64 | line-height: 1.5; 65 | } 66 | figure { 67 | display: inline-block; 68 | } 69 | .share { 70 | color: #007AFF; 71 | display: inline-block; 72 | margin-left: 8px; 73 | } 74 | .icon-share { 75 | margin-right: 0px; 76 | position: relative; 77 | top:0.5px; 78 | } 79 | .arrow { 80 | position: absolute; 81 | max-width: 240px; 82 | width: 100%; 83 | left:50%; margin-left:-120px; 84 | bottom: 24%; 85 | } 86 | .arrow figure { 87 | -webkit-animation: bounce 1.25s ease infinite; 88 | -moz-animation: bounce 1.25s ease infinite; 89 | -o-animation: bounce 1.25s ease infinite; 90 | animation: bounce 1.25s ease infinite; 91 | -webkit-transform-origin: center bottom; 92 | -ms-transform-origin: center bottom; 93 | transform-origin: center bottom; 94 | } 95 | /* Arrow animation */ 96 | @-webkit-keyframes bounce { 97 | 0%, 100% { 98 | -webkit-transform: translate3d(0,0,0); 99 | transform: translate3d(0,0,0); 100 | } 101 | 50% { 102 | -webkit-transform: translate3d(0, -16px, 0); 103 | transform: translate3d(0, -16px, 0); 104 | } 105 | } 106 | @keyframes bounce { 107 | 0%, 100% { 108 | -webkit-transform: translate3d(0,0,0); 109 | transform: translate3d(0,0,0); 110 | } 111 | 50% { 112 | -webkit-transform: translate3d(0, -16px, 0); 113 | transform: translate3d(0, -16px, 0); 114 | } 115 | } 116 | /* Icons */ 117 | .icon-close, 118 | .icon-framer, 119 | .icon-share, 120 | .icon-arrow { 121 | background-size: cover; 122 | } 123 | .icon-close { 124 | background-image: url("images/icon-close.png"); 125 | position: absolute; 126 | top:16px; 127 | right:16px; 128 | cursor: pointer; 129 | cursor: hand; 130 | width: 18px; 131 | height: 18px; 132 | } 133 | .icon-framer { 134 | background-image: url("images/icon-framer.png"); 135 | width: 60px; 136 | height: 60px; 137 | } 138 | .icon-share { 139 | background-image: url("images/icon-share.png"); 140 | width: 11px; 141 | height: 18px; 142 | } 143 | .icon-arrow { 144 | background-image: url("images/icon-arrow.png"); 145 | width: 18px; 146 | height: 30px; 147 | } 148 | /* Retina Icons */ 149 | @media screen and (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { 150 | .icon-close { 151 | background-image: url("images/icon-close@2x.png"); 152 | } 153 | .icon-framer { 154 | background-image: url("images/icon-framer@2x.png"); 155 | } 156 | .icon-share { 157 | background-image: url("images/icon-share@2x.png"); 158 | } 159 | .icon-arrow { 160 | background-image: url("images/icon-arrow@2x.png"); 161 | } 162 | } 163 | /* Avoid overflow scrolling when viewing in Portrait */ 164 | @media screen and (orientation:portrait) { 165 | html, body, .wrapper { 166 | overflow: hidden; 167 | } 168 | } 169 | /* iPad share icon is positioned in the navigation bar */ 170 | @media screen and (min-width: 576px){ 171 | .arrow { 172 | display: none; 173 | } 174 | .wrapper { 175 | padding-bottom: 25%; 176 | } 177 | } 178 | /* When it landscape, hide arrow and adjust spacing */ 179 | @media screen and (orientation:landscape) { 180 | .arrow { 181 | display: none; 182 | } 183 | .wrapper { 184 | padding-top: 10%; 185 | padding-bottom: 0; 186 | } 187 | } 188 | /* iPhone 6 Portrait */ 189 | @media screen and (min-device-width:375px) and (max-device-width:667px) and (-webkit-min-device-pixel-ratio:2) and (orientation:portrait) { 190 | .wrapper { 191 | padding-top: 48%; 192 | } 193 | .arrow { 194 | bottom: 27%; 195 | } 196 | } -------------------------------------------------------------------------------- /examples/basic-set.framer/framer/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | border: none; 5 | -webkit-user-select: none; 6 | -webkit-tap-highlight-color: rgba(0,0,0,0); 7 | } 8 | 9 | body { 10 | background-color: #fff; 11 | font: 28px/1em "Helvetica"; 12 | color: #FFF; 13 | overflow: hidden; 14 | cursor: url('images/cursor.png') 39 39, auto; 15 | } 16 | 17 | a { 18 | color: gray; 19 | } 20 | 21 | .framerAlertBackground { 22 | position: absolute; top:0px; left:0px; right:0px; bottom:0px; 23 | z-index: 1000; 24 | background-color: #fff; 25 | } 26 | 27 | .framerAlert { 28 | font:400 14px/1.4 "Helvetica Neue", Helvetica, Arial, sans-serif; 29 | -webkit-font-smoothing:antialiased; 30 | color:#616367; text-align:center; 31 | position: absolute; top:40%; left:50%; width:260px; margin-left:-130px; 32 | } 33 | .framerAlert strong { font-weight:500; color:#000; margin-bottom:8px; display:block; } 34 | .framerAlert a { color:#28AFFA; } 35 | .framerAlert .btn { 36 | font-weight:500; text-decoration:none; line-height:1; 37 | display:inline-block; padding:6px 12px 7px 12px; 38 | border-radius:3px; margin-top:12px; 39 | background:#28AFFA; color:#fff; 40 | } 41 | 42 | ::-webkit-scrollbar { 43 | display: none; 44 | } -------------------------------------------------------------------------------- /examples/basic-set.framer/framer/version: -------------------------------------------------------------------------------- 1 | 1 -------------------------------------------------------------------------------- /examples/basic-set.framer/images/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/basic-set.framer/images/.gitkeep -------------------------------------------------------------------------------- /examples/basic-set.framer/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /examples/basic-set.framer/modules/AnimationSequence.coffee: -------------------------------------------------------------------------------- 1 | # Animation Sequence 2 | # Manages a sequence of Animations 3 | # 4 | # by Isaac Weinhausen 5 | # http://isaacw.com 6 | 7 | 8 | class exports.AnimationSequence extends Framer.EventEmitter 9 | 10 | constructor: (options = {}) -> 11 | @_animationsArray = [] 12 | @_currentAnimation = null 13 | @add(animation) for k, animation of options.animations 14 | @repeat = options.repeat ? false 15 | 16 | add: (animation, index) => 17 | 18 | # Ensure the animation is stopped (needed for when passed via the layer.animate method) 19 | animation.stop() 20 | 21 | # Set animation callback 22 | animation.on Events.AnimationEnd, => 23 | @_update() 24 | 25 | # No valid index was passed? 26 | unless index? and index <= @_animationsArray.length 27 | index = @_animationsArray.length 28 | 29 | # Insert animation into its position 30 | @_animationsArray.splice index, 0, animation 31 | 32 | # Update Indices (animations need to track their own position) 33 | animation.index = i for animation, i in @_animationsArray 34 | 35 | 36 | front: (animation) => 37 | @add animation, 0 38 | # @_unshift animation 39 | 40 | _update: => 41 | 42 | # End of sequence? Do not restart? 43 | if @_isEndOfSequence() and @repeat is false 44 | @emit Events.AnimationEnd 45 | 46 | # Nevermind, move along... 47 | else 48 | # Start next animation (or restart sequence) 49 | @_next().start() 50 | 51 | # (Re)Set current Animation 52 | @_currentAnimation = @_next() 53 | 54 | 55 | _isEndOfSequence: (animation = @_currentAnimation) => 56 | animation.index is @_animationsArray.length - 1 57 | 58 | _next: => 59 | @_animationsArray[@_currentAnimation.index + 1] ? @_animationsArray[0] 60 | 61 | start: => 62 | if @_animationsArray.length > 0 63 | # Set _currentAnimation if not set 64 | unless @_currentAnimation? 65 | @_currentAnimation = @_animationsArray[0] 66 | @_currentAnimation.start() 67 | @emit Events.AnimationStart 68 | 69 | stop: => 70 | @_currentAnimation.stop() 71 | @emit Events.AnimationStop 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /examples/basic-set.framer/modules/AnimationSet.coffee: -------------------------------------------------------------------------------- 1 | # Animation Set 2 | # Manages a set of Animations 3 | # 4 | # by Isaac Weinhausen 5 | # http://isaacw.com 6 | 7 | 8 | class exports.AnimationSet extends Framer.EventEmitter 9 | 10 | constructor: (options = {}) -> 11 | @_animationsArray = [] 12 | @add(animation) for k, animation of options.animations 13 | @repeat = options.repeat ? false 14 | 15 | add: (animation) => 16 | 17 | # Ensure the animation is stopped (needed when passed via the layer.animate method) 18 | animation.stop() 19 | 20 | # Have the animation track its animating state 21 | animation.isAnimating = false 22 | 23 | animation.on Events.AnimationEnd, => 24 | animation.isAnimating = false 25 | @_update() 26 | 27 | @_animationsArray.push animation 28 | 29 | 30 | _update: () => 31 | # Have all animations stopped? 32 | if not @isAnimating() 33 | if @repeat 34 | @start() 35 | else 36 | @emit Events.AnimationEnd 37 | 38 | isAnimating: => 39 | _.any(@_animationsArray, "isAnimating", true) 40 | 41 | start: => 42 | for animation in @_animationsArray 43 | animation.start() 44 | animation.isAnimating = true 45 | @emit Events.AnimationStart 46 | 47 | stop: => 48 | for animation in @_animationsArray 49 | animation.stop() 50 | animation.isAnimating = false 51 | @emit Events.AnimationStop -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/.gitignore: -------------------------------------------------------------------------------- 1 | # Framer Git Ignore 2 | 3 | # General OSX 4 | 5 | .DS_Store 6 | .AppleDouble 7 | .LSOverride 8 | 9 | # Icon must end with two \r 10 | Icon 11 | 12 | # Thumbnails 13 | ._* 14 | 15 | # Files that might appear in the root of a volume 16 | .DocumentRevisions-V100 17 | .fseventsd 18 | .Spotlight-V100 19 | .TemporaryItems 20 | .Trashes 21 | .VolumeIcon.icns 22 | 23 | # Directories potentially created on remote AFP share 24 | .AppleDB 25 | .AppleDesktop 26 | Network Trash Folder 27 | Temporary Items 28 | .apdisk 29 | 30 | 31 | # Framer Specific 32 | .temp.html 33 | framer/*.old.* 34 | framer/backup.coffee 35 | framer/backups/* 36 | framer/.*.hash 37 | -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/app.coffee: -------------------------------------------------------------------------------- 1 | # Dynamic Sequence 2 | # by Isaac Weinhausen 3 | # http://isaacw.com 4 | 5 | 6 | 7 | 8 | # Import classes 9 | # ------------------------------------- 10 | 11 | {AnimationSequence} = require "AnimationSequence" 12 | {AnimationSet} = require "AnimationSet" 13 | 14 | 15 | 16 | 17 | # Setup 18 | # ------------------------------------- 19 | 20 | # Remember these nice colors 21 | colors = 22 | "purple" : "#877DD7" 23 | "blue" : "#28affa" 24 | "teal" : "#2DD7AA" 25 | "green" : "#7DDD11" 26 | "darkGray" : "#292929" 27 | 28 | 29 | # Override defaults 30 | Framer.Defaults.Layer.borderRadius = 8 31 | Framer.Defaults.Animation.time = 0.2 32 | 33 | 34 | # Set canvas props 35 | bg = new BackgroundLayer 36 | backgroundColor: colors["green"] 37 | borderRadius: 0 38 | 39 | 40 | # Useful animation functions 41 | moveDown = (layer) -> 42 | new Animation 43 | layer: layer 44 | properties: 45 | y: -> 46 | layer.y + 100 47 | flip = (layer) -> 48 | flipAnimation = new Animation 49 | layer: layer 50 | properties: 51 | rotationZ: 360 52 | flipAnimation.on Events.AnimationEnd, -> 53 | layer.rotationZ = 0 54 | 55 | 56 | 57 | 58 | # App 59 | # ------------------------------------- 60 | 61 | squareProps = 62 | width: 80 63 | height: 80 64 | spacing: 20 65 | 66 | cols = 3 67 | rows = 3 68 | 69 | purpleContainer = new Layer 70 | width: (squareProps.width + squareProps.spacing) * cols - squareProps.spacing 71 | height: (squareProps.height + squareProps.spacing) * rows - squareProps.spacing 72 | backgroundColor: "" 73 | clip: false 74 | purpleContainer.center() 75 | 76 | purpleGroup = new AnimationSequence 77 | 78 | for y in [1..rows] 79 | for x in [1..cols] 80 | square = new Layer 81 | width: squareProps.width 82 | height: squareProps.height 83 | x: (squareProps.width + squareProps.spacing) * (x - 1) 84 | y: (squareProps.height + squareProps.spacing) * (y - 1) 85 | backgroundColor: "white" 86 | superLayer: purpleContainer 87 | purpleGroup.front moveDown(square) 88 | square.on Events.Click, (event, layer) -> 89 | purpleGroup.start() 90 | 91 | 92 | 93 | 94 | # Execute 95 | # ------------------------------------- 96 | 97 | # purpleGroup.start() 98 | 99 | -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/app.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.9.3 2 | 3 | -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/framer/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "updateDelay" : 0.3, 3 | "deviceScale" : -1, 4 | "deviceOrientation" : 0, 5 | "contentScale" : 1, 6 | "sharedPrototype" : 0, 7 | "deviceType" : "fullscreen" 8 | } -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/framer/framer.init.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | function isFileLoadingAllowed() { 4 | return (window.location.protocol.indexOf("file") == -1) 5 | } 6 | 7 | function isHomeScreened() { 8 | return ("standalone" in window.navigator) && window.navigator.standalone == true 9 | } 10 | 11 | function isCompatibleBrowser() { 12 | return Utils.isWebKit() 13 | } 14 | 15 | var alertNode; 16 | 17 | function dismissAlert() { 18 | alertNode.parentElement.removeChild(alertNode) 19 | loadProject() 20 | } 21 | 22 | function showAlert(html) { 23 | 24 | alertNode = document.createElement("div") 25 | 26 | alertNode.classList.add("framerAlertBackground") 27 | alertNode.innerHTML = html 28 | 29 | document.addEventListener("DOMContentLoaded", function(event) { 30 | document.body.appendChild(alertNode) 31 | }) 32 | 33 | window.dismissAlert = dismissAlert; 34 | } 35 | 36 | function showBrowserAlert() { 37 | var html = "" 38 | html += "
" 39 | html += "Error: Not A WebKit Browser" 40 | html += "Your browser is not supported.
Please use Safari or Chrome.
" 41 | html += "Try anyway" 42 | html += "
" 43 | 44 | showAlert(html) 45 | } 46 | 47 | function showFileLoadingAlert() { 48 | var html = "" 49 | html += "
" 50 | html += "Error: Local File Restrictions" 51 | html += "Preview this prototype with Framer Mirror or learn more about " 52 | html += "file restrictions.
" 53 | html += "Try anyway" 54 | html += "
" 55 | 56 | showAlert(html) 57 | } 58 | 59 | function showHomeScreenAlert() { 60 | 61 | link = document.createElement("link"); 62 | link.href = "framer/mirror.css" 63 | link.type = "text/css" 64 | link.rel = "stylesheet" 65 | link.media = "screen" 66 | 67 | document.addEventListener("DOMContentLoaded", function(event) { 68 | document.getElementsByTagName("head")[0].appendChild(link) 69 | }) 70 | 71 | var html = "" 72 | html += "
" 73 | html += "
" 74 | html += "

Install Prototype

" 75 | html += "

Tap

, then choose 'Add to Home Screen'

" 76 | html += "
" 77 | html += "
" 78 | 79 | showAlert(html) 80 | } 81 | 82 | function loadProject() { 83 | CoffeeScript.load("app.coffee") 84 | } 85 | 86 | function setDefaultPageTitle() { 87 | // If no title was set we set it to the project folder name so 88 | // you get a nice name on iOS if you bookmark to desktop. 89 | document.addEventListener("DOMContentLoaded", function() { 90 | if (document.title == "") { 91 | if (window.FramerStudioInfo && window.FramerStudioInfo.documentTitle) { 92 | document.title = window.FramerStudioInfo.documentTitle 93 | } else { 94 | document.title = window.location.pathname.replace(/\//g, "") 95 | } 96 | } 97 | }) 98 | } 99 | 100 | function init() { 101 | 102 | if (Utils.isFramerStudio()) { 103 | return 104 | } 105 | 106 | setDefaultPageTitle() 107 | 108 | if (!isCompatibleBrowser()) { 109 | return showBrowserAlert() 110 | } 111 | 112 | if (!isFileLoadingAllowed()) { 113 | return showFileLoadingAlert() 114 | } 115 | 116 | // if (Utils.isMobile() && !isHomeScreened()) { 117 | // return showHomeScreenAlert() 118 | // } 119 | 120 | loadProject() 121 | 122 | } 123 | 124 | init() 125 | 126 | })() 127 | -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/framer/framer.modules.js: -------------------------------------------------------------------------------- 1 | require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0) { 79 | if (this._currentAnimation == null) { 80 | this._currentAnimation = this._animationsArray[0]; 81 | } 82 | this._currentAnimation.start(); 83 | return this.emit(Events.AnimationStart); 84 | } 85 | }; 86 | 87 | AnimationSequence.prototype.stop = function() { 88 | this._currentAnimation.stop(); 89 | return this.emit(Events.AnimationStop); 90 | }; 91 | 92 | return AnimationSequence; 93 | 94 | })(Framer.EventEmitter); 95 | 96 | 97 | 98 | },{}],"AnimationSet":[function(require,module,exports){ 99 | var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, 100 | extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, 101 | hasProp = {}.hasOwnProperty; 102 | 103 | exports.AnimationSet = (function(superClass) { 104 | extend(AnimationSet, superClass); 105 | 106 | function AnimationSet(options) { 107 | var animation, k, ref, ref1; 108 | if (options == null) { 109 | options = {}; 110 | } 111 | this.stop = bind(this.stop, this); 112 | this.start = bind(this.start, this); 113 | this.isAnimating = bind(this.isAnimating, this); 114 | this._update = bind(this._update, this); 115 | this.add = bind(this.add, this); 116 | this._animationsArray = []; 117 | ref = options.animations; 118 | for (k in ref) { 119 | animation = ref[k]; 120 | this.add(animation); 121 | } 122 | this.repeat = (ref1 = options.repeat) != null ? ref1 : false; 123 | } 124 | 125 | AnimationSet.prototype.add = function(animation) { 126 | animation.stop(); 127 | animation.isAnimating = false; 128 | animation.on(Events.AnimationEnd, (function(_this) { 129 | return function() { 130 | animation.isAnimating = false; 131 | return _this._update(); 132 | }; 133 | })(this)); 134 | return this._animationsArray.push(animation); 135 | }; 136 | 137 | AnimationSet.prototype._update = function() { 138 | if (!this.isAnimating()) { 139 | if (this.repeat) { 140 | return this.start(); 141 | } else { 142 | return this.emit(Events.AnimationEnd); 143 | } 144 | } 145 | }; 146 | 147 | AnimationSet.prototype.isAnimating = function() { 148 | return _.any(this._animationsArray, "isAnimating", true); 149 | }; 150 | 151 | AnimationSet.prototype.start = function() { 152 | var animation, i, len, ref; 153 | ref = this._animationsArray; 154 | for (i = 0, len = ref.length; i < len; i++) { 155 | animation = ref[i]; 156 | animation.start(); 157 | animation.isAnimating = true; 158 | } 159 | return this.emit(Events.AnimationStart); 160 | }; 161 | 162 | AnimationSet.prototype.stop = function() { 163 | var animation, i, len, ref; 164 | ref = this._animationsArray; 165 | for (i = 0, len = ref.length; i < len; i++) { 166 | animation = ref[i]; 167 | animation.stop(); 168 | animation.isAnimating = false; 169 | } 170 | return this.emit(Events.AnimationStop); 171 | }; 172 | 173 | return AnimationSet; 174 | 175 | })(Framer.EventEmitter); 176 | 177 | 178 | 179 | },{}]},{},[]) 180 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvVXNlcnMvd2VpbmhhdXMvc3JjL2ZyYW1lci1hbmltYXRpb24tY29sbGVjdGlvbnMvZXhhbXBsZXMvZHluYW1pYy1zZXF1ZW5jZS5mcmFtZXIvbW9kdWxlcy9BbmltYXRpb25TZXF1ZW5jZS5jb2ZmZWUiLCIvVXNlcnMvd2VpbmhhdXMvc3JjL2ZyYW1lci1hbmltYXRpb24tY29sbGVjdGlvbnMvZXhhbXBsZXMvZHluYW1pYy1zZXF1ZW5jZS5mcmFtZXIvbW9kdWxlcy9BbmltYXRpb25TZXQuY29mZmVlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDT0EsSUFBQTs7NkJBQUE7O0FBQUEsT0FBYSxDQUFDO0FBRWIsdUNBQUEsQ0FBQTs7QUFBYSxFQUFBLDJCQUFDLE9BQUQsR0FBQTtBQUNaLFFBQUEsdUJBQUE7O01BRGEsVUFBVTtLQUN2QjtBQUFBLHFDQUFBLENBQUE7QUFBQSx1Q0FBQSxDQUFBO0FBQUEsdUNBQUEsQ0FBQTtBQUFBLDZEQUFBLENBQUE7QUFBQSwyQ0FBQSxDQUFBO0FBQUEsdUNBQUEsQ0FBQTtBQUFBLG1DQUFBLENBQUE7QUFBQSxJQUFBLElBQUMsQ0FBQSxnQkFBRCxHQUFvQixFQUFwQixDQUFBO0FBQUEsSUFDQSxJQUFDLENBQUEsaUJBQUQsR0FBcUIsSUFEckIsQ0FBQTtBQUVBO0FBQUEsU0FBQSxRQUFBO3lCQUFBO0FBQUEsTUFBQSxJQUFDLENBQUEsR0FBRCxDQUFLLFNBQUwsQ0FBQSxDQUFBO0FBQUEsS0FGQTtBQUFBLElBR0EsSUFBQyxDQUFBLE1BQUQsNENBQTJCLEtBSDNCLENBRFk7RUFBQSxDQUFiOztBQUFBLDhCQU1BLEdBQUEsR0FBSyxTQUFDLFNBQUQsRUFBWSxLQUFaLEdBQUE7QUFHSixRQUFBLHVCQUFBO0FBQUEsSUFBQSxTQUFTLENBQUMsSUFBVixDQUFBLENBQUEsQ0FBQTtBQUFBLElBR0Es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QXhDLEVBRFk7RUFBQSxDQTVCYixDQUFBOztBQUFBLHlCQStCQSxLQUFBLEdBQU8sU0FBQSxHQUFBO0FBQ04sUUFBQSxzQkFBQTtBQUFBO0FBQUEsU0FBQSxxQ0FBQTt5QkFBQTtBQUNDLE1BQUEsU0FBUyxDQUFDLEtBQVYsQ0FBQSxDQUFBLENBQUE7QUFBQSxNQUNBLFNBQVMsQ0FBQyxXQUFWLEdBQXdCLElBRHhCLENBREQ7QUFBQSxLQUFBO1dBR0EsSUFBQyxDQUFBLElBQUQsQ0FBTSxNQUFNLENBQUMsY0FBYixFQUpNO0VBQUEsQ0EvQlAsQ0FBQTs7QUFBQSx5QkFxQ0EsSUFBQSxHQUFNLFNBQUEsR0FBQTtBQUNMLFFBQUEsc0JBQUE7QUFBQTtBQUFBLFNBQUEscUNBQUE7eUJBQUE7QUFDQyxNQUFBLFNBQVMsQ0FBQyxJQUFWLENBQUEsQ0FBQSxDQUFBO0FBQUEsTUFDQSxTQUFTLENBQUMsV0FBVixHQUF3QixLQUR4QixDQUREO0FBQUEsS0FBQTtXQUdBLElBQUMsQ0FBQSxJQUFELENBQU0sTUFBTSxDQUFDLGFBQWIsRUFKSztFQUFBLENBckNOLENBQUE7O3NCQUFBOztHQUZrQyxNQUFNLENBQUMsYUFBMUMsQ0FBQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIjIEFuaW1hdGlvbiBTZXF1ZW5jZVxuIyBNYW5hZ2VzIGEgc2VxdWVuY2Ugb2YgQW5pbWF0aW9uc1xuIyBcbiMgYnkgSXNhYWMgV2VpbmhhdXNlblxuIyBodHRwOi8vaXNhYWN3LmNvbVxuXG5cbmNsYXNzIGV4cG9ydHMuQW5pbWF0aW9uU2VxdWVuY2UgZXh0ZW5kcyBGcmFtZXIuRXZlbnRFbWl0dGVyXG5cdFxuXHRjb25zdHJ1Y3RvcjogKG9wdGlvbnMgPSB7fSkgLT5cblx0XHRAX2FuaW1hdGlvbnNBcnJheSA9IFtdXG5cdFx0QF9jdXJyZW50QW5pbWF0aW9uID0gbnVsbFxuXHRcdEBhZGQoYW5pbWF0aW9uKSBmb3IgaywgYW5pbWF0aW9uIG9mIG9wdGlvbnMuYW5pbWF0aW9uc1xuXHRcdEByZXBlYXQgPSBvcHRpb25zLnJlcGVhdCA/IGZhbHNlXG5cdFxuXHRhZGQ6IChhbmltYXRpb24sIGluZGV4KSA9PlxuXG5cdFx0IyBFbnN1cmUgdGhlIGFuaW1hdGlvbiBpcyBzdG9wcGVkIChuZWVkZWQgZm9yIHdoZW4gcGFzc2VkIHZpYSB0aGUgbGF5ZXIuYW5pbWF0ZSBtZXRob2QpXG5cdFx0YW5pbWF0aW9uLnN0b3AoKVxuXHRcdFxuXHRcdCMgU2V0IGFuaW1hdGlvbiBjYWxsYmFja1xuXHRcdGFuaW1hdGlvbi5vbiBFdmVudHMuQW5pbWF0aW9uRW5kLCA9PlxuXHRcdFx0QF91cGRhdGUoKVxuXHRcdFxuXHRcdCMgTm8gdmFsaWQgaW5kZXggd2FzIHBhc3NlZD9cblx0XHR1bmxlc3MgaW5kZXg/IGFuZCBpbmRleCA8PSBAX2FuaW1hdGlvbnNBcnJheS5sZW5ndGhcblx0XHRcdGluZGV4ID0gQF9hbmltYXRpb25zQXJyYXkubGVuZ3RoXG5cdFx0XG5cdFx0IyBJbnNlcnQgYW5pbWF0aW9uIGludG8gaXRzIHBvc2l0aW9uXG5cdFx0QF9hbmltYXRpb25zQXJyYXkuc3BsaWNlIGluZGV4LCAwLCBhbmltYXRpb25cblx0XHRcblx0XHQjIFVwZGF0ZSBJbmRpY2VzIChhbmltYXRpb25zIG5lZWQgdG8gdHJhY2sgdGhlaXIgb3duIHBvc2l0aW9uKVxuXHRcdGFuaW1hdGlvbi5pbmRleCA9IGkgZm9yIGFuaW1hdGlvbiwgaSBpbiBAX2FuaW1hdGlvbnNBcnJheVxuXHRcdFxuXHRcblx0ZnJvbnQ6IChhbmltYXRpb24pID0+XG5cdFx0QGFkZCBhbmltYXRpb24sIDBcblx0XHQjIEBfdW5zaGlmdCBhbmltYXRpb25cblx0XHRcblx0X3VwZGF0ZTogPT5cblx0XHRcblx0XHQjIEVuZCBvZiBzZXF1ZW5jZT8gRG8gbm90IHJlc3RhcnQ/XG5cdFx0aWYgQF9pc0VuZE9mU2VxdWVuY2UoKSBhbmQgQHJlcGVhdCBpcyBmYWxzZVxuXHRcdFx0QGVtaXQgRXZlbnRzLkFuaW1hdGlvbkVuZFxuXHRcdFx0XG5cdFx0IyBOZXZlcm1pbmQsIG1vdmUgYWxvbmcuLi5cblx0XHRlbHNlXG5cdFx0XHQjIFN0YXJ0IG5leHQgYW5pbWF0aW9uIChvciByZXN0YXJ0IHNlcXVlbmNlKVxuXHRcdFx0QF9uZXh0KCkuc3RhcnQoKVxuXHRcdFx0XG5cdFx0IyAoUmUpU2V0IGN1cnJlbnQgQW5pbWF0aW9uXG5cdFx0QF9jdXJyZW50QW5pbWF0aW9uID0gQF9uZXh0KClcblxuXG5cdF9pc0VuZE9mU2VxdWVuY2U6IChhbmltYXRpb24gPSBAX2N1cnJlbnRBbmltYXRpb24pID0+XG5cdFx0YW5pbWF0aW9uLmluZGV4IGlzIEBfYW5pbWF0aW9uc0FycmF5Lmxlbmd0aCAtIDFcblx0XHRcblx0X25leHQ6ID0+XG5cdFx0QF9hbmltYXRpb25zQXJyYXlbQF9jdXJyZW50QW5pbWF0aW9uLmluZGV4ICsgMV0gPyBAX2FuaW1hdGlvbnNBcnJheVswXVxuXHRcblx0c3RhcnQ6ID0+XG5cdFx0aWYgQF9hbmltYXRpb25zQXJyYXkubGVuZ3RoID4gMFxuXHRcdFx0IyBTZXQgX2N1cnJlbnRBbmltYXRpb24gaWYgbm90IHNldFxuXHRcdFx0dW5sZXNzIEBfY3VycmVudEFuaW1hdGlvbj9cblx0XHRcdFx0QF9jdXJyZW50QW5pbWF0aW9uID0gQF9hbmltYXRpb25zQXJyYXlbMF1cblx0XHRcdEBfY3VycmVudEFuaW1hdGlvbi5zdGFydCgpXG5cdFx0XHRAZW1pdCBFdmVudHMuQW5pbWF0aW9uU3RhcnRcblx0XHRcblx0c3RvcDogPT5cblx0XHRAX2N1cnJlbnRBbmltYXRpb24uc3RvcCgpXG5cdFx0QGVtaXQgRXZlbnRzLkFuaW1hdGlvblN0b3BcblxuXG5cbiIsIiMgQW5pbWF0aW9uIFNldFxuIyBNYW5hZ2VzIGEgc2V0IG9mIEFuaW1hdGlvbnNcbiMgXG4jIGJ5IElzYWFjIFdlaW5oYXVzZW5cbiMgaHR0cDovL2lzYWFjdy5jb21cblxuXG5jbGFzcyBleHBvcnRzLkFuaW1hdGlvblNldCBleHRlbmRzIEZyYW1lci5FdmVudEVtaXR0ZXJcblx0XG5cdGNvbnN0cnVjdG9yOiAob3B0aW9ucyA9IHt9KSAtPlxuXHRcdEBfYW5pbWF0aW9uc0FycmF5ID0gW11cblx0XHRAYWRkKGFuaW1hdGlvbikgZm9yIGssIGFuaW1hdGlvbiBvZiBvcHRpb25zLmFuaW1hdGlvbnNcblx0XHRAcmVwZWF0ID0gb3B0aW9ucy5yZXBlYXQgPyBmYWxzZVxuXHRcdFx0XG5cdGFkZDogKGFuaW1hdGlvbikgPT5cblx0XHRcblx0XHQjIEVuc3VyZSB0aGUgYW5pbWF0aW9uIGlzIHN0b3BwZWQgKG5lZWRlZCB3aGVuIHBhc3NlZCB2aWEgdGhlIGxheWVyLmFuaW1hdGUgbWV0aG9kKVxuXHRcdGFuaW1hdGlvbi5zdG9wKClcblx0XHRcblx0XHQjIEhhdmUgdGhlIGFuaW1hdGlvbiB0cmFjayBpdHMgYW5pbWF0aW5nIHN0YXRlXG5cdFx0YW5pbWF0aW9uLmlzQW5pbWF0aW5nID0gZmFsc2Vcblx0XHRcblx0XHRhbmltYXRpb24ub24gRXZlbnRzLkFuaW1hdGlvbkVuZCwgPT5cblx0XHRcdGFuaW1hdGlvbi5pc0FuaW1hdGluZyA9IGZhbHNlXG5cdFx0XHRAX3VwZGF0ZSgpXG5cdFx0XHRcblx0XHRAX2FuaW1hdGlvbnNBcnJheS5wdXNoIGFuaW1hdGlvblxuXHRcblx0XG5cdF91cGRhdGU6ICgpID0+XG5cdFx0IyBIYXZlIGFsbCBhbmltYXRpb25zIHN0b3BwZWQ/XG5cdFx0aWYgbm90IEBpc0FuaW1hdGluZygpXG5cdFx0XHRpZiBAcmVwZWF0XG5cdFx0XHRcdEBzdGFydCgpXG5cdFx0XHRlbHNlXG5cdFx0XHRcdEBlbWl0IEV2ZW50cy5BbmltYXRpb25FbmRcblx0XHRcblx0aXNBbmltYXRpbmc6ID0+XG5cdFx0Xy5hbnkoQF9hbmltYXRpb25zQXJyYXksIFwiaXNBbmltYXRpbmdcIiwgdHJ1ZSlcblx0XG5cdHN0YXJ0OiA9PlxuXHRcdGZvciBhbmltYXRpb24gaW4gQF9hbmltYXRpb25zQXJyYXlcblx0XHRcdGFuaW1hdGlvbi5zdGFydCgpXG5cdFx0XHRhbmltYXRpb24uaXNBbmltYXRpbmcgPSB0cnVlXG5cdFx0QGVtaXQgRXZlbnRzLkFuaW1hdGlvblN0YXJ0XG5cdFx0XG5cdHN0b3A6ID0+XG5cdFx0Zm9yIGFuaW1hdGlvbiBpbiBAX2FuaW1hdGlvbnNBcnJheVxuXHRcdFx0YW5pbWF0aW9uLnN0b3AoKVxuXHRcdFx0YW5pbWF0aW9uLmlzQW5pbWF0aW5nID0gZmFsc2Vcblx0XHRAZW1pdCBFdmVudHMuQW5pbWF0aW9uU3RvcCJdfQ== 181 | -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/framer/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/dynamic-sequence.framer/framer/images/background.png -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/framer/images/cursor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/dynamic-sequence.framer/framer/images/cursor.png -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/framer/images/cursor@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/dynamic-sequence.framer/framer/images/cursor@2x.png -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/framer/images/icon-120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/dynamic-sequence.framer/framer/images/icon-120.png -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/framer/images/icon-152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/dynamic-sequence.framer/framer/images/icon-152.png -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/framer/images/icon-180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/dynamic-sequence.framer/framer/images/icon-180.png -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/framer/images/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/dynamic-sequence.framer/framer/images/icon-192.png -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/framer/images/icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/dynamic-sequence.framer/framer/images/icon-76.png -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/framer/images/icon-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/dynamic-sequence.framer/framer/images/icon-arrow.png -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/framer/images/icon-arrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/dynamic-sequence.framer/framer/images/icon-arrow@2x.png -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/framer/images/icon-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/dynamic-sequence.framer/framer/images/icon-close.png -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/framer/images/icon-close@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/dynamic-sequence.framer/framer/images/icon-close@2x.png -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/framer/images/icon-framer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/dynamic-sequence.framer/framer/images/icon-framer.png -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/framer/images/icon-framer@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/dynamic-sequence.framer/framer/images/icon-framer@2x.png -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/framer/images/icon-share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/dynamic-sequence.framer/framer/images/icon-share.png -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/framer/images/icon-share@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/dynamic-sequence.framer/framer/images/icon-share@2x.png -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/framer/mirror.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | border: none; 5 | -webkit-user-select: none; 6 | -webkit-tap-highlight-color: rgba(0,0,0,0); 7 | } 8 | html, body, .wrapper { 9 | height: 100%; 10 | } 11 | body { 12 | background: #fff; 13 | font: 300 20px "Helvetica Neue", Helvetica, sans-serif; 14 | overflow: hidden; 15 | cursor: url('images/cursor.png') 39 39, auto; 16 | text-align: center; 17 | position: relative; 18 | -webkit-font-smoothing: antialiased; 19 | text-rendering: optimizeLegibility; 20 | color: #333740; 21 | } 22 | a { 23 | color: gray; 24 | } 25 | .framerAlert { 26 | font: 12px/1.6em Menlo; 27 | margin: 10px; 28 | color: gray; 29 | } 30 | ::-webkit-scrollbar { 31 | display: none; 32 | } 33 | .wrapper { 34 | width:100%; 35 | max-width: 240px; 36 | margin: 0 auto; 37 | padding-top: 38%; 38 | position: relative; 39 | } 40 | /* Text */ 41 | h1 { 42 | font-size: 22px; 43 | font-weight: 400; 44 | margin-top: 0px; 45 | line-height: 1.5; 46 | color: black; 47 | 48 | margin-bottom: 8px; 49 | margin-top: 16px; 50 | } 51 | h2 { 52 | font-size: 14px; 53 | font-weight: 400; 54 | color: #788594; 55 | } 56 | hr { 57 | border: none; width: 100%; 58 | border-bottom: 1px solid #EFF1F3; 59 | display: block; 60 | margin: 40px auto 32px auto; 61 | } 62 | p { 63 | display: inline-block; 64 | line-height: 1.5; 65 | } 66 | figure { 67 | display: inline-block; 68 | } 69 | .share { 70 | color: #007AFF; 71 | display: inline-block; 72 | margin-left: 8px; 73 | } 74 | .icon-share { 75 | margin-right: 0px; 76 | position: relative; 77 | top:0.5px; 78 | } 79 | .arrow { 80 | position: absolute; 81 | max-width: 240px; 82 | width: 100%; 83 | left:50%; margin-left:-120px; 84 | bottom: 24%; 85 | } 86 | .arrow figure { 87 | -webkit-animation: bounce 1.25s ease infinite; 88 | -moz-animation: bounce 1.25s ease infinite; 89 | -o-animation: bounce 1.25s ease infinite; 90 | animation: bounce 1.25s ease infinite; 91 | -webkit-transform-origin: center bottom; 92 | -ms-transform-origin: center bottom; 93 | transform-origin: center bottom; 94 | } 95 | /* Arrow animation */ 96 | @-webkit-keyframes bounce { 97 | 0%, 100% { 98 | -webkit-transform: translate3d(0,0,0); 99 | transform: translate3d(0,0,0); 100 | } 101 | 50% { 102 | -webkit-transform: translate3d(0, -16px, 0); 103 | transform: translate3d(0, -16px, 0); 104 | } 105 | } 106 | @keyframes bounce { 107 | 0%, 100% { 108 | -webkit-transform: translate3d(0,0,0); 109 | transform: translate3d(0,0,0); 110 | } 111 | 50% { 112 | -webkit-transform: translate3d(0, -16px, 0); 113 | transform: translate3d(0, -16px, 0); 114 | } 115 | } 116 | /* Icons */ 117 | .icon-close, 118 | .icon-framer, 119 | .icon-share, 120 | .icon-arrow { 121 | background-size: cover; 122 | } 123 | .icon-close { 124 | background-image: url("images/icon-close.png"); 125 | position: absolute; 126 | top:16px; 127 | right:16px; 128 | cursor: pointer; 129 | cursor: hand; 130 | width: 18px; 131 | height: 18px; 132 | } 133 | .icon-framer { 134 | background-image: url("images/icon-framer.png"); 135 | width: 60px; 136 | height: 60px; 137 | } 138 | .icon-share { 139 | background-image: url("images/icon-share.png"); 140 | width: 11px; 141 | height: 18px; 142 | } 143 | .icon-arrow { 144 | background-image: url("images/icon-arrow.png"); 145 | width: 18px; 146 | height: 30px; 147 | } 148 | /* Retina Icons */ 149 | @media screen and (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { 150 | .icon-close { 151 | background-image: url("images/icon-close@2x.png"); 152 | } 153 | .icon-framer { 154 | background-image: url("images/icon-framer@2x.png"); 155 | } 156 | .icon-share { 157 | background-image: url("images/icon-share@2x.png"); 158 | } 159 | .icon-arrow { 160 | background-image: url("images/icon-arrow@2x.png"); 161 | } 162 | } 163 | /* Avoid overflow scrolling when viewing in Portrait */ 164 | @media screen and (orientation:portrait) { 165 | html, body, .wrapper { 166 | overflow: hidden; 167 | } 168 | } 169 | /* iPad share icon is positioned in the navigation bar */ 170 | @media screen and (min-width: 576px){ 171 | .arrow { 172 | display: none; 173 | } 174 | .wrapper { 175 | padding-bottom: 25%; 176 | } 177 | } 178 | /* When it landscape, hide arrow and adjust spacing */ 179 | @media screen and (orientation:landscape) { 180 | .arrow { 181 | display: none; 182 | } 183 | .wrapper { 184 | padding-top: 10%; 185 | padding-bottom: 0; 186 | } 187 | } 188 | /* iPhone 6 Portrait */ 189 | @media screen and (min-device-width:375px) and (max-device-width:667px) and (-webkit-min-device-pixel-ratio:2) and (orientation:portrait) { 190 | .wrapper { 191 | padding-top: 48%; 192 | } 193 | .arrow { 194 | bottom: 27%; 195 | } 196 | } -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/framer/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | border: none; 5 | -webkit-user-select: none; 6 | -webkit-tap-highlight-color: rgba(0,0,0,0); 7 | } 8 | 9 | body { 10 | background-color: #fff; 11 | font: 28px/1em "Helvetica"; 12 | color: #FFF; 13 | overflow: hidden; 14 | cursor: url('images/cursor.png') 39 39, auto; 15 | } 16 | 17 | a { 18 | color: gray; 19 | } 20 | 21 | .framerAlertBackground { 22 | position: absolute; top:0px; left:0px; right:0px; bottom:0px; 23 | z-index: 1000; 24 | background-color: #fff; 25 | } 26 | 27 | .framerAlert { 28 | font:400 14px/1.4 "Helvetica Neue", Helvetica, Arial, sans-serif; 29 | -webkit-font-smoothing:antialiased; 30 | color:#616367; text-align:center; 31 | position: absolute; top:40%; left:50%; width:260px; margin-left:-130px; 32 | } 33 | .framerAlert strong { font-weight:500; color:#000; margin-bottom:8px; display:block; } 34 | .framerAlert a { color:#28AFFA; } 35 | .framerAlert .btn { 36 | font-weight:500; text-decoration:none; line-height:1; 37 | display:inline-block; padding:6px 12px 7px 12px; 38 | border-radius:3px; margin-top:12px; 39 | background:#28AFFA; color:#fff; 40 | } 41 | 42 | ::-webkit-scrollbar { 43 | display: none; 44 | } -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/framer/version: -------------------------------------------------------------------------------- 1 | 1 -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/images/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/dynamic-sequence.framer/images/.gitkeep -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/modules/AnimationSequence.coffee: -------------------------------------------------------------------------------- 1 | # Animation Sequence 2 | # Manages a sequence of Animations 3 | # 4 | # by Isaac Weinhausen 5 | # http://isaacw.com 6 | 7 | 8 | class exports.AnimationSequence extends Framer.EventEmitter 9 | 10 | constructor: (options = {}) -> 11 | @_animationsArray = [] 12 | @_currentAnimation = null 13 | @add(animation) for k, animation of options.animations 14 | @repeat = options.repeat ? false 15 | 16 | add: (animation, index) => 17 | 18 | # Ensure the animation is stopped (needed for when passed via the layer.animate method) 19 | animation.stop() 20 | 21 | # Set animation callback 22 | animation.on Events.AnimationEnd, => 23 | @_update() 24 | 25 | # No valid index was passed? 26 | unless index? and index <= @_animationsArray.length 27 | index = @_animationsArray.length 28 | 29 | # Insert animation into its position 30 | @_animationsArray.splice index, 0, animation 31 | 32 | # Update Indices (animations need to track their own position) 33 | animation.index = i for animation, i in @_animationsArray 34 | 35 | 36 | front: (animation) => 37 | @add animation, 0 38 | # @_unshift animation 39 | 40 | _update: => 41 | 42 | # End of sequence? Do not restart? 43 | if @_isEndOfSequence() and @repeat is false 44 | @emit Events.AnimationEnd 45 | 46 | # Nevermind, move along... 47 | else 48 | # Start next animation (or restart sequence) 49 | @_next().start() 50 | 51 | # (Re)Set current Animation 52 | @_currentAnimation = @_next() 53 | 54 | 55 | _isEndOfSequence: (animation = @_currentAnimation) => 56 | animation.index is @_animationsArray.length - 1 57 | 58 | _next: => 59 | @_animationsArray[@_currentAnimation.index + 1] ? @_animationsArray[0] 60 | 61 | start: => 62 | if @_animationsArray.length > 0 63 | # Set _currentAnimation if not set 64 | unless @_currentAnimation? 65 | @_currentAnimation = @_animationsArray[0] 66 | @_currentAnimation.start() 67 | @emit Events.AnimationStart 68 | 69 | stop: => 70 | @_currentAnimation.stop() 71 | @emit Events.AnimationStop 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /examples/dynamic-sequence.framer/modules/AnimationSet.coffee: -------------------------------------------------------------------------------- 1 | # Animation Set 2 | # Manages a set of Animations 3 | # 4 | # by Isaac Weinhausen 5 | # http://isaacw.com 6 | 7 | 8 | class exports.AnimationSet extends Framer.EventEmitter 9 | 10 | constructor: (options = {}) -> 11 | @_animationsArray = [] 12 | @add(animation) for k, animation of options.animations 13 | @repeat = options.repeat ? false 14 | 15 | add: (animation) => 16 | 17 | # Ensure the animation is stopped (needed when passed via the layer.animate method) 18 | animation.stop() 19 | 20 | # Have the animation track its animating state 21 | animation.isAnimating = false 22 | 23 | animation.on Events.AnimationEnd, => 24 | animation.isAnimating = false 25 | @_update() 26 | 27 | @_animationsArray.push animation 28 | 29 | 30 | _update: () => 31 | # Have all animations stopped? 32 | if not @isAnimating() 33 | if @repeat 34 | @start() 35 | else 36 | @emit Events.AnimationEnd 37 | 38 | isAnimating: => 39 | _.any(@_animationsArray, "isAnimating", true) 40 | 41 | start: => 42 | for animation in @_animationsArray 43 | animation.start() 44 | animation.isAnimating = true 45 | @emit Events.AnimationStart 46 | 47 | stop: => 48 | for animation in @_animationsArray 49 | animation.stop() 50 | animation.isAnimating = false 51 | @emit Events.AnimationStop -------------------------------------------------------------------------------- /examples/mixed-collections.framer/.gitignore: -------------------------------------------------------------------------------- 1 | # Framer Git Ignore 2 | 3 | # General OSX 4 | 5 | .DS_Store 6 | .AppleDouble 7 | .LSOverride 8 | 9 | # Icon must end with two \r 10 | Icon 11 | 12 | # Thumbnails 13 | ._* 14 | 15 | # Files that might appear in the root of a volume 16 | .DocumentRevisions-V100 17 | .fseventsd 18 | .Spotlight-V100 19 | .TemporaryItems 20 | .Trashes 21 | .VolumeIcon.icns 22 | 23 | # Directories potentially created on remote AFP share 24 | .AppleDB 25 | .AppleDesktop 26 | Network Trash Folder 27 | Temporary Items 28 | .apdisk 29 | 30 | 31 | # Framer Specific 32 | .temp.html 33 | framer/*.old.* 34 | framer/backup.coffee 35 | framer/backups/* 36 | framer/.*.hash 37 | -------------------------------------------------------------------------------- /examples/mixed-collections.framer/app.coffee: -------------------------------------------------------------------------------- 1 | # Mixed Collections 2 | # by Isaac Weinhausen 3 | # http://isaacw.com 4 | 5 | 6 | 7 | 8 | # Import classes 9 | # ------------------------------------- 10 | 11 | {AnimationSequence} = require "AnimationSequence" 12 | {AnimationSet} = require "AnimationSet" 13 | 14 | 15 | 16 | 17 | # Setup 18 | # ------------------------------------- 19 | 20 | # Remember these nice colors 21 | colors = 22 | "purple" : "#877DD7" 23 | "blue" : "#28affa" 24 | "teal" : "#2DD7AA" 25 | "green" : "#7DDD11" 26 | "darkGray" : "#292929" 27 | 28 | 29 | # Override defaults 30 | Framer.Defaults.Layer.width = 100 31 | Framer.Defaults.Layer.height = 100 32 | Framer.Defaults.Layer.borderRadius = 50 33 | Framer.Defaults.Layer.backgroundColor = "white" 34 | Framer.Defaults.Animation.time = 1 35 | 36 | 37 | # Set canvas props 38 | bg1 = new BackgroundLayer 39 | backgroundColor: colors["teal"] 40 | borderRadius: 0 41 | 42 | bg2 = new BackgroundLayer 43 | backgroundColor: "white" 44 | borderRadius: 0 45 | 46 | 47 | 48 | 49 | # App 50 | # ------------------------------------- 51 | 52 | 53 | circle1 = new Layer 54 | circle1.center() 55 | circle1.x -= 120 56 | 57 | circle2 = new Layer 58 | circle2.center() 59 | circle2.y -= 120 60 | 61 | circle3 = new Layer 62 | circle3.center() 63 | circle3.x += 120 64 | 65 | circle4 = new Layer 66 | circle4.center() 67 | circle4.y += 120 68 | 69 | circle5 = new Layer 70 | circle5.center() 71 | 72 | 73 | outwardAnimationSet = new AnimationSet 74 | animations: 75 | a: circle1.animate 76 | properties: 77 | x: circle1.x - 60 78 | b: circle2.animate 79 | properties: 80 | y: circle2.y - 60 81 | c: circle3.animate 82 | properties: 83 | x: circle3.x + 60 84 | d: circle4.animate 85 | properties: 86 | y: circle4.y + 60 87 | 88 | mainAnimationSequence = new AnimationSequence 89 | animations: 90 | 1: outwardAnimationSet 91 | 2: circle5.animate 92 | properties: 93 | borderRadius: 8 94 | 3: circle5.animate 95 | properties: 96 | scale: 1.75 97 | rotation: 360 98 | time: 0.85 99 | 4: bg1.animate 100 | properties: 101 | opacity: 0 102 | 103 | 104 | # Execute 105 | # ------------------------------------- 106 | 107 | mainAnimationSequence.start() 108 | 109 | 110 | -------------------------------------------------------------------------------- /examples/mixed-collections.framer/app.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.9.3 2 | 3 | -------------------------------------------------------------------------------- /examples/mixed-collections.framer/framer/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "updateDelay" : 0.3, 3 | "deviceScale" : -1, 4 | "deviceOrientation" : 0, 5 | "contentScale" : 1, 6 | "sharedPrototype" : 0, 7 | "deviceType" : "fullscreen" 8 | } -------------------------------------------------------------------------------- /examples/mixed-collections.framer/framer/framer.init.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | function isFileLoadingAllowed() { 4 | return (window.location.protocol.indexOf("file") == -1) 5 | } 6 | 7 | function isHomeScreened() { 8 | return ("standalone" in window.navigator) && window.navigator.standalone == true 9 | } 10 | 11 | function isCompatibleBrowser() { 12 | return Utils.isWebKit() 13 | } 14 | 15 | var alertNode; 16 | 17 | function dismissAlert() { 18 | alertNode.parentElement.removeChild(alertNode) 19 | loadProject() 20 | } 21 | 22 | function showAlert(html) { 23 | 24 | alertNode = document.createElement("div") 25 | 26 | alertNode.classList.add("framerAlertBackground") 27 | alertNode.innerHTML = html 28 | 29 | document.addEventListener("DOMContentLoaded", function(event) { 30 | document.body.appendChild(alertNode) 31 | }) 32 | 33 | window.dismissAlert = dismissAlert; 34 | } 35 | 36 | function showBrowserAlert() { 37 | var html = "" 38 | html += "
" 39 | html += "Error: Not A WebKit Browser" 40 | html += "Your browser is not supported.
Please use Safari or Chrome.
" 41 | html += "Try anyway" 42 | html += "
" 43 | 44 | showAlert(html) 45 | } 46 | 47 | function showFileLoadingAlert() { 48 | var html = "" 49 | html += "
" 50 | html += "Error: Local File Restrictions" 51 | html += "Preview this prototype with Framer Mirror or learn more about " 52 | html += "file restrictions.
" 53 | html += "Try anyway" 54 | html += "
" 55 | 56 | showAlert(html) 57 | } 58 | 59 | function showHomeScreenAlert() { 60 | 61 | link = document.createElement("link"); 62 | link.href = "framer/mirror.css" 63 | link.type = "text/css" 64 | link.rel = "stylesheet" 65 | link.media = "screen" 66 | 67 | document.addEventListener("DOMContentLoaded", function(event) { 68 | document.getElementsByTagName("head")[0].appendChild(link) 69 | }) 70 | 71 | var html = "" 72 | html += "
" 73 | html += "
" 74 | html += "

Install Prototype

" 75 | html += "

Tap

, then choose 'Add to Home Screen'

" 76 | html += "
" 77 | html += "
" 78 | 79 | showAlert(html) 80 | } 81 | 82 | function loadProject() { 83 | CoffeeScript.load("app.coffee") 84 | } 85 | 86 | function setDefaultPageTitle() { 87 | // If no title was set we set it to the project folder name so 88 | // you get a nice name on iOS if you bookmark to desktop. 89 | document.addEventListener("DOMContentLoaded", function() { 90 | if (document.title == "") { 91 | if (window.FramerStudioInfo && window.FramerStudioInfo.documentTitle) { 92 | document.title = window.FramerStudioInfo.documentTitle 93 | } else { 94 | document.title = window.location.pathname.replace(/\//g, "") 95 | } 96 | } 97 | }) 98 | } 99 | 100 | function init() { 101 | 102 | if (Utils.isFramerStudio()) { 103 | return 104 | } 105 | 106 | setDefaultPageTitle() 107 | 108 | if (!isCompatibleBrowser()) { 109 | return showBrowserAlert() 110 | } 111 | 112 | if (!isFileLoadingAllowed()) { 113 | return showFileLoadingAlert() 114 | } 115 | 116 | // if (Utils.isMobile() && !isHomeScreened()) { 117 | // return showHomeScreenAlert() 118 | // } 119 | 120 | loadProject() 121 | 122 | } 123 | 124 | init() 125 | 126 | })() 127 | -------------------------------------------------------------------------------- /examples/mixed-collections.framer/framer/framer.modules.js: -------------------------------------------------------------------------------- 1 | require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0) { 79 | if (this._currentAnimation == null) { 80 | this._currentAnimation = this._animationsArray[0]; 81 | } 82 | this._currentAnimation.start(); 83 | return this.emit(Events.AnimationStart); 84 | } 85 | }; 86 | 87 | AnimationSequence.prototype.stop = function() { 88 | this._currentAnimation.stop(); 89 | return this.emit(Events.AnimationStop); 90 | }; 91 | 92 | return AnimationSequence; 93 | 94 | })(Framer.EventEmitter); 95 | 96 | 97 | 98 | },{}],"AnimationSet":[function(require,module,exports){ 99 | var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, 100 | extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, 101 | hasProp = {}.hasOwnProperty; 102 | 103 | exports.AnimationSet = (function(superClass) { 104 | extend(AnimationSet, superClass); 105 | 106 | function AnimationSet(options) { 107 | var animation, k, ref, ref1; 108 | if (options == null) { 109 | options = {}; 110 | } 111 | this.stop = bind(this.stop, this); 112 | this.start = bind(this.start, this); 113 | this.isAnimating = bind(this.isAnimating, this); 114 | this._update = bind(this._update, this); 115 | this.add = bind(this.add, this); 116 | this._animationsArray = []; 117 | ref = options.animations; 118 | for (k in ref) { 119 | animation = ref[k]; 120 | this.add(animation); 121 | } 122 | this.repeat = (ref1 = options.repeat) != null ? ref1 : false; 123 | } 124 | 125 | AnimationSet.prototype.add = function(animation) { 126 | animation.stop(); 127 | animation.isAnimating = false; 128 | animation.on(Events.AnimationEnd, (function(_this) { 129 | return function() { 130 | animation.isAnimating = false; 131 | return _this._update(); 132 | }; 133 | })(this)); 134 | return this._animationsArray.push(animation); 135 | }; 136 | 137 | AnimationSet.prototype._update = function() { 138 | if (!this.isAnimating()) { 139 | if (this.repeat) { 140 | return this.start(); 141 | } else { 142 | return this.emit(Events.AnimationEnd); 143 | } 144 | } 145 | }; 146 | 147 | AnimationSet.prototype.isAnimating = function() { 148 | return _.any(this._animationsArray, "isAnimating", true); 149 | }; 150 | 151 | AnimationSet.prototype.start = function() { 152 | var animation, i, len, ref; 153 | ref = this._animationsArray; 154 | for (i = 0, len = ref.length; i < len; i++) { 155 | animation = ref[i]; 156 | animation.start(); 157 | animation.isAnimating = true; 158 | } 159 | return this.emit(Events.AnimationStart); 160 | }; 161 | 162 | AnimationSet.prototype.stop = function() { 163 | var animation, i, len, ref; 164 | ref = this._animationsArray; 165 | for (i = 0, len = ref.length; i < len; i++) { 166 | animation = ref[i]; 167 | animation.stop(); 168 | animation.isAnimating = false; 169 | } 170 | return this.emit(Events.AnimationStop); 171 | }; 172 | 173 | return AnimationSet; 174 | 175 | })(Framer.EventEmitter); 176 | 177 | 178 | 179 | },{}]},{},[]) 180 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvVXNlcnMvd2VpbmhhdXMvc3JjL2ZyYW1lci1hbmltYXRpb24tY29sbGVjdGlvbnMvZXhhbXBsZXMvbWl4ZWQtY29sbGVjdGlvbnMuZnJhbWVyL21vZHVsZXMvQW5pbWF0aW9uU2VxdWVuY2UuY29mZmVlIiwiL1VzZXJzL3dlaW5oYXVzL3NyYy9mcmFtZXItYW5pbWF0aW9uLWNvbGxlY3Rpb25zL2V4YW1wbGVzL21peGVkLWNvbGxlY3Rpb25zLmZyYW1lci9tb2R1bGVzL0FuaW1hdGlvblNldC5jb2ZmZWUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNPQSxJQUFBOzs2QkFBQTs7QUFBQSxPQUFhLENBQUM7QUFFYix1Q0FBQSxDQUFBOztBQUFhLEVBQUEsMkJBQUMsT0FBRCxHQUFBO0FBQ1osUUFBQSx1QkFBQTs7TUFEYSxVQUFVO0tBQ3ZCO0FBQUEscUNBQUEsQ0FBQTtBQUFBLHVDQUFBLENBQUE7QUFBQSx1Q0FBQSxDQUFBO0FBQUEsNkRBQUEsQ0FBQTtBQUFBLDJDQUFBLENBQUE7QUFBQSx1Q0FBQSxDQUFBO0FBQUEsbUNBQUEsQ0FBQTtBQUFBLElBQUEsSUFBQyxDQUFBLGdCQUFELEdBQW9CLEVBQXBCLENBQUE7QUFBQSxJQUNBLElBQUMsQ0FBQSxpQkFBRCxHQUFxQixJQURyQixDQUFBO0FBRUE7QUFBQSxTQUFBLFFBQUE7eUJBQUE7QUFBQSxNQUFBLElBQUMsQ0FBQSxHQUFELENBQUssU0FBTCxDQUFBLENBQUE7QUFBQSxLQUZBO0FBQUEsSUFHQSxJQUFDLENBQUEsTUFBRCw0Q0FBMkIsS0FIM0IsQ0FEWTtFQUFBLENBQWI7O0FBQUEsOEJBTUEsR0FBQSxHQUFLLFNBQUMsU0FBRCxFQUFZLEtBQVosR0FBQTtBQUdKLFFBQUEsdUJBQUE7QUFBQSxJQUFBLFNBQVMsQ0FBQyxJQUFWLENBQUEsQ0FBQSxDQUFBO0FBQUEsSUFH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SUFBeEMsRUFEWTtFQUFBLENBNUJiLENBQUE7O0FBQUEseUJBK0JBLEtBQUEsR0FBTyxTQUFBLEdBQUE7QUFDTixRQUFBLHNCQUFBO0FBQUE7QUFBQSxTQUFBLHFDQUFBO3lCQUFBO0FBQ0MsTUFBQSxTQUFTLENBQUMsS0FBVixDQUFBLENBQUEsQ0FBQTtBQUFBLE1BQ0EsU0FBUyxDQUFDLFdBQVYsR0FBd0IsSUFEeEIsQ0FERDtBQUFBLEtBQUE7V0FHQSxJQUFDLENBQUEsSUFBRCxDQUFNLE1BQU0sQ0FBQyxjQUFiLEVBSk07RUFBQSxDQS9CUCxDQUFBOztBQUFBLHlCQXFDQSxJQUFBLEdBQU0sU0FBQSxHQUFBO0FBQ0wsUUFBQSxzQkFBQTtBQUFBO0FBQUEsU0FBQSxxQ0FBQTt5QkFBQTtBQUNDLE1BQUEsU0FBUyxDQUFDLElBQVYsQ0FBQSxDQUFBLENBQUE7QUFBQSxNQUNBLFNBQVMsQ0FBQyxXQUFWLEdBQXdCLEtBRHhCLENBREQ7QUFBQSxLQUFBO1dBR0EsSUFBQyxDQUFBLElBQUQsQ0FBTSxNQUFNLENBQUMsYUFBYixFQUpLO0VBQUEsQ0FyQ04sQ0FBQTs7c0JBQUE7O0dBRmtDLE1BQU0sQ0FBQyxhQUExQyxDQUFBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIiMgQW5pbWF0aW9uIFNlcXVlbmNlXG4jIE1hbmFnZXMgYSBzZXF1ZW5jZSBvZiBBbmltYXRpb25zXG4jIFxuIyBieSBJc2FhYyBXZWluaGF1c2VuXG4jIGh0dHA6Ly9pc2FhY3cuY29tXG5cblxuY2xhc3MgZXhwb3J0cy5BbmltYXRpb25TZXF1ZW5jZSBleHRlbmRzIEZyYW1lci5FdmVudEVtaXR0ZXJcblx0XG5cdGNvbnN0cnVjdG9yOiAob3B0aW9ucyA9IHt9KSAtPlxuXHRcdEBfYW5pbWF0aW9uc0FycmF5ID0gW11cblx0XHRAX2N1cnJlbnRBbmltYXRpb24gPSBudWxsXG5cdFx0QGFkZChhbmltYXRpb24pIGZvciBrLCBhbmltYXRpb24gb2Ygb3B0aW9ucy5hbmltYXRpb25zXG5cdFx0QHJlcGVhdCA9IG9wdGlvbnMucmVwZWF0ID8gZmFsc2Vcblx0XG5cdGFkZDogKGFuaW1hdGlvbiwgaW5kZXgpID0+XG5cblx0XHQjIEVuc3VyZSB0aGUgYW5pbWF0aW9uIGlzIHN0b3BwZWQgKG5lZWRlZCBmb3Igd2hlbiBwYXNzZWQgdmlhIHRoZSBsYXllci5hbmltYXRlIG1ldGhvZClcblx0XHRhbmltYXRpb24uc3RvcCgpXG5cdFx0XG5cdFx0IyBTZXQgYW5pbWF0aW9uIGNhbGxiYWNrXG5cdFx0YW5pbWF0aW9uLm9uIEV2ZW50cy5BbmltYXRpb25FbmQsID0+XG5cdFx0XHRAX3VwZGF0ZSgpXG5cdFx0XG5cdFx0IyBObyB2YWxpZCBpbmRleCB3YXMgcGFzc2VkP1xuXHRcdHVubGVzcyBpbmRleD8gYW5kIGluZGV4IDw9IEBfYW5pbWF0aW9uc0FycmF5Lmxlbmd0aFxuXHRcdFx0aW5kZXggPSBAX2FuaW1hdGlvbnNBcnJheS5sZW5ndGhcblx0XHRcblx0XHQjIEluc2VydCBhbmltYXRpb24gaW50byBpdHMgcG9zaXRpb25cblx0XHRAX2FuaW1hdGlvbnNBcnJheS5zcGxpY2UgaW5kZXgsIDAsIGFuaW1hdGlvblxuXHRcdFxuXHRcdCMgVXBkYXRlIEluZGljZXMgKGFuaW1hdGlvbnMgbmVlZCB0byB0cmFjayB0aGVpciBvd24gcG9zaXRpb24pXG5cdFx0YW5pbWF0aW9uLmluZGV4ID0gaSBmb3IgYW5pbWF0aW9uLCBpIGluIEBfYW5pbWF0aW9uc0FycmF5XG5cdFx0XG5cdFxuXHRmcm9udDogKGFuaW1hdGlvbikgPT5cblx0XHRAYWRkIGFuaW1hdGlvbiwgMFxuXHRcdCMgQF91bnNoaWZ0IGFuaW1hdGlvblxuXHRcdFxuXHRfdXBkYXRlOiA9PlxuXHRcdFxuXHRcdCMgRW5kIG9mIHNlcXVlbmNlPyBEbyBub3QgcmVzdGFydD9cblx0XHRpZiBAX2lzRW5kT2ZTZXF1ZW5jZSgpIGFuZCBAcmVwZWF0IGlzIGZhbHNlXG5cdFx0XHRAZW1pdCBFdmVudHMuQW5pbWF0aW9uRW5kXG5cdFx0XHRcblx0XHQjIE5ldmVybWluZCwgbW92ZSBhbG9uZy4uLlxuXHRcdGVsc2Vcblx0XHRcdCMgU3RhcnQgbmV4dCBhbmltYXRpb24gKG9yIHJlc3RhcnQgc2VxdWVuY2UpXG5cdFx0XHRAX25leHQoKS5zdGFydCgpXG5cdFx0XHRcblx0XHQjIChSZSlTZXQgY3VycmVudCBBbmltYXRpb25cblx0XHRAX2N1cnJlbnRBbmltYXRpb24gPSBAX25leHQoKVxuXG5cblx0X2lzRW5kT2ZTZXF1ZW5jZTogKGFuaW1hdGlvbiA9IEBfY3VycmVudEFuaW1hdGlvbikgPT5cblx0XHRhbmltYXRpb24uaW5kZXggaXMgQF9hbmltYXRpb25zQXJyYXkubGVuZ3RoIC0gMVxuXHRcdFxuXHRfbmV4dDogPT5cblx0XHRAX2FuaW1hdGlvbnNBcnJheVtAX2N1cnJlbnRBbmltYXRpb24uaW5kZXggKyAxXSA/IEBfYW5pbWF0aW9uc0FycmF5WzBdXG5cdFxuXHRzdGFydDogPT5cblx0XHRpZiBAX2FuaW1hdGlvbnNBcnJheS5sZW5ndGggPiAwXG5cdFx0XHQjIFNldCBfY3VycmVudEFuaW1hdGlvbiBpZiBub3Qgc2V0XG5cdFx0XHR1bmxlc3MgQF9jdXJyZW50QW5pbWF0aW9uP1xuXHRcdFx0XHRAX2N1cnJlbnRBbmltYXRpb24gPSBAX2FuaW1hdGlvbnNBcnJheVswXVxuXHRcdFx0QF9jdXJyZW50QW5pbWF0aW9uLnN0YXJ0KClcblx0XHRcdEBlbWl0IEV2ZW50cy5BbmltYXRpb25TdGFydFxuXHRcdFxuXHRzdG9wOiA9PlxuXHRcdEBfY3VycmVudEFuaW1hdGlvbi5zdG9wKClcblx0XHRAZW1pdCBFdmVudHMuQW5pbWF0aW9uU3RvcFxuXG5cblxuIiwiIyBBbmltYXRpb24gU2V0XG4jIE1hbmFnZXMgYSBzZXQgb2YgQW5pbWF0aW9uc1xuIyBcbiMgYnkgSXNhYWMgV2VpbmhhdXNlblxuIyBodHRwOi8vaXNhYWN3LmNvbVxuXG5cbmNsYXNzIGV4cG9ydHMuQW5pbWF0aW9uU2V0IGV4dGVuZHMgRnJhbWVyLkV2ZW50RW1pdHRlclxuXHRcblx0Y29uc3RydWN0b3I6IChvcHRpb25zID0ge30pIC0+XG5cdFx0QF9hbmltYXRpb25zQXJyYXkgPSBbXVxuXHRcdEBhZGQoYW5pbWF0aW9uKSBmb3IgaywgYW5pbWF0aW9uIG9mIG9wdGlvbnMuYW5pbWF0aW9uc1xuXHRcdEByZXBlYXQgPSBvcHRpb25zLnJlcGVhdCA/IGZhbHNlXG5cdFx0XHRcblx0YWRkOiAoYW5pbWF0aW9uKSA9PlxuXHRcdFxuXHRcdCMgRW5zdXJlIHRoZSBhbmltYXRpb24gaXMgc3RvcHBlZCAobmVlZGVkIHdoZW4gcGFzc2VkIHZpYSB0aGUgbGF5ZXIuYW5pbWF0ZSBtZXRob2QpXG5cdFx0YW5pbWF0aW9uLnN0b3AoKVxuXHRcdFxuXHRcdCMgSGF2ZSB0aGUgYW5pbWF0aW9uIHRyYWNrIGl0cyBhbmltYXRpbmcgc3RhdGVcblx0XHRhbmltYXRpb24uaXNBbmltYXRpbmcgPSBmYWxzZVxuXHRcdFxuXHRcdGFuaW1hdGlvbi5vbiBFdmVudHMuQW5pbWF0aW9uRW5kLCA9PlxuXHRcdFx0YW5pbWF0aW9uLmlzQW5pbWF0aW5nID0gZmFsc2Vcblx0XHRcdEBfdXBkYXRlKClcblx0XHRcdFxuXHRcdEBfYW5pbWF0aW9uc0FycmF5LnB1c2ggYW5pbWF0aW9uXG5cdFxuXHRcblx0X3VwZGF0ZTogKCkgPT5cblx0XHQjIEhhdmUgYWxsIGFuaW1hdGlvbnMgc3RvcHBlZD9cblx0XHRpZiBub3QgQGlzQW5pbWF0aW5nKClcblx0XHRcdGlmIEByZXBlYXRcblx0XHRcdFx0QHN0YXJ0KClcblx0XHRcdGVsc2Vcblx0XHRcdFx0QGVtaXQgRXZlbnRzLkFuaW1hdGlvbkVuZFxuXHRcdFxuXHRpc0FuaW1hdGluZzogPT5cblx0XHRfLmFueShAX2FuaW1hdGlvbnNBcnJheSwgXCJpc0FuaW1hdGluZ1wiLCB0cnVlKVxuXHRcblx0c3RhcnQ6ID0+XG5cdFx0Zm9yIGFuaW1hdGlvbiBpbiBAX2FuaW1hdGlvbnNBcnJheVxuXHRcdFx0YW5pbWF0aW9uLnN0YXJ0KClcblx0XHRcdGFuaW1hdGlvbi5pc0FuaW1hdGluZyA9IHRydWVcblx0XHRAZW1pdCBFdmVudHMuQW5pbWF0aW9uU3RhcnRcblx0XHRcblx0c3RvcDogPT5cblx0XHRmb3IgYW5pbWF0aW9uIGluIEBfYW5pbWF0aW9uc0FycmF5XG5cdFx0XHRhbmltYXRpb24uc3RvcCgpXG5cdFx0XHRhbmltYXRpb24uaXNBbmltYXRpbmcgPSBmYWxzZVxuXHRcdEBlbWl0IEV2ZW50cy5BbmltYXRpb25TdG9wIl19 181 | -------------------------------------------------------------------------------- /examples/mixed-collections.framer/framer/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/mixed-collections.framer/framer/images/background.png -------------------------------------------------------------------------------- /examples/mixed-collections.framer/framer/images/cursor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/mixed-collections.framer/framer/images/cursor.png -------------------------------------------------------------------------------- /examples/mixed-collections.framer/framer/images/cursor@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/mixed-collections.framer/framer/images/cursor@2x.png -------------------------------------------------------------------------------- /examples/mixed-collections.framer/framer/images/icon-120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/mixed-collections.framer/framer/images/icon-120.png -------------------------------------------------------------------------------- /examples/mixed-collections.framer/framer/images/icon-152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/mixed-collections.framer/framer/images/icon-152.png -------------------------------------------------------------------------------- /examples/mixed-collections.framer/framer/images/icon-180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/mixed-collections.framer/framer/images/icon-180.png -------------------------------------------------------------------------------- /examples/mixed-collections.framer/framer/images/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/mixed-collections.framer/framer/images/icon-192.png -------------------------------------------------------------------------------- /examples/mixed-collections.framer/framer/images/icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/mixed-collections.framer/framer/images/icon-76.png -------------------------------------------------------------------------------- /examples/mixed-collections.framer/framer/images/icon-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/mixed-collections.framer/framer/images/icon-arrow.png -------------------------------------------------------------------------------- /examples/mixed-collections.framer/framer/images/icon-arrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/mixed-collections.framer/framer/images/icon-arrow@2x.png -------------------------------------------------------------------------------- /examples/mixed-collections.framer/framer/images/icon-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/mixed-collections.framer/framer/images/icon-close.png -------------------------------------------------------------------------------- /examples/mixed-collections.framer/framer/images/icon-close@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/mixed-collections.framer/framer/images/icon-close@2x.png -------------------------------------------------------------------------------- /examples/mixed-collections.framer/framer/images/icon-framer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/mixed-collections.framer/framer/images/icon-framer.png -------------------------------------------------------------------------------- /examples/mixed-collections.framer/framer/images/icon-framer@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/mixed-collections.framer/framer/images/icon-framer@2x.png -------------------------------------------------------------------------------- /examples/mixed-collections.framer/framer/images/icon-share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/mixed-collections.framer/framer/images/icon-share.png -------------------------------------------------------------------------------- /examples/mixed-collections.framer/framer/images/icon-share@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/mixed-collections.framer/framer/images/icon-share@2x.png -------------------------------------------------------------------------------- /examples/mixed-collections.framer/framer/mirror.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | border: none; 5 | -webkit-user-select: none; 6 | -webkit-tap-highlight-color: rgba(0,0,0,0); 7 | } 8 | html, body, .wrapper { 9 | height: 100%; 10 | } 11 | body { 12 | background: #fff; 13 | font: 300 20px "Helvetica Neue", Helvetica, sans-serif; 14 | overflow: hidden; 15 | cursor: url('images/cursor.png') 39 39, auto; 16 | text-align: center; 17 | position: relative; 18 | -webkit-font-smoothing: antialiased; 19 | text-rendering: optimizeLegibility; 20 | color: #333740; 21 | } 22 | a { 23 | color: gray; 24 | } 25 | .framerAlert { 26 | font: 12px/1.6em Menlo; 27 | margin: 10px; 28 | color: gray; 29 | } 30 | ::-webkit-scrollbar { 31 | display: none; 32 | } 33 | .wrapper { 34 | width:100%; 35 | max-width: 240px; 36 | margin: 0 auto; 37 | padding-top: 38%; 38 | position: relative; 39 | } 40 | /* Text */ 41 | h1 { 42 | font-size: 22px; 43 | font-weight: 400; 44 | margin-top: 0px; 45 | line-height: 1.5; 46 | color: black; 47 | 48 | margin-bottom: 8px; 49 | margin-top: 16px; 50 | } 51 | h2 { 52 | font-size: 14px; 53 | font-weight: 400; 54 | color: #788594; 55 | } 56 | hr { 57 | border: none; width: 100%; 58 | border-bottom: 1px solid #EFF1F3; 59 | display: block; 60 | margin: 40px auto 32px auto; 61 | } 62 | p { 63 | display: inline-block; 64 | line-height: 1.5; 65 | } 66 | figure { 67 | display: inline-block; 68 | } 69 | .share { 70 | color: #007AFF; 71 | display: inline-block; 72 | margin-left: 8px; 73 | } 74 | .icon-share { 75 | margin-right: 0px; 76 | position: relative; 77 | top:0.5px; 78 | } 79 | .arrow { 80 | position: absolute; 81 | max-width: 240px; 82 | width: 100%; 83 | left:50%; margin-left:-120px; 84 | bottom: 24%; 85 | } 86 | .arrow figure { 87 | -webkit-animation: bounce 1.25s ease infinite; 88 | -moz-animation: bounce 1.25s ease infinite; 89 | -o-animation: bounce 1.25s ease infinite; 90 | animation: bounce 1.25s ease infinite; 91 | -webkit-transform-origin: center bottom; 92 | -ms-transform-origin: center bottom; 93 | transform-origin: center bottom; 94 | } 95 | /* Arrow animation */ 96 | @-webkit-keyframes bounce { 97 | 0%, 100% { 98 | -webkit-transform: translate3d(0,0,0); 99 | transform: translate3d(0,0,0); 100 | } 101 | 50% { 102 | -webkit-transform: translate3d(0, -16px, 0); 103 | transform: translate3d(0, -16px, 0); 104 | } 105 | } 106 | @keyframes bounce { 107 | 0%, 100% { 108 | -webkit-transform: translate3d(0,0,0); 109 | transform: translate3d(0,0,0); 110 | } 111 | 50% { 112 | -webkit-transform: translate3d(0, -16px, 0); 113 | transform: translate3d(0, -16px, 0); 114 | } 115 | } 116 | /* Icons */ 117 | .icon-close, 118 | .icon-framer, 119 | .icon-share, 120 | .icon-arrow { 121 | background-size: cover; 122 | } 123 | .icon-close { 124 | background-image: url("images/icon-close.png"); 125 | position: absolute; 126 | top:16px; 127 | right:16px; 128 | cursor: pointer; 129 | cursor: hand; 130 | width: 18px; 131 | height: 18px; 132 | } 133 | .icon-framer { 134 | background-image: url("images/icon-framer.png"); 135 | width: 60px; 136 | height: 60px; 137 | } 138 | .icon-share { 139 | background-image: url("images/icon-share.png"); 140 | width: 11px; 141 | height: 18px; 142 | } 143 | .icon-arrow { 144 | background-image: url("images/icon-arrow.png"); 145 | width: 18px; 146 | height: 30px; 147 | } 148 | /* Retina Icons */ 149 | @media screen and (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { 150 | .icon-close { 151 | background-image: url("images/icon-close@2x.png"); 152 | } 153 | .icon-framer { 154 | background-image: url("images/icon-framer@2x.png"); 155 | } 156 | .icon-share { 157 | background-image: url("images/icon-share@2x.png"); 158 | } 159 | .icon-arrow { 160 | background-image: url("images/icon-arrow@2x.png"); 161 | } 162 | } 163 | /* Avoid overflow scrolling when viewing in Portrait */ 164 | @media screen and (orientation:portrait) { 165 | html, body, .wrapper { 166 | overflow: hidden; 167 | } 168 | } 169 | /* iPad share icon is positioned in the navigation bar */ 170 | @media screen and (min-width: 576px){ 171 | .arrow { 172 | display: none; 173 | } 174 | .wrapper { 175 | padding-bottom: 25%; 176 | } 177 | } 178 | /* When it landscape, hide arrow and adjust spacing */ 179 | @media screen and (orientation:landscape) { 180 | .arrow { 181 | display: none; 182 | } 183 | .wrapper { 184 | padding-top: 10%; 185 | padding-bottom: 0; 186 | } 187 | } 188 | /* iPhone 6 Portrait */ 189 | @media screen and (min-device-width:375px) and (max-device-width:667px) and (-webkit-min-device-pixel-ratio:2) and (orientation:portrait) { 190 | .wrapper { 191 | padding-top: 48%; 192 | } 193 | .arrow { 194 | bottom: 27%; 195 | } 196 | } -------------------------------------------------------------------------------- /examples/mixed-collections.framer/framer/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | border: none; 5 | -webkit-user-select: none; 6 | -webkit-tap-highlight-color: rgba(0,0,0,0); 7 | } 8 | 9 | body { 10 | background-color: #fff; 11 | font: 28px/1em "Helvetica"; 12 | color: #FFF; 13 | overflow: hidden; 14 | cursor: url('images/cursor.png') 39 39, auto; 15 | } 16 | 17 | a { 18 | color: gray; 19 | } 20 | 21 | .framerAlertBackground { 22 | position: absolute; top:0px; left:0px; right:0px; bottom:0px; 23 | z-index: 1000; 24 | background-color: #fff; 25 | } 26 | 27 | .framerAlert { 28 | font:400 14px/1.4 "Helvetica Neue", Helvetica, Arial, sans-serif; 29 | -webkit-font-smoothing:antialiased; 30 | color:#616367; text-align:center; 31 | position: absolute; top:40%; left:50%; width:260px; margin-left:-130px; 32 | } 33 | .framerAlert strong { font-weight:500; color:#000; margin-bottom:8px; display:block; } 34 | .framerAlert a { color:#28AFFA; } 35 | .framerAlert .btn { 36 | font-weight:500; text-decoration:none; line-height:1; 37 | display:inline-block; padding:6px 12px 7px 12px; 38 | border-radius:3px; margin-top:12px; 39 | background:#28AFFA; color:#fff; 40 | } 41 | 42 | ::-webkit-scrollbar { 43 | display: none; 44 | } -------------------------------------------------------------------------------- /examples/mixed-collections.framer/framer/version: -------------------------------------------------------------------------------- 1 | 1 -------------------------------------------------------------------------------- /examples/mixed-collections.framer/images/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacw/framer-animation-collections/57d272ab2ceed23463b67712b21aafdaff1a941e/examples/mixed-collections.framer/images/.gitkeep -------------------------------------------------------------------------------- /examples/mixed-collections.framer/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /examples/mixed-collections.framer/modules/AnimationSequence.coffee: -------------------------------------------------------------------------------- 1 | # Animation Sequence 2 | # Manages a sequence of Animations 3 | # 4 | # by Isaac Weinhausen 5 | # http://isaacw.com 6 | 7 | 8 | class exports.AnimationSequence extends Framer.EventEmitter 9 | 10 | constructor: (options = {}) -> 11 | @_animationsArray = [] 12 | @_currentAnimation = null 13 | @add(animation) for k, animation of options.animations 14 | @repeat = options.repeat ? false 15 | 16 | add: (animation, index) => 17 | 18 | # Ensure the animation is stopped (needed for when passed via the layer.animate method) 19 | animation.stop() 20 | 21 | # Set animation callback 22 | animation.on Events.AnimationEnd, => 23 | @_update() 24 | 25 | # No valid index was passed? 26 | unless index? and index <= @_animationsArray.length 27 | index = @_animationsArray.length 28 | 29 | # Insert animation into its position 30 | @_animationsArray.splice index, 0, animation 31 | 32 | # Update Indices (animations need to track their own position) 33 | animation.index = i for animation, i in @_animationsArray 34 | 35 | 36 | front: (animation) => 37 | @add animation, 0 38 | # @_unshift animation 39 | 40 | _update: => 41 | 42 | # End of sequence? Do not restart? 43 | if @_isEndOfSequence() and @repeat is false 44 | @emit Events.AnimationEnd 45 | 46 | # Nevermind, move along... 47 | else 48 | # Start next animation (or restart sequence) 49 | @_next().start() 50 | 51 | # (Re)Set current Animation 52 | @_currentAnimation = @_next() 53 | 54 | 55 | _isEndOfSequence: (animation = @_currentAnimation) => 56 | animation.index is @_animationsArray.length - 1 57 | 58 | _next: => 59 | @_animationsArray[@_currentAnimation.index + 1] ? @_animationsArray[0] 60 | 61 | start: => 62 | if @_animationsArray.length > 0 63 | # Set _currentAnimation if not set 64 | unless @_currentAnimation? 65 | @_currentAnimation = @_animationsArray[0] 66 | @_currentAnimation.start() 67 | @emit Events.AnimationStart 68 | 69 | stop: => 70 | @_currentAnimation.stop() 71 | @emit Events.AnimationStop 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /examples/mixed-collections.framer/modules/AnimationSet.coffee: -------------------------------------------------------------------------------- 1 | # Animation Set 2 | # Manages a set of Animations 3 | # 4 | # by Isaac Weinhausen 5 | # http://isaacw.com 6 | 7 | 8 | class exports.AnimationSet extends Framer.EventEmitter 9 | 10 | constructor: (options = {}) -> 11 | @_animationsArray = [] 12 | @add(animation) for k, animation of options.animations 13 | @repeat = options.repeat ? false 14 | 15 | add: (animation) => 16 | 17 | # Ensure the animation is stopped (needed when passed via the layer.animate method) 18 | animation.stop() 19 | 20 | # Have the animation track its animating state 21 | animation.isAnimating = false 22 | 23 | animation.on Events.AnimationEnd, => 24 | animation.isAnimating = false 25 | @_update() 26 | 27 | @_animationsArray.push animation 28 | 29 | 30 | _update: () => 31 | # Have all animations stopped? 32 | if not @isAnimating() 33 | if @repeat 34 | @start() 35 | else 36 | @emit Events.AnimationEnd 37 | 38 | isAnimating: => 39 | _.any(@_animationsArray, "isAnimating", true) 40 | 41 | start: => 42 | for animation in @_animationsArray 43 | animation.start() 44 | animation.isAnimating = true 45 | @emit Events.AnimationStart 46 | 47 | stop: => 48 | for animation in @_animationsArray 49 | animation.stop() 50 | animation.isAnimating = false 51 | @emit Events.AnimationStop --------------------------------------------------------------------------------