From b78ddb12ce6b9967e801f2aea7db4aac966e0aa8 Mon Sep 17 00:00:00 2001 From: Koen Bok Date: Sat, 19 Apr 2014 12:11:55 +0200 Subject: [PATCH] - Add Cactus test project - Add default view size and color --- Makefile | 3 + build/framer.js | 533 +----------------- extras/CactusFramerTest/.gitignore | 3 + extras/CactusFramerTest/config.json | 1 + extras/CactusFramerTest/pages/error.html | 23 + extras/CactusFramerTest/pages/index.html | 4 + extras/CactusFramerTest/pages/robots.txt | 6 + extras/CactusFramerTest/pages/sitemap.xml | 8 + extras/CactusFramerTest/plugins/__init__.py | 0 extras/CactusFramerTest/plugins/default.py | 29 + extras/CactusFramerTest/static/app-cs.coffee | 3 + extras/CactusFramerTest/static/css/style.css | 18 + .../CactusFramerTest/static/framer/framer.js | 1 + .../static/images/checker-pattern.png | Bin 0 -> 136 bytes .../static/images/favicon.ico | Bin 0 -> 5182 bytes .../static/images/framer-logo.png | Bin 0 -> 14530 bytes .../apple-touch-icon-114x114-precomposed.png | Bin 0 -> 5038 bytes .../apple-touch-icon-144x144-precomposed.png | Bin 0 -> 6664 bytes .../apple-touch-icon-72x72-precomposed.png | Bin 0 -> 3149 bytes .../icon/apple-touch-icon-precomposed.png | Bin 0 -> 2403 bytes extras/CactusFramerTest/templates/base.html | 32 ++ src/config.coffee | 5 +- src/views/view.coffee | 8 + todo.txt | 6 + 24 files changed, 172 insertions(+), 511 deletions(-) create mode 100644 extras/CactusFramerTest/.gitignore create mode 100644 extras/CactusFramerTest/config.json create mode 100644 extras/CactusFramerTest/pages/error.html create mode 100644 extras/CactusFramerTest/pages/index.html create mode 100644 extras/CactusFramerTest/pages/robots.txt create mode 100644 extras/CactusFramerTest/pages/sitemap.xml create mode 100644 extras/CactusFramerTest/plugins/__init__.py create mode 100755 extras/CactusFramerTest/plugins/default.py create mode 100644 extras/CactusFramerTest/static/app-cs.coffee create mode 100644 extras/CactusFramerTest/static/css/style.css create mode 120000 extras/CactusFramerTest/static/framer/framer.js create mode 100644 extras/CactusFramerTest/static/images/checker-pattern.png create mode 100644 extras/CactusFramerTest/static/images/favicon.ico create mode 100644 extras/CactusFramerTest/static/images/framer-logo.png create mode 100644 extras/CactusFramerTest/static/images/icon/apple-touch-icon-114x114-precomposed.png create mode 100644 extras/CactusFramerTest/static/images/icon/apple-touch-icon-144x144-precomposed.png create mode 100644 extras/CactusFramerTest/static/images/icon/apple-touch-icon-72x72-precomposed.png create mode 100644 extras/CactusFramerTest/static/images/icon/apple-touch-icon-precomposed.png create mode 100644 extras/CactusFramerTest/templates/base.html create mode 100644 todo.txt diff --git a/Makefile b/Makefile index fb69f797e..e41f0a7df 100644 --- a/Makefile +++ b/Makefile @@ -31,5 +31,8 @@ dist: cp build/framer.js build/Framer/framer.js cd build; zip -r Framer.zip Framer +cactus: + cd extras/CactusFramerTest; cactus serve + .PHONY: build clean lint test diff --git a/build/framer.js b/build/framer.js index bf983b055..23e1a8c37 100644 --- a/build/framer.js +++ b/build/framer.js @@ -1,7 +1,7 @@ -// Framer 2.0-43-g5d463ce (c) 2013 Koen Bok +// Framer 2.0-58-g4b76906 (c) 2013 Koen Bok // https://github.com/koenbok/Framer -window.FramerVersion = "2.0-43-g5d463ce"; +window.FramerVersion = "2.0-58-g4b76906"; (function(){var require = function (file, cwd) { @@ -459,7 +459,10 @@ require.define("/src/config.coffee",function(require,module,exports,__dirname,__ roundingDecimals: 5, animationPrecision: 60, animationDebug: false, - animationProfile: false + animationProfile: false, + defaultViewWidth: 100, + defaultViewHeight: 100, + defaultViewBackgroundColor: "rgba(0,150,200,0.5)" }; }).call(this); @@ -2323,7 +2326,7 @@ require.define("/src/tools/facebook.coffee",function(require,module,exports,__di }); require.define("/src/views/view.coffee",function(require,module,exports,__dirname,__filename,process,global){(function() { - var Animation, EventEmitter, FilterProperties, Frame, Matrix, View, k, utils, v, _, + var Animation, EventEmitter, FilterProperties, Frame, Matrix, View, config, k, utils, v, _, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, __extends = 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; }, @@ -2333,6 +2336,8 @@ require.define("/src/views/view.coffee",function(require,module,exports,__dirnam _ = require("underscore"); + config = require("../config").config; + Frame = require("../primitives/frame").Frame; Matrix = require("../primitives/matrix").Matrix; @@ -2366,6 +2371,13 @@ require.define("/src/views/view.coffee",function(require,module,exports,__dirnam this.addClass("framer"); this._subViews = []; this._currentAnimations = []; + if (args.width == null) { + args.width = config.defaultViewWidth; + } + if (args.height == null) { + args.height = config.defaultViewHeight; + } + this.style.backgroundColor = config.defaultViewBackgroundColor; this.clip = args.clip || View.Properties.clip; this.properties = args; this.index = 0; @@ -3035,507 +3047,6 @@ require.define("/src/views/view.coffee",function(require,module,exports,__dirnam }).call(this); -}); - -require.define("/node_modules/check-types/package.json",function(require,module,exports,__dirname,__filename,process,global){module.exports = {"main":"./src/check-types.js"} -}); - -require.define("/node_modules/check-types/src/check-types.js",function(require,module,exports,__dirname,__filename,process,global){/** - * This module exports functions for checking types - * and throwing exceptions. - */ - -/*globals define, module */ - -(function (globals) { - 'use strict'; - - var functions = { - verifyQuack: verifyQuack, - quacksLike: quacksLike, - verifyInstance: verifyInstance, - isInstance: isInstance, - verifyEmptyObject: verifyEmptyObject, - isEmptyObject: isEmptyObject, - verifyObject: verifyObject, - isObject: isObject, - verifyLength: verifyLength, - isLength: isLength, - verifyArray: verifyArray, - isArray: isArray, - verifyDate: verifyDate, - isDate: isDate, - verifyFunction: verifyFunction, - isFunction: isFunction, - verifyUnemptyString: verifyUnemptyString, - isUnemptyString:isUnemptyString, - verifyString: verifyString, - isString: isString, - verifyEvenNumber: verifyEvenNumber, - isEvenNumber: isEvenNumber, - verifyOddNumber: verifyOddNumber, - isOddNumber: isOddNumber, - verifyPositiveNumber: verifyPositiveNumber, - isPositiveNumber: isPositiveNumber, - verifyNegativeNumber: verifyNegativeNumber, - isNegativeNumber: isNegativeNumber, - verifyNumber: verifyNumber, - isNumber: isNumber - }; - - exportFunctions(); - - /** - * Public function `verifyQuack`. - * - * Throws an exception if an object does not share - * the properties of a second, archetypal object - * (i.e. doesn't 'quack like a duck'). - * - * @param thing {object} The object to test. - * @param duck {object} The archetypal object, - * or 'duck', that the test - * is against. - * @param [message] {string} An optional error message - * to set on the thrown Error. - */ - function verifyQuack (thing, duck, message) { - verify(quacksLike, [ thing, duck ], message, 'Invalid type'); - } - - function verify (fn, args, message, defaultMessage) { - if (fn.apply(null, args) === false) { - throw new Error(message || defaultMessage); - } - } - - /** - * Public function `quacksLike`. - * - * Tests whether an object 'quacks like a duck'. - * Returns `true` if the first argument has all of - * the properties of the second, archetypal argument - * (the 'duck'). Returns `false` otherwise. If either - * argument is not an object, an exception is thrown. - * - * @param thing {object} The object to test. - * @param duck {object} The archetypal object, or - * 'duck', that the test is - * against. - */ - function quacksLike (thing, duck) { - var property; - - verifyObject(thing); - verifyObject(duck); - - for (property in duck) { - if (duck.hasOwnProperty(property)) { - if (thing.hasOwnProperty(property) === false) { - return false; - } - - if (typeof thing[property] !== typeof duck[property]) { - return false; - } - } - } - - return true; - } - - /** - * Public function `verifyInstance`. - * - * Throws an exception if an object is not an instance - * of a prototype. - * - * @param thing {object} The object to test. - * @param prototype {function} The prototype that the - * test is against. - * @param [message] {string} An optional error message - * to set on the thrown Error. - */ - function verifyInstance (thing, prototype, message) { - verify(isInstance, [ thing, prototype ], message, 'Invalid type'); - } - - /** - * Public function `isInstance`. - * - * Returns `true` if an object is an instance of a prototype, - * `false` otherwise. - * - * @param thing {object} The object to test. - * @param prototype {function} The prototype that the - * test is against. - */ - function isInstance (thing, prototype) { - if (typeof thing === 'undefined' || thing === null) { - return false; - } - - if (isFunction(prototype) && thing instanceof prototype) { - return true; - } - - return false; - } - - /** - * Public function `verifyEmptyObject`. - * - * Throws an exception unless something is an empty, non-null, - * non-array object. - * - * @param thing The thing to test. - * @param [message] {string} An optional error message - * to set on the thrown Error. - */ - function verifyEmptyObject (thing, message) { - verify(isEmptyObject, [ thing ], message, 'Invalid object'); - } - - /** - * Public function `isEmptyObject`. - * - * Returns `true` if something is an empty, non-null, non-array object, `false` otherwise. - * - * @param thing The thing to test. - */ - function isEmptyObject (thing) { - var property; - - if (isObject(thing)) { - for (property in thing) { - if (thing.hasOwnProperty(property)) { - return false; - } - } - - return true; - } - - return false; - } - - /** - * Public function `verifyObject`. - * - * Throws an exception unless something is a non-null, - * non-array, non-date object. - * - * @param thing The thing to test. - * @param [message] {string} An optional error message - * to set on the thrown Error. - */ - function verifyObject (thing, message) { - verify(isObject, [ thing ], message, 'Invalid object'); - } - - /** - * Public function `isObject`. - * - * Returns `true` if something is a non-null, non-array, - * non-date object, `false` otherwise. - * - * @param thing The thing to test. - */ - function isObject (thing) { - return typeof thing === 'object' && thing !== null && isArray(thing) === false && isDate(thing) === false; - } - - /** - * Public function `verifyLength`. - * - * Throws an exception unless something is a non-null, - * non-array object. - * - * @param thing The thing to test. - * @param [message] {string} An optional error message - * to set on the thrown Error. - */ - function verifyLength (thing, length, message) { - verify(isLength, [ thing, length ], message, 'Invalid length'); - } - - /** - * Public function `isLength`. - * - * Returns `true` if something is has a length property - * matching the specified value, `false` otherwise. - * - * @param thing The thing to test. - * @param length The required length to test against. - */ - function isLength (thing, length) { - return thing && thing.length === length; - } - - /** - * Public function `verifyArray`. - * - * Throws an exception unless something is an array. - * - * @param thing The thing to test. - * @param [message] {string} An optional error message - * to set on the thrown Error. - */ - function verifyArray (thing, message) { - verify(isArray, [ thing ], message, 'Invalid array'); - } - - /** - * Public function `isArray`. - * - * Returns `true` something is an array, `false` otherwise. - * - * @param thing The thing to test. - */ - function isArray (thing) { - if (Array.isArray) { - return Array.isArray(thing); - } - - return Object.prototype.toString.call(thing) === '[object Array]'; - } - - /** - * Public function `verifyDate`. - * - * Throws an exception unless something is a date. - * - * @param thing The thing to test. - * @param [message] {string} An optional error message - * to set on the thrown Error. - */ - function verifyDate (thing, message) { - verify(isDate, [ thing ], message, 'Invalid date'); - } - - /** - * Public function `isDate`. - * - * Returns `true` something is a date, `false` otherwise. - * - * @param thing The thing to test. - */ - function isDate (thing) { - return Object.prototype.toString.call(thing) === '[object Date]'; - } - - /** - * Public function `verifyFunction`. - * - * Throws an exception unless something is function. - * - * @param thing The thing to test. - * @param [message] {string} An optional error message - * to set on the thrown Error. - */ - function verifyFunction (thing, message) { - verify(isFunction, [ thing ], message, 'Invalid function'); - } - - /** - * Public function `isFunction`. - * - * Returns `true` if something is function, `false` otherwise. - * - * @param thing The thing to test. - */ - function isFunction (thing) { - return typeof thing === 'function'; - } - - /** - * Public function `verifyUnemptyString`. - * - * Throws an exception unless something is a non-empty string. - * - * @param thing The thing to test. - * @param [message] {string} An optional error message - * to set on the thrown Error. - */ - function verifyUnemptyString (thing, message) { - verify(isUnemptyString, [ thing ], message, 'Invalid string'); - } - - /** - * Public function `isUnemptyString`. - * - * Returns `true` if something is a non-empty string, `false` - * otherwise. - * - * @param thing The thing to test. - */ - function isUnemptyString (thing) { - return isString(thing) && thing !== ''; - } - - /** - * Public function `verifyString`. - * - * Throws an exception unless something is a string. - * - * @param thing The thing to test. - * @param [message] {string} An optional error message - * to set on the thrown Error. - */ - function verifyString (thing, message) { - verify(isString, [ thing ], message, 'Invalid string'); - } - - /** - * Public function `isString`. - * - * Returns `true` if something is a string, `false` otherwise. - * - * @param thing The thing to test. - */ - function isString (thing) { - return typeof thing === 'string'; - } - - /** - * Public function `verifyOddNumber`. - * - * Throws an exception unless something is an odd number. - * - * @param thing The thing to test. - * @param [message] {string} An optional error message - * to set on the thrown Error. - */ - function verifyOddNumber (thing, message) { - verify(isOddNumber, [ thing ], message, 'Invalid number'); - } - - /** - * Public function `isOddNumber`. - * - * Returns `true` if something is an odd number, - * `false` otherwise. - * - * @param thing The thing to test. - */ - function isOddNumber (thing) { - return isNumber(thing) && (thing % 2 === 1 || thing % 2 === -1); - } - - /** - * Public function `verifyEvenNumber`. - * - * Throws an exception unless something is an even number. - * - * @param thing The thing to test. - * @param [message] {string} An optional error message - * to set on the thrown Error. - */ - function verifyEvenNumber (thing, message) { - verify(isEvenNumber, [ thing ], message, 'Invalid number'); - } - - /** - * Public function `isEvenNumber`. - * - * Returns `true` if something is an even number, - * `false` otherwise. - * - * @param thing The thing to test. - */ - function isEvenNumber (thing) { - return isNumber(thing) && thing % 2 === 0; - } - - /** - * Public function `verifyPositiveNumber`. - * - * Throws an exception unless something is a positive number. - * - * @param thing The thing to test. - * @param [message] {string} An optional error message - * to set on the thrown Error. - */ - function verifyPositiveNumber (thing, message) { - verify(isPositiveNumber, [ thing ], message, 'Invalid number'); - } - - /** - * Public function `isPositiveNumber`. - * - * Returns `true` if something is a positive number, - * `false` otherwise. - * - * @param thing The thing to test. - */ - function isPositiveNumber (thing) { - return isNumber(thing) && thing > 0; - } - - /** - * Public function `verifyNegativeNumber`. - * - * Throws an exception unless something is a positive number. - * - * @param thing The thing to test. - * @param [message] {string} An optional error message - * to set on the thrown Error. - */ - function verifyNegativeNumber (thing, message) { - verify(isNegativeNumber, [ thing ], message, 'Invalid number'); - } - - /** - * Public function `isNegativeNumber`. - * - * Returns `true` if something is a positive number, - * `false` otherwise. - * - * @param thing The thing to test. - */ - function isNegativeNumber (thing) { - return isNumber(thing) && thing < 0; - } - - /** - * Public function `verifyNumber`. - * - * Throws an exception unless something is a number, excluding NaN. - * - * @param thing The thing to test. - * @param [message] {string} An optional error message - * to set on the thrown Error. - */ - function verifyNumber (thing, message) { - verify(isNumber, [ thing ], message, 'Invalid number'); - } - - /** - * Public function `isNumber`. - * - * Returns `true` if something is a number other than NaN, - * `false` otherwise. - * - * @param thing The thing to test. - */ - function isNumber (thing) { - return typeof thing === 'number' && isNaN(thing) === false; - } - - function exportFunctions () { - if (typeof define === 'function' && define.amd) { - define(function () { - return functions; - }); - } else if (typeof module !== 'undefined' && module !== null) { - module.exports = functions; - } else { - globals.check = functions; - } - } -}(this)); - - }); require.define("/src/primitives/frame.coffee",function(require,module,exports,__dirname,__filename,process,global){(function() { @@ -5083,17 +4594,19 @@ require.define("/src/ui/draggable.coffee",function(require,module,exports,__dirn this.emit(Events.DragMove, event); touchEvent = Events.touchEvent(event); delta = { - x: touchEvent.webkitMovementX, - y: touchEvent.webkitMovementY + x: touchEvent.clientX - this._start.x({ + y: touchEvent.clientY - this._start.y + }) }; correctedDelta = { x: delta.x * this.speed.x, y: delta.y * this.speed.y, t: event.timeStamp }; - this.view.x += correctedDelta.x; - this.view.y += correctedDelta.y; - return this._deltas.push(correctedDelta); + this.view.x = this._start.x + correctedDelta.x - this._offset.x; + this.view.y = this._start.y + correctedDelta.y - this._offset.y; + this._deltas.push(correctedDelta); + return this.emit(Events.DragMove, event); }; Draggable.prototype._touchStart = function(event) { diff --git a/extras/CactusFramerTest/.gitignore b/extras/CactusFramerTest/.gitignore new file mode 100644 index 000000000..5e8f58444 --- /dev/null +++ b/extras/CactusFramerTest/.gitignore @@ -0,0 +1,3 @@ +.build +*.pyc +app-cs.js \ No newline at end of file diff --git a/extras/CactusFramerTest/config.json b/extras/CactusFramerTest/config.json new file mode 100644 index 000000000..e68ffa937 --- /dev/null +++ b/extras/CactusFramerTest/config.json @@ -0,0 +1 @@ +{"port":8857} \ No newline at end of file diff --git a/extras/CactusFramerTest/pages/error.html b/extras/CactusFramerTest/pages/error.html new file mode 100644 index 000000000..85cd09e71 --- /dev/null +++ b/extras/CactusFramerTest/pages/error.html @@ -0,0 +1,23 @@ +{% extends "base.html" %} +{% block content %} + + + + +

+ Sorry the page could not be found on this server. +

+{% endblock %} diff --git a/extras/CactusFramerTest/pages/index.html b/extras/CactusFramerTest/pages/index.html new file mode 100644 index 000000000..7a46fd03d --- /dev/null +++ b/extras/CactusFramerTest/pages/index.html @@ -0,0 +1,4 @@ +{% extends "base.html" %} +{% block content %} + +{% endblock content%} diff --git a/extras/CactusFramerTest/pages/robots.txt b/extras/CactusFramerTest/pages/robots.txt new file mode 100644 index 000000000..3cc2eb05a --- /dev/null +++ b/extras/CactusFramerTest/pages/robots.txt @@ -0,0 +1,6 @@ +{% verbatim %} +User-agent: * +Disallow: + +Sitemap: sitemap.xml +{% endverbatim %} diff --git a/extras/CactusFramerTest/pages/sitemap.xml b/extras/CactusFramerTest/pages/sitemap.xml new file mode 100644 index 000000000..461680122 --- /dev/null +++ b/extras/CactusFramerTest/pages/sitemap.xml @@ -0,0 +1,8 @@ + +{% for page in CACTUS.pages %}{% if page.path != 'error.html' %} + + {{ page.absolute_final_url }} + daily + 1.0 + {% endif %}{% endfor %} + diff --git a/extras/CactusFramerTest/plugins/__init__.py b/extras/CactusFramerTest/plugins/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/extras/CactusFramerTest/plugins/default.py b/extras/CactusFramerTest/plugins/default.py new file mode 100755 index 000000000..662d76bd3 --- /dev/null +++ b/extras/CactusFramerTest/plugins/default.py @@ -0,0 +1,29 @@ +import os +import pipes +import subprocess +import logging + +def run(command): + + logger = logging.getLogger(__name__) + + logger.debug(command) + + # logger.info(os.environ['PATH']) + + process = subprocess.Popen([command], + shell=True, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + + stdout = process.stdout.readline() + stderr = process.stderr.readline() + + if stdout: logger.info(stdout) + if stderr: logger.warning(stderr) + +def preBuild(site): + run('find %s -name "*.scss" -not -name "_*" -exec scss -C --update {} \;' % pipes.quote(site.static_path)) + run('find %s -name "*.sass" -not -name "_*" -exec scss -C --update {} \;' % pipes.quote(site.static_path)) + run('find %s -name "*.coffee" -exec coffee -c {} \;' % pipes.quote(site.static_path)) diff --git a/extras/CactusFramerTest/static/app-cs.coffee b/extras/CactusFramerTest/static/app-cs.coffee new file mode 100644 index 000000000..9d9ce6144 --- /dev/null +++ b/extras/CactusFramerTest/static/app-cs.coffee @@ -0,0 +1,3 @@ +view = new View + +view.style.backgroundColor = null \ No newline at end of file diff --git a/extras/CactusFramerTest/static/css/style.css b/extras/CactusFramerTest/static/css/style.css new file mode 100644 index 000000000..39f8c7d89 --- /dev/null +++ b/extras/CactusFramerTest/static/css/style.css @@ -0,0 +1,18 @@ +* { + margin:0; + padding:0; + border:none; + -webkit-user-select:none; +} + +body { + background: black url('/static/images/checker-pattern.png') + repeat scroll top left; + font: 28px/1em "Helvetica"; + color: #FFF; + -webkit-tap-highlight-color: rgba(0,0,0,0) +} + +a { + color: #bfbfbf; +} \ No newline at end of file diff --git a/extras/CactusFramerTest/static/framer/framer.js b/extras/CactusFramerTest/static/framer/framer.js new file mode 120000 index 000000000..fe883d450 --- /dev/null +++ b/extras/CactusFramerTest/static/framer/framer.js @@ -0,0 +1 @@ +../../../../build/framer.js \ No newline at end of file diff --git a/extras/CactusFramerTest/static/images/checker-pattern.png b/extras/CactusFramerTest/static/images/checker-pattern.png new file mode 100644 index 0000000000000000000000000000000000000000..d8c2fcabe81cf6a7c4dcd0da7b81b7137de4613f GIT binary patch literal 136 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQak|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5X*aCb)T#b#5d4#35F-k-NMI=03978H@B_%X4yICYiTxvRe fRK9>gAc0}&7KW1_|Jb?%)i8Lv`njxgN@xNAv-~AN literal 0 HcmV?d00001 diff --git a/extras/CactusFramerTest/static/images/favicon.ico b/extras/CactusFramerTest/static/images/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..2bba4e94d4be21c1cd47e8b00277399dd116ce60 GIT binary patch literal 5182 zcmeHLOK;Oa5Z<(Z0dX!T@+(MBAbtV|BxuEn3kSF$xWECmNSu&3!I4)Hs)P`V096E9 zB!UDg^g=<1iiZI;iQ|xmYiF3x%0_E@?AUE@O{y=uo}HO*X7=S&sRI8^O(}e<;y$JJ zE2WAI7O80lq8}nsW02aseJlpEE<8TLIK;ThSY}v^-T>%BhB4?&L~K)iLziu0 z7|6jp!}!dgB-rJP<`{Hg6U4!-=zCO*Y*%EwWthIje(&3gB!?}0Y={3S+c{adp+mk$ zjYnss7~liGLNS=R3-yOS=2r42%Bb&C_iKeV?;e-N;VTqF3P0+VId2^!_yN!ULCvKr zQVj4poQnkhN!F=qpIKY`*`5a@R2=_$&$YKcAqR8iVGM+JrR#e{%x=%iZKp z;Rb(2;J5PfgTu_*t8Y+yZISFJ=TmFOJeI(p>%3`IZ<70KHQ;k9*QmaDdK9NQ-rFue z);n^{TdRn^#GhJ!@VeGoP;Y1X`cCrV|rnWG%Q+{dv%|&W7fC>Y5$cZyHM_fJI4L_j=Eo7kk|Om?Gn}QoyZ$gNmzg4`D^BG?lrUTH8!a6_*~W) zaQ+qqe%wEJXA1f8o!_B7Zt|M_zT2VJ>l-24sIS3u()|PeNyZz~uKnR*CVm}@X)E;M z8ywR8r{9kb@_19*)*hT9zg^E217hiWF14z+%zEJc1HJ>Eg!=0k4zu3yJZwI{O#Q8H z<`}%DMRxgu$qipeG&kB2{D@;|lDZ3j7ChGP^_o literal 0 HcmV?d00001 diff --git a/extras/CactusFramerTest/static/images/framer-logo.png b/extras/CactusFramerTest/static/images/framer-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..594cab1960d4e6dd027b1defd5f5c6643403316c GIT binary patch literal 14530 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 literal 0 HcmV?d00001 diff --git a/extras/CactusFramerTest/static/images/icon/apple-touch-icon-precomposed.png b/extras/CactusFramerTest/static/images/icon/apple-touch-icon-precomposed.png new file mode 100644 index 0000000000000000000000000000000000000000..1f9bbc0500cb15ba0aac33eeb206eac51c21aebb GIT binary patch literal 2403 zcmV-p37qzcP)}PZbGhK@7pSn()|Zr*sG4V zcXT>hT5Ic0mRHyh96XH9|0jnImmx2*!vQAnalcAROAj#A*Pm)@yHrtONBc_vCh&ok ztA~`79su?Ar_VH;g*)0`4)B2$+?fB8;*$Lpl~rfXG@|ik^4*yR7@|RJ#ifmB&!L6J z#woIuL|bC~dHiTgEZUnA6K*g>gH+n9kCay;?#4;6rt(GNzwhwh=Fh=9Uo6>UP1}^n zFtppN$%)#!!lL30vM)O~NT>g5yWe(BfL{QY0d4eXg7vt%@f0Uc)Gg0zL7{EkTp9Xq+)T^N#7K;1Rsd%O;;c0_$;r+4ouuSFBB{)e6R?BJ z!@(4&)#Vr2D(qDrj60p)v|eftH<@r3?nMN|NlLM_{0Q-+XDjywqmYGjA)1nZ<9F&Sw3q*vi9Xr*p-wbk}I%ka7E~# zU_H{foanA}y02V`jZZ*KL`HnET!CD48G>EO2KFqDMt`0lKp+yy6xQ^;6;)6<`dOgj z3)prIXV2k0L40IEE}h;;@gbRC?_&dd7Aua$ijLiR_((ZLj_yilXk_G2S(#8KM=oTf z_z-LwHvG6;h+5M#>_?CK%(06tEwAS1XJ%)e6O+z~2_Na|?m;eOr1+4GyJ zY%s12Vx`KuH?wkO=DevnQHy+7P>3?FE}lJqK6&TPs+Jhvck}xuhvQt+MZmaHd`MdQ zUN&%`U{c+|=X+74N$Vl-aR%;p?I7j#r*{THTji(zMu_ut5;_A))=?D0*Jr7YY5EdCJJ|tyN8XNw6 zAzv!@Kp<1>wx*tLXhih3j?Tg1VIN)R7Zx5refn@_2D;b!`Ytp(JX{eR8QFc{nqp;x z!xsu5=SE0mRCUd9ET219dV8^~6O)rJmj3#Bv$**D`P`$K8F%m}b#z^JkAwKgNbwz32Y71R0R<;$7Jk0Iv`=D2@o$kEou1VI*L zr1+5CNhxe_1R|`sP_9g}reV>sYIH7jb`1`XOiWHKExiTv3$LF%efnr-mJUkddfyG) zj$Ft{@gci*C$qs3iUo3IzO4j-e8th?oSgde&wnp2y?rzb6<@hMIEY-xNbw`1nLNxI&3Yu5u?V%3NLZZBuiL3(QCVz#z^e#?r%;dA)!C0Z%g?C4o}GS9AAJ zh>wgEAF?wpfsFu>M5s`CAX2K6QqxyTqNS(z8nftt;_6Wnu0_A_R}dT-DLy22XFMBt zm_V_viZL?kTHg&ENig%#l_`n27cbhoE<@BCghfV*4~dD5V}mP}Vir9Rs{-?E#RJ2` z6H|BYKX~|Ze%?pdKiZ^qX?E0pbRxejIGE#hqC1xiZ-maE}U0pp_VCl~6 z<0r4*EK*!QeEj(9ufKWxJt!WOkhd$vhnOv~Y;eUgkus1W$PoJN$x|>}m8rY;p3nWb z>N)W4_up|8pmSAlV{3b7lcN;LaT?KDpkTevpx!gP4e{)aZ}}xsZ|KL&Cx%>EM2x!(ovoe6H|i z3b8sU&sKtxShwqopI+9~os5KW{|g-7A1k~n1ftO*GXi|_@MHcn%$-pIoj1cfTd z$dts|TyY9_U+vX}ML4r}rrDB^h?4NJUeTYF zmVvu)FCrigq9La50>l^+wkEI^7E7!#ECP@50;xi*`fo|FyFQ!y@rb<|Bl%K=K&HgK zhycsArX~hM$U2CKh{CL>HM#(?lrLAR4I#%*);p)BJY4ZB2EOa!D#l=>S{rOO$ApJR zt}iJG)*IJ{-hgklChWQ8GaO&X6{_fj#E$MB#ublXBV%JRyOYt6s~Cfk7>~Qwosk%g zp~1n1b%WcnIhOYve&bki$|KYX+w zv5Y5E3KVL*b3{_~pdVK^o&uf(|1{d*je~I5cE-?f?70Am6z^!G2mPB8f7w-|(QP7n zy%F0^Zw$dZ+M64k1O{n!!3MlOjp_fvD9%TLq$01#T6HQW>~a_z!^g VB5mEtuD$>O002ovPDHLkV1fvVqUitt literal 0 HcmV?d00001 diff --git a/extras/CactusFramerTest/templates/base.html b/extras/CactusFramerTest/templates/base.html new file mode 100644 index 000000000..59c08312b --- /dev/null +++ b/extras/CactusFramerTest/templates/base.html @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + {% block header %} + {% block title %}Default{% endblock %} + {% endblock header %} + + + + {% block scripts %} + + {% endblock scripts%} + + {% block content %} + Main content + {% endblock content %} + + diff --git a/src/config.coffee b/src/config.coffee index bb752d5de..b5899eb6e 100644 --- a/src/config.coffee +++ b/src/config.coffee @@ -5,4 +5,7 @@ exports.config = # Animations animationPrecision: 60 animationDebug: false - animationProfile: false \ No newline at end of file + animationProfile: false + defaultViewWidth: 100 + defaultViewHeight: 100 + defaultViewBackgroundColor: "rgba(0,150,200,0.5)" \ No newline at end of file diff --git a/src/views/view.coffee b/src/views/view.coffee index 8e310f10d..b51f85a1a 100644 --- a/src/views/view.coffee +++ b/src/views/view.coffee @@ -1,6 +1,8 @@ utils = require "../utils" _ = require "underscore" +{config} = require "../config" + {Frame} = require "../primitives/frame" {Matrix} = require "../primitives/matrix" @@ -31,6 +33,12 @@ class View extends Frame @_subViews = [] @_currentAnimations = [] + # We'll set a default width, height and background color + args.width ?= config.defaultViewWidth + args.height ?= config.defaultViewHeight + + @style.backgroundColor = config.defaultViewBackgroundColor + # Set the view properties @clip = args.clip or View.Properties.clip @properties = args diff --git a/todo.txt b/todo.txt new file mode 100644 index 000000000..c39ed2c0a --- /dev/null +++ b/todo.txt @@ -0,0 +1,6 @@ +- Add a delay option to animations ++ Fix the draggable +- Fix the curve typo: https://www.facebook.com/groups/framerjs/permalink/469402916520118/ +- Add a default width, height and color +- Fix frame error +- Make the invisible psd layers invisible in Framer too \ No newline at end of file