2.0.1 • Published 2 years ago

@lf2com/magnet.js v2.0.1

Weekly downloads
64
License
MIT
Repository
github
Last release
2 years ago

Magnet.js

Magnet.js is a JavaScript library making HTML elements attractable to each other.


Demo

Basic

Samples of using magnet.js:

Groups

Creates magnet blocks of different groups.

Get Started

:warning: Since 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/magnet.min.js"></script>
<!-- or -->
<script defer src="https://cdn.jsdelivr.net/gh/lf2com/magnet.js@latest/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

Build magnet.js with the command:

npm run build

The built would be at ./dist/magnet.min.js.

Magnet Nodes

There are 2 magnet elements: \<magnet-block> and \<magnet-pack>.

\<magnet-block>

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>

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>

Properties

Settable properties are defined as the confuration 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.

Multiple Values

If a property accepts multiple values. Use any of the following character as separator: |, ,, ;, or space.

.disabled

Type of getting 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'));

.group

Type of getting 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'));

.parentMagnet

Type of getting 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);

.unattractable

Type of getting 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'));

.unmovable

Type of getting 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'));

.attractDistance

Type of getting 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'));

.alignTos

Type of getting value: string[]

Default: ['outer', 'center', 'extend']

Accepts multiple values.

Sides of rectangle that can be converted to alignments for magnet aligning to other magnets:

NameDescription
outerAlign to the outer sides of target
innerAlign to the inner sides of target
centerAlign to the center lines of target
extendAlign 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'));

.alignToParents

Type of getting value: string[]

Default: []

Accepts multiple values.

Sides of rectangle that can be converted to alignments for magnet aligning to it's parent element.

NameDescription
innerAlign to the inner sides of target
centerAlign 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'));

.alignments

Type of getting value: string[]

Returns the side-to-side alignments from magnet to other magnets. The values are converted from .alignTos.

NameAlign toDescription
topToTopinnerSource top to target top
topToBottomouterSource top to target bottom
rightToRightinnerSource right to target right
rightToLeftouterSource right to target left
bottomToTopouterSource bottom to target top
bottomToBottominnerSource bottom to target bottom
leftToRightouterSource left to target right
leftToLeftinnerSource left to target left
xCenterToXCentercenterThe center of source left and right to the center of target left and right
yCenterToYCentercenterThe center of source top and bottom to the center of target top and bottom
// get alignments
console.log('Alignments:', magnet.alignments);

.parentAlignments

Type of getting 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);

.crossPrevents

Type of getting value: string[]

Default: []

Accepts multiple values.

Prevents magnet from crossing specific targets such as parent:

NameDescription
parentThe 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'));

.magnetRect

Returns temporarily created rectangle of magnet.

.magnetRect would not be updated util calling .resetMagnetRect

// get rectangle
console.log('Magnet rect:', magnet.magnetRect);

.parentPack

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);

.targetMagnetPacks

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);

.lastMagnetOffset

Returns the last offset in point of magnet.

const { x, y } = magnet.lastMagnetOffset;

// get last offset
console.log(`Last offset: (${x}, ${y})`);

.bestAttraction

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);

Methods

Magnet methods handle stuffs related to magnet such as alignment, distance, attraction, and position.

Static

Magnet.getAlignmentsFromAlignTo(alignTo)

ArgumentTypeDescription
alignTostring | 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']));

Magnet.getMagnetAttractionOffset(attraction)

ArgumentTypeDescription
attractionAttractionResult of magnet attraction

Returns the offset in point from attraction result.

Instance

.traceMagnetAttributeValue(attrName)

ArgumentTypeDescription
attrNamestringAttribute 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>

.resetMagnetRect()

Removes the temporarily created rectangle of the magnet.

.resetparentPack()

Removes the temporarily created pack of the magnet parent element.

.resetTargetMagnetPacks()

Removes the temporarily created packs of the magnet attractable targets.

.getOtherMagnets()

Returns all other magnet nodes except magnet packs and the magnet caller.

.getAttractableMagnets()

Returns all magnet elements attractable to the magnet caller.

Consideration:

PropertyDescription
disabledShould be false
unattractableShould be false
groupShould be seen as attractable group magnet as the magnet caller

.judgeMagnetDistance(distance, options?)

ArgumentTypeDescription
distanceDistanceResult of distance from distance.source to distance.target on distance.alignment
options?objectOptions 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:

NameTypeDescription
attractDistance?numberDistance of attraction. (Default .attractDistance)
alignTos?AlignToThe target alignment sides. (Default .alignTos)

.judgeMagnetDistanceInParent(distance, options?)

The same as .judgeMagnetDistance but also consider a wrapper as the parent.

Properties of options:

NameTypeDescription
parent?Pack | Rectable | nullWrapper as the parent. If parent is null or undefined, it would be default as .parentPack
onJudgeDistance?.judgeMagnetDistanceFunction for judging the distance result. (Default .judgeMagnetDistance)

.judgeMagnetAttraction(attraction)

ArgumentTypeDescription
attractionAttractionResult of attraction from attraction.source to attraction.target

Returns true if attraction passes the judgement.

.judgeMagnetMovement(pack)

ArgumentTypeDescription
packPackPack with the next movement as pack.rect for pack.raw

Returns true if the movement of pack passes the judgement.

.rawDistanceTo(target, alignment)

ArgumentTypeDescription
targetRectable | PackTarget for calculating the distance from magnet caller
alignmentAlignmentAlignment of distance

Returns the value of distance from magnet caller to target on specific alignment.

.distanceTo(target, alignment)

ArgumentTypeDescription
targetRectable | PackTarget for calculating the distance from magnet caller
alignmentAlignmentAlignment of distance

Returns the result of distance from magnet caller to target on specific alignment.

.attractionTo(target, options?)

ArgumentTypeDescription
targetRectable | PackTarget for calculating the attraction from magnet caller
options?objectOptions for attraction

Returns the result of attraction from magnet caller to target.

Properties of options:

NameTypeDescription
attractDistance?numberDistance of attraction. (Default .attractDistance)
alignTos?AlignToTarget alignment sides. (Default .alignTos)
alignments?AlignmentAlignments of attraction. (Default Magnet.getAlignmentsFromAlignTo(alignTos))
onJudgeDistance?.judgeMagnetDistanceFunction for judging the distance result. (Default .judgeMagnetDistance)

.attractionToParent(options?)

The same as .attractionTo but target is the parent of magnet caller.

Different default values of options:

NameDefault Value
alignTos.alignToParents

.multiAttractionsTo(targets, options?)

ArgumentTypeDescription
targets(Rectable | Pack)[]Targets for calculating the attraction from magnet caller
options?objectOptions for attraction

Returns the results of attractions from magnet caller to targets.

The properties of options extends that of .attractionTo:

NameTypeDescription
alignToParents?AlignToParent[]Target alignment sides to the parent of magnet caller. (Default .alignToParents)
attractionBest?AttractionBestInitial result of attraction joining the comparison of other attraction results
onJudgeAttraction?.judgeMagnetAttractionFunction for judging the attraction result. (Default .judgeMagnetAttraction)

.getMagnetAttractionResultOfPosition(position, options?)

ArgumentTypeDescription
positionPointTarget position for magnet caller to move to
options?objectOptions for attraction

Returns the result of final position and attraction after considering position and options:

NameTypeDescription
positionPoint | nullFinal position of magnet caller. If the movement doesn't pass the judgement, the value would be null
attractionBestAttractionBest | nullAttraction result. If the attraction doesn't pass the judgement, the value would be null

Properties of options:

NameTypeDescription
ignoreEvent?booleanSet true to ignore dispatching attraction related events to magnets. (Default true only if magnet caller is HTMLElement)
unattractable?booleanSet true to disallow attraction but consider options.crossPrevents. (Default .unattractable)
attractDistance?numberDistance of attraction. (Default .attractDistance)
alignTos?AlignToTarget alignment sides. (Default .alignTos)
alignments?AlignmentAlignments 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?PackParent of magnet caller. (Default .parentPack)
lastAttractionBest?AttractionBestReference result of attraction for attraction related events
onJudgeDistance?.judgeMagnetDistanceFunction for judging the distance result. (Default .judgeMagnetDistance)
onJudgeDistanceInParent?.judgeMagnetDistanceInParentFunction for judging the distance result to the parent of magnet caller. (Default .judgeMagnetDistanceInParent)
onJudgeAttraction?.judgeMagnetAttractionFunction for judging the attraction result. (Default .judgeMagnetAttraction)
onJudgeMovement?.judgeMagnetMovementFunction for judging the movement result. (Default .judgeMagnetAttraction)

.getMagnetAttractionResultOfPosition(x, y, options?)

ArgumentTypeDescription
xnumberValue on x-axis
ynumberValue on y-axis
options?objectOptions for attraction

The same as .getMagnetAttractionResultOfPosition(point, options?) but the input is (x, y).

.resetMagnetOffset()

Resets the offset of magnet to (0, 0).

.setMagnetOffset(dx, dy)

ArgumentTypeDescription
dxnumberOffset value on x-axis
dynumberOffset value on y-axis

Sets the offset of magnet to (dx, dy).

.setMagnetOffset(offset)

ArgumentTypeDescription
offsetPointOffset of magnet

The same as .setMagnetOffset but the input is Point.

.setMagnetPosition(x, y)

ArgumentTypeDescription
xnumberValue on x-axis
ynumberValue on y-axis

Sets the position of magnet to (x, y) without any judgement.

.setMagnetPosition(point)

ArgumentTypeDescription
pointPointPosition of magnet

The same as .setMagnetPosition but the input is Point.

Events

Events for magnet elements.

magnetstart

Cancelable: true

Magnet would not be dragged if the event is canceled.

Dispatches on starting to drag a magnet.

Properties of event.detail:

NameTypeDescription
sourcePackCurrent magnet info
targetsPack[]Attractable magnets
startPointPointThe start point of dragging

magnetmove

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:

NameTypeDescription
movePointPointThe move point of dragging

magnetend

Cancelable: false

Dispatches on the end of dragging a magnet.

attract

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:

NameTypeDescription
sourcePackCurrent magnet info
nextRectRectThe rectangle of magnet after attracting
attractionAttractionAttraction result from source to targets

attracted

Cancelable: false

Dispatches on the magnet being attracted by other magnet.

Properties of event.detail:

NameTypeDescription
sourcePackThe info of magnet attracting target
targetPackthe info of magnet being attracted by source
sourceNextRectRectThe rectangle of source after attracting
distanceDistanceDistance detail from source to target

attractmove

Cancelable: false

Dispatches on the magnet already attracting a magnet and still on moving.

Properties of event.detail are the same as attract.

attractedmove

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.

unattract

Cancelable: false

Dispatches on the magnet unattracting a magnet.

Properties of event.detail are the same as attract.

unattracted

Cancelable: false

Dispatches on the magnet being unattracted by other magnet.

Properties of event.detail:

NameTypeDescription
sourcePackThe info of magnet attracting target
targetPackthe info of magnet being attracted by source
sourceNextRectRectThe rectangle of source after attracting

Types

Rectable

Defines objects that are able to be converted to rectangle:

Point

Uses DOMPoint as the type of point (x, y).

Properties of point:

NameTypeDescription
xnumberValue on x-axis
ynumberValue on y-axis

Rectangle

Uses DOMRect as the type of rectangle.

Properties of rectangle:

NameTypeDescription
topnumberValue on y-axis. Always greater than or equal to bottom
rightnumberValue on x-axis. Always greater than or equal to left
bottomnumberValue on y-axis. Always lesser than or equal to top
rightnumberValue on x-axis. Always lesser than or equal to right
xnumberThe same as left
ynumberThe same as top
widthnumberValue of right minuses left
heightnumberValue of bottom minuses top

Pack

Wraps the source and its rectangle.

new Pack(source, rect?)

rect represents the rectangle of source since the rectangle may not be the same as the current one of source.

If rect is undefined, source must be rectable so that the rect could be generated from source.

Properties of pack object:

NameTypeDescription
rawanyReturns source
rectRectangleReturns rect of the stage on creation. Default is the rectangle based on source

Distance

Wraps the info from source to target.

Properties of distance object:

NameTypeDescription
sourcePackSource info
targetPackTarget info
alignmentAlignmentAlignment from source to target
rawDistancenumberDistance from source to target
absDistancenumberAbsolute distance from source to target

Attraction

Wraps the result(s) of source attracting to target(s).

Properties of attraction object:

NameTypeDescription
sourcePackSource info
targetPack | Pack[]Target info for .attractionTo. Targets infos in array for .multiAttractionsTo
resultsDistance[]Distance results from source to target on alignments
bestAttractionBestThe best attraction result

AttractionBest

Wraps the best distance results on axes of x and y.

Properties of best attraction object:

NameTypeDescription
x?DistanceThe best result on x-axis
y?DistanceThe best result on y-axis

License

MIT Copyright @ Wan Wan

2.0.1

2 years ago

1.0.9

2 years ago

1.0.8

4 years ago

1.0.7

4 years ago

1.0.6

4 years ago

1.0.5

5 years ago