├── navigationComponentSimple.framer ├── Icon ├── framer │ ├── version │ ├── images │ │ ├── cursor.png │ │ ├── icon-76.png │ │ ├── background.png │ │ ├── cursor@2x.png │ │ ├── icon-120.png │ │ ├── icon-152.png │ │ ├── icon-180.png │ │ ├── icon-192.png │ │ ├── icon-arrow.png │ │ ├── icon-close.png │ │ ├── icon-share.png │ │ ├── icon-framer.png │ │ ├── icon-arrow@2x.png │ │ ├── icon-close@2x.png │ │ ├── icon-framer@2x.png │ │ └── icon-share@2x.png │ ├── config.json │ ├── style.css │ ├── framer.init.js │ ├── mirror.css │ └── framer.generated.js ├── images │ ├── .gitkeep │ └── demo.gif ├── app.js ├── modules │ └── navigationComponent.coffee ├── .gitignore ├── app.coffee └── index.html ├── navigationComponentComplex.framer ├── Icon ├── framer │ ├── version │ ├── images │ │ ├── cursor.png │ │ ├── cursor@2x.png │ │ ├── icon-120.png │ │ ├── icon-152.png │ │ ├── icon-180.png │ │ ├── icon-192.png │ │ ├── icon-76.png │ │ ├── background.png │ │ ├── icon-arrow.png │ │ ├── icon-close.png │ │ ├── icon-framer.png │ │ ├── icon-share.png │ │ ├── icon-arrow@2x.png │ │ ├── icon-close@2x.png │ │ ├── icon-framer@2x.png │ │ └── icon-share@2x.png │ ├── config.json │ ├── style.css │ ├── framer.init.js │ ├── mirror.css │ └── framer.generated.js ├── images │ ├── .gitkeep │ └── demo.gif ├── app.js ├── modules │ └── navigationComponent.coffee ├── .gitignore ├── index.html └── app.coffee ├── navigationComponentCustomAnimation.framer ├── Icon ├── framer │ ├── version │ ├── images │ │ ├── cursor.png │ │ ├── icon-120.png │ │ ├── icon-152.png │ │ ├── icon-180.png │ │ ├── icon-192.png │ │ ├── icon-76.png │ │ ├── background.png │ │ ├── cursor@2x.png │ │ ├── icon-arrow.png │ │ ├── icon-close.png │ │ ├── icon-framer.png │ │ ├── icon-share.png │ │ ├── icon-arrow@2x.png │ │ ├── icon-close@2x.png │ │ ├── icon-share@2x.png │ │ └── icon-framer@2x.png │ ├── config.json │ ├── style.css │ ├── framer.init.js │ ├── mirror.css │ └── framer.generated.js ├── images │ ├── .gitkeep │ └── demo.gif ├── app.js ├── modules │ └── navigationComponent.coffee ├── .gitignore ├── index.html └── app.coffee ├── navigationComponentCustomHeader.framer ├── Icon ├── framer │ ├── version │ ├── images │ │ ├── cursor.png │ │ ├── cursor@2x.png │ │ ├── icon-120.png │ │ ├── icon-152.png │ │ ├── icon-180.png │ │ ├── icon-192.png │ │ ├── icon-76.png │ │ ├── background.png │ │ ├── icon-arrow.png │ │ ├── icon-close.png │ │ ├── icon-framer.png │ │ ├── icon-share.png │ │ ├── icon-arrow@2x.png │ │ ├── icon-close@2x.png │ │ ├── icon-framer@2x.png │ │ └── icon-share@2x.png │ ├── config.json │ ├── style.css │ ├── framer.init.js │ ├── mirror.css │ └── framer.generated.js ├── images │ ├── .gitkeep │ └── demo.gif ├── app.js ├── modules │ └── navigationComponent.coffee ├── .gitignore ├── index.html └── app.coffee ├── LICENSE ├── README.md └── modules └── navigationComponent.coffee /navigationComponentSimple.framer/Icon : -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /navigationComponentComplex.framer/Icon : -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/Icon : -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/Icon : -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /navigationComponentSimple.framer/framer/version: -------------------------------------------------------------------------------- 1 | 1 -------------------------------------------------------------------------------- /navigationComponentSimple.framer/images/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /navigationComponentComplex.framer/framer/version: -------------------------------------------------------------------------------- 1 | 1 -------------------------------------------------------------------------------- /navigationComponentComplex.framer/images/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/framer/version: -------------------------------------------------------------------------------- 1 | 1 -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/images/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/framer/version: -------------------------------------------------------------------------------- 1 | 1 -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/images/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /navigationComponentSimple.framer/app.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.9.3 2 | 3 | -------------------------------------------------------------------------------- /navigationComponentComplex.framer/app.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.9.3 2 | 3 | -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/app.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.9.3 2 | 3 | -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/app.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.9.3 2 | 3 | -------------------------------------------------------------------------------- /navigationComponentComplex.framer/modules/navigationComponent.coffee: -------------------------------------------------------------------------------- 1 | ../../modules/navigationComponent.coffee -------------------------------------------------------------------------------- /navigationComponentSimple.framer/modules/navigationComponent.coffee: -------------------------------------------------------------------------------- 1 | ../../modules/navigationComponent.coffee -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/modules/navigationComponent.coffee: -------------------------------------------------------------------------------- 1 | ../../modules/navigationComponent.coffee -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/modules/navigationComponent.coffee: -------------------------------------------------------------------------------- 1 | ../../modules/navigationComponent.coffee -------------------------------------------------------------------------------- /navigationComponentSimple.framer/images/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentSimple.framer/images/demo.gif -------------------------------------------------------------------------------- /navigationComponentComplex.framer/images/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentComplex.framer/images/demo.gif -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/images/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomHeader.framer/images/demo.gif -------------------------------------------------------------------------------- /navigationComponentComplex.framer/framer/images/cursor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentComplex.framer/framer/images/cursor.png -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/images/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomAnimation.framer/images/demo.gif -------------------------------------------------------------------------------- /navigationComponentSimple.framer/framer/images/cursor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentSimple.framer/framer/images/cursor.png -------------------------------------------------------------------------------- /navigationComponentSimple.framer/framer/images/icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentSimple.framer/framer/images/icon-76.png -------------------------------------------------------------------------------- /navigationComponentComplex.framer/framer/images/cursor@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentComplex.framer/framer/images/cursor@2x.png -------------------------------------------------------------------------------- /navigationComponentComplex.framer/framer/images/icon-120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentComplex.framer/framer/images/icon-120.png -------------------------------------------------------------------------------- /navigationComponentComplex.framer/framer/images/icon-152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentComplex.framer/framer/images/icon-152.png -------------------------------------------------------------------------------- /navigationComponentComplex.framer/framer/images/icon-180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentComplex.framer/framer/images/icon-180.png -------------------------------------------------------------------------------- /navigationComponentComplex.framer/framer/images/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentComplex.framer/framer/images/icon-192.png -------------------------------------------------------------------------------- /navigationComponentComplex.framer/framer/images/icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentComplex.framer/framer/images/icon-76.png -------------------------------------------------------------------------------- /navigationComponentSimple.framer/framer/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentSimple.framer/framer/images/background.png -------------------------------------------------------------------------------- /navigationComponentSimple.framer/framer/images/cursor@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentSimple.framer/framer/images/cursor@2x.png -------------------------------------------------------------------------------- /navigationComponentSimple.framer/framer/images/icon-120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentSimple.framer/framer/images/icon-120.png -------------------------------------------------------------------------------- /navigationComponentSimple.framer/framer/images/icon-152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentSimple.framer/framer/images/icon-152.png -------------------------------------------------------------------------------- /navigationComponentSimple.framer/framer/images/icon-180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentSimple.framer/framer/images/icon-180.png -------------------------------------------------------------------------------- /navigationComponentSimple.framer/framer/images/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentSimple.framer/framer/images/icon-192.png -------------------------------------------------------------------------------- /navigationComponentSimple.framer/framer/images/icon-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentSimple.framer/framer/images/icon-arrow.png -------------------------------------------------------------------------------- /navigationComponentSimple.framer/framer/images/icon-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentSimple.framer/framer/images/icon-close.png -------------------------------------------------------------------------------- /navigationComponentSimple.framer/framer/images/icon-share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentSimple.framer/framer/images/icon-share.png -------------------------------------------------------------------------------- /navigationComponentComplex.framer/framer/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentComplex.framer/framer/images/background.png -------------------------------------------------------------------------------- /navigationComponentComplex.framer/framer/images/icon-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentComplex.framer/framer/images/icon-arrow.png -------------------------------------------------------------------------------- /navigationComponentComplex.framer/framer/images/icon-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentComplex.framer/framer/images/icon-close.png -------------------------------------------------------------------------------- /navigationComponentComplex.framer/framer/images/icon-framer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentComplex.framer/framer/images/icon-framer.png -------------------------------------------------------------------------------- /navigationComponentComplex.framer/framer/images/icon-share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentComplex.framer/framer/images/icon-share.png -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/framer/images/cursor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomHeader.framer/framer/images/cursor.png -------------------------------------------------------------------------------- /navigationComponentSimple.framer/framer/images/icon-framer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentSimple.framer/framer/images/icon-framer.png -------------------------------------------------------------------------------- /navigationComponentComplex.framer/framer/images/icon-arrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentComplex.framer/framer/images/icon-arrow@2x.png -------------------------------------------------------------------------------- /navigationComponentComplex.framer/framer/images/icon-close@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentComplex.framer/framer/images/icon-close@2x.png -------------------------------------------------------------------------------- /navigationComponentComplex.framer/framer/images/icon-framer@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentComplex.framer/framer/images/icon-framer@2x.png -------------------------------------------------------------------------------- /navigationComponentComplex.framer/framer/images/icon-share@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentComplex.framer/framer/images/icon-share@2x.png -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/framer/images/cursor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomAnimation.framer/framer/images/cursor.png -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/framer/images/cursor@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomHeader.framer/framer/images/cursor@2x.png -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/framer/images/icon-120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomHeader.framer/framer/images/icon-120.png -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/framer/images/icon-152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomHeader.framer/framer/images/icon-152.png -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/framer/images/icon-180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomHeader.framer/framer/images/icon-180.png -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/framer/images/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomHeader.framer/framer/images/icon-192.png -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/framer/images/icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomHeader.framer/framer/images/icon-76.png -------------------------------------------------------------------------------- /navigationComponentSimple.framer/framer/images/icon-arrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentSimple.framer/framer/images/icon-arrow@2x.png -------------------------------------------------------------------------------- /navigationComponentSimple.framer/framer/images/icon-close@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentSimple.framer/framer/images/icon-close@2x.png -------------------------------------------------------------------------------- /navigationComponentSimple.framer/framer/images/icon-framer@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentSimple.framer/framer/images/icon-framer@2x.png -------------------------------------------------------------------------------- /navigationComponentSimple.framer/framer/images/icon-share@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentSimple.framer/framer/images/icon-share@2x.png -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/framer/images/icon-120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomAnimation.framer/framer/images/icon-120.png -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/framer/images/icon-152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomAnimation.framer/framer/images/icon-152.png -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/framer/images/icon-180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomAnimation.framer/framer/images/icon-180.png -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/framer/images/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomAnimation.framer/framer/images/icon-192.png -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/framer/images/icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomAnimation.framer/framer/images/icon-76.png -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/framer/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomHeader.framer/framer/images/background.png -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/framer/images/icon-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomHeader.framer/framer/images/icon-arrow.png -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/framer/images/icon-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomHeader.framer/framer/images/icon-close.png -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/framer/images/icon-framer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomHeader.framer/framer/images/icon-framer.png -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/framer/images/icon-share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomHeader.framer/framer/images/icon-share.png -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/framer/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomAnimation.framer/framer/images/background.png -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/framer/images/cursor@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomAnimation.framer/framer/images/cursor@2x.png -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/framer/images/icon-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomAnimation.framer/framer/images/icon-arrow.png -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/framer/images/icon-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomAnimation.framer/framer/images/icon-close.png -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/framer/images/icon-framer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomAnimation.framer/framer/images/icon-framer.png -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/framer/images/icon-share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomAnimation.framer/framer/images/icon-share.png -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/framer/images/icon-arrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomHeader.framer/framer/images/icon-arrow@2x.png -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/framer/images/icon-close@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomHeader.framer/framer/images/icon-close@2x.png -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/framer/images/icon-framer@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomHeader.framer/framer/images/icon-framer@2x.png -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/framer/images/icon-share@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomHeader.framer/framer/images/icon-share@2x.png -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/framer/images/icon-arrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomAnimation.framer/framer/images/icon-arrow@2x.png -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/framer/images/icon-close@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomAnimation.framer/framer/images/icon-close@2x.png -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/framer/images/icon-share@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomAnimation.framer/framer/images/icon-share@2x.png -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/framer/images/icon-framer@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/FramerNavigationComponent/HEAD/navigationComponentCustomAnimation.framer/framer/images/icon-framer@2x.png -------------------------------------------------------------------------------- /navigationComponentComplex.framer/framer/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "updateDelay" : 0.3, 3 | "deviceScale" : -1, 4 | "deviceOrientation" : 0, 5 | "contentScale" : 1, 6 | "sharedPrototype" : 1, 7 | "deviceType" : "iphone-5s-silver" 8 | } -------------------------------------------------------------------------------- /navigationComponentSimple.framer/framer/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "updateDelay" : 0.3, 3 | "deviceScale" : -1, 4 | "deviceOrientation" : 0, 5 | "contentScale" : 1, 6 | "sharedPrototype" : 1, 7 | "deviceType" : "iphone-5s-silver" 8 | } -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/framer/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "updateDelay" : 0.3, 3 | "deviceScale" : -1, 4 | "deviceOrientation" : 0, 5 | "contentScale" : 1, 6 | "sharedPrototype" : 1, 7 | "deviceType" : "iphone-5s-silver" 8 | } -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/framer/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "updateDelay" : 0.3, 3 | "deviceScale" : -1, 4 | "deviceOrientation" : 0, 5 | "contentScale" : 1, 6 | "sharedPrototype" : 1, 7 | "deviceType" : "iphone-6-silver" 8 | } -------------------------------------------------------------------------------- /navigationComponentComplex.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 | 13 | # Thumbnails 14 | ._* 15 | 16 | # Files that might appear in the root of a volume 17 | .DocumentRevisions-V100 18 | .fseventsd 19 | .Spotlight-V100 20 | .TemporaryItems 21 | .Trashes 22 | .VolumeIcon.icns 23 | 24 | # Directories potentially created on remote AFP share 25 | .AppleDB 26 | .AppleDesktop 27 | Network Trash Folder 28 | Temporary Items 29 | .apdisk 30 | 31 | 32 | # Framer Specific 33 | .temp.html 34 | framer/*.old.* 35 | framer/backup.coffee 36 | framer/backups/* 37 | framer/.*.hash 38 | -------------------------------------------------------------------------------- /navigationComponentSimple.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 | 13 | # Thumbnails 14 | ._* 15 | 16 | # Files that might appear in the root of a volume 17 | .DocumentRevisions-V100 18 | .fseventsd 19 | .Spotlight-V100 20 | .TemporaryItems 21 | .Trashes 22 | .VolumeIcon.icns 23 | 24 | # Directories potentially created on remote AFP share 25 | .AppleDB 26 | .AppleDesktop 27 | Network Trash Folder 28 | Temporary Items 29 | .apdisk 30 | 31 | 32 | # Framer Specific 33 | .temp.html 34 | framer/*.old.* 35 | framer/backup.coffee 36 | framer/backups/* 37 | framer/.*.hash 38 | -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.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 | 13 | # Thumbnails 14 | ._* 15 | 16 | # Files that might appear in the root of a volume 17 | .DocumentRevisions-V100 18 | .fseventsd 19 | .Spotlight-V100 20 | .TemporaryItems 21 | .Trashes 22 | .VolumeIcon.icns 23 | 24 | # Directories potentially created on remote AFP share 25 | .AppleDB 26 | .AppleDesktop 27 | Network Trash Folder 28 | Temporary Items 29 | .apdisk 30 | 31 | 32 | # Framer Specific 33 | .temp.html 34 | framer/*.old.* 35 | framer/backup.coffee 36 | framer/backups/* 37 | framer/.*.hash 38 | -------------------------------------------------------------------------------- /navigationComponentCustomHeader.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 | 13 | # Thumbnails 14 | ._* 15 | 16 | # Files that might appear in the root of a volume 17 | .DocumentRevisions-V100 18 | .fseventsd 19 | .Spotlight-V100 20 | .TemporaryItems 21 | .Trashes 22 | .VolumeIcon.icns 23 | 24 | # Directories potentially created on remote AFP share 25 | .AppleDB 26 | .AppleDesktop 27 | Network Trash Folder 28 | Temporary Items 29 | .apdisk 30 | 31 | 32 | # Framer Specific 33 | .temp.html 34 | framer/*.old.* 35 | framer/backup.coffee 36 | framer/backups/* 37 | framer/.*.hash 38 | -------------------------------------------------------------------------------- /navigationComponentSimple.framer/app.coffee: -------------------------------------------------------------------------------- 1 | NavigationComponent = (require "navigationComponent").NavigationComponent 2 | 3 | createFullScreenLayer = (text, title) -> 4 | newLayer = new Layer 5 | width: Screen.width 6 | height: Screen.height 7 | html: text 8 | backgroundColor: Framer.Utils.randomColor() 9 | newLayer.title = title 10 | newLayer.style = 11 | "font-size" : "600px" 12 | "color" : "white" 13 | "line-height" : Screen.height + "px" 14 | "font-weight" : "bold" 15 | "text-align" : "center" 16 | return newLayer 17 | 18 | firstLayer = createFullScreenLayer("1", "Settings") 19 | firstLayer.name = "First screen" 20 | firstLayer.backgroundColor = "white" 21 | firstLayer.style["color"] = "orange" 22 | 23 | navigationComponent = new NavigationComponent 24 | rootLayer: firstLayer 25 | 26 | firstLayer.on Events.Click, -> 27 | secondLayer = createFullScreenLayer("2", "Long title screen") 28 | secondLayer.name = "Second screen" 29 | navigationComponent.push(secondLayer) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Javi 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 | -------------------------------------------------------------------------------- /navigationComponentSimple.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 | } -------------------------------------------------------------------------------- /navigationComponentComplex.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 | } -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.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 | } -------------------------------------------------------------------------------- /navigationComponentCustomHeader.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 | } -------------------------------------------------------------------------------- /navigationComponentComplex.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 | -------------------------------------------------------------------------------- /navigationComponentSimple.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 | -------------------------------------------------------------------------------- /navigationComponentCustomHeader.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 | -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.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 | -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/app.coffee: -------------------------------------------------------------------------------- 1 | NavigationComponent = (require "navigationComponent").NavigationComponent 2 | 3 | animationTime = 0.5 4 | animationCurve = "spring(300,40,0)" 5 | 6 | createFullScreenLayer = (text, title) -> 7 | newLayer = new Layer 8 | width: Screen.width 9 | height: Screen.height 10 | html: text 11 | backgroundColor: Framer.Utils.randomColor() 12 | newLayer.title = title 13 | newLayer.style = 14 | "font-size" : "600px" 15 | "color" : "white" 16 | "line-height" : Screen.height + "px" 17 | "font-weight" : "bold" 18 | "text-align" : "center" 19 | newLayer.states.add 20 | pushed: 21 | scale: 5 22 | opacity: 0 23 | popped: 24 | scale: 0.2 25 | opacity: 0 26 | newLayer.states.animationOptions = 27 | curve: "spring(300,40,0)" 28 | time: 0.5 29 | return newLayer 30 | 31 | firstLayer = createFullScreenLayer("1", "Settings") 32 | firstLayer.name = "First screen" 33 | firstLayer.backgroundColor = "white" 34 | firstLayer.style["color"] = "orange" 35 | firstLayer.on Events.Click, -> 36 | secondLayer = createFullScreenLayer("2", "User configuration") 37 | navigationComponent.push(secondLayer) 38 | 39 | # Custom configuration for Navigation Component 40 | animationPush = (fromLayer, toLayer) -> 41 | fromLayer.states.switch("pushed") 42 | toLayer.states.switchInstant("popped") 43 | toLayer.states.switch("default") 44 | animationPop = (fromLayer, toLayer) -> 45 | fromLayer.states.switch("popped") 46 | toLayer.states.switchInstant("pushed") 47 | toLayer.states.switch("default") 48 | 49 | navigationComponent = new NavigationComponent 50 | rootLayer: firstLayer 51 | animationTime: animationTime 52 | animationPush: animationPush 53 | animationPop: animationPop -------------------------------------------------------------------------------- /navigationComponentComplex.framer/app.coffee: -------------------------------------------------------------------------------- 1 | NavigationComponent = (require "navigationComponent").NavigationComponent 2 | 3 | createFullScreenLayer = (text, title) -> 4 | newLayer = new Layer 5 | width: Screen.width 6 | height: Screen.height 7 | html: text 8 | backgroundColor: Framer.Utils.randomColor() 9 | newLayer.title = title 10 | newLayer.style = 11 | "font-size" : "600px" 12 | "color" : "white" 13 | "line-height" : Screen.height + "px" 14 | "font-weight" : "bold" 15 | "text-align" : "center" 16 | return newLayer 17 | 18 | firstLayer = createFullScreenLayer("1", "Settings") 19 | firstLayer.name = "First screen" 20 | firstLayer.backgroundColor = "white" 21 | firstLayer.style["color"] = "orange" 22 | 23 | navigationComponent = new NavigationComponent 24 | rootLayer: firstLayer 25 | 26 | firstLayer.on Events.Click, -> 27 | secondLayer = createFullScreenLayer("2", "User profile") 28 | secondLayer.name = "Second screen" 29 | secondLayer.on Events.Click, -> 30 | thirdLayer = createFullScreenLayer("3", "Notifications") 31 | thirdLayer.name = "Third screen" 32 | backButton = new Layer 33 | superLayer: thirdLayer 34 | y: 200 35 | width: 320 36 | height: 90 37 | shadowY: 1 38 | shadowBlur: 2 39 | backgroundColor: "white" 40 | html: "Back home" 41 | backButton.style = 42 | color: "black" 43 | lineHeight: backButton.height + "px" 44 | textAlign: "center" 45 | fontSize: "34px" 46 | fontWeight: 500 47 | fontFamily: "'Helvetica Neue', Helvetica, Arial, sans-serif" 48 | boxShadow: "0 1px 3px rgba(0,0,0,0.2)" 49 | backButton.centerX() 50 | backButton.on Events.Click, -> 51 | navigationComponent.popToRootLayer() 52 | navigationComponent.push(thirdLayer) 53 | navigationComponent.push(secondLayer) -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/app.coffee: -------------------------------------------------------------------------------- 1 | NavigationComponent = (require "navigationComponent").NavigationComponent 2 | 3 | createFullScreenLayer = (text, title) -> 4 | newLayer = new Layer 5 | width: Screen.width 6 | height: Screen.height 7 | html: text 8 | backgroundColor: Framer.Utils.randomColor() 9 | newLayer.title = title 10 | newLayer.style = 11 | "font-size" : "600px" 12 | "color" : "white" 13 | "line-height" : Screen.height + "px" 14 | "font-weight" : "bold" 15 | "text-align" : "center" 16 | return newLayer 17 | 18 | firstLayer = createFullScreenLayer("1", "Settings") 19 | firstLayer.name = "First screen" 20 | firstLayer.backgroundColor = "white" 21 | firstLayer.style["color"] = "orange" 22 | 23 | headerLayer = new Layer 24 | width: Screen.width 25 | height: 100 26 | backgroundColor: "#28affa" 27 | 28 | circleLayers = [] 29 | 30 | addCircleLayer = (navigationLayersLength) -> 31 | circleLayer = new Layer 32 | superLayer: headerLayer 33 | x: Screen.width 34 | width: 50 35 | height: 50 36 | borderRadius: 25 37 | backgroundColor: "white" 38 | circleLayer.centerY() 39 | circleLayer.animate 40 | properties: 41 | x: (navigationLayersLength + 1) * 80 + 55 42 | curve: "spring(400, 20, 10)" 43 | circleLayers.push(circleLayer) 44 | 45 | removeCircleLayer = (index) -> 46 | for circleIndex in [index+1...circleLayers.length] 47 | circleLayer = circleLayers[circleIndex] 48 | circleLayerAnimation = new Animation 49 | layer: circleLayer 50 | properties: 51 | x: Screen.width + 100 52 | curve: "spring(400, 20, 10)" 53 | delay: 0.3 * (circleLayers.length - 1 - circleIndex) 54 | circleLayerAnimation.start() 55 | circleLayerAnimation.on Events.AnimationEnd, -> 56 | circleLayers[circleLayers.length - 1].destroy() 57 | circleLayers.pop() 58 | 59 | addCircleLayer(1) 60 | 61 | navigationComponent = new NavigationComponent 62 | rootLayer: firstLayer 63 | headerLayer: headerLayer 64 | 65 | navigationComponent.on Events.NavigationWillPush, (event) -> 66 | addCircleLayer(event.navigationLayer.navigationLayers.length + 1) 67 | 68 | navigationComponent.on Events.NavigationWillPop, (event) -> 69 | removeCircleLayer(event.index) 70 | 71 | firstLayer.on Events.Click, -> 72 | secondLayer = createFullScreenLayer("2", "User profile") 73 | secondLayer.name = "Second screen" 74 | secondLayer.on Events.Click, -> 75 | thirdLayer = createFullScreenLayer("3", "Notifications") 76 | thirdLayer.name = "Third screen" 77 | thirdLayer.on Events.Click, -> 78 | navigationComponent.popToRootLayer() 79 | navigationComponent.push(thirdLayer) 80 | navigationComponent.push(secondLayer) -------------------------------------------------------------------------------- /navigationComponentComplex.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 | -------------------------------------------------------------------------------- /navigationComponentSimple.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 | -------------------------------------------------------------------------------- /navigationComponentCustomHeader.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 | -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.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 | -------------------------------------------------------------------------------- /navigationComponentComplex.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 | } -------------------------------------------------------------------------------- /navigationComponentSimple.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 | } -------------------------------------------------------------------------------- /navigationComponentCustomHeader.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 | } -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.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 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Navigation Component 2 | 3 | A navigation component for Framer. It features: 4 | 5 | - Default transitions animations for pushing and popping views, based on iOS UINavigationController, that you can replace with your own ones. 6 | - Default header style and animations to show the current and previous layer, also easily customizable. 7 | - Default header style adapts to iPhone6+ screen size 8 | - Custom events are emitted before and after popping and pushing 9 | 10 | ## Examples 11 | 12 | #### [Simple](http://share.framerjs.com/atdu7phom7cz/) 13 | #### [Complex](http://share.framerjs.com/5bb4btk491ux/) 14 | ![Navigation component](navigationComponentComplex.framer/images/demo.gif) 15 | #### [Custom header](http://share.framerjs.com/r6k5788vlyds/) 16 | ![Custom header](navigationComponentCustomHeader.framer/images/demo.gif) 17 | #### [Custom transition animation](http://share.framerjs.com/c7e89e4wnvu0/) 18 | ![Custom transition animation](navigationComponentCustomAnimation.framer/images/demo.gif) 19 | 20 | ## Get started 21 | 22 | - Copy the `navigationComponent.coffee` file into your `modules` folder 23 | - Add `NavigationComponent = (require "navigationComponent").NavigationComponent` 24 | - Create the NavigationComponent: `navigationComponent = new NavigationComponent 25 | rootLayer: yourFirstLayer` 26 | 27 | ## Simple example 28 | 29 | ```coffee 30 | 31 | NavigationComponent = (require "navigationComponent").NavigationComponent 32 | 33 | createFullScreenLayer = (text, title) -> 34 | newLayer = new Layer 35 | width: Screen.width 36 | height: Screen.height 37 | html: text 38 | backgroundColor: Framer.Utils.randomColor() 39 | newLayer.title = title 40 | newLayer.style = 41 | "font-size" : "600px" 42 | "color" : "white" 43 | "line-height" : Screen.height + "px" 44 | "font-weight" : "bold" 45 | "text-align" : "center" 46 | return newLayer 47 | 48 | firstLayer = createFullScreenLayer("1", "Settings") 49 | firstLayer.name = "First screen" 50 | firstLayer.backgroundColor = "white" 51 | firstLayer.style["color"] = "orange" 52 | 53 | navigationComponent = new NavigationComponent 54 | rootLayer: firstLayer 55 | 56 | firstLayer.on Events.Click, -> 57 | secondLayer = createFullScreenLayer("2", "Long title screen") 58 | secondLayer.name = "Second screen" 59 | navigationComponent.push(secondLayer) 60 | 61 | ``` 62 | 63 | ## Constructor params 64 | 65 | - `firstLayer` *(required)* — The layer to initialize the navigation component with. 66 | - `animationPush` — A function that is called when the push animation is needed. It expects two parameters: `fromLayer` -the layer that is on-screen and is going to be pushed- and `toLayer` -the layer that will be shown-. Use these parameters to implement custom animations. 67 | - `animationPop` — You guessed it :) Same as `animationPush` but when popping. 68 | - `animationTime` — A custom transition time. *This parameter is required when implementing custom animations*. 69 | 70 | ## Properties 71 | 72 | - `navigationLayers` — The array of layers that are handled by the navigation component. 73 | - `headerLayer` — The layer that is shown on top of the navigation layer. By default, this layer shows always a custom property `title` string that can be added to each layer on the navigation stack. This layer, when using the default style, has 3 properties: `titleLayer`, `leftLayer` and `backArrow`. 74 | - `currentLayerIndex` — The index of the layer that is being shown. 75 | 76 | ## Functions 77 | 78 | - `push()` — Push a new layer into the navigation component. 79 | - `pop()` — Pop the latest added layer from the navigation component. NOTE: The layer popped is destroyed after being removed from the navigation component, so you might want to create a copy if you want to reuse it later. 80 | - `popToRootLayer()` — Pops to the root layer. 81 | - `popToLayerAtIndex(index)` — Pops layers until the specified index is at the top of the navigation stack 82 | 83 | ## Events 84 | 85 | - `Events.NavigationWillPush` — Called before a new layer is pushed into the navigation stack. It includes an object that has the following properties: `navigationLayer`, `currentLayer` and `nextLayer`. 86 | - `Events.NavigationDidPush` — Called after a new layer has been pushed into the navigation stack. It includes an object that has the following properties: `navigationLayer`, `currentLayer` and `nextLayer`. 87 | - `Events.NavigationWillPop` — Called before a layer (or layers) are popped from the navigation stack. It includes an object that has the following properties: `navigationLayer`, `currentLayer`, `nextLayer` and `index`. 88 | - `Events.NavigationDidPop` — Called after a layer (or layers) are popped from the navigation stack. It includes an object that has the following properties: `navigationLayer`, `currentLayer`, `nextLayer` and `index`. 89 | 90 | ### References 91 | 92 | Thanks to the following creators for sharing their work: 93 | 94 | - [framer-viewNavigationComponent](https://github.com/chriscamargo/framer-viewNavigationComponent) by Chris Camargo 95 | - [Cloning the UI of iOS 7 with HTML, CSS and JavaScript](http://come.ninja/2013/cloning-the-ui-of-ios-7-with-html-css-and-javascript/) by Côme Courteault 96 | 97 | Other references: 98 | 99 | - [iOS 8 Design Cheat Sheet for iPhone 6 and iPhone 6 Plus](http://click-labs.com/ios-8-design-cheat-sheet-and-free-iphone6plus-gui-psd/) 100 | 101 | ## TODO 102 | 103 | - Add slide right to pop 104 | - Replace header layers animations for state transitions 105 | - Add right button action -------------------------------------------------------------------------------- /modules/navigationComponent.coffee: -------------------------------------------------------------------------------- 1 | class exports.NavigationComponent extends Layer 2 | 3 | #iOS animation constants 4 | _ANIMATION_TIME = 0.4 5 | _ANIMATION_CURVE = "cubic-bezier(.6, .1, .3, 1)" 6 | _LEFT_PADDING = if Framer.Device.deviceType.indexOf("iphone-6plus") is -1 then 46 else 69 7 | 8 | #Custom events 9 | Events.NavigationWillPush = "navigationWillPush" 10 | Events.NavigationDidPush = "navigationDidPush" 11 | Events.NavigationWillPop = "navigationWillPop" 12 | Events.NavigationDidPop = "navigationDidPop" 13 | 14 | # Shared class variables 15 | navigationComponentsCounter = 1 16 | 17 | # Public constructor 18 | constructor: (@options={}) -> 19 | 20 | # Check required params 21 | if not @options.rootLayer 22 | throw new Error("Can't initialize NavigationComponent: parameter 'rootLayer' is required.") 23 | return 24 | 25 | @options.width ?= Screen.width 26 | @options.height ?= Screen.height 27 | @options.clip ?= true 28 | @options.backgroundColor ?= "transparent" 29 | @options.name ?= "Navigation Component " + navigationComponentsCounter 30 | 31 | super @options 32 | 33 | navigationComponentsCounter++ 34 | 35 | @navigationLayers = [] 36 | @headerLayer = null 37 | @animationTime = @options.animationTime or _ANIMATION_TIME 38 | @animationCurve = @options.animationCurve or _ANIMATION_CURVE 39 | @animationPush = @options.animationPush or @_defaultAnimationPush 40 | @animationPop = @options.animationPop or @_defaultAnimationPop 41 | @currentLayerIndex = -1 42 | @lock = false 43 | @customHeader = false 44 | 45 | if @options.headerLayer 46 | @headerLayer = @options.headerLayer 47 | @addSubLayer(@headerLayer) 48 | @customHeader = true 49 | else # Default iOS7 header 50 | @headerLayer = new Layer 51 | superLayer: @ 52 | name: "Header Layer" 53 | width: @width 54 | height: 88 55 | clip: false 56 | backgroundColor: "rgba(248, 248, 248, 0.9)" 57 | @headerLayer.style["background-image"] = "linear-gradient(0deg, rgb(200, 199, 204), rgb(200, 199, 204) 50%, transparent 50%)" 58 | @headerLayer.style["background-size"] = "100% 1px" 59 | @headerLayer.style["background-repeat"] = "no-repeat" 60 | @headerLayer.style["background-position"] = "bottom" 61 | 62 | titleLayer = new Layer 63 | superLayer: @headerLayer 64 | name: "Title Layer" 65 | width: @headerLayer.width / 2 66 | height: @headerLayer.height 67 | backgroundColor: "" 68 | titleLayer.centerX() 69 | titleLayer.style = 70 | "font-size" : "34px" 71 | "color" : "black" 72 | "line-height" : @headerLayer.height + "px" 73 | "font-weight" : "500" 74 | "text-align" : "center" 75 | "font-family": "'Helvetica Neue', Helvetica, Arial, sans-serif" 76 | "white-space": "nowrap" 77 | "height" : @headerLayer.height + "px" 78 | 79 | leftLayer = new Layer 80 | superLayer: @headerLayer 81 | name: "Left Layer" 82 | width: 140 83 | height: @headerLayer.height 84 | backgroundColor: "" 85 | opacity: 0 86 | x: _LEFT_PADDING 87 | leftLayer.style = 88 | "font-size" : "34px" 89 | "color" : "rgb(21, 125, 251)" 90 | "line-height" : @headerLayer.height + "px" 91 | "font-weight" : "300" 92 | "text-align" : "left" 93 | "font-family": "'Helvetica Neue', Helvetica, Arial, sans-serif" 94 | "white-space": "nowrap" 95 | "height" : @headerLayer.height + "px" 96 | leftLayer.on Events.Click, => 97 | @pop() 98 | 99 | backArrow = new Layer 100 | superLayer: @headerLayer 101 | name: "Back Arrow" 102 | originX: 0 103 | originY: 0 104 | backgroundColor: "" 105 | opacity: 0 106 | html: " " 107 | backArrow.on Events.Click, => 108 | @pop() 109 | 110 | @headerLayer.titleLayer = titleLayer 111 | @headerLayer.backArrow = backArrow 112 | @headerLayer.leftLayer = leftLayer 113 | 114 | if Framer.Device.deviceType.indexOf("iphone-6plus") >= 0 115 | @headerLayer.height = 132 116 | titleLayer.height = 132 117 | titleLayer.style["font-size"] = "48px" 118 | titleLayer.style["line-height"] = titleLayer.height + "px" 119 | leftLayer.height = 132 120 | leftLayer.style["font-size"] = "48px" 121 | leftLayer.style["line-height"] = titleLayer.height + "px" 122 | leftLayer.width = leftLayer.width * 1.5 123 | backArrow.scale = 1.5 124 | 125 | if @options.rootLayer 126 | @navigationLayers = [@options.rootLayer] 127 | @currentLayerIndex = 0 128 | @addSubLayer(@options.rootLayer) 129 | @headerLayer.bringToFront() 130 | if @options.rootLayer.title and @headerLayer.titleLayer 131 | @headerLayer.titleLayer.html = "
" + @options.rootLayer.title + "
" 132 | 133 | # Public methods 134 | push: (layer) -> 135 | if not @lock 136 | @emit(Events.NavigationWillPush, {navigationLayer: @, currentLayer: currentLayer, nextLayer: nextLayer}) 137 | @lock = true 138 | @navigationLayers.push(layer) 139 | @addSubLayer(layer) 140 | if @headerLayer 141 | @headerLayer.bringToFront() 142 | currentLayer = @navigationLayers[@currentLayerIndex] 143 | nextLayer = layer 144 | if typeof currentLayer.layerWillDisappear is "function" 145 | currentLayer.layerWillDisappear() 146 | if typeof nextLayer.layerWillAppear is "function" 147 | nextLayer.layerWillAppear() 148 | @currentLayerIndex++ 149 | @animationPush(currentLayer, nextLayer) 150 | @_defaultHeaderAnimationPush(currentLayer, nextLayer) 151 | Utils.delay @animationTime, => 152 | currentLayer.visible = false 153 | @lock = false 154 | @emit(Events.NavigationDidPush, {navigationLayer: @, currentLayer: currentLayer, nextLayer: nextLayer}) 155 | else 156 | # If there was a transitioning going on, just remove the new layer 157 | layer.destroy() 158 | 159 | pop: -> 160 | @popToLayerAtIndex(@currentLayerIndex - 1) 161 | 162 | popToRootLayer: -> 163 | @popToLayerAtIndex(0) 164 | 165 | popToLayerAtIndex: (index) -> 166 | if not @lock 167 | @lock = true 168 | if @currentLayerIndex > 0 and (0 <= index <= @navigationLayers.length) 169 | @emit(Events.NavigationWillPop, {navigationLayer: @, index: index, currentLayer: currentLayer, nextLayer: nextLayer}) 170 | currentLayer = @navigationLayers[@currentLayerIndex] 171 | nextLayer = @navigationLayers[index] 172 | nextLayer.visible = true 173 | if typeof currentLayer.layerWillDisappear is "function" 174 | currentLayer.layerWillDisappear() 175 | if typeof nextLayer.layerWillAppear is "function" 176 | nextLayer.layerWillAppear() 177 | @animationPop(currentLayer, nextLayer) 178 | @_defaultHeaderAnimationPop(currentLayer, nextLayer, index) 179 | Utils.delay @animationTime, => 180 | for indexToBeDeleted in [@navigationLayers.length-1..index+1] 181 | layerToBeDeleted = @navigationLayers[indexToBeDeleted] 182 | layerToBeDeleted.destroy() 183 | @navigationLayers.pop() 184 | @currentLayerIndex = index 185 | @lock = false 186 | @emit(Events.NavigationDidPop, {navigationLayer: @, index: index, currentLayer: currentLayer, nextLayer: nextLayer}) 187 | else 188 | @lock = false 189 | 190 | # Private methods 191 | 192 | _animateHeaderSubLayer: (subLayerName, fromLayer, toLayer, newTitle, currentToX, newFromX) -> 193 | if @headerLayer[subLayerName] 194 | headerSubLayer = @headerLayer[subLayerName] 195 | origSubLayerX = headerSubLayer.x 196 | 197 | # Animate current sublayer 198 | headerSubLayer.animate 199 | properties: 200 | opacity: 0 201 | x: currentToX 202 | curve: _ANIMATION_CURVE 203 | time: _ANIMATION_TIME 204 | 205 | #Create new layer to animate 206 | if newTitle isnt undefined 207 | newHeaderSubLayer = headerSubLayer.copy() 208 | newHeaderSubLayer.style = headerSubLayer.style 209 | @headerLayer.addSubLayer(newHeaderSubLayer) 210 | newHeaderSubLayer.name = "tmp " + subLayerName 211 | newHeaderSubLayer.x = newFromX 212 | newHeaderSubLayer.opacity = 0 213 | newHeaderSubLayer.html = "
" + newTitle + "
" 214 | newHeaderSubLayerAnimation = new Animation 215 | layer: newHeaderSubLayer 216 | properties: 217 | opacity: 1 218 | x: origSubLayerX 219 | curve: _ANIMATION_CURVE 220 | time: _ANIMATION_TIME 221 | newHeaderSubLayerAnimation.start() 222 | newHeaderSubLayerAnimation.on "end", -> 223 | headerSubLayer.html = newHeaderSubLayer.html 224 | headerSubLayer.opacity = 1 225 | headerSubLayer.x = origSubLayerX 226 | newHeaderSubLayer.destroy() 227 | 228 | _defaultHeaderAnimationPush: (fromLayer, toLayer)-> 229 | if @headerLayer and not @customHeader 230 | 231 | @_animateHeaderSubLayer("titleLayer", fromLayer, toLayer, toLayer.title, -_LEFT_PADDING, @headerLayer.width) 232 | 233 | @_animateHeaderSubLayer("leftLayer", fromLayer, toLayer, fromLayer.title, - @headerLayer.width / 2, @headerLayer.width / 2) 234 | 235 | if @headerLayer.backArrow 236 | @headerLayer.backArrow.animate 237 | properties: 238 | opacity: 1 239 | curve: _ANIMATION_CURVE 240 | time: _ANIMATION_TIME 241 | 242 | _defaultHeaderAnimationPop: (fromLayer, toLayer, index)-> 243 | #Animate header 244 | if @headerLayer and not @customHeader 245 | 246 | @_animateHeaderSubLayer("titleLayer", fromLayer, toLayer, toLayer.title, @headerLayer.width, 0) 247 | 248 | newLeftLayerTitle = "" 249 | if @navigationLayers[index - 1] and @navigationLayers[index - 1].title 250 | newLeftLayerTitle = @navigationLayers[index - 1].title 251 | else 252 | if @headerLayer.backArrow 253 | @headerLayer.backArrow.animate 254 | properties: 255 | opacity: 0 256 | curve: _ANIMATION_CURVE 257 | time: _ANIMATION_TIME 258 | @_animateHeaderSubLayer("leftLayer", fromLayer, toLayer, newLeftLayerTitle, @headerLayer.width / 2, -@headerLayer.width / 2) 259 | 260 | 261 | _defaultAnimationPush: (fromLayer, toLayer) -> 262 | shadowLayer = new Layer 263 | superLayer: fromLayer 264 | width: fromLayer.width 265 | height: fromLayer.height 266 | name: "shadowLayer" 267 | backgroundColor: "black" 268 | opacity: 0 269 | shadowLayer.animate 270 | properties: 271 | opacity: 0.2 272 | curve: _ANIMATION_CURVE 273 | time: _ANIMATION_TIME 274 | fromLayer.animate 275 | properties: 276 | x: -@width * 0.25 277 | curve: _ANIMATION_CURVE 278 | time: _ANIMATION_TIME 279 | toLayer.shadowColor = "rgba(0,0,0,0.2)" 280 | toLayer.shadowX = -10 281 | toLayer.shadowBlur = 14 282 | toLayer.x = @width + (-toLayer.shadowX) 283 | toLayer.animate 284 | properties: 285 | x: 0 286 | curve: _ANIMATION_CURVE 287 | time: _ANIMATION_TIME 288 | 289 | 290 | _defaultAnimationPop: (fromLayer, toLayer) -> 291 | fromLayer.animate 292 | properties: 293 | x: @width + (-fromLayer.shadowX) 294 | curve: _ANIMATION_CURVE 295 | time: _ANIMATION_TIME 296 | toLayer.animate 297 | properties: 298 | x: 0 299 | curve: _ANIMATION_CURVE 300 | time: _ANIMATION_TIME 301 | shadowLayer = toLayer.subLayersByName("shadowLayer")[0] 302 | shadowLayerAnimation = new Animation 303 | layer: shadowLayer 304 | properties: 305 | opacity: 0 306 | curve: _ANIMATION_CURVE 307 | time: _ANIMATION_TIME 308 | shadowLayerAnimation.start() 309 | shadowLayerAnimation.on "end", -> 310 | shadowLayer.destroy() 311 | 312 | -------------------------------------------------------------------------------- /navigationComponentComplex.framer/framer/framer.generated.js: -------------------------------------------------------------------------------- 1 | // This is autogenerated by Framer Studio 2 | 3 | 4 | if (typeof(DeviceComponent) !== "undefined") {DeviceComponent.Devices["iphone-6-silver"].deviceImageJP2 = false}; 5 | window.Framer.Defaults.DeviceView = {"deviceScale":-1,"deviceType":"iphone-5s-silver","contentScale":1,"orientation":0}; 6 | 7 | window.Framer.Defaults.DeviceComponent = {"deviceScale":-1,"deviceType":"iphone-5s-silver","contentScale":1,"orientation":0}; 8 | 9 | window.FramerStudioInfo = {"deviceImagesUrl":"\/_server\/resources\/DeviceImages","documentTitle":"navigationComponentComplex.framer"}; 10 | 11 | Framer.Device = new Framer.DeviceView(); 12 | Framer.Device.setupContext(); 13 | (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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o (this.info.height + margin)) { 562 | if (midXPos > canvasFrame.width - ((this.info.width / 2) + margin)) { 563 | this.info.style.textAlign = "right"; 564 | this.info.maxX = Math.min(this.layer.x - margin, canvasFrame.width - margin); 565 | infoOnTopOrBottom = false; 566 | } else if (midXPos < ((this.info.width / 2) + margin)) { 567 | this.info.style.textAlign = "left"; 568 | this.info.x = Math.max(this.layer.maxX + margin, margin); 569 | infoOnTopOrBottom = false; 570 | } 571 | if (!infoOnTopOrBottom) { 572 | this.info.midY = Math.max(Math.min(midYPos, canvasFrame.height - ((this.info.height + margin) - margin)), (this.info.height + margin) - margin); 573 | } 574 | } 575 | if (infoOnTopOrBottom) { 576 | yPos = this.layer.maxY + margin; 577 | if (yPos > canvasFrame.height - (this.info.height + margin)) { 578 | yPos = this.layer.y - (this.info.height + margin); 579 | if (yPos > canvasFrame.height - (this.info.height + margin)) { 580 | yPos = canvasFrame.height - (this.info.height + margin); 581 | } 582 | } else if (yPos < margin) { 583 | yPos = margin; 584 | } 585 | if (midXPos > canvasFrame.width - ((this.info.width / 2) + margin)) { 586 | midXPos = canvasFrame.width - ((this.info.width / 2) + margin); 587 | this.info.style.textAlign = "right"; 588 | } else if (midXPos < ((this.info.width / 2) + margin)) { 589 | midXPos = (this.info.width / 2) + margin; 590 | this.info.style.textAlign = "left"; 591 | } 592 | this.info.midX = midXPos; 593 | this.info.y = yPos; 594 | } 595 | this.info.x = Math.max(margin, this.info.x); 596 | this.info.maxX = Math.min(canvasFrame.width - margin, this.info.maxX); 597 | this.info.y = Math.max(margin, this.info.y); 598 | this.info.maxY = Math.min(canvasFrame.height - margin, this.info.maxY); 599 | return this.info.pixelAlign(); 600 | }; 601 | 602 | return HighlightComponent; 603 | 604 | })(); 605 | 606 | 607 | 608 | },{}],5:[function(require,module,exports){ 609 | var BUILDS, EventEmitter, Runtime, bridge, parseUrl, 610 | bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, 611 | 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; }, 612 | hasProp = {}.hasOwnProperty; 613 | 614 | EventEmitter = require("eventemitter3"); 615 | 616 | bridge = require("./Bridge").bridge; 617 | 618 | BUILDS = 0; 619 | 620 | parseUrl = function(url) { 621 | var parser; 622 | parser = document.createElement("a"); 623 | parser.href = url; 624 | return parser; 625 | }; 626 | 627 | Runtime = (function(superClass) { 628 | extend(Runtime, superClass); 629 | 630 | function Runtime() { 631 | this._errorHandler = bind(this._errorHandler, this); 632 | this.setup(); 633 | } 634 | 635 | Runtime.prototype.setup = function() { 636 | var properties; 637 | if (typeof Framer !== "undefined" && Framer !== null ? Framer.Device : void 0) { 638 | properties = ["deviceScale", "contentScale", "deviceType", "keyboard", "orientation", "fullScreen"]; 639 | properties.map(function(propertyName) { 640 | return Framer.Device.on("change:" + propertyName, function() { 641 | return bridge.send("device:change"); 642 | }); 643 | }); 644 | } 645 | return bridge.send("runtime.init"); 646 | }; 647 | 648 | Runtime.prototype.compile = function(coffeescript) { 649 | var result; 650 | if (this.coffeescript === coffeescript) { 651 | return; 652 | } 653 | console.log("» Framer build " + (BUILDS++)); 654 | this._errorHandlerRemove(); 655 | this.coffeescript = coffeescript; 656 | result = this.uncoffee(this.coffeescript); 657 | this.sourceMap = result.sourceMap; 658 | this.javascript = result.js; 659 | this._errorHandlerSetup(); 660 | return JSON.stringify({ 661 | js: this.javascript 662 | }); 663 | }; 664 | 665 | Runtime.prototype.reset = function() { 666 | return Utils.reset(); 667 | }; 668 | 669 | Runtime.prototype.uncoffee = function(code) { 670 | var compile, error, options, optionsEx, ref, result; 671 | options = { 672 | sourceMap: true, 673 | filename: "app.coffee" 674 | }; 675 | optionsEx = { 676 | returnAST: false, 677 | returnScope: false, 678 | returnGlobals: false, 679 | returnInfo: false, 680 | framerInstanceInfo: true 681 | }; 682 | if (Inferencer.cs2js) { 683 | compile = Inferencer.cs2js; 684 | } else { 685 | compile = CoffeeScript.compile; 686 | } 687 | result = compile(code, options, optionsEx); 688 | if (result.error != null) { 689 | error = new SyntaxError(result.error.message); 690 | error.lineNumber = -1; 691 | if (result.error.location != null) { 692 | error.lineNumber = ((ref = result.error.location) != null ? ref.first_line : void 0) + 1; 693 | } 694 | bridge.sendError(error); 695 | throw new Error("Framer syntax error line " + error.lineNumber + ": " + error.message); 696 | } 697 | return result; 698 | }; 699 | 700 | Runtime.prototype._errorHandler = function(runtimeError) { 701 | var error, errorFromCompiledCoffeeScript, fileName; 702 | errorFromCompiledCoffeeScript = runtimeError.filename === window.location.href; 703 | if (errorFromCompiledCoffeeScript) { 704 | error = new Error(runtimeError.message); 705 | error.lineNumber = this._lookupLine(runtimeError.lineno); 706 | } else { 707 | fileName = _.last(parseUrl(runtimeError.filename).pathname.split("/")); 708 | error = new Error("[" + fileName + "] " + runtimeError.message); 709 | error.lineNumber = -1; 710 | } 711 | console.log("_errorHandler", runtimeError, error); 712 | return bridge.sendError(error); 713 | }; 714 | 715 | Runtime.prototype._errorHandlerSetup = function() { 716 | return window.addEventListener("error", this._errorHandler); 717 | }; 718 | 719 | Runtime.prototype._errorHandlerRemove = function() { 720 | return window.removeEventListener("error", this._errorHandler); 721 | }; 722 | 723 | Runtime.prototype._lookupLine = function(lineNumber) { 724 | var char, charIndex, errorColNumber, errorLine, errorLineIndex, errorLineNumber, i, len, loc, sourceLines; 725 | sourceLines = this.javascript.split("\n"); 726 | errorLineIndex = lineNumber - 1; 727 | errorLine = sourceLines[errorLineIndex]; 728 | if (!errorLine) { 729 | return lineNumber; 730 | } 731 | errorLineNumber = 1; 732 | errorColNumber = 0; 733 | for (charIndex = i = 0, len = errorLine.length; i < len; charIndex = ++i) { 734 | char = errorLine[charIndex]; 735 | loc = this.sourceMap.sourceLocation([errorLineIndex, charIndex]); 736 | if (loc && loc[0] > errorLineNumber) { 737 | errorLineNumber = loc[0] + 1; 738 | errorColNumber = loc[1]; 739 | } 740 | } 741 | return errorLineNumber; 742 | }; 743 | 744 | return Runtime; 745 | 746 | })(EventEmitter); 747 | 748 | exports.runtime = new Runtime(); 749 | 750 | 751 | 752 | },{"./Bridge":2,"eventemitter3":1}],6:[function(require,module,exports){ 753 | var HighlightComponent, getLayerById, setupContext; 754 | 755 | exports.bridge = (require("./Bridge.coffee")).bridge; 756 | 757 | exports.runtime = (require("./Runtime.coffee")).runtime; 758 | 759 | exports.context = require("./Context.coffee"); 760 | 761 | HighlightComponent = require("./HighlightComponent.coffee").HighlightComponent; 762 | 763 | if (window.require == null) { 764 | window.require = function(module) { 765 | throw Error("Module " + module + " can't be found"); 766 | }; 767 | } 768 | 769 | getLayerById = function(id) { 770 | var i, layer, len, ref; 771 | ref = Framer.CurrentContext._layerList; 772 | for (i = 0, len = ref.length; i < len; i++) { 773 | layer = ref[i]; 774 | if (layer.id === id) { 775 | return layer; 776 | } 777 | } 778 | }; 779 | 780 | setupContext = function() { 781 | var context, highlighter, savedProperties; 782 | context = new exports.context.ContextListener(Framer.CurrentContext); 783 | highlighter = new HighlightComponent(); 784 | exports.bridge.on("ui:highlight", function(info) { 785 | return highlighter.highlight(getLayerById(info.id)); 786 | }); 787 | exports.bridge.on("ui:unhighlight", function() { 788 | return highlighter.unhighlight(); 789 | }); 790 | savedProperties = null; 791 | exports.bridge.on("ui:setstate", function(info) { 792 | var layer; 793 | layer = getLayerById(info.id); 794 | if (info.state === "Current") { 795 | return layer.properties = savedProperties; 796 | } else { 797 | savedProperties = layer.properties; 798 | return layer.states.switchInstant(info.state); 799 | } 800 | }); 801 | return exports.bridge.on("ui:updateState", function(info) { 802 | var layer; 803 | layer = getLayerById(info.layerId); 804 | layer[info.propertyName] = info.value; 805 | return layer.states._states[info.stateName][info.propertyName] = info.value; 806 | }); 807 | }; 808 | 809 | if (typeof window !== "undefined" && window !== null) { 810 | window.FramerStudio = exports; 811 | setupContext(); 812 | } 813 | 814 | 815 | 816 | },{"./Bridge.coffee":2,"./Context.coffee":3,"./HighlightComponent.coffee":4,"./Runtime.coffee":5}]},{},[6]) -------------------------------------------------------------------------------- /navigationComponentSimple.framer/framer/framer.generated.js: -------------------------------------------------------------------------------- 1 | // This is autogenerated by Framer Studio 2 | 3 | 4 | if (typeof(DeviceComponent) !== "undefined") {DeviceComponent.Devices["iphone-6-silver"].deviceImageJP2 = false}; 5 | window.Framer.Defaults.DeviceView = {"deviceScale":-1,"deviceType":"iphone-5s-silver","contentScale":1,"orientation":0}; 6 | 7 | window.Framer.Defaults.DeviceComponent = {"deviceScale":-1,"deviceType":"iphone-5s-silver","contentScale":1,"orientation":0}; 8 | 9 | window.FramerStudioInfo = {"deviceImagesUrl":"\/_server\/resources\/DeviceImages","documentTitle":"navigationComponentSimple.framer"}; 10 | 11 | Framer.Device = new Framer.DeviceView(); 12 | Framer.Device.setupContext(); 13 | (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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o (this.info.height + margin)) { 562 | if (midXPos > canvasFrame.width - ((this.info.width / 2) + margin)) { 563 | this.info.style.textAlign = "right"; 564 | this.info.maxX = Math.min(this.layer.x - margin, canvasFrame.width - margin); 565 | infoOnTopOrBottom = false; 566 | } else if (midXPos < ((this.info.width / 2) + margin)) { 567 | this.info.style.textAlign = "left"; 568 | this.info.x = Math.max(this.layer.maxX + margin, margin); 569 | infoOnTopOrBottom = false; 570 | } 571 | if (!infoOnTopOrBottom) { 572 | this.info.midY = Math.max(Math.min(midYPos, canvasFrame.height - ((this.info.height + margin) - margin)), (this.info.height + margin) - margin); 573 | } 574 | } 575 | if (infoOnTopOrBottom) { 576 | yPos = this.layer.maxY + margin; 577 | if (yPos > canvasFrame.height - (this.info.height + margin)) { 578 | yPos = this.layer.y - (this.info.height + margin); 579 | if (yPos > canvasFrame.height - (this.info.height + margin)) { 580 | yPos = canvasFrame.height - (this.info.height + margin); 581 | } 582 | } else if (yPos < margin) { 583 | yPos = margin; 584 | } 585 | if (midXPos > canvasFrame.width - ((this.info.width / 2) + margin)) { 586 | midXPos = canvasFrame.width - ((this.info.width / 2) + margin); 587 | this.info.style.textAlign = "right"; 588 | } else if (midXPos < ((this.info.width / 2) + margin)) { 589 | midXPos = (this.info.width / 2) + margin; 590 | this.info.style.textAlign = "left"; 591 | } 592 | this.info.midX = midXPos; 593 | this.info.y = yPos; 594 | } 595 | this.info.x = Math.max(margin, this.info.x); 596 | this.info.maxX = Math.min(canvasFrame.width - margin, this.info.maxX); 597 | this.info.y = Math.max(margin, this.info.y); 598 | this.info.maxY = Math.min(canvasFrame.height - margin, this.info.maxY); 599 | return this.info.pixelAlign(); 600 | }; 601 | 602 | return HighlightComponent; 603 | 604 | })(); 605 | 606 | 607 | 608 | },{}],5:[function(require,module,exports){ 609 | var BUILDS, EventEmitter, Runtime, bridge, parseUrl, 610 | bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, 611 | 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; }, 612 | hasProp = {}.hasOwnProperty; 613 | 614 | EventEmitter = require("eventemitter3"); 615 | 616 | bridge = require("./Bridge").bridge; 617 | 618 | BUILDS = 0; 619 | 620 | parseUrl = function(url) { 621 | var parser; 622 | parser = document.createElement("a"); 623 | parser.href = url; 624 | return parser; 625 | }; 626 | 627 | Runtime = (function(superClass) { 628 | extend(Runtime, superClass); 629 | 630 | function Runtime() { 631 | this._errorHandler = bind(this._errorHandler, this); 632 | this.setup(); 633 | } 634 | 635 | Runtime.prototype.setup = function() { 636 | var properties; 637 | if (typeof Framer !== "undefined" && Framer !== null ? Framer.Device : void 0) { 638 | properties = ["deviceScale", "contentScale", "deviceType", "keyboard", "orientation", "fullScreen"]; 639 | properties.map(function(propertyName) { 640 | return Framer.Device.on("change:" + propertyName, function() { 641 | return bridge.send("device:change"); 642 | }); 643 | }); 644 | } 645 | return bridge.send("runtime.init"); 646 | }; 647 | 648 | Runtime.prototype.compile = function(coffeescript) { 649 | var result; 650 | if (this.coffeescript === coffeescript) { 651 | return; 652 | } 653 | console.log("» Framer build " + (BUILDS++)); 654 | this._errorHandlerRemove(); 655 | this.coffeescript = coffeescript; 656 | result = this.uncoffee(this.coffeescript); 657 | this.sourceMap = result.sourceMap; 658 | this.javascript = result.js; 659 | this._errorHandlerSetup(); 660 | return JSON.stringify({ 661 | js: this.javascript 662 | }); 663 | }; 664 | 665 | Runtime.prototype.reset = function() { 666 | return Utils.reset(); 667 | }; 668 | 669 | Runtime.prototype.uncoffee = function(code) { 670 | var compile, error, options, optionsEx, ref, result; 671 | options = { 672 | sourceMap: true, 673 | filename: "app.coffee" 674 | }; 675 | optionsEx = { 676 | returnAST: false, 677 | returnScope: false, 678 | returnGlobals: false, 679 | returnInfo: false, 680 | framerInstanceInfo: true 681 | }; 682 | if (Inferencer.cs2js) { 683 | compile = Inferencer.cs2js; 684 | } else { 685 | compile = CoffeeScript.compile; 686 | } 687 | result = compile(code, options, optionsEx); 688 | if (result.error != null) { 689 | error = new SyntaxError(result.error.message); 690 | error.lineNumber = -1; 691 | if (result.error.location != null) { 692 | error.lineNumber = ((ref = result.error.location) != null ? ref.first_line : void 0) + 1; 693 | } 694 | bridge.sendError(error); 695 | throw new Error("Framer syntax error line " + error.lineNumber + ": " + error.message); 696 | } 697 | return result; 698 | }; 699 | 700 | Runtime.prototype._errorHandler = function(runtimeError) { 701 | var error, errorFromCompiledCoffeeScript, fileName; 702 | errorFromCompiledCoffeeScript = runtimeError.filename === window.location.href; 703 | if (errorFromCompiledCoffeeScript) { 704 | error = new Error(runtimeError.message); 705 | error.lineNumber = this._lookupLine(runtimeError.lineno); 706 | } else { 707 | fileName = _.last(parseUrl(runtimeError.filename).pathname.split("/")); 708 | error = new Error("[" + fileName + "] " + runtimeError.message); 709 | error.lineNumber = -1; 710 | } 711 | console.log("_errorHandler", runtimeError, error); 712 | return bridge.sendError(error); 713 | }; 714 | 715 | Runtime.prototype._errorHandlerSetup = function() { 716 | return window.addEventListener("error", this._errorHandler); 717 | }; 718 | 719 | Runtime.prototype._errorHandlerRemove = function() { 720 | return window.removeEventListener("error", this._errorHandler); 721 | }; 722 | 723 | Runtime.prototype._lookupLine = function(lineNumber) { 724 | var char, charIndex, errorColNumber, errorLine, errorLineIndex, errorLineNumber, i, len, loc, sourceLines; 725 | sourceLines = this.javascript.split("\n"); 726 | errorLineIndex = lineNumber - 1; 727 | errorLine = sourceLines[errorLineIndex]; 728 | if (!errorLine) { 729 | return lineNumber; 730 | } 731 | errorLineNumber = 1; 732 | errorColNumber = 0; 733 | for (charIndex = i = 0, len = errorLine.length; i < len; charIndex = ++i) { 734 | char = errorLine[charIndex]; 735 | loc = this.sourceMap.sourceLocation([errorLineIndex, charIndex]); 736 | if (loc && loc[0] > errorLineNumber) { 737 | errorLineNumber = loc[0] + 1; 738 | errorColNumber = loc[1]; 739 | } 740 | } 741 | return errorLineNumber; 742 | }; 743 | 744 | return Runtime; 745 | 746 | })(EventEmitter); 747 | 748 | exports.runtime = new Runtime(); 749 | 750 | 751 | 752 | },{"./Bridge":2,"eventemitter3":1}],6:[function(require,module,exports){ 753 | var HighlightComponent, getLayerById, setupContext; 754 | 755 | exports.bridge = (require("./Bridge.coffee")).bridge; 756 | 757 | exports.runtime = (require("./Runtime.coffee")).runtime; 758 | 759 | exports.context = require("./Context.coffee"); 760 | 761 | HighlightComponent = require("./HighlightComponent.coffee").HighlightComponent; 762 | 763 | if (window.require == null) { 764 | window.require = function(module) { 765 | throw Error("Module " + module + " can't be found"); 766 | }; 767 | } 768 | 769 | getLayerById = function(id) { 770 | var i, layer, len, ref; 771 | ref = Framer.CurrentContext._layerList; 772 | for (i = 0, len = ref.length; i < len; i++) { 773 | layer = ref[i]; 774 | if (layer.id === id) { 775 | return layer; 776 | } 777 | } 778 | }; 779 | 780 | setupContext = function() { 781 | var context, highlighter, savedProperties; 782 | context = new exports.context.ContextListener(Framer.CurrentContext); 783 | highlighter = new HighlightComponent(); 784 | exports.bridge.on("ui:highlight", function(info) { 785 | return highlighter.highlight(getLayerById(info.id)); 786 | }); 787 | exports.bridge.on("ui:unhighlight", function() { 788 | return highlighter.unhighlight(); 789 | }); 790 | savedProperties = null; 791 | exports.bridge.on("ui:setstate", function(info) { 792 | var layer; 793 | layer = getLayerById(info.id); 794 | if (info.state === "Current") { 795 | return layer.properties = savedProperties; 796 | } else { 797 | savedProperties = layer.properties; 798 | return layer.states.switchInstant(info.state); 799 | } 800 | }); 801 | return exports.bridge.on("ui:updateState", function(info) { 802 | var layer; 803 | layer = getLayerById(info.layerId); 804 | layer[info.propertyName] = info.value; 805 | return layer.states._states[info.stateName][info.propertyName] = info.value; 806 | }); 807 | }; 808 | 809 | if (typeof window !== "undefined" && window !== null) { 810 | window.FramerStudio = exports; 811 | setupContext(); 812 | } 813 | 814 | 815 | 816 | },{"./Bridge.coffee":2,"./Context.coffee":3,"./HighlightComponent.coffee":4,"./Runtime.coffee":5}]},{},[6]) -------------------------------------------------------------------------------- /navigationComponentCustomHeader.framer/framer/framer.generated.js: -------------------------------------------------------------------------------- 1 | // This is autogenerated by Framer Studio 2 | 3 | 4 | if (typeof(DeviceComponent) !== "undefined") {DeviceComponent.Devices["iphone-6-silver"].deviceImageJP2 = false}; 5 | window.Framer.Defaults.DeviceView = {"deviceScale":-1,"deviceType":"iphone-5s-silver","contentScale":1,"orientation":0}; 6 | 7 | window.Framer.Defaults.DeviceComponent = {"deviceScale":-1,"deviceType":"iphone-5s-silver","contentScale":1,"orientation":0}; 8 | 9 | window.FramerStudioInfo = {"deviceImagesUrl":"\/_server\/resources\/DeviceImages","documentTitle":"navigationComponentCustomHeader.framer"}; 10 | 11 | Framer.Device = new Framer.DeviceView(); 12 | Framer.Device.setupContext(); 13 | (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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o (this.info.height + margin)) { 562 | if (midXPos > canvasFrame.width - ((this.info.width / 2) + margin)) { 563 | this.info.style.textAlign = "right"; 564 | this.info.maxX = Math.min(this.layer.x - margin, canvasFrame.width - margin); 565 | infoOnTopOrBottom = false; 566 | } else if (midXPos < ((this.info.width / 2) + margin)) { 567 | this.info.style.textAlign = "left"; 568 | this.info.x = Math.max(this.layer.maxX + margin, margin); 569 | infoOnTopOrBottom = false; 570 | } 571 | if (!infoOnTopOrBottom) { 572 | this.info.midY = Math.max(Math.min(midYPos, canvasFrame.height - ((this.info.height + margin) - margin)), (this.info.height + margin) - margin); 573 | } 574 | } 575 | if (infoOnTopOrBottom) { 576 | yPos = this.layer.maxY + margin; 577 | if (yPos > canvasFrame.height - (this.info.height + margin)) { 578 | yPos = this.layer.y - (this.info.height + margin); 579 | if (yPos > canvasFrame.height - (this.info.height + margin)) { 580 | yPos = canvasFrame.height - (this.info.height + margin); 581 | } 582 | } else if (yPos < margin) { 583 | yPos = margin; 584 | } 585 | if (midXPos > canvasFrame.width - ((this.info.width / 2) + margin)) { 586 | midXPos = canvasFrame.width - ((this.info.width / 2) + margin); 587 | this.info.style.textAlign = "right"; 588 | } else if (midXPos < ((this.info.width / 2) + margin)) { 589 | midXPos = (this.info.width / 2) + margin; 590 | this.info.style.textAlign = "left"; 591 | } 592 | this.info.midX = midXPos; 593 | this.info.y = yPos; 594 | } 595 | this.info.x = Math.max(margin, this.info.x); 596 | this.info.maxX = Math.min(canvasFrame.width - margin, this.info.maxX); 597 | this.info.y = Math.max(margin, this.info.y); 598 | this.info.maxY = Math.min(canvasFrame.height - margin, this.info.maxY); 599 | return this.info.pixelAlign(); 600 | }; 601 | 602 | return HighlightComponent; 603 | 604 | })(); 605 | 606 | 607 | 608 | },{}],5:[function(require,module,exports){ 609 | var BUILDS, EventEmitter, Runtime, bridge, parseUrl, 610 | bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, 611 | 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; }, 612 | hasProp = {}.hasOwnProperty; 613 | 614 | EventEmitter = require("eventemitter3"); 615 | 616 | bridge = require("./Bridge").bridge; 617 | 618 | BUILDS = 0; 619 | 620 | parseUrl = function(url) { 621 | var parser; 622 | parser = document.createElement("a"); 623 | parser.href = url; 624 | return parser; 625 | }; 626 | 627 | Runtime = (function(superClass) { 628 | extend(Runtime, superClass); 629 | 630 | function Runtime() { 631 | this._errorHandler = bind(this._errorHandler, this); 632 | this.setup(); 633 | } 634 | 635 | Runtime.prototype.setup = function() { 636 | var properties; 637 | if (typeof Framer !== "undefined" && Framer !== null ? Framer.Device : void 0) { 638 | properties = ["deviceScale", "contentScale", "deviceType", "keyboard", "orientation", "fullScreen"]; 639 | properties.map(function(propertyName) { 640 | return Framer.Device.on("change:" + propertyName, function() { 641 | return bridge.send("device:change"); 642 | }); 643 | }); 644 | } 645 | return bridge.send("runtime.init"); 646 | }; 647 | 648 | Runtime.prototype.compile = function(coffeescript) { 649 | var result; 650 | if (this.coffeescript === coffeescript) { 651 | return; 652 | } 653 | console.log("» Framer build " + (BUILDS++)); 654 | this._errorHandlerRemove(); 655 | this.coffeescript = coffeescript; 656 | result = this.uncoffee(this.coffeescript); 657 | this.sourceMap = result.sourceMap; 658 | this.javascript = result.js; 659 | this._errorHandlerSetup(); 660 | return JSON.stringify({ 661 | js: this.javascript 662 | }); 663 | }; 664 | 665 | Runtime.prototype.reset = function() { 666 | return Utils.reset(); 667 | }; 668 | 669 | Runtime.prototype.uncoffee = function(code) { 670 | var compile, error, options, optionsEx, ref, result; 671 | options = { 672 | sourceMap: true, 673 | filename: "app.coffee" 674 | }; 675 | optionsEx = { 676 | returnAST: false, 677 | returnScope: false, 678 | returnGlobals: false, 679 | returnInfo: false, 680 | framerInstanceInfo: true 681 | }; 682 | if (Inferencer.cs2js) { 683 | compile = Inferencer.cs2js; 684 | } else { 685 | compile = CoffeeScript.compile; 686 | } 687 | result = compile(code, options, optionsEx); 688 | if (result.error != null) { 689 | error = new SyntaxError(result.error.message); 690 | error.lineNumber = -1; 691 | if (result.error.location != null) { 692 | error.lineNumber = ((ref = result.error.location) != null ? ref.first_line : void 0) + 1; 693 | } 694 | bridge.sendError(error); 695 | throw new Error("Framer syntax error line " + error.lineNumber + ": " + error.message); 696 | } 697 | return result; 698 | }; 699 | 700 | Runtime.prototype._errorHandler = function(runtimeError) { 701 | var error, errorFromCompiledCoffeeScript, fileName; 702 | errorFromCompiledCoffeeScript = runtimeError.filename === window.location.href; 703 | if (errorFromCompiledCoffeeScript) { 704 | error = new Error(runtimeError.message); 705 | error.lineNumber = this._lookupLine(runtimeError.lineno); 706 | } else { 707 | fileName = _.last(parseUrl(runtimeError.filename).pathname.split("/")); 708 | error = new Error("[" + fileName + "] " + runtimeError.message); 709 | error.lineNumber = -1; 710 | } 711 | console.log("_errorHandler", runtimeError, error); 712 | return bridge.sendError(error); 713 | }; 714 | 715 | Runtime.prototype._errorHandlerSetup = function() { 716 | return window.addEventListener("error", this._errorHandler); 717 | }; 718 | 719 | Runtime.prototype._errorHandlerRemove = function() { 720 | return window.removeEventListener("error", this._errorHandler); 721 | }; 722 | 723 | Runtime.prototype._lookupLine = function(lineNumber) { 724 | var char, charIndex, errorColNumber, errorLine, errorLineIndex, errorLineNumber, i, len, loc, sourceLines; 725 | sourceLines = this.javascript.split("\n"); 726 | errorLineIndex = lineNumber - 1; 727 | errorLine = sourceLines[errorLineIndex]; 728 | if (!errorLine) { 729 | return lineNumber; 730 | } 731 | errorLineNumber = 1; 732 | errorColNumber = 0; 733 | for (charIndex = i = 0, len = errorLine.length; i < len; charIndex = ++i) { 734 | char = errorLine[charIndex]; 735 | loc = this.sourceMap.sourceLocation([errorLineIndex, charIndex]); 736 | if (loc && loc[0] > errorLineNumber) { 737 | errorLineNumber = loc[0] + 1; 738 | errorColNumber = loc[1]; 739 | } 740 | } 741 | return errorLineNumber; 742 | }; 743 | 744 | return Runtime; 745 | 746 | })(EventEmitter); 747 | 748 | exports.runtime = new Runtime(); 749 | 750 | 751 | 752 | },{"./Bridge":2,"eventemitter3":1}],6:[function(require,module,exports){ 753 | var HighlightComponent, getLayerById, setupContext; 754 | 755 | exports.bridge = (require("./Bridge.coffee")).bridge; 756 | 757 | exports.runtime = (require("./Runtime.coffee")).runtime; 758 | 759 | exports.context = require("./Context.coffee"); 760 | 761 | HighlightComponent = require("./HighlightComponent.coffee").HighlightComponent; 762 | 763 | if (window.require == null) { 764 | window.require = function(module) { 765 | throw Error("Module " + module + " can't be found"); 766 | }; 767 | } 768 | 769 | getLayerById = function(id) { 770 | var i, layer, len, ref; 771 | ref = Framer.CurrentContext._layerList; 772 | for (i = 0, len = ref.length; i < len; i++) { 773 | layer = ref[i]; 774 | if (layer.id === id) { 775 | return layer; 776 | } 777 | } 778 | }; 779 | 780 | setupContext = function() { 781 | var context, highlighter, savedProperties; 782 | context = new exports.context.ContextListener(Framer.CurrentContext); 783 | highlighter = new HighlightComponent(); 784 | exports.bridge.on("ui:highlight", function(info) { 785 | return highlighter.highlight(getLayerById(info.id)); 786 | }); 787 | exports.bridge.on("ui:unhighlight", function() { 788 | return highlighter.unhighlight(); 789 | }); 790 | savedProperties = null; 791 | exports.bridge.on("ui:setstate", function(info) { 792 | var layer; 793 | layer = getLayerById(info.id); 794 | if (info.state === "Current") { 795 | return layer.properties = savedProperties; 796 | } else { 797 | savedProperties = layer.properties; 798 | return layer.states.switchInstant(info.state); 799 | } 800 | }); 801 | return exports.bridge.on("ui:updateState", function(info) { 802 | var layer; 803 | layer = getLayerById(info.layerId); 804 | layer[info.propertyName] = info.value; 805 | return layer.states._states[info.stateName][info.propertyName] = info.value; 806 | }); 807 | }; 808 | 809 | if (typeof window !== "undefined" && window !== null) { 810 | window.FramerStudio = exports; 811 | setupContext(); 812 | } 813 | 814 | 815 | 816 | },{"./Bridge.coffee":2,"./Context.coffee":3,"./HighlightComponent.coffee":4,"./Runtime.coffee":5}]},{},[6]) -------------------------------------------------------------------------------- /navigationComponentCustomAnimation.framer/framer/framer.generated.js: -------------------------------------------------------------------------------- 1 | // This is autogenerated by Framer Studio 2 | 3 | 4 | if (typeof(DeviceComponent) !== "undefined") {DeviceComponent.Devices["iphone-6-silver"].deviceImageJP2 = false}; 5 | window.Framer.Defaults.DeviceView = {"deviceScale":-1,"deviceType":"iphone-6-silver","contentScale":1,"orientation":0}; 6 | 7 | window.Framer.Defaults.DeviceComponent = {"deviceScale":-1,"deviceType":"iphone-6-silver","contentScale":1,"orientation":0}; 8 | 9 | window.FramerStudioInfo = {"deviceImagesUrl":"\/_server\/resources\/DeviceImages","documentTitle":"navigationComponentCustomAnimation.framer"}; 10 | 11 | Framer.Device = new Framer.DeviceView(); 12 | Framer.Device.setupContext(); 13 | (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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o (this.info.height + margin)) { 562 | if (midXPos > canvasFrame.width - ((this.info.width / 2) + margin)) { 563 | this.info.style.textAlign = "right"; 564 | this.info.maxX = Math.min(this.layer.x - margin, canvasFrame.width - margin); 565 | infoOnTopOrBottom = false; 566 | } else if (midXPos < ((this.info.width / 2) + margin)) { 567 | this.info.style.textAlign = "left"; 568 | this.info.x = Math.max(this.layer.maxX + margin, margin); 569 | infoOnTopOrBottom = false; 570 | } 571 | if (!infoOnTopOrBottom) { 572 | this.info.midY = Math.max(Math.min(midYPos, canvasFrame.height - ((this.info.height + margin) - margin)), (this.info.height + margin) - margin); 573 | } 574 | } 575 | if (infoOnTopOrBottom) { 576 | yPos = this.layer.maxY + margin; 577 | if (yPos > canvasFrame.height - (this.info.height + margin)) { 578 | yPos = this.layer.y - (this.info.height + margin); 579 | if (yPos > canvasFrame.height - (this.info.height + margin)) { 580 | yPos = canvasFrame.height - (this.info.height + margin); 581 | } 582 | } else if (yPos < margin) { 583 | yPos = margin; 584 | } 585 | if (midXPos > canvasFrame.width - ((this.info.width / 2) + margin)) { 586 | midXPos = canvasFrame.width - ((this.info.width / 2) + margin); 587 | this.info.style.textAlign = "right"; 588 | } else if (midXPos < ((this.info.width / 2) + margin)) { 589 | midXPos = (this.info.width / 2) + margin; 590 | this.info.style.textAlign = "left"; 591 | } 592 | this.info.midX = midXPos; 593 | this.info.y = yPos; 594 | } 595 | this.info.x = Math.max(margin, this.info.x); 596 | this.info.maxX = Math.min(canvasFrame.width - margin, this.info.maxX); 597 | this.info.y = Math.max(margin, this.info.y); 598 | this.info.maxY = Math.min(canvasFrame.height - margin, this.info.maxY); 599 | return this.info.pixelAlign(); 600 | }; 601 | 602 | return HighlightComponent; 603 | 604 | })(); 605 | 606 | 607 | 608 | },{}],5:[function(require,module,exports){ 609 | var BUILDS, EventEmitter, Runtime, bridge, parseUrl, 610 | bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, 611 | 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; }, 612 | hasProp = {}.hasOwnProperty; 613 | 614 | EventEmitter = require("eventemitter3"); 615 | 616 | bridge = require("./Bridge").bridge; 617 | 618 | BUILDS = 0; 619 | 620 | parseUrl = function(url) { 621 | var parser; 622 | parser = document.createElement("a"); 623 | parser.href = url; 624 | return parser; 625 | }; 626 | 627 | Runtime = (function(superClass) { 628 | extend(Runtime, superClass); 629 | 630 | function Runtime() { 631 | this._errorHandler = bind(this._errorHandler, this); 632 | this.setup(); 633 | } 634 | 635 | Runtime.prototype.setup = function() { 636 | var properties; 637 | if (typeof Framer !== "undefined" && Framer !== null ? Framer.Device : void 0) { 638 | properties = ["deviceScale", "contentScale", "deviceType", "keyboard", "orientation", "fullScreen"]; 639 | properties.map(function(propertyName) { 640 | return Framer.Device.on("change:" + propertyName, function() { 641 | return bridge.send("device:change"); 642 | }); 643 | }); 644 | } 645 | return bridge.send("runtime.init"); 646 | }; 647 | 648 | Runtime.prototype.compile = function(coffeescript) { 649 | var result; 650 | if (this.coffeescript === coffeescript) { 651 | return; 652 | } 653 | console.log("» Framer build " + (BUILDS++)); 654 | this._errorHandlerRemove(); 655 | this.coffeescript = coffeescript; 656 | result = this.uncoffee(this.coffeescript); 657 | this.sourceMap = result.sourceMap; 658 | this.javascript = result.js; 659 | this._errorHandlerSetup(); 660 | return JSON.stringify({ 661 | js: this.javascript 662 | }); 663 | }; 664 | 665 | Runtime.prototype.reset = function() { 666 | return Utils.reset(); 667 | }; 668 | 669 | Runtime.prototype.uncoffee = function(code) { 670 | var compile, error, options, optionsEx, ref, result; 671 | options = { 672 | sourceMap: true, 673 | filename: "app.coffee" 674 | }; 675 | optionsEx = { 676 | returnAST: false, 677 | returnScope: false, 678 | returnGlobals: false, 679 | returnInfo: false, 680 | framerInstanceInfo: true 681 | }; 682 | if (Inferencer.cs2js) { 683 | compile = Inferencer.cs2js; 684 | } else { 685 | compile = CoffeeScript.compile; 686 | } 687 | result = compile(code, options, optionsEx); 688 | if (result.error != null) { 689 | error = new SyntaxError(result.error.message); 690 | error.lineNumber = -1; 691 | if (result.error.location != null) { 692 | error.lineNumber = ((ref = result.error.location) != null ? ref.first_line : void 0) + 1; 693 | } 694 | bridge.sendError(error); 695 | throw new Error("Framer syntax error line " + error.lineNumber + ": " + error.message); 696 | } 697 | return result; 698 | }; 699 | 700 | Runtime.prototype._errorHandler = function(runtimeError) { 701 | var error, errorFromCompiledCoffeeScript, fileName; 702 | errorFromCompiledCoffeeScript = runtimeError.filename === window.location.href; 703 | if (errorFromCompiledCoffeeScript) { 704 | error = new Error(runtimeError.message); 705 | error.lineNumber = this._lookupLine(runtimeError.lineno); 706 | } else { 707 | fileName = _.last(parseUrl(runtimeError.filename).pathname.split("/")); 708 | error = new Error("[" + fileName + "] " + runtimeError.message); 709 | error.lineNumber = -1; 710 | } 711 | console.log("_errorHandler", runtimeError, error); 712 | return bridge.sendError(error); 713 | }; 714 | 715 | Runtime.prototype._errorHandlerSetup = function() { 716 | return window.addEventListener("error", this._errorHandler); 717 | }; 718 | 719 | Runtime.prototype._errorHandlerRemove = function() { 720 | return window.removeEventListener("error", this._errorHandler); 721 | }; 722 | 723 | Runtime.prototype._lookupLine = function(lineNumber) { 724 | var char, charIndex, errorColNumber, errorLine, errorLineIndex, errorLineNumber, i, len, loc, sourceLines; 725 | sourceLines = this.javascript.split("\n"); 726 | errorLineIndex = lineNumber - 1; 727 | errorLine = sourceLines[errorLineIndex]; 728 | if (!errorLine) { 729 | return lineNumber; 730 | } 731 | errorLineNumber = 1; 732 | errorColNumber = 0; 733 | for (charIndex = i = 0, len = errorLine.length; i < len; charIndex = ++i) { 734 | char = errorLine[charIndex]; 735 | loc = this.sourceMap.sourceLocation([errorLineIndex, charIndex]); 736 | if (loc && loc[0] > errorLineNumber) { 737 | errorLineNumber = loc[0] + 1; 738 | errorColNumber = loc[1]; 739 | } 740 | } 741 | return errorLineNumber; 742 | }; 743 | 744 | return Runtime; 745 | 746 | })(EventEmitter); 747 | 748 | exports.runtime = new Runtime(); 749 | 750 | 751 | 752 | },{"./Bridge":2,"eventemitter3":1}],6:[function(require,module,exports){ 753 | var HighlightComponent, getLayerById, setupContext; 754 | 755 | exports.bridge = (require("./Bridge.coffee")).bridge; 756 | 757 | exports.runtime = (require("./Runtime.coffee")).runtime; 758 | 759 | exports.context = require("./Context.coffee"); 760 | 761 | HighlightComponent = require("./HighlightComponent.coffee").HighlightComponent; 762 | 763 | if (window.require == null) { 764 | window.require = function(module) { 765 | throw Error("Module " + module + " can't be found"); 766 | }; 767 | } 768 | 769 | getLayerById = function(id) { 770 | var i, layer, len, ref; 771 | ref = Framer.CurrentContext._layerList; 772 | for (i = 0, len = ref.length; i < len; i++) { 773 | layer = ref[i]; 774 | if (layer.id === id) { 775 | return layer; 776 | } 777 | } 778 | }; 779 | 780 | setupContext = function() { 781 | var context, highlighter, savedProperties; 782 | context = new exports.context.ContextListener(Framer.CurrentContext); 783 | highlighter = new HighlightComponent(); 784 | exports.bridge.on("ui:highlight", function(info) { 785 | return highlighter.highlight(getLayerById(info.id)); 786 | }); 787 | exports.bridge.on("ui:unhighlight", function() { 788 | return highlighter.unhighlight(); 789 | }); 790 | savedProperties = null; 791 | exports.bridge.on("ui:setstate", function(info) { 792 | var layer; 793 | layer = getLayerById(info.id); 794 | if (info.state === "Current") { 795 | return layer.properties = savedProperties; 796 | } else { 797 | savedProperties = layer.properties; 798 | return layer.states.switchInstant(info.state); 799 | } 800 | }); 801 | return exports.bridge.on("ui:updateState", function(info) { 802 | var layer; 803 | layer = getLayerById(info.layerId); 804 | layer[info.propertyName] = info.value; 805 | return layer.states._states[info.stateName][info.propertyName] = info.value; 806 | }); 807 | }; 808 | 809 | if (typeof window !== "undefined" && window !== null) { 810 | window.FramerStudio = exports; 811 | setupContext(); 812 | } 813 | 814 | 815 | 816 | },{"./Bridge.coffee":2,"./Context.coffee":3,"./HighlightComponent.coffee":4,"./Runtime.coffee":5}]},{},[6]) --------------------------------------------------------------------------------