Skip to content

Commit d66abce

Browse files
committed
Initial
0 parents  commit d66abce

File tree

5 files changed

+1107
-0
lines changed

5 files changed

+1107
-0
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.idea
2+
*.iml
3+
*.tgz
4+
.nyc_output
5+
coverage
6+
node_modules

package-lock.json

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "@minogin/vue-drag-resize-rotate",
3+
"version": "0.1.0",
4+
"description": "Vue drag-resize-rotate component",
5+
"keywords": [
6+
"vue",
7+
"drag",
8+
"resize",
9+
"rotate",
10+
"draggable",
11+
"resizable",
12+
"rotateable"
13+
],
14+
"author": {
15+
"name": "Andrey Minogin",
16+
"email": "minogin@gmail.com"
17+
},
18+
"license": "MIT",
19+
"main": "src/drr.vue",
20+
"repository": {
21+
"type": "git",
22+
"url": "https://github.com/minogin/drr"
23+
},
24+
"scripts": {
25+
"test": "echo \"Error: no test specified\" && exit 1"
26+
},
27+
"dependencies": {
28+
"vue": "^2.5.17",
29+
"@minogin/vector": "^1.0.2"
30+
}
31+
}

readme.md

Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
# Description
2+
Vue component which acts as a draggable, resizable and rotateable container for any content.
3+
4+
### Features
5+
* All the properties are reactive.
6+
* Correct rotation based on vector geometry. Rotated container resizes correctly.
7+
* Supports fixed aspect ratio which is applied correctly when container is rotated.
8+
* Supports active (e.g. editable) content. For example you can create a draggable and resizable textbox and edit the text inside on double click.
9+
* Supports both outer and inner boundaries. E.g. container would always contain inner boundary and outer boundary would always contain the container.
10+
* DRR-containers could be nested, e.g. for editing tree-like structures.
11+
12+
### Caution!
13+
14+
(x; y) are always the coordinates of the **center** of the container, not the left-top corner. It is because the container could be rotated and therefore we don't know which corner would be left-top.
15+
16+
### Inspired by
17+
18+
[Vue-drag-resize component](https://www.npmjs.com/package/vue-drag-resize)
19+
20+
21+
22+
# Installation and usage
23+
24+
Install with npm
25+
26+
```bash
27+
npm i @minogin/vue-drag-resize-rotate
28+
```
29+
30+
Add the following lines to your index.js (main.js):
31+
32+
```javascript
33+
import drr from '@minogin/vue-drag-resize-rotate'
34+
35+
...
36+
37+
Vue.component('drr', drr)
38+
```
39+
40+
Use DRR in your Vue templates:
41+
42+
```javascript
43+
<drr
44+
:x="item.x"
45+
:y="item.y"
46+
:w="item.weight"
47+
:h="item.height"
48+
:angle="item.angle"
49+
:aspectRatio="true"
50+
@change="itemChange"
51+
>
52+
<img src="/static/cat.jpg" style="width: 100%; height: 100%" />
53+
</drr>
54+
```
55+
56+
```javascript
57+
<drr
58+
:x="textbox.x"
59+
:y="textbox.y"
60+
:w="textbox.weight"
61+
:h="textbox.height"
62+
:rotateable="false"
63+
:isActive="textbox.selected"
64+
:selectable="!textbox.locked"
65+
:hasActiveContent="true"
66+
@activated="selectItem(textbox.id)"
67+
@deactivated="deselectItem(textbox.id)"
68+
@dragstop="textboxDragStop(textbox, ...arguments)"
69+
@resizestop="textboxResizeStop(textbox, ...arguments)"
70+
@rotatestop="textboxRotateStop(textbox, ...arguments)"
71+
:innerBox="innerBox"
72+
:outerBox="outerBox"
73+
>
74+
<TextBox />
75+
</drr>
76+
```
77+
78+
# Documentation
79+
80+
## Properties
81+
82+
#### x, y
83+
Type: `Number`\
84+
Required: `true`
85+
86+
Center of the container.
87+
88+
**Attention!**\
89+
(x; y) are the coordinates of the **center** of the container, not the left-top corner. It is because the container could be rotated and therefore we don't know which corner would be left-top.
90+
91+
#### w, h
92+
Type: `Number`\
93+
Required: `true`
94+
95+
Width and height of the container.
96+
97+
#### angle
98+
Type: `Number`\
99+
Required: `false`\
100+
Default: `0`
101+
102+
Rotation angle in degrees starting from up-axis.
103+
104+
#### selected
105+
Type: `Boolean`\
106+
Required: `false`\
107+
Default: `false`
108+
109+
Whether the container is selected and therefore able to be dragged, resized and rotated.
110+
111+
#### selectable
112+
Type: `Boolean`\
113+
Required: `false`\
114+
Default: `true`
115+
116+
Whether the container could be selected by mouse click or touch.
117+
118+
#### draggable
119+
Type: `Boolean`\
120+
Required: `false`\
121+
Default: `true`
122+
123+
Whether the container could be dragged.
124+
125+
#### resizable
126+
Type: `Boolean`\
127+
Required: `false`\
128+
Default: `true`
129+
130+
Whether the container could be resized.
131+
132+
#### rotatable
133+
Type: `Boolean`\
134+
Required: `false`\
135+
Default: `true`
136+
137+
Whether the container could be rotated.
138+
139+
#### aspectRatio
140+
Type: `Boolean`\
141+
Required: `false`\
142+
Default: `false`
143+
144+
Whether to preserve aspect ratio on resize.
145+
146+
#### hasActiveContent
147+
Type: `Boolean`\
148+
Required: `false`\
149+
Default: `false`
150+
151+
True means that there is some content in the container that could be activated by double click. For example editable text field, an image which enlarges or some nested elements.
152+
When content is activated by double click the container is locked and every child receives 'content-active' event. The content must determine by itself when the job is finished and send the 'content-inactive' event to the parent DRR like this:
153+
```javascript
154+
this.$parent.$emit('content-inactive')
155+
```
156+
157+
#### outerBound
158+
Type: `Object`\
159+
Required: `false`\
160+
Default: `null`
161+
162+
A rectangular object
163+
```javascript
164+
{
165+
x: ...,
166+
y: ...,
167+
w: ...,
168+
h: ...
169+
}
170+
```
171+
which is the outer limit for DRR dragging and resizing. This boundary currently applies only to not rotated DRR. x and y are the coordinates of the center of the rectangle.
172+
173+
#### innerBound
174+
Type: `Object`\
175+
Required: `false`\
176+
Default: `null`
177+
178+
A rectangular object
179+
```javascript
180+
{
181+
x: ...,
182+
y: ...,
183+
w: ...,
184+
h: ...
185+
}
186+
```
187+
which is the inner limit for DRR dragging and resizing. It means that this rectangle will always be contained inside the container.
188+
This boundary currently applies only to not rotated DRR. x and y are the coordinates of the center of the rectangle.
189+
190+
## Events
191+
192+
#### select
193+
Fires when container is selected (focused).
194+
195+
#### deselect
196+
Fires when container loses focus by clicking outside of the container.
197+
198+
**Caution!** Currently clicking on another DRRs does not deselect current DRR. You must keep proper selection yourself using `selected` property.
199+
200+
#### dragstart (rect)
201+
Properties:\
202+
`rect`: `Object { x, y, w, h, angle }` - container coordinates on drag start
203+
204+
Fires on drag start.
205+
206+
#### drag (rect)
207+
Properties:\
208+
`rect`: `Object { x, y, w, h, angle }` - current container coordinates
209+
210+
Fires continuously while dragging
211+
212+
**Caution!** This event fires many times per second. Consider handler [debouncing](https://lodash.com/docs/#debounce).
213+
214+
#### dragstop (rect, startRect)
215+
Properties:\
216+
`rect`: `Object { x, y, w, h, angle }` - final container coordinates\
217+
`startRect`: `Object { x, y, w, h, angle }` - initial container coordinates.
218+
219+
Fires when drag finishes.
220+
221+
#### resizestart (rect)
222+
Properties:\
223+
`rect`: `Object { x, y, w, h, angle }` - container coordinates on resize start.
224+
225+
Fires on resize start.
226+
227+
#### resize (rect)
228+
Properties:\
229+
`rect`: `Object { x, y, w, h, angle }` - current container coordinates
230+
231+
Fires continuously while resizing.
232+
233+
**Caution!** This event fires many times per second. Consider handler [debouncing](https://lodash.com/docs/#debounce).
234+
235+
#### resizestop (rect, startRect)
236+
Properties:\
237+
`rect`: `Object { x, y, w, h, angle }` - final container coordinates\
238+
`startRect`: `Object { x, y, w, h, angle }` - initial container coordinates
239+
240+
Fires when resize finishes.
241+
242+
#### rotatestart (rect)
243+
Properties:\
244+
`rect`: `Object { x, y, w, h, angle }` - container coordinates on rotation start.
245+
246+
Fires on rotation start.
247+
248+
#### rotate (rect)
249+
Properties:\
250+
`rect`: `Object { x, y, w, h, angle }` - current container coordinates
251+
252+
Fires continuously while rotating.
253+
254+
**Caution!** This event fires many times per second. Consider handler [debouncing](https://lodash.com/docs/#debounce).
255+
256+
#### rotatestop (rect, startRect)
257+
Properties:\
258+
`rect`: `Object { x, y, w, h, angle }` - final container coordinates\
259+
`startRect`: `Object { x, y, w, h, angle }` - initial container coordinates
260+
261+
Fires when rotation finishes.
262+
263+
#### change (rect)
264+
Properties:\
265+
`rect`: `Object { x, y, w, h, angle }` - final container coordinates\
266+
267+
Fired when drag, resize or rotate finishes.
268+
269+
#### content-active
270+
271+
Fired when container is double-clicked and `hasActiveContent` property is set to `true`.
272+
273+
#### active
274+
275+
Fired on every child when container is double-clicked and `hasActiveContent` property is set to `true`.
276+
277+
#### inactive
278+
279+
Fired on every child when container receives 'content-inactive' event and `hasActiveContent` property is set to `true`.
280+
281+
# Hints
282+
283+
For the content (img, div, etc.) to resize along with the container use
284+
```css
285+
width: 100%;
286+
height: 100%;
287+
```
288+
style on the content element.
289+
290+
# Contacts
291+
292+
Please contact me at [minogin@gmail.com](mailto:minogin@gmail.com)
293+
294+
# License
295+
296+
[ISC](https://opensource.org/licenses/ISC)

0 commit comments

Comments
 (0)