alenkas / autolayout.js

Apple's Auto Layout and Visual Format Language for javascript (using cassowary constraints)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Logo

Build Status view on npm

AutoLayout.js implements Apple's Auto Layout and Visual Format Language in Javascript. Auto layout is a system which lets you perform lay out using mathematical relationships (constraints). It uses the awesome Cassowary.js library to do the actual constraint resolving and implements Apple's constraint system and Visual Format Language (vfl) on top of that.

Example - click me Visual Format Language Example (click image to edit)

Index

Getting started

AutoLayout.js is an abstract library for integrating Auto Layout and VFL into other javascript technologies. It provides a simple API and programming model that you can use to build your own auto layout and VFL solution. A simple example of this is, is using position: absolute; to lay out DOM elements. A more elobarate example of is the Visual Format Editor, which is built using famo.us and famous-flex. AutoLayout.js is written in ES6 and contains transpiled distribution files.

Installation

npm install autolayout

AutoLayout.js has a dependency on Cassowary.js. When you are using the dist/autolayout{.min}.js file, make sure Cassowary.js is loaded as well.

<head>
  <script type="text/javascript" src="node_modules/autolayout/node_modules/cassowary/bin/c.js"></script>
  <script type="text/javascript" src="node_modules/autolayout/dist/autolayout.js"></script>
</head>
var AutoLayout = window.AutoLayout;

When using a bundler like webpack or browserify, use:

var AutoLayout = require('autolayout.js');

(do make sure plugins for transpiling .es6 files are installed!)

Using the API

To parse VFL into constraints, use:

try {
  // The VFL can be either a string or an array of strings.
  // strings may also contain '\n' which indicates that a new line of VFL will begin.
  var constraints = AutoLayout.VisualFormat.parse([
    '|-[child(==child2)]-[child2]-|',
    'V:|[child(==child2)]|',
  ]);
} catch (err) {
    console.log('parse error: ' + err.toString());
}

A View is the main entity onto which constraints are added. It uses the cassowary SimplexSolver to add relations and variables. You can set the size of the view and other properties such as spacing. When constraints are added it automatically creates so called "sub-views" for every unique name that is encountered in the constraints. The evaluated size and position of these sub-views can be accessed through the .subViews property.

// Create a view with a set of constraints
var view = new AutoLayout.View({
    constraints: constraints, // initial constraints (optional)
    width: 100,               // initial width (optional)
    height: 200,              // initial height (optional)
    spacing: 10               // spacing size to use (optional, default: 8)
});

// get the size and position of the sub-views
for (var key in view.subViews) {
    console.log(key + ': ' + view.subViews[key]);
    // e.g. {
    //   name: 'child1',
    //   left: 20,
    //   top: 10,
    //   width: 70,
    //   height: 80
    // }
}

By changing the size, the layout is re-evaluated and the subView's are updated:

view.setSize(300, 600);

// get the new size & position of the sub-views
for (var key in view.subViews) {
    console.log(key + ': ' + view.subViews[key]);
}

Instead of using VFL, you can also add constraints directly. The properties are identical to those of NSLayoutConstraint.

view.addConstraint({
    view1: 'child3',
    attr1: 'width',    // see AutoLayout.Attribute
    relation: 'equ',   // see AutoLayout.Relation
    view2: 'child4',
    attr2: 'width',    // see AutoLayout.Attribute
    constant: 10,
    multiplier: 1
});

API Documentation

The API reference documentation can be found here.

Examples

Extended Visual Format Language (EVFL)

Apple's Visual Format Language prefers good notation over completeness of expressibility. Because of this some useful constraints cannot be expressed by "Standard" VFL. AutoLayout.js defines an extended syntax (superset of VFL) which you opt-in to use. To enable the extended syntax, set option extended to true when parsing the visual format:

var evfl = '|-[view1(==50%)]';
var constraints = AutoLayout.VisualFormat.parse(evfl, {extended: true});

Language features

Proportional size

To make the size proportional to the size of the parent, you can use the following % syntax:

|-[view1(==50%)]    // view1 is 50% the width of the parent (regardless of any spacing)
[view1(>=50%)]      // view1 should always be more than 50% the width of the parent

Operators

Operators can be used to create linear equations of the form: view1.attr1 <relation> view2.attr2 * multiplier + constant.

Syntax:

(view[.{attribute}]['*'|'/'{value}]['+'|'-'{value}])

To for instance, make the width or height proportional to another view, use:

|-[view1(==view2/2)]-[view2]-|  // view1 is half the width of view2
|-[view1(==view2*4-100)]-[view2]-|  // view1 is four times the width minus 100 of view2

Attributes

In some cases it is useful to for instance make the width equal to the height. To do this you can use the .{attribute} syntax, like this:

|-[view1]-|
V:|-[view1(view1.width)]

You can also combine with operators to for instance enforce a certain aspect ratio:

V:|-[view1(view1.width/3)]

Supported attributes:

.width
.height
.left
.top
.right
.bottom
.centerX
.centerY

Z-Ordering

When sub-views overlap it can be useful to specify the z-ordering for the sub-views:

Z:|[child1][child2]  // child2 is placed in front of child1

By default, all sub-views have a z-index of 0. When placed in front of each other, the z-index will be 1 higher than the sub-view it was placed in front of. The z-index of the sub-view can be accessed through the zIndex property:

console.log('zIndex: ' + view.subViews.child2.zIndex);

Comments

Single line comments can be used to explain the VFL or to prevent its execution:

// Enfore aspect ratios
[view1(view1.height/3)] // enfore aspect ratio 1/3
// [view2(view2.height/3)] <-- uncomment to enable

Additional resources

ToDo list

AutoLayout.js is currently a work in progress. Once feature complete, this todo list will be removed and replaced by a roadmap.

Overal:

  • Toolchain (ES6, external cassowary.js, distributable output, testing, doc generation, travis CI)
  • Instructions
  • Documentation
  • Some examples
  • DOM layouting primitives

Features:

  • Namespace & classes (AutoLayout, VisualFormat, View, Relation, Attribute)
  • Visual format
    • Vfl Parser (thanks to the awesome angular-autolayout team!)
    • Size constraints
    • Greater than, less than relationships.
  • Equality relationships
    • Base functionality
    • Multiplier support
  • In-equality relationships
  • Spacing.
  • Priorities.
  • Fitting size.
  • Intrinsic content size.
  • Checking for ambigous layout.
  • Content hugging?
  • Compression resistance?
  • Remove constraints?
  • Generate visual sub-view output from View (ASCII-art'ish)
  • Get constraint definitions from View
  • LTR (left to right reading) (Attribute.LEADING & Attribute.TRAILING)
  • Baseline support?
  • Margins? (View & Attributes)

Extended format features:

  • Percentage support (e.g. |-[child(50%)]-[child2]-])
  • Multiplier/divider support (e.g. [child(child2/2)])
  • Sub-properties access (e.g. [child(==child.height)])
  • Addition/substraction support (e.g. [child(child2-100)])
  • Single line comments (// bla)
  • Z-ordering (z-index)
  • View stacks (inspsired by UIStackView) (this make it a lot)
  • Multi line comments (/* bla */)

Parked Features:

  • Variables support (e.g. |-(leftMargin)-[child]]).

Contribute

If you like this project and want to support it, show some love and give it a star.

If you want to participate in development, drop me a line or just issue a pull request. Also have a look at CONTRIBUTING.

Contact

© 2015 Hein Rutjes

About

Apple's Auto Layout and Visual Format Language for javascript (using cassowary constraints)

License:MIT License


Languages

Language:JavaScript 98.2%Language:HTML 1.4%Language:CSS 0.4%