Skip to content

Instantly share code, notes, and snippets.

@subtleGradient
Last active July 28, 2017 17:27
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save subtleGradient/6445897 to your computer and use it in GitHub Desktop.
Save subtleGradient/6445897 to your computer and use it in GitHub Desktop.
Simple Behavior sheet system for FramerJS. Allows you to apply pre-defined behaviors to your layers by changing the layer name. by Thomas Aylott (http://subtlegradient.com) Copyright 2013 Facebook. All rights reserved. MIT License.
// Add this line to the top of your own code.
// This will apply all the behaviors
Behavior(PSD)
function Behavior(PSD){
var _BehaviorNames = Object.keys(Behavior.behaviors)
.filter(function(BehaviorName){ return !!Behavior.behaviors[BehaviorName].namingPattern });
Object.keys(PSD).forEach(function(layerName){
var layer = PSD[layerName];
_BehaviorNames.forEach(function(BehaviorName){
var match = layerName.match(Behavior.behaviors[BehaviorName].namingPattern);
try {
if (match) Behavior.behaviors[BehaviorName].apply(layer, [layer].concat(match));
} catch(e){
console.error('The Behavior "' + BehaviorName + '" is broken');
console.error(e)
}
})
})
}
Behavior.behaviors = {};
// Add this to your project
// Either link to it from your index.html file
// Or paste it into your app.js file after the Behavior.framer.js stuff
//
// These are pretty terrible. Someone should make nicer ones.
Behavior.behaviors.Toggle = function(layer){
layer.opacity = Number(!layer.opacity)
}
Behavior.behaviors.Hide = function(layer){
layer.opacity = 0
}
Behavior.behaviors.Show = function(layer){
layer.opacity = 1
}
/**
* Always(callback) will run callback up to 60 times every second
* Return false from your callback to stop it
*/
function Always(callback){
function always(){ if (callback() !== false) requestAnimationFrame(always) }
always()
}
window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
/**
* Usage:
* Behavior.behaviors.Do(PSD['My Awesome Layer'], '{opacity=Math.random()}')
*
* With OnWhatever, name your layer "onClick-Do-{opacity = SomeOtherLayer.opacity}"
*/
Behavior.behaviors.Do = function Do(layer, code){
Do.fun(code, layer)()
}
Behavior.behaviors.Do.fun = function(code, layer){
if (typeof code == 'function') return code;
if (layer && typeof layer == 'object'){
if (!layer.__fun) layer.__fun = {};
if (layer.__fun[code]) return layer.__fun[code];
}
code = 'with(PSD||{}){' + code + '}';
code = 'with(behaviors||{}){' + code + '}';
code = 'with(layer||{}){' + code + '}';
var fun = Function('PSD', 'behaviors', 'layer', code).bind(layer, PSD, Behavior.behaviors, layer);
if (layer && typeof layer == 'object') layer.__fun[code] = fun;
return fun;
}
/**
* The View onalways property is code that gets run up to 60 times a second.
* Use it to bind stuff or anything else you can think of.
* WARNING: This code gets run a LOT, don't do anything slow in there.
*
* Example:
* myAwesomeView.onalways = "opacity=Pointer.y/document.height"
* myAwesomeView.onalways += "scale=Pointer.x/document.width"
*/
Object.defineProperty(View.prototype, "onalways", {
get: function(){ return this._onAlways_source || "" },
set: function(onAlways){
var view = this;
view._onAlways_source = onAlways
if (typeof view._onAlways_source == 'string')
view._onAlways_source += ";";
view._onAlways = Behavior.behaviors.Do.fun(onAlways, view);
if (!view._onAlways_isRunning){
view._onAlways_isRunning = true;
Always(function(){
if (typeof view._onAlways == 'function')
if (view._onAlways() === false) view._onAlways_isRunning = false;
return view._onAlways_isRunning
})
}
},
})
/**
* Name your Photoshop layer "My Awesome Layer `opacity=Math.random()`"
* Same as doing PSD['My Awesome Layer'].onalways = "opacity=Math.random()"
* NOTE: Use backtick quotes "`"
*/
Behavior.behaviors.Always = function(layer, layerName, code){
if (typeof PSD == 'object') PSD[layer._name.split(' `')[0]] = layer;
layer.onalways = code
}
Behavior.behaviors.Always.namingPattern = /`([^`]+)`/;
The MIT License (MIT)
Copyright (c) 2013 Facebook
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
// Add this to your project
// Either link to it from your index.html file
// Or paste it into your app.js file after the Behavior.framer.js stuff
Behavior.behaviors.OnWhatever = function(layer, layerName, eventName, behaviorName, targetName){
function callback(){ Behavior.behaviors[behaviorName](PSD[targetName] || layer, targetName) }
// 'MyLayer onFoo-…' should show up as PSD.MyLayer also.
PSD[layer._name.split(Behavior.behaviors.OnWhatever.namingPattern)[0]] = layer;
eventName = eventName.toLowerCase();
if (eventName == 'always') return Always(callback);
layer.on(eventName, callback)
};
Behavior.behaviors.OnWhatever.namingPattern = /on(\w+)-([^-]+)-([^ ]*)/i;
// Forces a layer to stay stuck to your mouse
// TODO: Add touch support
Behavior.behaviors.Pointer = function(layer, layerName){
var position = Behavior.behaviors.Pointer.position
if (!position.isListening){
position.isListening = true;
window.addEventListener('mousemove', function onMouseMove(event){
position.x = event.x
position.y = event.y
}, false)
}
Always(function(){
layer.x = position.x
layer.y = position.y
})
}
Behavior.behaviors.Pointer.namingPattern = /^Pointer$/;
Behavior.behaviors.Pointer.position = {}
// Add this to your project
// Either link to it from your index.html file
// Or paste it into your app.js file after the Behavior.framer.js stuff
Behavior.behaviors['Show on Hover'] = function(layer, layerName){
layer.opacity = 0;
layer.style.cursor = 'pointer';
layer.on('mouseover', function(){
layer.opacity = 1;
})
layer.on('mouseout', function(){
layer.opacity = 0;
})
};
Behavior.behaviors['Show on Hover'].namingPattern = /^Hover/;
@escapist
Copy link

I think this code might be too old to work with the current version of Framer. Is that the case? I'd love to help update it, but I'm afraid I wouldn't know where to begin..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment