CLI tool
gorkys/vue-draggable-resizable-gorkys avatar
gorkys/vue-draggable-resizable-gorkys

vue-draggable-resizable-gorkys: Draggable, Resizable Vue 3 Components With Snapping

Vue 用于可调整大小和可拖动元素的组件并支持冲突检测、元素吸附、元素对齐、辅助线

1,271 stars240 forksJavaScriptMIT

At a glance

What is it?
This fork of vue-draggable-resizable adds conflict detection, snap alignment, guide lines, rotation and right click selection to a draggable and resizable component, and has been migrated to Vue 3.5, Vite 5, Vitest 2 and Storybook 8. It is aimed at editors and canvas tools built in Vue.
Who is it for?
vue-draggable-resizable-gorkys fits a Vue 3 project that needs movable, resizable elements with alignment feedback, such as a dashboard editor or a diagram tool, and it does not fit a Vue 2 codebase, since the peer dependency is vue ^3.5.0 and the main line has moved to Vue 3.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A Fork That Carried the Enhancements Through the Vue 3 Migration

This component is a second stage development of vue-draggable-resizable, and the README says so directly, explaining that the fork previously focused on maintaining the enhanced capabilities such as conflict detection, snap alignment and guide lines. The main line has now switched to Vue 3, and the README, the examples and the build method all follow Vue 3.

The migration was substantial in the tooling rather than the API. The build chain moved from Vue CLI plus Karma to Vite 5 plus Vitest 2 plus Storybook 8, the README and the examples were rewritten for Vue 3 usage, and the full Storybook case set was restored, including the examples for conflict detection, snap alignment, guide lines and multi element dragging. The new demos of the fork's own features live in the Advanced category of the Storybook.

The package on npm is vue-draggable-resizable-gorkys, at version 3.0.0, and it is MIT licensed. It is written as a Vue 3 single file component, with the source at src/components/vue-draggable-resizable.vue, and the package exports a single file component entry point as well as the built library and the stylesheet.

Conflict Detection and Snap Alignment Are the Core Additions

Two features justify the fork on their own.

Conflict detection is enabled with the is-conflict-check prop, a boolean that defaults to false. With it on, the component knows when it would overlap another element, which is the check you want in a layout editor where a canvas of movable boxes has to stay legible. The conflict check applies to the elements that are registered with the same parent, so the scope of the check is the set of siblings rather than the whole page.

Snap alignment is the second, enabled with the snap prop, also a boolean defaulting to false, and controlled in detail by snap-tolerance. That is a number, also optional, which defaults to 5, and it defines the alignment distance between the component and other elements in pixels. So the default is a five pixel threshold, and the example in the README raises it to 20 for a looser, more forgiving feel.

The two features are independent. Snapping decides where an element comes to rest, and conflict detection decides whether it is allowed to be there, and a layout editor that wants both turns on both. The README also lists element alignment and guide lines as separate capabilities from snapping, which is a distinction worth keeping in mind, since alignment is what the element snaps to and guide lines are the visual feedback that shows it.

Guide Lines Come Back as Data, Not as Markup

The guide line feature is delivered through an event rather than through rendered elements, and that is the most interesting design decision in the component.

When snapping is active, the component emits a refLineParams event whose argument is an object containing vLine and hLine. The README explains that these can be used to render the guide lines yourself, and the example stores the two arrays in data and renders them as spans:

vue
<span
  v-for="item in vLine"
  :key="item.position + item.origin"
  class="ref-line v-line"
  v-show="item.display"
  :style="{ left: item.position, top: item.origin, height: item.lineLength }"
/>

The horizontal version is the mirror image, with top and left swapped and width set from lineLength. The v-show binding on item.display is how a line is hidden, and the key combines position and origin so that two lines at the same place but different origins do not collide in the list.

Leaving the rendering to the application is the right call for a library, because the guide lines have to sit above the canvas, follow the same coordinate space as the elements, and match the visual language of whatever design system is in use. The cost is that the feature does nothing until you write the six lines of markup, which the README makes clear by pointing at the Advanced stories.

parent as a CSS Selector, and Sizing With auto

The parent prop constrains where the component can be dragged and resized, and this fork widened its type to Boolean or String. Passing true limits the component to its direct parent element, and passing a string limits it to the element matched by that CSS selector, for example parent=".canvas-container". So a component can be constrained to a canvas that is not its DOM parent, which is what you need when the editable area is a sibling of the element list rather than an ancestor.

The w and h props also widened. They are Number or String, and apart from a number they accept the string auto, in which case the component initialises itself to the size of its content and converts to a concrete number after the first manual resize. That is the behaviour you want for a text box whose size should follow its content until the user takes over.

There is also a fix in the same area of the component. The changelog notes that the x, y, w and h property setters were fixed so that setting them takes effect, and that formatTransformVal now supports decimal points, which matters when a component is positioned at a fractional offset.

handleInfo and scaleRatio for a Scaled Canvas

Two props exist to handle the case where the canvas itself is scaled with a CSS transform, and they are the props most likely to save you an afternoon.

handleInfo is an object with a default of size 8, offset -5 and switch true. The switch flag controls whether the drag handle keeps a constant visual size, size is the handle size, and offset is the handle position offset. The README explains that this is for when you use transform: scale() to zoom, and the example passes a size of 14 with the same offset and switch value.

scaleRatio is a number that defaults to 1, and it fixes the offset between the mouse position and the drag or resize position in a transform: scale() scenario. The example uses 0.6, which corresponds to a canvas scaled to 60 percent.

Both props exist because the browser reports pointer coordinates in the scaled space, while the component works in the unscaled coordinate system of the element. Without them, the handle grows and shrinks with the zoom and the cursor drifts away from the edge being dragged. The pair is the price of supporting a zoomable canvas, and it is a price worth paying only if you actually zoom.

Rotation, Right Click Selection and Bringing an Element to the Front

Three smaller props round out the fork's additions.

rotate is a number that defaults to 0 and defines the rotation angle of the component in degrees. An example passes 45, and the README lists rotation support among the capabilities this fork adds over the original component.

selectOnContextMenu is a boolean defaulting to false, and it defines whether the component supports selection with the right mouse button. That is a small addition in code and a large one in practice, because right click is the gesture users reach for when they want to select an element without disturbing its position, and a component that swallows the right click breaks that expectation.

activeOnTop is a boolean defaulting to false that defines whether the component is automatically raised to the front when it is activated. It is the z-order answer to the same problem, for canvases where a dozen overlapping boxes can hide each other, and the README lists it as supporting the dragging of obscured elements.

The changelog for the migration also records fixes in the same area, including a fix for multiple guide lines displaying incorrectly and a fix for the transform attribute being lost when a component is activated, which is the kind of bug that only appears in a long editing session.

The Vue 3 Toolchain and the Project's Current State

The development commands are the standard set for a Vite library with Storybook, and the README states that the current development environment requires Node.js 20 or newer:

bash
npm install

# lint
npm run lint

# unit / feature tests
npm test

# library build
npm run build

# storybook dev
npm run storybook

The package.json matches. The build is vite build, the dev server is vite, the tests are vitest run with coverage, the linter is eslint over src, tests, the Storybook config and the vite and vitest configuration files, and the Storybook dev server runs on port 9001. The peer dependency is vue ^3.5.0 with no runtime dependencies, and the exports map exposes the library for import and require, the stylesheet as ./style.css, and the single file component source as ./sfc. The sideEffects field marks CSS files as having side effects, which is what keeps the stylesheet from being dropped by a bundler's tree shaking.

Two details in the package deserve attention. The style import path changed with the migration, from dist/VueDraggableResizable.css to style.css, which will break an existing import silently if you upgrade. And the package publishes no GitHub releases, so the npm version is the one to track, with 3.0.0 being the current one.

The project is MIT licensed, and the repository is not archived, but the last push was on 2026-04-08, which is more than six months before the present day, so an evaluation should plan around a component that is not currently receiving updates.

Editorial conclusion

vue-draggable-resizable-gorkys fits a Vue 3 project that needs movable, resizable elements with alignment feedback, such as a dashboard editor or a diagram tool, and it does not fit a Vue 2 codebase, since the peer dependency is vue ^3.5.0 and the main line has moved to Vue 3. Before adopting it, check the import path for the stylesheet, which is now style.css rather than the old dist/VueDraggableResizable.css, and confirm the guide line rendering is what you want, since the component exposes the line data through an event and leaves the drawing to you. The package is MIT licensed at version 3.0.0, it publishes no GitHub releases, and the last push was on 2026-04-08.

Frequently asked questions

How do I install and use vue-draggable-resizable-gorkys?

Run `npm install vue-draggable-resizable-gorkys`, then register the component globally with app.component('vdr', VueDraggableResizable) or import it locally, and import the stylesheet from 'vue-draggable-resizable-gorkys/style.css'. The peer dependency is vue ^3.5.0.

How do I enable conflict detection and snapping?

Set the is-conflict-check prop to true to turn on conflict detection, and the snap prop to true to turn on element alignment and snapping. The snap-tolerance prop, a number defaulting to 5, sets the alignment distance in pixels when snapping is on.

How are the guide lines rendered?

The component does not draw them. It emits a refLineParams event with an object containing vLine and hLine, and you render those yourself, using item.position, item.origin, item.lineLength and item.display, as the README example does.

Can I constrain a component to a specific container?

Yes. The parent prop accepts Boolean or String. Passing true limits the component to its direct parent element, and passing a CSS selector string, such as parent=".canvas-container", limits it to the element that selector matches.

What does the scaleRatio prop do?

It is a number defaulting to 1 that fixes the offset between the mouse position and the drag or resize position when the canvas is scaled with transform: scale(). The handleInfo prop, with size, offset and switch, handles the same scenario for the drag handle.

Official sources

  1. gorkys/vue-draggable-resizable-gorkys on GitHub
  2. Issues
  3. License: MIT
  4. Project website
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/gorkys-vue-draggable-resizable-gorkys.svg)](https://hysenlabs.com/projects/gorkys-vue-draggable-resizable-gorkys)

Was this useful?