├── README.md ├── StickyHeaders.coffee ├── example.coffee ├── module.json └── thumb.gif /README.md: -------------------------------------------------------------------------------- 1 | # Sticky headers for Framer 2 | A Framer module to enable sticky headers within scroll components. 3 | 4 | 5 | Install with Framer Modules 7 | 8 | 9 | ## Examples 10 | - [Demo 1](https://framer.cloud/peGYM/) 11 | - [Demo 2](https://framer.cloud/bgIIg/) 12 | 13 | ## Installation 14 | 15 | 1. Download `StickyHeaders.coffee` and put it in your `modules` folder. 16 | 2. Add this line at the top of your document. 17 | ```coffeescript 18 | {StickyHeaders} = require "StickyHeaders" 19 | ``` 20 | 21 | ## How to use 22 | 23 | ***Guide*** 24 | 25 | Demo 1 and Demo 2 show a list of conference talks grouped by their starting time. The headers for each group are sticky headers. 26 | 27 | 1 - Import the module. 28 | ```coffeescript 29 | {StickyHeaders} = require "StickyHeaders" 30 | ``` 31 | 32 | 33 | 2 - Create a Scroll Component as you normally do. 34 | ```coffeescript 35 | conferenceTalks = new ScrollComponent 36 | width: Screen.width 37 | height: Screen.height 38 | scrollHorizontal: false 39 | ``` 40 | 41 | 42 | 3 - Create the headers. **Set their parent to be the Scroll Component, and their name to be 'StickyHeader'**. 43 | ```coffeescript 44 | header1 = new Layer 45 | y: 175, width: Screen.width, height: 140 46 | name: 'StickyHeader' 47 | parent: conferenceTalks.content 48 | ``` 49 | Since this is a `Layer` as any other, you can use it as a parent and nest inside anything you need. 50 | 51 | 52 | 4 - Enable the module for your scroll component. 53 | ```coffeescript 54 | StickyHeaders.enableFor(conferenceTalks) 55 | ``` 56 | 57 | 58 | Optional - You can pass a second parameter to set a custom top margin for the sticky headers. By default the value is 0. 59 | ```coffeescript 60 | StickyHeaders.enableFor(conferenceTalks, 100) 61 | ``` 62 | 63 | 64 | ## Planning your prototype 65 | Make sure to plan ahead what you need to show in your prototype. My workflow is: 66 | - Design the view/list in Sketch or PS. 67 | - Export the list as a .png **without** the headers. 68 | - Export each header apart from the list. 69 | - Create the scroll component in Framer and then the layers for each header. 70 | 71 | [Medium - Unlocking ideas with Framer Studio](https://medium.com/@72mena/unlocking-ideas-with-framer-studio-790b5e9c249f) - This module has changed a lot from my initial exploration described in this article, but the recommendations I shared still hold. Give it a read if you have a chance. 72 | 73 | I hope this module saves you some time on your projects. 74 | 75 | ## Contact 76 | Twitter: [@72mena](http://twitter.com/72mena) 77 | -------------------------------------------------------------------------------- /StickyHeaders.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | StickyHeaders for Framer 3 | By @72mena 4 | ### 5 | class exports.StickyHeaders 6 | 7 | @enableFor: (scrollComponent, topMargin) -> 8 | 9 | dataSH = [] 10 | topMargin ?= 0 11 | 12 | # Check for sticky headers. 13 | stickyHeaders = scrollComponent.content.childrenWithName("StickyHeader") 14 | if stickyHeaders.length > 0 15 | for header in stickyHeaders 16 | dataSH.push(header.y) 17 | 18 | # Scroll logic. I'm using 'change:y' instead of 'onMove' to detect animations and mousewheel. 19 | scrollComponent.content.on "change:y", -> 20 | for header, i in stickyHeaders 21 | header.y = dataSH[i] 22 | currentY = dataSH[i] - scrollComponent.scrollY 23 | 24 | if i > 0 25 | prevStickyPosition = dataSH[i] - stickyHeaders[i-1].height 26 | prevMaxY = stickyHeaders[i-1].height + topMargin 27 | 28 | if currentY < prevMaxY 29 | stickyHeaders[i-1].y = prevStickyPosition 30 | 31 | if currentY <= topMargin 32 | header.y = scrollComponent.scrollY + topMargin -------------------------------------------------------------------------------- /example.coffee: -------------------------------------------------------------------------------- 1 | # Create the scroll component 2 | mainScroll = new ScrollComponent 3 | width: Screen.width 4 | height: Screen.height 5 | scrollHorizontal: false 6 | backgroundColor: 'white' 7 | 8 | # Create Headers and add them to the scroll component 9 | header1 = new Layer 10 | name: 'StickyHeader' 11 | html: '1' 12 | y: 175, width: Screen.width, height: 120 13 | backgroundColor: '#1E88E5' 14 | parent: mainScroll.content 15 | 16 | header2 = new Layer 17 | name: 'StickyHeader' 18 | html: '2' 19 | y: 1000, width: Screen.width, height: 95 20 | backgroundColor: '#AA00AA' 21 | parent: mainScroll.content 22 | 23 | header3 = new Layer 24 | name: 'StickyHeader' 25 | html: '3' 26 | y: 1775, width: Screen.width, height: 120 27 | backgroundColor: '#3949AB' 28 | parent: mainScroll.content 29 | 30 | header4 = new Layer 31 | name: 'StickyHeader' 32 | html: '4' 33 | y: 3475, width: Screen.width, height: 120 34 | backgroundColor: 'pink' 35 | parent: mainScroll.content 36 | 37 | # Enable StickyHeaders for your scroll component 38 | StickyHeaders.enableFor(mainScroll) -------------------------------------------------------------------------------- /module.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Sticky Headers", 3 | "description": "A module to add sticky headers to your scroll components", 4 | "author": "Juan F. Mena", 5 | 6 | "require": "{StickyHeaders} = require 'StickyHeaders'", 7 | "install": "StickyHeaders.coffee", 8 | "example": "example.coffee", 9 | 10 | "thumb": "thumb.gif" 11 | } -------------------------------------------------------------------------------- /thumb.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/72/StickyHeaders-for-Framer/b59241c3b91c025864f6491bc7e609406a1929f5/thumb.gif --------------------------------------------------------------------------------