Blocky.js is a JavaScript library for us to create blockys to build customized blocky chain. To know more about it, have a try here.
Drag blockys from template rows to the platform and composite them into a chain. Also we can get the root chain result in detail.
Blocky is a custom element extending native HTMLElement so that we could treat it as a HTML element.
Create blocky elements by the following ways:
Create a blocky by HTML tag:
<blocky-block type="stackTop">
This is a stackTop blocky
</blocky-block>
Create a blocky by JavaScript:
let blocky = document.createElement('blocky-block');
blocky.setAttribute('type', 'stackTop');
blocky.innerHTML = 'This is a stackTop blocky';
document.body.appendChild(blocky);
Or create a blocky by newing a blocky object:
let blocky = new BlockyBlack(); // if use released blocky.js
blocky.type = 'stackTop';
blocky.innerHTML = 'This is a stackTop blocky';
document.body.appendChild(blocky);
Create a series of blockys:
<blocky-block type="stackTop">
#top
<blocky-block type="stackMiddle">
#middle
<blocky-block type="stackBottom">
#bottom
</blocky-block>
</blocky-block>
</blocky-block>
<blocky-block type="composite">
#composite
<blocky-block type="contained">
#contained-1
<blocky-block type="contained">
#contained-2
</blocky-block>
</blocky-block>
</blocky-block>
Equals to
function createBlocky(type, html) {
let blocky = document.createElement('blocky-block');
blocky.type = type;
blocky.innerHTML = html;
return blocky;
}
let topBlocky = createBlocky('stackTop', '#top');
let middleBlocky = createBlocky('stackMiddle', '#middle');
let bottomBlocky = createBlocky('stackBottom', '#bottom');
topBlocky.appendChild(middleBlocky);
middleBlocky.appendChild(bottomBlocky);
document.body.appendChild(topBlocky);
let compositeBlocky = createBlocky('composite', '#composite');
let contained1Blocky = createBlocky('contained', '#contained-1');
let contained2Blocky = createBlocky('contained', '#contained-2');
compositeBlocky.appendChild(contained1Blocky);
contained1Blocky.appendChild(contained2Blocky);
document.body.appendChild(compositeBlocky);
Types of blocky that we can use to create blocky.
Type | Value |
---|---|
stackTop | stackTop |
stackMiddle | stackMiddle |
stackBottom | stackBottom |
composite | composite |
contained | contained |
expression | expression |
expressionHole | expressionHole |
console.log(Blocky.TYPE.stackTop); // "stackTop"
Types of link way that blockys connect to each other.
Type | Value | Reversed Type |
---|---|---|
last | last |
next |
next | next |
last |
parent | parent |
parent |
child | child |
child |
console.log(Blocky.LINK_TYPE.last); // "last"
Node name of blocky.
Always get blocky-block
.
console.log(Blocky.nodeName); // "blocky-block"
Get/set the distance of attracting blockys.
20
in pixel for default.
console.log(Blocky.attractDistance); // 20
Blocky.attractDistance = 30;
console.log(Blocky.attractDistance); // 30
Get/set the handler that sets the position of blocky offset.
console.log(Blocky.onSetBlockyOffset); // null
// What the default handler does is like
Blocky.onSetBlockyOffset = function(x, y) {
// Set translate of transform on the blockyContainerDOM
this.blockyContainerDOM.style.transform = `translate(${x}px, ${y}px)`;
};
console.log(Blocky.onSetBlockyOffset); // The above function
Get/set blocky type.
console.log(blocky.type);
// equals to
console.log(blocky.getAttribute('type'));
blocky.type = 'stackTop';
// equals to
blocky.setAttribute('type', 'stackTop');
Blocky supports the following types:
Used as the root/topest blocky of the chain.
console.log(Blocky.TYPE.stackTop); // "stackTop"
Last: none
Next: stackMiddle, stackBottom, composite
Parent: none
Child: none
Used as the middle blocky to link blockys on the main chain.
console.log(Blocky.TYPE.stackMiddle); // "stackMiddle"
Last: stackTop, stackMiddle, composite
Next: stackMiddle, composite, stackBottom
Parent: none
Child: none
Used as the end blocky of the chain.
console.log(Blocky.TYPE.stackBottom); // "stackBottom"
Last: stackTop, stackMiddle, composite
Next: none
Parent: none
Child: none
Similar to stackMiddle blocky but could hold child blocky.
console.log(Blocky.TYPE.composite); // "composite"
Last: stackTop, stackMiddle, composite
Next: stackMiddle, composite, stackBottom
Parent: none
Child: contained
Similar to stackMiddle blocky but could only exist as a child blocky.
console.log(Blocky.TYPE.contained); // "contained"
Last: contained
Next: contained
Parent: composite
Child: none
Used to connect to expressionHole blocky as parent blocky.
console.log(Blocky.TYPE.expression); // "expression"
Last: none
Next: none
Parent: expressionHole
Child: none
Used to hold expression blocky as child blocky.
console.log(Blocky.TYPE.expressionHole); // "expressionHole"
Last: none
Next: none
Parent: none
Child: expression
Get/set whether the blocky is draggable and attractable or not true|false
.
console.log(blocky.disabled);
// equals to
console.log(blocky.getAttribute('disabled'));
blocky.disabled = true;
// equals to
blocky.setAttribute('disabled', '');
The array of blocky types that can be the last blocky for this blocky.
console.log(stackTopBlocky.lastableBlockyTypes); // []
console.log(stackBottomBlocky.lastableBlockyTypes); // ["stackTop", "stackMiddle", "composite"]
The array of blocky types that can be the next blocky for this blocky.
console.log(stackTopBlocky.nextableBlockyTypes); // ["stackMiddle", "stackBottom", "composite"]
console.log(stackBottomBlocky.nextableBlockyTypes); // []
The array of blocky types that can be the parent blocky for this blocky.
console.log(stackTopBlocky.parentableBlockyTypes); // []
console.log(containedBlocky.parentableBlockyTypes); // ["composite"]
The array of blocky types that can be the child blocky for this blocky.
console.log(stackTopBlocky.childableBlockyTypes); // []
console.log(compositeBlocky.childableBlockyTypes); // ["contained"]
The array of blocky types that can be the top blocky for this blocky. That is the combination of lastableBlockyTypes and parentableBlockyTypes.
console.log(containedBlocky.lastableBlockyTypes); // ["contained"]
console.log(containedBlocky.parentableBlockyTypes); // ["composite"]
console.log(containedBlocky.rootableBlockyTypes); // ["contained", "composite"]
The array of blocky types that can be the bottom blocky for this blocky. That is the combination of nextableBlockyTypes and childableBlockyTypes.
console.log(compositeBlocky.nextableBlockyTypes); // ["stackMiddle", "composite", "stackBottom"]
console.log(compositeBlocky.childableBlockyTypes); // ["contained"]
console.log(compositeBlocky.leafableBlockyTypes); // ["stackMiddle", "composite", "stackBottom", "contained"]
The array of blocky types that can be any linkable blocky for the blocky. That is the combination of rootableBlockyTypes and leafableBlockyTypes.
console.log(stackTopBlocky.attractableBlockyTypes); // ["stackMiddle", "stackBottom", "composite"]
The last blocky of this blocky.
null
if not exist.
The next blocky of this blocky.
null
if not exist.
The parent blocky of this blocky.
null
if not exist.
The child blocky of this blocky.
null
if not exist.
The container DOM hosting the shape and content of this blocky.
The next blocky container DOM hosting the next blocky of this blocky.
To access the next blocky, call nextBlocky.
The child blocky container DOM hosting the child blocky of this blocky.
To access the child blocky, call childBlocky.
The topest blocky of this blocky. That is finding the last/parent blocky until hits the root.
Return this
if there is no last/parent blocky for this blocky.
The layers from the rootestBlocky of this blocky.
0
if this blocky is the topest blocky.
The array of all the next blockys from this blocky.
The last blocky of nextBlockys from this blocky.
this
if there is no next blocky for this blocky.
The array of all child blockys belong to this blocky.
Syntax: getBlockyOffset()
Return offset [x, y]
of this blocky in pixel unit.
Syntax: setBlockyOffset(x, y)
Set offset [x, y]
of this blocky in pixel unit.
Syntax: addBlockyOffset(dx, dy)
Add offset differences [dx, dy]
of this blocky in pixel unit.
let [x, y] = blocky.getBlockyOffset();
blocky.setBlokcyOffset((x + 10), (y + 20));
// equals to
blocky.addBlockyOffset(10, 20);
Syntax: linkBlockyTest(target[, options])
Get the result of attraction between this blocky and target blocky.
Options
Property | Type | Description |
---|---|---|
targetRect | Object | Rectangle (x , y , width , height ) of target blocky to detect attraction |
selfRect | Object | Rectangle (x , y , width , height ) of this blocky to detect attraction |
Return
Property | Type | Description |
---|---|---|
distance | Number | Distance between this blocky and target blocky. Infinity if unable to attract. |
linkType | String | Link type for this blocky to connect to target blocky. null if unable to attract. |
target.type | String | Blocky type of target blocky. |
target.blocky | Blocky | Target blocky element. |
self.type | String | Blocky type of this blocky. |
self.blocky | Blocky | This blocky element. |
Syntax: linkBlocky(linkType, target)
Connect a target blocky to this blocky by specific link type.
stackTopBlocky.linkBlocky('next', stackBottomBlocky);
// equals to
stackBottomBlocky.linkBlocky('last', stackTopBlocky);
compositeBlocky.linkBlocky('child', containedBlocky);
// equals to
containedBlocky.linkBlocky('parent', compositeBlocky);
Syntax: unlinkBlocky(linkType)
Disconnect specific link type of this blocky.
Return
Disconnected blocky.
null
if there is no connected blocky.
stackTopBlocky.unlinkBlocky('next'); // null
stackTopBlocky.linkBlocky('next', stackBottomBlocky);
stackTopBlocky.unlinkBlocky('next'); // stackBottomBlocky
Syntax: unlinkAllBlockys()
Disconnect all link types of this blocky.
stackTopBlocky.unlinkAllBlockys();
Except expressionHole blocky, all the other blocky types are default set their style as:
position: absolute;
height: 0;
The mission of expressionHole blocky is not to be dragged for connecting but to be the container of expression blocky. So it is designed to be used as a normal inline HTML element such as
<span>
.
Until the blocky is connected as one's child/next blocky, its style would be set as:
position: relative;
height: auto;
NOTICE: The DOM handling position of a blocky is the shadow DOM element belong to the blocky element. Setting position on the blocky element might cause unexpected result on dragging and connecting.
To change the position of blockys, use setBlockyOffset to set the [x, y]
in pixel on the actual blocky DOM.
To get the current position of blockys, use getBlockyOffset to get the [x, y]
of the blocky in pixel.
Currently the default handler sets [x, y]
by unit of pixel. We can replace onSetBlockyOffset to handle the changes ourselves.
Based on the demo. Here are 2 samples about getting chain of blockys:
Get the array of next blockys with branches of child's next blockys.
Each element of array in result
Property | Type | Description |
---|---|---|
target | Blocky | Blocky element. |
child | Array | Array of child chain if exist. |
let chain = [rootBlocky]
.concat(rootBlocky.nextBlockys)
.map(function(node) {
return {
target: node,
child: node.childBlockys,
};
});
Get the linked list of next/child blockys.
Each element in result
Property | Type | Description |
---|---|---|
target | Blocky | Blocky element. |
next | Object | Object of next chain. null if not exist. |
child | Object | Object of child chain. null if not exist. |
function getLeaf(node) {
if (!node) {
return null;
}
return {
target: node,
next: getLeaf(node.nextBlocky),
child: getLeaf(node.childBlocky),
};
}
let chain = getLeaf(rootBlocky);