The Illustrated Framer Docs
Source: https://framer.com/docs/
Table of Contents
001 demo
options [5]
layerA = new Layer Align y: Align.bottom() x and y: Align.center() x: Align.left() x: Align.right() y: Align.top() Offset y: Align.bottom(-50) x and y: Align.center(50) x: Align.left(50) x: Align.right(-50) y: Align.top(50)
001 demo
options [8]
↗️ animationA.start() animationC = animationA.reverse() options: curve: Bezier(0.25, 0.1, 0.25, 1) Animatable Properties x, y, z minX, midX, maxX minY, midY, maxY width, height opacity rotation, rotationX, rotationY, rotationZ scale scaleX, scaleY, scaleZ originX, originY, perspective scrollX, scrollY borderRadius, borderWidth shadowX, shadowY, shadowBlur, shadowSpread blur, brightness, saturate hueRotate, contrast, invert, grayscale, sepia Not Shown animation.stop() animation.reset() animation.restart() animation.finish()
003 demo
options [0]
bg = new BackgroundLayer Note: backgroundLayer is overridden by an artboard If it has a parent, it will inherit the size of the parent
004 demo
options [10]
Note: Canvas only works when viewing 📱 🍇 Canvas.backgroundColor = "#862e9c" Canvas.image = "bg-canvas.png" 📏 - Read Only Values Canvas.width Canvas.height Canvas.size Canvas.frame Not Shown Canvas.convertPointToScreen(point) Canvas.convertPointToLayer(point, layer)
005 demo
options [16]
🎨 📱 violet = new Color("rgba(95, 61, 196, 1)") violet2 = new Color(violet).saturate(80) (default 10) violet3 = new Color(violet).desaturate(80) (default 10) violet4 = new Color(violet).darken(20) violet5 = new Color(violet).lighten(100) (default 10) ☑️ violet6 = violet.grayscale() violet7 = Color.gray(0.5) 🔮 violet8 = violet.alpha(0.4) violet9 = Color.mix(violet, violet4, 0.2) violet10 = Color.random() Not Shown 🖨️ Color.isColor() (returns boolean) Color.isColorObject() (returns boolean)(value a color string) Color.toHexString() (returns hex representation of color) Color.toRgbString() (returns rgb representation of color) Color.toHSlString() (returns HSL representation of color)
007 demo
options [0]
Framer.Defaults.Layer.size = 100 🔷 🔷Framer.Defaults.Layer.borderRadius = 12 Framer.Defaults.Layer.size = 100 Framer.Defaults.Animation = curve: Spring(damping: 0.75) Replicated layer to demonstrate default change ⚠️ Order default overrides first Layers include bg layer
008 demo
options [12]
📱 Framer.Device.customise() Framer.Device.Type.Phone ↩️Framer.Device.orientationName = "landscape" Not Shown But Similar .orientation .setOrientation() .rotateLeft() .rotateRight() Not Shown .fullScreen .deviceScale .setDeviceScale .contentScale .setContentScale()
009 demo
options [29]
layerA.draggable.enabled = true 1st ↕️ 2nd 🔄 3rd 🔃 .draggable.enabled = true ↕️ .draggable.horizontal = false .draggable.speedY = 1.1 (< 1 is slower than mouse movement) .draggable.constraints = - y:100 - height: 50 print <layer>.draggable.constraintsOffset print <layer>.draggable.isBeyondConstraints .draggable.overdrag = true .draggable.overdragScale = 0.25 .draggable.bounce = true (default true) .draggable.bounceOptions = - friction: 40, - tension: 200, - tolerance: 0.0001 <layer>.draggable.on Events.DragMove ➡️ - print.<layer>.draggable.direction 🔄 .draggable.momentum = true (default true) .draggable.momentumOptions = - friction: 2.1 - tolerance: 0.1 <layer>.draggable.on Events.DragMove ➡️ - print <layer>.draggable.velocity - print <layer>.draggable.angle Not Shown .draggable.vertical = false .draggable.speedX = 0.5 🔃 print <layer>.draggable.angle print <layer>.draggable.updatePosition() (increments 20px) print <layer>.draggable.directionLock = true print <layer>.draggable.directionLockThreshold = x: 10 y: 20 print <layer>.draggable.pixelAlign = true print <layer>.draggable.isDragging (check if layer is being dragged) isMoving print <layer>.draggable.offset (get x and y layer position) print <layer>.draggable.layerStartPoint (start x and y) print <layer>.draggable.cursorStartPoint (x and y of cursor) print <layer>.draggable.layerCursorOffset print <layer>.draggable.propagateEvents = falsethis one let you to drag a layer without affecting scrollComponent!
010 events is in progress
010 demo 1
options [1 - 4 / 22]
Events 1 Tap . LongPress . Swipe . Pinch
[1] Tap .onTap / .onSingleTap .onDoubleTap [3] LongPress .onLongPress .onLongPressStart .onLongPressEnd [4] Swipe .onSwipeUp / .onSwipeUpStart / .onSwipeUpEnd .onSwipeRight /.onSwipeRightStart /.onSwipeRightEnd .onSwipeDown / .onSwipeDownStart /.onSwipeDownEnd .onSwipeLeft /.onSwipeLeftStart /.onSwipeLeftEnd [6] Pinch .Pinch / .PinchStart / .PinchEnd
010 demo 2
options [5 - 9 / 22]
Events 2 Scale . Rotate . Touch . Click . Mouse
[7] Scale .Scale / .ScaleStart / .ScaleEnd [8] Rotate .Rotate / RotateStart / .RotateEnd [9] Touch .TouchStart / .TouchMove / .TouchEnd [10] Click .Click (or touch - no delay on mobile) [11] Mouse .MouseUp / .MouseDown .MouseOver / .MouseOut (unhover with mouse cursor) .MouseMove / .MouseWheel
010 demo 3
options [10 - 13 / 22]
Events 3 Animation . State . Drag . Scroll
[12] Animation .AnimationStart / .AnimationStop / .AnimationEnd [13] State .StateSwitchStart .StateSwitchStop / .StateSwitchEnd [14] Drag .Move (the layer is moving) .Drag / .DragStart / .DragEnd .DragAnimationStart / .DragAnimationEnd .DirectionLockStart (Did start lock direction?) [15] Scroll .Move (the layer is moving) .Scroll / .ScrollStart / .ScrollEnd .ScrollAnimationDidStart / .ScrollAnimationDidEnd
010 demo 4
options [14 - 16 / 22]
Events 4 EdgeSwipe . Transition . Value
[16] EdgeSwipe .EdgeSwipe / .EdgeSwipeStart / .EdgeSwipeEnd .EdgeSwipeTop / .EdgeSwipeTopStart / .EdgeSwipeTopEnd .EdgeSwipeRight / .EdgeSwipeRightStart / .EdgeSwipeRightEnd .EdgeSwipeBottom / .EdgeSwipeBottomStart / .EdgeSwipeBottomEnd .EdgeSwipeLeft / .EdgeSwipeLeftStart / .EdgeSwipeLeftEnd [18] Value (used for sliders ⚪) .SliderValueChange .SliderMinValueChange (range slider only) .SliderMaxValueChange (range slider only) To Add [17] Transition .TransitionStart .TransitionHalt / .TransitionStop / .TransitionEnd
010 demo 5
options [17 - 20 / 22]
Events 5 Change . Gesture Event . touchEvent() . wrap()
[22] wrap() Wrap a given DOM Element - use to bind events to arbitrary dom elements Events.wrap(window).addEventListener "resize", (event) -> - print "Page is resizing" To Add [19] Change - listen to properties as they change layerA.on "change:x", -> layerA.on "change:y", -> layerA.on "change:point", -> layerA.on "change:width", -> layerA.on "change:height", -> layerA.on "change:size", -> layerA.on "change:frame", -> layerA.on "change:scale", -> layerA.on "change:rotation", -> layerA.on "change:borderRadius", -> layerA.on "change:currentPage", -> layerA.on "change:style", -> layerA.on "change:html", -> layerA.on "change:children", -> layerA.on "change:parent", -> [20] Gesture Event Properties Positioning event.point (current x and y position) event.start / event.previous ([] x and y position) Offset .offset (current x and y offset) .offsetTime / .offsetAngel / .offsetDirection Deltas .delta (offset since last event) .deltaTime / .deltaAngle / .deltaDirection Velocity & Force .velocity (current speed) .force (current pressure sensitivity of a tap) Input .fingers (amount of fingers on screen! ✋ ) .touchCenter / .touchDistance / .touchOffset Scale & Rotation .scale (scale value from two fingers .scaleDirection / .scaleRotation [21] touchEvent() Extract the touch event from a given event on mobile
010 demo 6
options [20 - 22 / 22]
Events 6 Force Tap . Pan
[2] Force Tap 📱 .onForceTap / .onForceTapStart .onForceTapChange .onForceTapEnd [5] Pan 📱 .Pan / .PanStart / .PanMove / .PanEnd .PanLeft / .PanRight / .PanUp / .PanDown
011 extras
011 demo
options [02]
Framer.Extras.Hints.enable() 🆔 Hints can be customised Framer.Extras.Hints.enable() If you want your hints to show immediately: Framer.Extras.Hints.showHints() 🕙 Preloader - only enabled outside of Framer, i.e. mirroring Framer.Extras.Preloader.enable() Framer.Extras.Preloader.setLogo()
012 demo
options [12]
flow = new FlowComponent 📗 flow.showNext(layerB, animate: true) flow.showPrevious(animate: true) scroll - have to be careful about order Header and Footer header (creates a sticky header) navBar = newLayer flow.header = navBar footer (creates a sticky footer) tabBar = new Layer flow.footer = tabBar Overlays flow.showOverlayCenter(modal, modal: true) flow.showOverlayTop(notification) hamburger.onTap -> flow.showOverlayLeft(swipeMenu) Not shown but similar .showOverlayRight() .showOverlayBottom() 🔰 flow.transition = (layer, transition, [options.animate] [options.scroll]) Custom transition is a function that returns an object with states This gif shows a custom transition function from Framer Docs Not Shown 🖨️ print flow.current (shows current page)
013 demo
options [3]
🍌 start: "#fff9db" end: "#ffd43b" 🌅 angle: 45 start: "#e67700" end: "#ffe066" Animatable: YES (animated angle: (180+45)
014 demo
options [95]
🔶 NAME - SIZE - COLOR - BORDER - 2D ROTATION [A] z, hueRotate (0 to 360) [B] gradient, visible = true, name = "square1" (can inherit from sketch import) [C] borderRadius, borderWidth, borderColor, image, brightness [D] contrast [E] saturate [F] invert, opacity [G] grayscale [I] scale, sepia
🔶NAME - SIZE - COLOR - BORDER - 2D ROTATION id name x / y / z width / height minX / midX / maxX minY / midY / maxY size scale / scaleX / scaleY frame props backgroundColor / gradient / image visible opacity brightness saturate hueRotate contrast invert grayscale sepia borderRadius / borderColor / borderWidth rotation rotationZ
014 demo
options [95]
🐔 🐣 PARENTS - CHILDREN
🐔 🐣 PARENT - CHILDREN parent children (READ ONLY) childrenWithName() siblings siblingsWithName() descendants ancestors() addChild() removeChild()
014 demo
options [95]
🌓 POSITIONING - FRONT - BACK
🌓 POSITIONING - FRONT - BACK index placeBefore() placeBehind() bringToFront() sendToBack()
014 demo
options [95]
💫 ANIMATION - STATES
💫 ANIMATION - STATES animationOptions Properties (these set the options for all animations performed on the layer unless they are overruled) curve curveOptions time delay repeat colorModel instant animations() isAnimating (read only, boolean) stateSwitch() stateCycle() stateNames Not Showm EXTRA computedStyle()[specific] (note - computationally expensive)
014 demo
options [95]
🌖 SHADOWS - BLENDING
🌖 SHADOWS - BLENDING blur backgroundBlur (couldn't tell any difference, does not work all the time) shadows shadowX shadowY shadowBlur shadowSpread (adjusted in animation from 1 to 10) shadowColor shadowType Blending - TO ADD OPTIONS Blending.normal (default blending mode) Blending.darken Blending.multiply Blending.colorBurn Blending.lighten Blending.screen Blending.colorDodge Blending.overlay Blending.softLight Blending.hardLight Blending.difference Blending.exclusion Blending.hue Blending.saturation Blending.color Blending.luminosity
014 demo
options [95]
CONVERTPOINTTOCANVAS() EVENTS
014 demo
options [95]
DYNAMIC CENTERING FRAMES MOVING AROUND
014 demo
options [95]
💻 HTML AND CSS
💻 HTML AND CSS clip (disabled by default - if parent clips children) html (best to use this in conjunction with ignoreEvents = false) Remeber: only available after Framer has rendered them Used to insert html content into a layer style (get CSS variables for a property) classList destroy()(remove a layer and its children) copy()(note: will not copy layer listeners) copySingle()(copies a layer without its children) color (as with css - this is for text and not background layer)
017 demo
options [14]
page = new PageComponent 🌲💚 page.addPage(layername, "right") page.originX page.originY page.velocityThreshold = 5 switch to be based on distance page.animationOptions = - curve: Bezier.ease - time: 1 page.currentPage (read only) page.closestPage (read only) page.previousPage page.snapToPage( - pageFive - true - animationOptions = time: 2 ) page.snapToNextPage (page, animate, animationOptions ) page.snapToPreviousPage(direction, animate, animationOptions) page.horizontalPageIndex(pageThree) page.verticalPageIndex(pageThree) To Add
018 demo
options [11]
layerA.pinchable.enabled = true 🌲💚 pinchable.centerOrigin = false (t default) pinchable.minScale = 0.9 pinchable.maxScale = 2 🌲 pinchable.threshold = 6 pinchable.rotate = false (t default) pinchable.scaleFactor = 1.2 💚 pinchable.rotateIncrements = 15 pinchable.rotateFactor = 0.5 Not Shown pinchable.scaleIncrements = 0.5 pinchable.scale = false (t default)
019 demo
options [0]
Acts in a similar manner to console.log() in JavaScript. Want to use this section to show print in context
020 demo
options [10]
range = new RangeSliderComponent ➖ RangeSliderComponent min: 0 (0 default) max: 10 (1 default) minValue: 2 (0 default) maxValue: 8 (0.5 default) 🌀 range.fill.backgroundColor = "#EF2D56" ⚪ ⚪ range.knobSize = 30 (30 default) range.minKnob.draggable.momentum = false (t default) range.maxKnob.draggable.momentum = false (t default) ⚡ range.animateToMinValue(1) range.animateToMaxValue(9)
021 demo
options [10]
💈 🔷 Screen.perspective = 1000 (1200 by default) Screen.perspectiveOriginX = 1 (default 0.5) Screen.perspectiveOriginY = 1 (default 0.5) 🖨️📱 (not shown, read only) Screen.size Screen.frame (read only) 📱 - not shown: Screen.width Screen.height Not Shown/Not Sure Screen.convertPointToCanvas(point) Screen.convertPointToLayer(point, layer)
022 scrollComponent is in progress
022 demo
options [28]
📜 Version 1 💻⌨️ Version 2
scroll = new ScrollComponent Introduction ScrollComponent is built with two layers The scroll component itself masks another layer 📜 Version 1: Built Primarily in Design Mode .scroll: true .scrollVertical: true .scrollHorizontal: false .speedX: 1 (default 1) .mouseWheelEnabled: true (default f) .contentInset = - top: 150 gives content extra padding between the constraints and actual content layers 💻⌨️ Version 2: Built entirely in Code Mode layerA.parent = scroll.content scroll.content is the layer content is added to scroll.directionLock = true (only allows scrolling in one direction at a time) .speedY: 0.5 (default 1) speedX: 0.5 (default 1) scroll.direction (read only) scroll.on Events.Scroll, -> print scroll.direction scroll.isMoving (printed alongside scroll.direction) scroll.directionLockThreshold = - x: 550 - y: 0 (used here to make a tempermental horizontal scrolling component) scroll.velocity scroll.on Events.Scroll, -> print scroll2.velocity scroll.angle (printed in this example alongside velocity) scroll.isDragging (printed alongside angle and velocity) To Add .scrollPoint .scrollFrame .closestContentLayer() .closestContentLayerForScrollPoint() .scrollToPoint .scrollToLayer .scrollToClosestLayer() .updateContent() scroll.propagateEvents - (set to true by default) Use when working with nested ScrollComponents or PageComponents Use it to prevent draggable children passing events to their parents To Investigate .scrollX (horizontal scroll location) .scrollY (vertical scroll location) Not Shown .wrap() - used when making imported layers scrollable scroll.copy - duplicate a scroll component
023 demo
options [9]
slider = new SliderComponent ➖ silder.backgroundColor = "#e599f7" slider.fill.backgroundColor = "#be4bdb" ⚪ silder.knob.backgroundColor = "#FCF7FF" slider.knobSize = 45 (30 default) slider.knob.draggable.momentum = false (t default) 🔢 silder.min = 0 (0 default) slider.max = 100 (1 default) ⚡ silder.animateToValue(20, {curve: Spring } ) Not Shown: To Add silder.pointForValue slider.valueForPoint
024 demo
options [2]
Default The initially active state Current The currently active state Previous The previously active state
025 demo
options [24]
title = new TextLayer 🔡 TextLayer text: "Hello {name}" fontSize: 60 fontFamily: "Helvetica" fontWeight: 700 fontStyle: "bold" (italic / bold / oblique) padding: - top: -10 (default 0) - left: 0 - bottom: 0 - right: 0 lineHeight: 1.2 (0 default) letterSpacing: 1.2 (0 default) wordSpacing: 0 (default 0) textAlign: "left" (left, right, center) textTransform: "capitalize" (uppercase, lowercase, capitalize) textDecoration: "none" textIndent: 1 shadowX: 2 shadowY: 2 shadowBlur: 4; shadowColor: "rgba (0,0,0,0.2)" .template = - name: "github" 🔢 .templateFormatter = count: (value) -> - Utils.round(value, 0) .animate -template: count: 1000 🔀 .textReplace("replace", "Lorem ipsum dolor sit") ("from", "to") truncate: true height: 50 Not Shown: To Troubleshoot textOverflow: "ellipsis" - truncate boolean worked however font: "bold, 700, 60px/1, Helvetica" - (fontStyle fontWeight fontSize*/lineHeight fontFamily*) * = mandatory
026 demo
options [23]
⏫ Utils.modulate() used here for parallax scroll ✒️ Utils.loadWebFont("Bungee Shade") Utils.loadWebFont("Roboto", 700) 🔢text.text = Utils.round(Utils.randomNumber(0, 100), 2) 🌈.backgroundColor = Utils.randomColor(1) 🔦Utils.labelLayer(layer, "Hello") 📷.image = Utils.randomImage() Utils.randomImage(Layer) (clips to layer) 🔲 (only works for border?)layer.classList.add("testClass") css = {...;} 🔍 Printed Items Utils.cycle(["a", "b", "c"]) Utils.randomChoice([":banana:",":apple:",":watermelon:"]) Utils.delay 0.5, -> print "delayed reaction"print Utils.frameInset({x:0, y:0, width:100, height:100}, 10) Utils.interval 1, -> print "one second"handler = Utils.throttle 0.5, -> print "hello" for i in [10...100] handler()handler = Utils.debounce 0.1, -> print "hello" for i in [1..100] handler() Not Shown - these return a boolean Utils.isWebKit() Utils.isChrome() Utils.isSafari() Utils.isTouch() Utils.isDesktop() Utils.isPhone() Utils.isTablet() Utils.isMobile()
027 demo
options [2]
layerA = new VideoLayer 🎥 new VideoLayer: video: "name.mp4" .player.autoplay = true .player.fastSeek(2)
RayPS - iPhone X Framer device mockup from: https://gist.github.com/RayPS/0a21af6cf3b0578ffab62c604b5ea6e2