Convert Figma logo to code with AI

daybrush logomoveable

Moveable! Draggable! Resizable! Scalable! Rotatable! Warpable! Pinchable! Groupable! Snappable!

9,916
612
9,916
436

Top Related Projects

Beautiful and accessible drag and drop for lists with React

A set of higher-order components to turn any list into an animated, accessible and touch-friendly sortable list✌️

10,773

Infinite responsive, sortable, filterable and draggable layouts

29,388

Reorderable drag-and-drop lists for modern browsers and touch devices. No jQuery or framework required.

🖱 A resizable and draggable component for React.

A draggable and resizable grid layout with responsive breakpoints, for React.

Quick Overview

Moveable is a powerful JavaScript library that enables draggable, resizable, scalable, rotatable, and groupable elements on web pages. It provides a versatile set of tools for creating interactive user interfaces with smooth and customizable element manipulation.

Pros

  • Highly flexible with support for multiple transformation types (drag, resize, rotate, etc.)
  • Extensive customization options for appearance and behavior
  • Supports both mouse and touch events for broad device compatibility
  • Lightweight and performant, with minimal dependencies

Cons

  • Steep learning curve due to the wide range of features and options
  • Documentation could be more comprehensive, especially for advanced use cases
  • Some users report occasional issues with complex nested transformations
  • Limited built-in styling options, requiring additional CSS for polished looks

Code Examples

Creating a basic moveable element:

import Moveable from "moveable";

const moveable = new Moveable(document.body, {
  target: document.querySelector(".target"),
  draggable: true,
  resizable: true,
  rotatable: true
});

moveable.on("drag", ({ target, transform }) => {
  target.style.transform = transform;
});

Implementing a snappable grid:

const moveable = new Moveable(document.body, {
  target: document.querySelector(".target"),
  draggable: true,
  snappable: true,
  snapGridWidth: 50,
  snapGridHeight: 50
});

moveable.on("drag", ({ target, transform }) => {
  target.style.transform = transform;
});

Creating a group of moveable elements:

const moveableGroup = new Moveable(document.body, {
  target: [".target1", ".target2", ".target3"],
  draggable: true,
  resizable: true,
  rotatable: true,
  groupable: true
});

moveableGroup.on("dragGroupStart", ({ targets }) => {
  console.log("Group drag started", targets);
});

Getting Started

To use Moveable in your project, follow these steps:

  1. Install the package:

    npm install moveable
    
  2. Import and initialize Moveable in your JavaScript file:

    import Moveable from "moveable";
    
    const moveable = new Moveable(document.body, {
      target: document.querySelector(".your-target-element"),
      draggable: true,
      resizable: true,
      rotatable: true
    });
    
    moveable.on("drag", ({ target, transform }) => {
      target.style.transform = transform;
    });
    
  3. Add the target element to your HTML:

    <div class="your-target-element">Moveable Element</div>
    
  4. Style your target element as needed and start interacting with it on your web page.

Competitor Comparisons

Beautiful and accessible drag and drop for lists with React

Pros of react-beautiful-dnd

  • Specifically designed for React applications, offering seamless integration
  • Provides a natural and accessible drag-and-drop experience
  • Extensive documentation and community support

Cons of react-beautiful-dnd

  • Limited to list and grid layouts, less flexible for complex scenarios
  • Heavier bundle size compared to Moveable
  • Less suitable for non-React projects or those requiring broader functionality

Code Comparison

react-beautiful-dnd:

import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';

<DragDropContext onDragEnd={onDragEnd}>
  <Droppable droppableId="list">
    {(provided) => (
      <ul {...provided.droppableProps} ref={provided.innerRef}>
        {items.map((item, index) => (
          <Draggable key={item.id} draggableId={item.id} index={index}>
            {(provided) => (
              <li ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
                {item.content}
              </li>
            )}
          </Draggable>
        ))}
        {provided.placeholder}
      </ul>
    )}
  </Droppable>
</DragDropContext>

Moveable:

import Moveable from "moveable";

const moveable = new Moveable(document.body, {
  target: document.querySelector(".target"),
  draggable: true,
  resizable: true,
  rotatable: true
});

moveable.on("drag", ({ target, transform }) => {
  target.style.transform = transform;
});

A set of higher-order components to turn any list into an animated, accessible and touch-friendly sortable list✌️

Pros of react-sortable-hoc

  • Specifically designed for React applications, offering seamless integration
  • Focuses on sortable functionality, providing a more specialized solution
  • Extensive documentation and examples for various use cases

Cons of react-sortable-hoc

  • Limited to sorting functionality, lacking other drag-and-drop features
  • Less flexible for non-React projects or complex interactions

Code Comparison

react-sortable-hoc:

import { SortableContainer, SortableElement } from 'react-sortable-hoc';

const SortableItem = SortableElement(({value}) => <li>{value}</li>);
const SortableList = SortableContainer(({items}) => {
  return (
    <ul>
      {items.map((value, index) => (
        <SortableItem key={`item-${index}`} index={index} value={value} />
      ))}
    </ul>
  );
});

Moveable:

import Moveable from "moveable";

const moveable = new Moveable(document.body, {
  target: document.querySelector(".target"),
  draggable: true,
  resizable: true,
  rotatable: true
});

moveable.on("drag", ({ target, transform }) => {
  target.style.transform = transform;
});

Summary

While react-sortable-hoc excels in providing a specialized sorting solution for React applications, Moveable offers a more versatile toolkit for various drag-and-drop interactions across different frameworks. react-sortable-hoc is ideal for projects requiring simple, efficient sorting functionality, whereas Moveable is better suited for complex, multi-faceted drag-and-drop implementations.

10,773

Infinite responsive, sortable, filterable and draggable layouts

Pros of Muuri

  • Specialized in grid layouts and sorting
  • Built-in support for animations and drag-and-drop functionality
  • Lightweight and performant, with minimal dependencies

Cons of Muuri

  • Limited to grid-based layouts
  • Less flexible for non-grid positioning and resizing
  • Smaller community and fewer updates compared to Moveable

Code Comparison

Muuri:

const grid = new Muuri('.grid', {
  dragEnabled: true,
  sortData: {
    id: (item, element) => element.getAttribute('data-id')
  }
});

Moveable:

const moveable = new Moveable(document.body, {
  target: document.querySelector(".target"),
  draggable: true,
  resizable: true,
  rotatable: true
});

Summary

Muuri excels in creating responsive grid layouts with built-in sorting and drag-and-drop functionality. It's lightweight and performant, making it ideal for projects focused on grid-based designs. However, its specialization limits its flexibility compared to Moveable.

Moveable offers a more versatile approach, allowing for various types of element manipulation beyond grid layouts. It provides a wider range of features for positioning, resizing, and rotating elements, making it suitable for more diverse projects. However, this versatility may come at the cost of a steeper learning curve and potentially more complex implementation for simpler grid-based layouts.

Choose Muuri for grid-focused projects with sorting needs, and Moveable for more flexible element manipulation across different layout types.

29,388

Reorderable drag-and-drop lists for modern browsers and touch devices. No jQuery or framework required.

Pros of Sortable

  • Focused specifically on drag-and-drop sorting functionality
  • Lightweight and easy to implement for basic sorting needs
  • Extensive browser support, including older versions

Cons of Sortable

  • Limited to sorting functionality, less versatile for other interactions
  • May require additional plugins or libraries for more complex use cases

Code Comparison

Sortable:

new Sortable(document.getElementById('list'), {
  animation: 150,
  ghostClass: 'blue-background-class'
});

Moveable:

const moveable = new Moveable(document.body, {
  target: document.querySelector(".target"),
  draggable: true,
  resizable: true,
  rotatable: true
});

Key Differences

  • Sortable focuses on list sorting, while Moveable offers a broader range of element manipulations (dragging, resizing, rotating)
  • Moveable provides more advanced features like snapping and guidelines
  • Sortable is generally simpler to set up for basic sorting needs, while Moveable offers more flexibility for complex interactions

Use Cases

  • Choose Sortable for straightforward list reordering tasks
  • Opt for Moveable when you need diverse element manipulations beyond sorting, such as resizing or rotating elements

🖱 A resizable and draggable component for React.

Pros of react-rnd

  • Specifically designed for React applications, ensuring seamless integration
  • Simpler API with fewer options, making it easier to get started quickly
  • Built-in support for both resizing and dragging out of the box

Cons of react-rnd

  • Limited to React applications, lacking versatility for other frameworks
  • Fewer customization options and advanced features compared to Moveable
  • Less frequent updates and potentially slower bug fixes

Code Comparison

react-rnd:

<Rnd
  default={{
    x: 0,
    y: 0,
    width: 320,
    height: 200
  }}
>
  Resizable and draggable content
</Rnd>

Moveable:

<Moveable
  target={document.querySelector(".target")}
  draggable={true}
  resizable={true}
  rotatable={true}
/>

Key Differences

  • react-rnd is React-specific, while Moveable is framework-agnostic
  • Moveable offers more advanced features like rotation, scaling, and snapping
  • react-rnd has a simpler API, while Moveable provides more granular control
  • Moveable supports a wider range of interactions and transformations

Use Cases

  • Choose react-rnd for quick implementation in React projects with basic needs
  • Opt for Moveable when requiring advanced features or working with multiple frameworks

A draggable and resizable grid layout with responsive breakpoints, for React.

Pros of react-grid-layout

  • Specifically designed for React applications, offering seamless integration
  • Provides a grid-based layout system with draggable and resizable elements
  • Supports responsive layouts and breakpoints out of the box

Cons of react-grid-layout

  • Limited to grid-based layouts, less flexible for free-form positioning
  • Steeper learning curve due to its specific API and configuration options
  • May introduce unnecessary complexity for simpler layout requirements

Code Comparison

react-grid-layout:

import GridLayout from 'react-grid-layout';

<GridLayout
  className="layout"
  layout={[
    { i: 'a', x: 0, y: 0, w: 1, h: 2 },
    { i: 'b', x: 1, y: 0, w: 3, h: 2 },
    { i: 'c', x: 4, y: 0, w: 1, h: 2 }
  ]}
  cols={12}
  rowHeight={30}
>
  <div key="a">A</div>
  <div key="b">B</div>
  <div key="c">C</div>
</GridLayout>

moveable:

import Moveable from "moveable";

const moveable = new Moveable(document.body, {
  target: document.querySelector(".target"),
  draggable: true,
  resizable: true,
  rotatable: true
});

moveable.on("drag", ({ target, transform }) => {
  target.style.transform = transform;
});

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Moveable

npm version Github actions React Preact Angular Vue Vue 3 Svelte Lit

Moveable is Draggable, Resizable, Scalable, Rotatable, Warpable, Pinchable, Groupable, Snappable

Github / Demo / Storybook / API / Main Project

Moveable
Draggable Resizable Scalable Rotatable
Warpable Pinchable Groupable Snappable
Clippable Roundable OriginDraggable Selecto

🔥 Features

  • Draggable refers to the ability to drag and move targets.
  • Resizable indicates whether the target's width and height can be increased or decreased.
  • Scalable indicates whether the target's x and y can be scale of transform.
  • Rotatable indicates whether the target can be rotated.
  • Warpable indicates whether the target can be warped (distorted, bented).
  • Pinchable indicates whether the target can be pinched with draggable, resizable, scalable, rotatable.
  • Groupable indicates Whether the targets can be moved in group with draggable, resizable, scalable, rotatable.
  • Snappable indicates whether to snap to the guideline.
  • OriginDraggable* indicates Whether to drag origin.
  • Clippable indicates Whether to clip the target.
  • Roundable indicates Whether to show and drag or double click border-radius.
  • Support SVG Elements (svg, path, line, ellipse, g, rect, ...etc)
  • Support Major Browsers
  • Support 3d Transform

⚙️ Installation

npm

$ npm i moveable

scripts

<script src="//daybrush.com/moveable/release/latest/dist/moveable.min.js"></script>

📄 Documents

🚀 How to use

  • All classes of moveable control box and able elements have a moveable- prefix. So please don't put moveable- class name in target.
import Moveable from "moveable";

const moveable = new Moveable(document.body, {
    target: document.querySelector(".target"),
    // If the container is null, the position is fixed. (default: parentElement(document.body))
    container: document.body,
    draggable: true,
    resizable: true,
    scalable: true,
    rotatable: true,
    warpable: true,
    // Enabling pinchable lets you use events that
    // can be used in draggable, resizable, scalable, and rotateable.
    pinchable: true, // ["resizable", "scalable", "rotatable"]
    origin: true,
    keepRatio: true,
    // Resize, Scale Events at edges.
    edge: false,
    throttleDrag: 0,
    throttleResize: 0,
    throttleScale: 0,
    throttleRotate: 0,
});
/* draggable */
moveable.on("dragStart", ({ target, clientX, clientY }) => {
    console.log("onDragStart", target);
}).on("drag", ({
    target, transform,
    left, top, right, bottom,
    beforeDelta, beforeDist, delta, dist,
    clientX, clientY,
}) => {
    console.log("onDrag left, top", left, top);
    target!.style.left = `${left}px`;
    target!.style.top = `${top}px`;
    // console.log("onDrag translate", dist);
    // target!.style.transform = transform;
}).on("dragEnd", ({ target, isDrag, clientX, clientY }) => {
    console.log("onDragEnd", target, isDrag);
});

/* resizable */
moveable.on("resizeStart", ({ target, clientX, clientY }) => {
    console.log("onResizeStart", target);
}).on("resize", ({ target, width, height, dist, delta, clientX, clientY }) => {
    console.log("onResize", target);
    delta[0] && (target!.style.width = `${width}px`);
    delta[1] && (target!.style.height = `${height}px`);
}).on("resizeEnd", ({ target, isDrag, clientX, clientY }) => {
    console.log("onResizeEnd", target, isDrag);
});

/* scalable */
moveable.on("scaleStart", ({ target, clientX, clientY }) => {
    console.log("onScaleStart", target);
}).on("scale", ({
    target, scale, dist, delta, transform, clientX, clientY,
}: OnScale) => {
    console.log("onScale scale", scale);
    target!.style.transform = transform;
}).on("scaleEnd", ({ target, isDrag, clientX, clientY }) => {
    console.log("onScaleEnd", target, isDrag);
});

/* rotatable */
moveable.on("rotateStart", ({ target, clientX, clientY }) => {
    console.log("onRotateStart", target);
}).on("rotate", ({ target, beforeDelta, delta, dist, transform, clientX, clientY }) => {
    console.log("onRotate", dist);
    target!.style.transform = transform;
}).on("rotateEnd", ({ target, isDrag, clientX, clientY }) => {
    console.log("onRotateEnd", target, isDrag);
});

/* warpable */
this.matrix = [
    1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1,
];
moveable.on("warpStart", ({ target, clientX, clientY }) => {
    console.log("onWarpStart", target);
}).on("warp", ({
    target,
    clientX,
    clientY,
    delta,
    dist,
    multiply,
    transform,
}) => {
    console.log("onWarp", target);
    // target.style.transform = transform;
    this.matrix = multiply(this.matrix, delta);
    target.style.transform = `matrix3d(${this.matrix.join(",")})`;
}).on("warpEnd", ({ target, isDrag, clientX, clientY }) => {
    console.log("onWarpEnd", target, isDrag);
});

/* pinchable */
// Enabling pinchable lets you use events that
// can be used in draggable, resizable, scalable, and rotateable.
moveable.on("pinchStart", ({ target, clientX, clientY }) => {
    // pinchStart event occur before dragStart, rotateStart, scaleStart, resizeStart
    console.log("onPinchStart");
}).on("pinch", ({ target, clientX, clientY, datas }) => {
    // pinch event occur before drag, rotate, scale, resize
    console.log("onPinch");
}).on("pinchEnd", ({ isDrag, target, clientX, clientY, datas }) => {
    // pinchEnd event occur before dragEnd, rotateEnd, scaleEnd, resizeEnd
    console.log("onPinchEnd");
});

📦 Packages

  • moveable: A Vanilla Component that create Moveable, Draggable, Resizable, Scalable, Rotatable, Warpable, Pinchable.
  • react-moveable: A React Component that create Moveable, Draggable, Resizable, Scalable, Rotatable, Warpable, Pinchable.
  • preact-moveable: A Preact Component that create Moveable, Draggable, Resizable, Scalable, Rotatable, Warpable, Pinchable.
  • ngx-moveable: An Angular Component that create Moveable, Draggable, Resizable, Scalable, Rotatable, Warpable, Pinchable.
  • svelte-moveable: A Svelte Component that create Moveable, Draggable, Resizable, Scalable, Rotatable, Warpable, Pinchable.
  • lit-moveable: A Lit Component that create Moveable, Draggable, Resizable, Scalable, Rotatable, Warpable, Pinchable.
  • vue-moveable: A Vue Component that create Moveable, Draggable, Resizable, Scalable, Rotatable, Warpable, Pinchable.
  • vue3-moveable: A Vue 3 Component that create Moveable, Draggable, Resizable, Scalable, Rotatable, Warpable, Pinchable.

⚙️ Developments

The moveable repo is managed as a monorepo with yarn.

yarn config set registry https://registry.npmjs.org/

The main project was made with react and I used croact to make it lighter with umd.

For development and testing, check in packages/react-moveable.

npm run storybook

$ yarn
$ npm run packages:build
$ npm run storybook

Runs the app in the development mode.
Open http://localhost:6006 to view it in the browser.

The page will reload if you make edits.
You will also see any lint errors in the console.

⭐️ Show Your Support

Please give a ⭐️ if this project helped you!

👏 Contributing

If you have any questions or requests or want to contribute to moveable or other packages, please write the issue or give me a Pull Request freely.

Code Contributors

This project exists thanks to all the people who contribute. [Contribute].

🐞 Bug Report

If you find a bug, please report to us opening a new Issue on GitHub.

Sponsors

Open Collective Financial Contributors

Become a financial contributor and help us sustain our community. [Contribute]

Individuals

Organizations

Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]

📝 License

This project is MIT licensed.

MIT License

Copyright (c) 2019 Daybrush

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

NPM DownloadsLast 30 Days