Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added float attribute on element #231

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions docs/essentials/element_attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,38 @@ Besides using values in pixels (i.e. `w="100" h="300"`), you can also specify _p
The percentage value specified for `w` and `x` will be calculated as the percentage of the _width_ (`w`) of the parent element.
And the percentage specified for `h` and `y` will use the _height_ (`h`) of the parent element as the base of the percentage calculation.

### Predefined placement options

In addition to the absolute positions that Blits and Lightning use, there are a few predefined placement options available. By adding the `placement`-attribute to an Element we can easily align it to the _center_, _left_, _right_, _top_, _bottom_, or even a combination like `{y: 'middle', x: 'left'}`, without having to calculate the positions yourself.


On the `x`-axis the following _placement_ options can be used: `left` (default), `center` and `right`. On the `y`-axis the _placement_ attribute accepts `top` (default), `middle` and `bottom`.

The _placement_ attribute also accepts and object with an `x` and a `y` key, to specify a placement for both axes.

The placement of an Element is calculated based on the dimensions of it's direct parent. This means that the containing Element _must_ have it's own dimensions (i.e. a `w` and a `h` attribute).

```xml
<Element w="300" h="300">
<!-- x placement -->
<Element w="40" h="40" placement="left" color="#818cf8" />
<Element w="40" h="40" placement="center" color="#2563eb" />
<Element w="40" h="40" placement="right" color="#1e40af" />

<!-- y placement -->
<Element w="40" h="40" x="54" placement="top" color="#f472b6" />
<Element w="40" h="40" x="54" placement="middle" color="#db2777" />
<Element w="40" h="40" x="54" placement="bottom" color="#be185d" />

<!-- x/y placement -->
<Element w="40" h="40" placement="{x: 'center', y: 'bottom'}" color="#a3e635" />
<Element w="40" h="40" placement="{x: 'right', y: 'middle'}" color="#65a30d" />
<Element w="40" h="40" placement="{x: 'center', y: 'middle'}" color="#4d7c0f" />
</Element>
```

> note: the `x` or `y` attributes on the Element are ignored for those axes defined in the `placement`-attribute

## Colors

By default, Elements have a transparent background color. The `color` attribute can be used to give an Element a color.
Expand Down
31 changes: 31 additions & 0 deletions src/engines/L3/element.js
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,37 @@ const propsTransformer = {
set content(v) {
this.props['text'] = '' + v
},
set placement(v) {
let x, y
if (typeof v === 'object' || (isObjectString(v) === true && (v = parseToObject(v)))) {
if ('x' in v === true) {
x = v.x
}
if ('y' in v === true) {
y = v.y
}
} else {
v === 'center' || v === 'right' ? (x = v) : (y = v)
}

// Set X position
if (x === 'center') {
this.x = '50%'
this.props['mountX'] = 0.5
} else if (x === 'right') {
this.x = '100%'
this.props['mountX'] = 1
}

// Set Y position
if (y === 'middle') {
this.y = '50%'
this.props['mountY'] = 0.5
} else if (y === 'bottom') {
this.y = '100%'
this.props['mountY'] = 1
}
},
}

const Element = {
Expand Down
142 changes: 138 additions & 4 deletions src/engines/L3/element.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -362,30 +362,164 @@ test('Element - Set `fit` property should not set not required keys', (assert) =
assert.end()
})

test('Element - Set `float` property with value `center`', (assert) => {
test('Element - Set `placement` property with value `center`', (assert) => {
assert.capture(renderer, 'createNode', () => new EventEmitter())
const el = createElement()

el.set('float', 'center')
el.set('placement', 'center')

assert.equal(el.node['mountX'], 0.5, 'Node mountX parameter should set to 0.5')
assert.equal(el.props.props['mountX'], 0.5, 'Props mountX parameter should set to 0.5')
assert.equal(el.node['x'], 960, 'Node x parameter should set to half of parent node width, 960')
assert.equal(el.props.props['x'], 960, 'props x parameter should be set to 960')
assert.equal(
el.node['y'],
undefined,
'Node Y parameter should not be modified from default value'
)

assert.end()
})

test('Element - Set `float` property with value `right`', (assert) => {
test('Element - Set `placement` property with value `right`', (assert) => {
assert.capture(renderer, 'createNode', () => new EventEmitter())
const el = createElement()

el.set('float', 'right')
el.set('placement', 'right')

assert.equal(el.node['mountX'], 1, 'Node mountX parameter should set to 1')
assert.equal(el.props.props['mountX'], 1, 'Props mountX parameter should set to 1')
assert.equal(el.node['x'], 1920, 'Node x parameter should set to parent node full width, 1920')
assert.equal(el.props.props['x'], 1920, 'props x parameter should be set to 1920')
assert.equal(
el.node['y'],
undefined,
'Node Y parameter should not be modified from default value'
)

assert.end()
})

test('Element - Set `placement` property with value `middle`', (assert) => {
assert.capture(renderer, 'createNode', () => new EventEmitter())
const el = createElement()

el.set('placement', 'middle')

assert.equal(el.node['mountY'], 0.5, 'Node mountY parameter should set to 0.5')
assert.equal(el.props.props['mountY'], 0.5, 'Props mountY parameter should set to 0.5')
assert.equal(el.node['y'], 540, 'Node Y parameter should set to half of parent node height, 540')
assert.equal(el.props.props['y'], 540, 'props Y parameter should be set to 540')
assert.equal(
el.node['x'],
undefined,
'Node X parameter should not be modified from default value'
)

assert.end()
})

test('Element - Set `placement` property with value `bottom`', (assert) => {
assert.capture(renderer, 'createNode', () => new EventEmitter())
const el = createElement()

el.set('placement', 'bottom')

assert.equal(el.node['mountY'], 1, 'Node mountY parameter should set to 1')
assert.equal(el.props.props['mountY'], 1, 'Props mountY parameter should set to 1')
assert.equal(el.node['y'], 1080, 'Node Y parameter should set to parent node full height, 1080')
assert.equal(el.props.props['y'], 1080, 'props Y parameter should be set to 1080')
assert.equal(
el.node['x'],
undefined,
'Node X parameter should not be modified from default value'
)

assert.end()
})

test('Element - Set `placement` property with value `bottom` & x = 300', (assert) => {
assert.capture(renderer, 'createNode', () => new EventEmitter())
const el = createElement()

el.set('placement', 'bottom')

assert.equal(el.node['mountY'], 1, 'Node mountY parameter should set to 1')
assert.equal(el.props.props['mountY'], 1, 'Props mountY parameter should set to 1')
assert.equal(el.node['y'], 1080, 'Node Y parameter should set to parent node full height, 1080')
assert.equal(el.props.props['y'], 1080, 'props Y parameter should be set to 1080')

el.set('x', 300)

assert.equal(el.node['x'], 300, 'Node x parameter should set custom value 300')

assert.end()
})

test('Element - Set `placement` property with object value `{x:"center", y:"middle"}`', (assert) => {
assert.capture(renderer, 'createNode', () => new EventEmitter())
const el = createElement()

el.set('placement', "{x:'center', y:'middle'}")

assert.equal(el.node['mountX'], 0.5, 'Node mountX parameter should set to 0.5')
assert.equal(el.props.props['mountX'], 0.5, 'Props mountX parameter should set to 0.5')
assert.equal(el.node['x'], 960, 'Node x parameter should set to half of parent node width, 960')

assert.equal(el.node['mountY'], 0.5, 'Node mountY parameter should set to 0.5')
assert.equal(el.props.props['mountY'], 0.5, 'Props mountY parameter should set to 0.5')
assert.equal(el.node['y'], 540, 'Node Y parameter should set to half of parent node height, 540')

assert.end()
})

test('Element - Set `placement` property with object value `{x:"center", y:"bottom"}`', (assert) => {
assert.capture(renderer, 'createNode', () => new EventEmitter())
const el = createElement()

el.set('placement', "{x:'center', y:'bottom'}")

assert.equal(el.node['mountX'], 0.5, 'Node mountX parameter should set to 0.5')
assert.equal(el.props.props['mountX'], 0.5, 'Props mountX parameter should set to 0.5')
assert.equal(el.node['x'], 960, 'Node x parameter should set to half of parent node width, 960')

assert.equal(el.node['mountY'], 1, 'Node mountY parameter should set to 1')
assert.equal(el.props.props['mountY'], 1, 'Props mountY parameter should set to 1')
assert.equal(el.node['y'], 1080, 'Node Y parameter should set to parent node full height , 1080')

assert.end()
})

test('Element - Set `placement` property with object value `{x:"right", y:"middle"}`', (assert) => {
assert.capture(renderer, 'createNode', () => new EventEmitter())
const el = createElement()

el.set('placement', "{x:'right', y:'middle'}")

assert.equal(el.node['mountX'], 1, 'Node mountX parameter should set to 1')
assert.equal(el.props.props['mountX'], 1, 'Props mountX parameter should set to 1')
assert.equal(el.node['x'], 1920, 'Node x parameter should set to parent node full width, 1920')

assert.equal(el.node['mountY'], 0.5, 'Node mountY parameter should set to 0.5')
assert.equal(el.props.props['mountY'], 0.5, 'Props mountY parameter should set to 0.5')
assert.equal(el.node['y'], 540, 'Node Y parameter should set to half of parent node height, 540')

assert.end()
})

test('Element - Set `placement` property with object value `{x:"right", y:"bottom"}`', (assert) => {
assert.capture(renderer, 'createNode', () => new EventEmitter())
const el = createElement()

el.set('placement', "{x:'right', y:'bottom'}")

assert.equal(el.node['mountX'], 1, 'Node mountX parameter should set to 1')
assert.equal(el.props.props['mountX'], 1, 'Props mountX parameter should set to 1')
assert.equal(el.node['x'], 1920, 'Node x parameter should set to parent node full width, 1920')

assert.equal(el.node['mountY'], 1, 'Node mountY parameter should set to 1')
assert.equal(el.props.props['mountY'], 1, 'Props mountY parameter should set to 1')
assert.equal(el.node['y'], 1080, 'Node Y parameter should set to parent node height, 1080')

assert.end()
})
Expand Down