Magnet.js is a JavaScript library making HTML elements attractable to each other.
Samples of using magnet.js:
Creates magnet blocks of different groups.
v2.0.0
, magnet.js has become a HTML element for us to wrap other elements or directly use it as a attractable block.
Add magnet.js to your HTML file:
<script defer src="https://unpkg.com/@lf2com/magnet.js@latest/dist/magnet.min.js"></script>
<!-- or -->
<script defer src="https://cdn.jsdelivr.net/gh/lf2com/magnet.js@latest/dist/magnet.min.js"></script>
We can use magnets directly in HTML:
<magnet-block
style="width: 100px; height: 50px; background: #fcc;"
attract-distance="10"
align-to="outer|center"
>
foo
</magnet-block>
<magnet-block attract-distance="10" align-to="outer|center">
<div style="width: 100px; height: 50px; background: #fcc;">
bar
</div>
</magnet-block>
Or in JavaScript code:
const magnet = document.createElement('magnet-block');
magnet.setAttribute('attract-distance', '10');
magnet.setAttribute('align-to', 'outer|center');
// or
magnet.attractDistance = 10;
magnet.alignTos = ['outer', 'center'];
magnet.style.setProperty('width', '100px');
magnet.style.setProperty('height', '50px');
magnet.style.setProperty('background', '#fcc');
magnet.innerText = 'foo';
document.body.append(magnet);
Since magnet.js is an element, we can handle it with jQuery:
$('<magnet-block>')
.attr({
'attract-distance': '10',
'align-to': 'outer|center',
})
.css({
width: '100px',
height: '50px',
background: '#fcc',
})
.html('foo')
.appendTo($('body'));
Of course we can use it in React:
const Magnet = () => (
<magnet-block
style={{
width: '100px',
height: '50px',
background: '#fcc',
}}
attract-distance="10"
align-to="outer|center"
>
foo
</magnet-block>
);
Build magnet.js with the command:
npm run build
The built would be at ./dist/magnet.min.js
.
There are 2 magnet elements: <magnet-block> and <magnet-pack>.
Magnet block can be dragged and attracted by other magnets.
<magnet-block>
<div style="padding: 1em; background-color: #eee;">
magnet
</div>
</magnet-block>
<!-- or directly use <magnet-block> -->
<magnet-block style="padding: 1em; background-color: #eee;">
magnet
</magnet-block>
Magnet pack is unable to be dragged but it defines the default values for it's sub magnets. The sub manget blocks would reference to the nearest parent magnet pack for the attribute value if it doesn't have assigned the corresponding values.
<magnet-pack attract-distance="20">
<!-- distance of attraction is 10 -->
<magnet-block attract-distance="10">
10
</magnet-block>
<!-- distance of attraction is 20 -->
<magnet-block>
default
</magnet-block>
</magnet-pack>
Settable properties are defined as the configuration values of magnet element. If the magnet has no some magnet settings, it would reference to the nearest parent magnet having the value. Otherwise the value would be the default one.
If a property accepts multiple values. Use any of the following character as separator: |
, ,
, ;
, or space.
Type of value:
boolean
Default:
false
If set, the magnet would be unable to be dragging and attracted.
<!-- disabled magnet -->
<magnet-block disabled>
magnet
</magnet-block>
// disable magnet
magnet.disabled = true;
// or
magnet.setAttribute('disabled', '');
// get disabled
console.log('Disabled:', magnet.disabled);
// or
console.log('Disabled:', magnet.hasAttribute('disabled'));
Type of value:
string
|null
Default:
null
as ungrouped
The group of magnet element. Once we assign a group for a magnet, it would only attract magnets in the same group. If no group is assigned, the magnet can attract all magnets including grouped ones.
<!-- set group -->
<magnet-block group="alpha">
alpha
</magnet-block>
<magnet-block group="beta">
beta
</magnet-block>
<magnet-block>
ungrouped
</magnet-block>
// set group
magnet.group = 'alpha';
// or
magnet.setAttribute('group', 'alpha');
// get group
console.log('Group:', magnet.group);
// or
console.log('Group:', magnet.getAttribute('group'));
Type of value:
Magnet
Returns the nearest parent magnet node.
The
.parentMagnet
of grouped magnet would be the nearest parent magnet in the same group or ungrouped one.
// get parent magnet
console.log('Nearest parent magnet:', magnet.parentMagnet);
Type of value:
boolean
Default:
false
If set, the magnet would not be attracted.
<!-- set unattractable -->
<magnet-block unattractable>
magnet
</magnet-block>
// set unattractable
magnet.unattractable = true;
// or
magnet.setAttribute('unattractable', '');
// get unattractable
console.log('Unattractable:', magnet.unattractable);
// or
console.log('Unattractable:', magnet.hasAttribute('unattractable'));
Type of value:
boolean
Default:
false
If set, the magnet would not be dragged.
<!-- set unmovable -->
<magnet-block unmovable>
magnet
</magnet-block>
// set unmovable
magnet.unmovable = true;
// or
magnet.setAttribute('unmovable', '');
// get unmovable
console.log('Unmovable:', magnet.unmovable);
// or
console.log('Unmovable:', magnet.hasAttribute('unmovable'));
Type of value:
number
Default:
10
Distance for magnet being dragged to attract other magnets.
We don't define the distance for magnet to be attracted.
<!-- set distance of attraction -->
<magnet-block attract-distance="20">
magnet 20
</magnet-block>
<!-- default distance of attraction -->
<magnet-block>
magnet default
</magnet-block>
// set distance of attraction
magnet.attractDistance = 20;
// or
magnet.setAttribute('attract-distance', '20');
// get distance of attracion in number
console.log('Attraction distance:', magnet.attractDistance);
// or in string
console.log('Attraction distance:', magnet.getAttribute('attract-distance'));
Type of value:
string[]
Default:
['outer', 'center', 'extend']
Accepts multiple values.
Sides of rectangle that can be converted to alignments for magnet aligning to other magnets:
Name | Description |
---|---|
outer | Align to the outer sides of target |
inner | Align to the inner sides of target |
center | Align to the center lines of target |
extend | Align to extended line of assigned alignment including outer , inner and center |
<!-- set align to -->
<magnet-block align-to="outer|extend">
magnet
</magnet-block>
// set align to
magnet.alignTos = ['outer', 'extend'];
// or
magnet.alignTos = 'outer|extend';
// oe
magnet.setAttribute('align-to', 'outer|extend');
// get align-to in array
console.log('Align to:', magnet.alignTos);
// or in string
console.log('Align to:', magnet.getAttribute('align-to'));
Type of value:
string[]
Default:
[]
Accepts multiple values.
Sides of rectangle that can be converted to alignments for magnet aligning to it's parent element.
Name | Description |
---|---|
inner | Align to the inner sides of target |
center | Align to the center lines of target |
<!-- set align to parent -->
<magnet-block align-to-parent="inner|center">
magnet
</magnet-block>
// set align to parent
magnet.alignToParents = ['inner', 'center'];
// or
magnet.alignToParents = 'inner|center';
// oe
magnet.setAttribute('align-to-parent', 'inner|center');
// get align-to-parent in array
console.log('Align to parent:', magnet.alignToParents);
// or in string
console.log('Align to parent:', magnet.getAttribute('align-to-parent'));
Type of value:
string[]
Returns the side-to-side alignments from magnet to other magnets. The values are converted from .alignTos
.
Name | Align to | Description |
---|---|---|
topToTop | inner | Source top to target top |
topToBottom | outer | Source top to target bottom |
rightToRight | inner | Source right to target right |
rightToLeft | outer | Source right to target left |
bottomToTop | outer | Source bottom to target top |
bottomToBottom | inner | Source bottom to target bottom |
leftToRight | outer | Source left to target right |
leftToLeft | inner | Source left to target left |
xCenterToXCenter | center | The center of source left and right to the center of target left and right |
yCenterToYCenter | center | The center of source top and bottom to the center of target top and bottom |
// get alignments
console.log('Alignments:', magnet.alignments);
Type of value:
string[]
Returns the side-to-side alignments from magnet to it's parent element. The values are converted from .alignToParents
.
// get alignments to parent
console.log('Alignments to parent:', magnet.parentAlignments);
Type of value:
string[]
Default:
[]
Accepts multiple values.
Prevents magnet from crossing specific targets such as parent
:
Name | Description |
---|---|
parent | The parent element of magnet |
<!-- set cross prevent -->
<magnet-block cross-prevent="parent">
magnet
</magnet-block>
// set cross prevent
magnet.crossPrevents = ['parent'];
// or
magnet.crossPrevents = 'parent';
// or
magnet.setAttribute('cross-prevent', 'parent');
// get cross-prevent in array
console.log('Cross prevent:', magnet.crossPrevents);
// or in string
console.log('Cross prevent:', magnet.getAttribute('cross-prevent'));
Returns temporarily created rectangle of magnet.
.magnetRect
would not be updated util calling.resetMagnetRect
// get rectangle
console.log('Magnet rect:', magnet.magnetRect);
Returns temporarily created pack of the parent element of magnet.
.parentPack
would not be updated util calling.resetParentPack
const parentPack = magnet.parentPack;
// get parent element
console.log('Parent element:', parentPack.raw);
// get parent rectangle
console.log('Parent rect:', parentPack.rect);
Returns temporarily created packs of attractable magnets.
.targetMagnetPacks
would not be updated util calling.resetTargetMagnetPacks
// get target magnet packs
console.log('Attractable magnet packs:', magnet.targetMagnetPacks);
Returns the last offset in point of magnet.
const { x, y } = magnet.lastMagnetOffset;
// get last offset
console.log(`Last offset: (${x}, ${y})`);
Returns the best attraction in the last attraction.
const { x, y } = magnet.bestAttraction;
// get best attraction result
console.log('Best attraction on x-axis:', x);
console.log('Best attraction on y-axis:', y);
Magnet methods handle stuffs related to magnet such as alignment, distance, attraction, and position.
Argument | Type | Description |
---|---|---|
alignTo | string | string[] | Value(s) of sides to align |
Returns the array of alignments converted from alignTo
values.
// get alignments of align-to
console.log('Alignments:', Magnet.getAlignmentsFromAlignTo('inner'));
// get alignments of align-tos
console.log('Alignments:', Magnet.getAlignmentsFromAlignTo(['outer', 'inner']));
Argument | Type | Description |
---|---|---|
attraction | Attraction | Result of magnet attraction |
Returns the offset in point from attraction
result.
Argument | Type | Description |
---|---|---|
attrName | string | Attribute name |
Returns the value of specific attribute name of magnet. If the magnet doesn't have the value, it would reference to the nearest parent magnet having the value. Or return null
rather than global default value.
// get group
const group = magnet.traceMagnetAttributeValue('group');
// equals to (due to the default value is `null` too)
const group = magnet.group;
<!-- custom attribute -->
<magnet-pack some-attr="some-value">
<magnet-block id="magnet">
magnet
</magnet-block>
</magnet-pack>
<script>
const magnet = document.getElementById('magnet');
// trace the custom attribute
magnet.traceMagnetAttributeValue('some-attr'); // 'some-value'
</script>
Removes the temporarily created rectangle of the magnet.
Removes the temporarily created pack of the magnet parent element.
Removes the temporarily created packs of the magnet attractable targets.
Returns all other magnet nodes except magnet packs and the magnet caller.
Returns all magnet elements attractable to the magnet caller.
Consideration:
Property | Description |
---|---|
disabled | Should be false |
unattractable | Should be false |
group | Should be seen as attractable group magnet as the magnet caller |
Argument | Type | Description |
---|---|---|
distance | Distance | Result of distance from distance.source to distance.target on distance.alignment |
options? | object | Options for judgement |
Returns true
if distance
passes the judgement.
This method would be called for judging distance result on any method related to attraction.
Properties of options
:
Name | Type | Description |
---|---|---|
attractDistance? | number | Distance of attraction. (Default .attractDistance ) |
alignTos? | AlignTo | The target alignment sides. (Default .alignTos ) |
The same as .judgeMagnetDistance
but also consider a wrapper as the parent.
Properties of options
:
Name | Type | Description |
---|---|---|
parent? | Pack | Rectable | null | Wrapper as the parent. If parent is null or undefined , it would be default as .parentPack |
onJudgeDistance? | .judgeMagnetDistance |
Function for judging the distance result. (Default .judgeMagnetDistance ) |
Argument | Type | Description |
---|---|---|
attraction | Attraction | Result of attraction from attraction.source to attraction.target |
Returns true
if attraction
passes the judgement.
Argument | Type | Description |
---|---|---|
pack | Pack | Pack with the next movement as pack.rect for pack.raw |
Returns true
if the movement of pack
passes the judgement.
Argument | Type | Description |
---|---|---|
target | Rectable | Pack | Target for calculating the distance from magnet caller |
alignment | Alignment | Alignment of distance |
Returns the value of distance from magnet caller to target
on specific alignment
.
Argument | Type | Description |
---|---|---|
target | Rectable | Pack | Target for calculating the distance from magnet caller |
alignment | Alignment | Alignment of distance |
Returns the result of distance from magnet caller to target
on specific alignment
.
Argument | Type | Description |
---|---|---|
target | Rectable | Pack | Target for calculating the attraction from magnet caller |
options? | object | Options for attraction |
Returns the result of attraction from magnet caller to target
.
Properties of options
:
Name | Type | Description |
---|---|---|
attractDistance? | number | Distance of attraction. (Default .attractDistance ) |
alignTos? | AlignTo | Target alignment sides. (Default .alignTos ) |
alignments? | Alignment | Alignments of attraction. (Default Magnet.getAlignmentsFromAlignTo(alignTos) ) |
onJudgeDistance? | .judgeMagnetDistance |
Function for judging the distance result. (Default .judgeMagnetDistance ) |
The same as .attractionTo
but target
is the parent of magnet caller.
Different default values of options
:
Name | Default Value |
---|---|
alignTos | .alignToParents |
Argument | Type | Description |
---|---|---|
targets | (Rectable | Pack)[] | Targets for calculating the attraction from magnet caller |
options? | object | Options for attraction |
Returns the results of attractions from magnet caller to targets
.
The properties of options
extends that of .attractionTo
:
Name | Type | Description |
---|---|---|
alignToParents? | AlignToParent[] | Target alignment sides to the parent of magnet caller. (Default .alignToParents ) |
attractionBest? | AttractionBest | Initial result of attraction joining the comparison of other attraction results |
onJudgeAttraction? | .judgeMagnetAttraction |
Function for judging the attraction result. (Default .judgeMagnetAttraction ) |
Argument | Type | Description |
---|---|---|
position | Point | Target position for magnet caller to move to |
options? | object | Options for attraction |
Returns the result of final position and attraction after considering position
and options
:
Name | Type | Description |
---|---|---|
position | Point | null | Final position of magnet caller. If the movement doesn't pass the judgement, the value would be null |
attractionBest | AttractionBest | null | Attraction result. If the attraction doesn't pass the judgement, the value would be null |
Properties of options
:
Name | Type | Description |
---|---|---|
ignoreEvent? | boolean | Set true to ignore dispatching attraction related events to magnets. (Default true only if magnet caller is HTMLElement) |
unattractable? | boolean | Set true to disallow attraction but consider options.crossPrevents . (Default .unattractable ) |
attractDistance? | number | Distance of attraction. (Default .attractDistance ) |
alignTos? | AlignTo | Target alignment sides. (Default .alignTos ) |
alignments? | Alignment | Alignments of attraction. (Default the alignments converted from alignTos ) |
alignToParents? | AlignToParent[] | Target alignment sides to the parent of magnet caller. (Default .alignToParents ) |
crossPrevents? | CrossPrevent[] | Prevent from crossing specific objectives. (Default `.crossPrevents) |
parentPack? | Pack | Parent of magnet caller. (Default .parentPack ) |
lastAttractionBest? | AttractionBest | Reference result of attraction for attraction related events |
onJudgeDistance? | .judgeMagnetDistance |
Function for judging the distance result. (Default .judgeMagnetDistance ) |
onJudgeDistanceInParent? | .judgeMagnetDistanceInParent |
Function for judging the distance result to the parent of magnet caller. (Default .judgeMagnetDistanceInParent ) |
onJudgeAttraction? | .judgeMagnetAttraction |
Function for judging the attraction result. (Default .judgeMagnetAttraction ) |
onJudgeMovement? | .judgeMagnetMovement |
Function for judging the movement result. (Default .judgeMagnetAttraction ) |
Argument | Type | Description |
---|---|---|
x | number | Value on x-axis |
y | number | Value on y-axis |
options? | object | Options for attraction |
The same as .getMagnetAttractionResultOfPosition(point, options?)
but the input is (x
, y
).
Resets the offset of magnet to (0
, 0
).
Argument | Type | Description |
---|---|---|
dx | number | Offset value on x-axis |
dy | number | Offset value on y-axis |
Sets the offset of magnet to (dx
, dy
).
Argument | Type | Description |
---|---|---|
offset | Point | Offset of magnet |
The same as .setMagnetOffset but the input is Point.
Argument | Type | Description |
---|---|---|
x | number | Value on x-axis |
y | number | Value on y-axis |
Sets the position of magnet to (x
, y
) without any judgement.
Argument | Type | Description |
---|---|---|
point | Point | Position of magnet |
The same as .setMagnetPosition but the input is Point.
Events for magnet elements.
Cancelable:
true
Magnet would not be dragged if the event is canceled.
Dispatches on starting to drag a magnet.
Properties of event.detail
:
Name | Type | Description |
---|---|---|
source | Pack | Current magnet info |
targets | Pack[] | Attractable magnets |
startPoint | Point | The start point of dragging |
Cancelable:
true
Magnet would not move at that step if the event is canceled.
Dispatches on dragging a magnet.
Properties of event.detail
extend those of magnetstart:
Name | Type | Description |
---|---|---|
movePoint | Point | The move point of dragging |
Cancelable:
false
Dispatches on the end of dragging a magnet.
Cancelable:
true
The magnet would not attract the target magnet if the event is canceled.
Dispatches on the magnet attracting other magnet.
Properties of event.detail
:
Name | Type | Description |
---|---|---|
source | Pack | Current magnet info |
nextRect | Rect | The rectangle of magnet after attracting |
attraction | Attraction | Attraction result from source to targets |
Cancelable:
false
Dispatches on the magnet being attracted by other magnet.
Properties of event.detail
:
Name | Type | Description |
---|---|---|
source | Pack | The info of magnet attracting target |
target | Pack | the info of magnet being attracted by source |
sourceNextRect | Rect | The rectangle of source after attracting |
distance | Distance | Distance detail from source to target |
Cancelable:
false
Dispatches on the magnet already attracting a magnet and still on moving.
Properties of event.detail
are the same as attract.
Cancelable:
false
Dispatches on the magnet being attracted by other magnet and it's still on moving.
Properties of event.detail
are the same as attract.
Cancelable:
false
Dispatches on the magnet unattracting a magnet.
Properties of event.detail
are the same as attract.
Cancelable:
false
Dispatches on the magnet being unattracted by other magnet.
Properties of event.detail
:
Name | Type | Description |
---|---|---|
source | Pack | The info of magnet attracting target |
target | Pack | the info of magnet being attracted by source |
sourceNextRect | Rect | The rectangle of source after attracting |
Defines objects that are able to be converted to rectangle:
- DOMRect
- HTMLElement
document
window
Uses DOMPoint as the type of point (x
, y
).
Properties of point:
Name | Type | Description |
---|---|---|
x | number | Value on x-axis |
y | number | Value on y-axis |
Uses DOMRect as the type of rectangle.
Properties of rectangle:
Name | Type | Description |
---|---|---|
top | number | Value on y-axis. Always greater than or equal to bottom |
right | number | Value on x-axis. Always greater than or equal to left |
bottom | number | Value on y-axis. Always lesser than or equal to top |
right | number | Value on x-axis. Always lesser than or equal to right |
x | number | The same as left |
y | number | The same as top |
width | number | Value of right minuses left |
height | number | Value of bottom minuses top |
Wraps the source and its rectangle.
rect
represents the rectangle of source
since the rectangle may not be the same as the current one of source
.
If
rect
isundefined
,source
must be rectable so that therect
could be generated fromsource
.
Properties of pack object:
Name | Type | Description |
---|---|---|
raw | any | Returns source |
rect | Rectangle | Returns rect of the stage on creation. Default is the rectangle based on source |
Wraps the info from source to target.
Properties of distance object:
Name | Type | Description |
---|---|---|
source | Pack | Source info |
target | Pack | Target info |
alignment | Alignment | Alignment from source to target |
rawDistance | number | Distance from source to target |
absDistance | number | Absolute distance from source to target |
Wraps the result(s) of source attracting to target(s).
Properties of attraction object:
Name | Type | Description |
---|---|---|
source | Pack | Source info |
target | Pack | Pack[] | Target info for .attractionTo . Targets infos in array for .multiAttractionsTo |
results | Distance[] | Distance results from source to target on alignments |
best | AttractionBest | The best attraction result |
Wraps the best distance results on axes of x and y.
Properties of best attraction object:
Name | Type | Description |
---|---|---|
x? | Distance | The best result on x-axis |
y? | Distance | The best result on y-axis |
MIT Copyright @ Wan Wan