Skip to content

Latest commit

Jul 24, 2026
21afec4 · · Jul 24, 2026

History

84 Commits

Folders and files

NameName
Last commit message
Last commit date
Jun 20, 2026
Jul 20, 2026
Jul 19, 2026
Jul 24, 2026
Jul 24, 2026
Jul 24, 2026
Jul 20, 2026
Jun 18, 2026
Jul 24, 2026
Jun 21, 2026
Jul 24, 2026
Jul 24, 2026
Jun 21, 2026
Jun 21, 2026
Jun 21, 2026
Jun 21, 2026
Jun 21, 2026

Repository files navigation

Move it!

hackatime badge

A library that adds simple PowerPoint like DOM object manipulation: resize, drag, and rotate. Pretty lightweight and comes with (very beautifully) styled controls. This library also provides the means for you to calculate collision via an implementation of oriented bounding boxes.

demo gif

Installing

Run npm i @andynoob/move-it and read on.

The lifecycle

Fully functional sample code can be found here.

Please ensure that the moving element is absolutely positioned, relative to the control root. Otherwise, expect the transform controls to be mis-fit around the moving element.

To start, create an instance of Moving by calling createMoveMe (or MoveIt.createMoveMe). For example:

const el = document.querySelector(/* ... */);

const controlRoot = el.parentElement!;

const snapping = {
   // omitted... we'll get to this later

};


const moving = createMoveMe(el, {
   initialState: { // optional, the code will call computeState on the target (first parameter) if this is absent
     x: 200,
     y: 200,
     width: 200,
     height: 120,
     rotation: 75,
   },
   format: {
     // when asPercent = true, the x, y, width, and height values is in 
     // percentages (in decimal) relative to the control root
     asPercent: false,
     // when centered = true, the RectState represents the pivot of the element (which can be changed
     // by `pivotOffset`). this can be used with usePercent. when this is paired with `autoSize`,
     // the library will keep the element centered on the pivot point whenever resizing happens
     centered: false
   },
  snappingg, // optional
  controlRoott, // required, sets the bounds for the object
   // when autoSize = true, the library stops assigning width and height directly via CSS, but rather syncs the 
   // `RectState` automatically whenever the size changes via DOM `ResizeObserver`.   
   // this also implicitly disables the resize feature. 
   autoSize: false,
   // percent (expressed as decimal) of each axis to offset the pivot point of the moving element.
   // this will impact the rotation pivot, the grid snapping location, and `autoSize` if enabled. the default pivot
   // point is the center of the element. to make it top left, do `{x: -0.5, y: -0.5}`. this will affect `centered` states
   pivotOffset: {x: 0, y: 0}

});

If initialState is not present as a part of the option parameter, computeState will be called to calculate a RectState from the target element (width, rotation, etc.).

Calling the createMoveMe function will return an instance of the Moving interface:

interface Moving {
   element: HTMLElement,
   id: string,
   /**

   * @description a copy of the current `RectState`. in the format option provided in the initial options

   */
   getState: () =>gt; RectState,
   /**

   * @description partial in the format option provided in the options

   */
   updateState: (partial: PartialRectState>gt;) =>gt; void,
   destroy: () =>gt; void,
   render: () =>gt; void,
   select: () =>gt; void,
   isSelected: () =>gt; boolean,
   checkBounds: () =>gt; void,
   updateControls: (select: boolean) =>gt; Controls,
   getCollisionSiblings: () =>gt; Moving[],
   /**

   * You need to do this for both instances, the behavior is not mirrored by default

   * For example, say you have `instanceA` and `instanceB`, you need to run both

   * `instanceA.addCollisionSibling(instanceB)` and `instanceB.addCollisionSibling(instanceA)`

   * for both instances to collide with the other.

   */
   addCollisionSibling: (sibling: Moving) =>gt; void,
   removeCollisionSibling: (sibling: Moving) =>gt; void,
   getOptions: () =>gt; MoveMeOpt

}

Call destroy when you're done moving the object.

The transform controls

The transform control is added immediately when you call the createMoveMe. As seen in the GIF below, it consists of five lines and five dots.

transforms gif

The CSS for these controls can be found here (the CONTROL_ID is E4UKgq3cxN, contrary to its name, it's actually a class). The style is injected into the ad> tag (if not present), under a