Coder Social home page Coder Social logo

daybrush / moveable Goto Github PK

View Code? Open in Web Editor NEW
9.6K 75.0 592.0 79.06 MB

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

Home Page: https://daybrush.com/moveable/

License: MIT License

JavaScript 4.08% HTML 4.65% CSS 0.95% TypeScript 89.82% Svelte 0.10% Vue 0.40%
moveable movable draggable resizable scalable rotatable warpable pinchable groupable snappable

moveable's Introduction

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.

moveable's People

Contributors

6xiaowu9 avatar a-alexander avatar arturovt avatar awesomestmason avatar barklund avatar carlambroselli avatar ccpu avatar danish1994 avatar daybrush avatar dejorrit avatar elijahgun avatar emmanuelgeoffray avatar faustort avatar kant avatar liady avatar maloguertin avatar merapi avatar mjangir avatar monkeywithacupcake avatar netizen-ais avatar oppoffice avatar osbre avatar ovasylenko avatar robin-dela avatar stevezhu avatar tilak999 avatar tombyrer avatar xiaoxiangmoe avatar yojona avatar zsoerenm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

moveable's Issues

global variable (b)

Hello.
The following are global variables
Is this a specification?

window.b

スクリーンショット 2019-09-20 21 24 25

Add MoaveableGroup

@daybrush

Can I combine multiple elements for dragging?

I made a patch method

image

I have a moveable nested inside element A and element B.

When I manipulate the moveable, I change the element A and the element B.

If you can provide a combined parameter, I think that's awesome.

Can not get delta x coordinate

onResize={({ target, width, height, drag, delta }) => {

This drag property is not defined in type definitions.

export interface OnResize {
    target: HTMLElement | SVGElement;
    clientX: number;
    clientY: number;
    datas: IObject<any>;
    direction: number[];
    width: number;
    height: number;
    dist: number[];
    delta: number[];
    isPinch: boolean;
}

Can you add the drag property? Thank You for this great library.

when i press a right click, dragging starts

Thanks for awesome project!

I found an issue about a dragging feature. when i press a right click it starts dragging like below.

I think drag library needs a moving distance feature.(mousedown -> mousemove = trigger drag start)

Is it possible to destroy (safely kill) movable instance?

Hi, @daybrush

Is it possible to destory (safely kill) moveable instance? I mean, remove elements with moveable-control-box class from the DOM

As you know I created a simple POC on Vue.js but I have a problem - it doesn't work well with Hot Module Replacement.

I'm observing a strange behavior when new element created and old element is not removed.
Screenshot from 2019-07-31 00-36-03

I've checked documentation already - there is nothing about that.

Expected result: movable instance has destroy() method or moveable can reuse existing moveable-control-box

Add events to oversee events

import { IObject } from "@daybrush/utils";

interface OnRenderStart {
    target: HTMLElement | SVGElement;
    clientX: number;
    clientY: number;
    datas: IObject<any>;
    isPinch: boolean;
}
interface OnRender {
    target: HTMLElement | SVGElement;
    clientX: number;
    clientY: number;
    datas: IObject<any>;
    isPinch: boolean;
}
interface OnRenderEnd {
    target: HTMLElement | SVGElement;
    clientX: number;
    clientY: number;
    datas: IObject<any>;
    isPinch: boolean;
    isDrag: boolean;
}
interface OnRenderGroupStart extends OnRenderStart {
    targets: Array<HTMLElement | SVGElement>;
}
interface OnRenderGroup extends OnRender {
    targets: Array<HTMLElement | SVGElement>;
}
interface OnRenderGroupEnd extends OnRenderEnd {
    targets: Array<HTMLElement | SVGElement>;
}
interface RenderProps {
 onRenderStart: (e: OnRenderStart) => any;
 onRender: (e: OnRender) => any;
 onRenderEnd: (e: OnRenderEnd) => any;
 onRenderGroupStart: (e: OnRenderGroupStart) => any;
 onRenderGroup: (e: OnRenderGroup) => any;
 onRenderGroupEnd: (e: OnRenderGroupEnd) => any;
}

In latest Angular AOT mode Drag only moves the text inside...

So I tested the project and it seems to be broken with AOT.
While it works fine in Angular CLI JIT mode, with AOT mode dragging only moves the text inside the frame.
You can check it out here:
http://secure.digitalsignage.com/pokes
enter anything for user/pass and click the resources on the left navigation tree.

here are my versions:

Angular CLI: 8.0.6
Node: 10.15.0
OS: win32 x64
Angular: 8.0.0
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... platform-server, router

Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.800.2
@angular-devkit/build-angular      0.800.2
@angular-devkit/build-optimizer    0.800.2
@angular-devkit/build-webpack      0.800.2
@angular-devkit/core               8.0.2
@angular-devkit/schematics         8.0.6
@angular/cdk                       8.0.1
@angular/cli                       8.0.6
@angular/flex-layout               8.0.0-beta.26
@angular/http                      7.2.15
@angular/material                  8.0.1
@angular/material-moment-adapter   8.0.1
@ngtools/webpack                   8.0.2
@schematics/angular                8.0.6
@schematics/update                 0.800.6
rxjs                               6.4.0
typescript                         3.4.5
webpack                            4.30.0

and this is the error:

main-es2015.c07aaa5292bb6a22d65a.js:1 ERROR TypeError: this.setState is not a function
    at t.n.updateState (main-es2015.c07aaa5292bb6a22d65a.js:1)
    at t.n.updateRect (main-es2015.c07aaa5292bb6a22d65a.js:1)
    at t.n.updateTarget (main-es2015.c07aaa5292bb6a22d65a.js:1)
    at main-es2015.c07aaa5292bb6a22d65a.js:1
    at r.<computed> (main-es2015.c07aaa5292bb6a22d65a.js:1)
    at onDrag (main-es2015.c07aaa5292bb6a22d65a.js:1)
    at s.invokeTask (polyfills-es2015.0c0a6f8e1b4dd0704186.js:1)
    at Object.onInvokeTask (main-es2015.c07aaa5292bb6a22d65a.js:1)
    at s.invokeTask (polyfills-es2015.0c0a6f8e1b4dd0704186.js:1)
    at e.runTask (polyfills-es2015.0c0a6f8e1b4dd0704186.js:1)

Please let me know if there is anything else I can try?

Thanks,

Sean.

resizeEnd not firing up

hello based on the examples i have the following

  .on('resizeEnd', ({ target, isDrag }) => {
        console.log('onResizeEnd', target, isDrag);
      });

but it dont seems to triger the event. No problems with resizeStart and resize.

Support SVG Elements(Like path, ellipse, line)

Support SVG Elements(Like path, ellipse, line)

The svg elements are not only offsetWidth, offsetHeight, but also clientWidth, clientHeight. Instead, they try to use getBBox() to get the size.

auto scrolling (feature request)

Hello.
I have a feature request.

[auto scroll]
If the pointer crosses the edge of the container while dragging, scroll automatically.

I would be happy if you could consider it.

Single moveable control box

Is it possible to create only one control box for all the elements, which dynamically switches between selected items? It would reduce number of HTML elements and enhance overall app speed when you have 1000+ items on the page.

Vanilla implementation needs Preact module

Tried to make it work with Angular 7. This message is shown :
ERROR in node_modules/preact-moveable/declaration/types.d.ts(2,27): error TS2307: Cannot find module 'preact'.

Add Pinchable

Add the pinchi zoom that combines scaleable (resizable), draggable, and rotatable.

Rotation handle position

Hi,

I assume there's currently no way to have a rotation handle on the bottom instead of the top ? At least I can't find a way. Would you be able to add this feature later on ?

css independence

Is it possible to move css of moveable to a separate file independently?
For example, when operating with a smartphone, the pointer is too small to catch well.
I would like to adjust such things with an independent css file.

Resize event edges/corners

How can i get the edges in which a resize is occurring? eg: Top-left, Bottom Left... is that possible?

Element Guidelines not working

Hi,

Amazing Project I must say. However, there seems to be a typo in elementGuidelines. In some places, it is named "elementGuildelines". Check it out when time permits.

Events on children of Moveable not working

I have Moveables on the page but would like their children elements to be able to have their own events and triggers. And bubble a prevent up to the Moveable instance so that the container is moveable but the elements with their own drag triggers prevent the moveable from triggering. But nothing triggers.

Pseudocode:

<MoveableTarget
<Child
draggable={true}
onDragStart={ this.handleDragStart } -- does not trigger
onDrag={ this.handleDrag } -- does not trigger

<Moveable
target={this.moveableTarget.current}

Resizable - centers

if you resize from left, right, top or bottom, it does a center resize. Moving both right and left or top and bottom.
Other libs. resize by only moving the side you have clicked on and keeping the others in place.
( hope it make sence :-/ )

Add guildeline, snap

Moveable will add guidelines and magnetic functions.

The guidelines help Moveable.

It can also have properties that attach magnetic functions to guide lines.

Groupable documentation

The onScaleGroup function in the groupable documentation is not complete. It does not show how to change the target CSS of all elements in a group. Currently it only shows how to get some variables from the onScaleGroup event:

events.forEach(ev => {
   const target = ev.target;
   // ev.drag is a drag event that occurs when the group scale.
   const left = ev.drag.beforeDist[0];
   const top = ev.drag.beforeDist[0];
   const scaleX = ev.scale[0];
   const scaleX = ev.scale[1];
});

Is it possible to see an example which includes moving and scaling a group of elements? Thanks in advance.

Strange behaviour on demo page

I was playing with the demos, when I decided to rotate and then scale the logo, and suddenly it seems that the logo was scaled to 0 for no reason, when I tried to interact with it again it just disappears. Here's a GIF to show what happens:

moveable

I'm on Windows 7, Chrome 76.0.3809.100 (64 bits).

Scenejs recommended

Hi ! First of all "chapeau " for this create tool, it's very exciting to play around with. Currently combining it with Vue. I tried to get a basic example going from the docs but noticed something odd. Probably just odd for me since I barely touched css transform and only have vague understanding of it.

  • When I first use the scale feature on an element to squeeze or stretch it and
  • then use the resize feature to alter its width/heigth it appears that
  • the "resizing" does not come from the center of the object anymore (like in your vanilla code pen), more like from somewhere off the stage. It's getting hard to resize.
  • Also it "rotates" really weird after the element got stretched/squeezed.
  • To reproduce I was really just using the basic example from the doc and/or github repo readme.

I took a close look at your vanilla code pen again and noticed you are using your other repo "scenejs" and its Frame feature along with Moveable. Is SceneJs recommend to use with Moveable ? Thanks !

Custom amount of draggable markers

Hi! Thanks for an outstanding library. Is there a way to add more draggable markers with option "warpable" turned on? Im aiming to fire this lib on an image then mark specified part of it with markers (draggable dots). Docs are not clear about this.

Is this possible? Thanks!

Edit: Im aiming for something like: https://i.stack.imgur.com/kM1OH.png

Added dragstart method while changing to target

To start the drag, the target must be changed first and then mousedown, touchstart must occur.

But touchstart, mousedown changes the target.

So add a method that starts drag in touchstart, mousedown event.

Add parameters to send data to events

onDragStart={({ datas }) => {
    datas.temp = 1;
}}
onDrag={({ datas }) => {
    // 1
    console.log(datas.temp);
}}
onDragEnd={({ datas }) => {
    // 1
    console.log(datas.temp);
}}

snap option

Are you planning to add the snap option?
For example, while holding down the shift key, it is easy to adjust the rotation to 0, 90, 180 and 270 degrees.

Scrolls and drags occur simultaneously and racks occur.

Scrolls and drags occur simultaneously and racks occur.

Ignored attempt to cancel a touchstart event with cancelable=false, for example because scrolling is in progress and cannot be interrupted.

Scrolls should not occur.
스크린샷 2019-08-23 오전 7 58 17

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.