0
# Advanced Features
1
2
Advanced functionality including aspect ratio locking, handle customization, programmatic control methods, and specialized configuration options.
3
4
## Capabilities
5
6
### Aspect Ratio Control
7
8
Lock aspect ratio during resize operations to maintain proportional dimensions.
9
10
```javascript { .api }
11
/**
12
* Aspect ratio locking configuration
13
*/
14
interface AspectRatioControl {
15
/** Enable aspect ratio locking (default: false) */
16
lockAspectRatio: boolean;
17
}
18
```
19
20
**Usage Examples:**
21
22
```vue
23
<template>
24
<!-- Image with locked aspect ratio -->
25
<vue-draggable-resizable
26
:lock-aspect-ratio="true"
27
:w="300"
28
:h="200"
29
>
30
<img src="photo.jpg" style="width: 100%; height: 100%; object-fit: cover;" />
31
</vue-draggable-resizable>
32
33
<!-- Video player with 16:9 ratio -->
34
<vue-draggable-resizable
35
:lock-aspect-ratio="true"
36
:w="480"
37
:h="270"
38
:min-width="320"
39
:min-height="180"
40
>
41
<video controls style="width: 100%; height: 100%;">
42
<source src="video.mp4" type="video/mp4">
43
</video>
44
</vue-draggable-resizable>
45
</template>
46
```
47
48
### Handle Customization
49
50
Configure which resize handles are available and customize their appearance and behavior.
51
52
```javascript { .api }
53
/**
54
* Resize handle configuration and types
55
*/
56
interface HandleCustomization {
57
/** Array of enabled resize handles (default: all 8 handles) */
58
handles: HandleType[];
59
60
/** Base CSS class for handles, used to create handle-specific classes */
61
classNameHandle: string;
62
}
63
64
/** Available resize handle positions */
65
type HandleType = 'tl' | 'tm' | 'tr' | 'mr' | 'br' | 'bm' | 'bl' | 'ml';
66
67
/** Handle position meanings */
68
interface HandlePositions {
69
'tl': 'top-left'; // Corner: top-left
70
'tm': 'top-middle'; // Edge: top-middle
71
'tr': 'top-right'; // Corner: top-right
72
'mr': 'middle-right'; // Edge: middle-right
73
'br': 'bottom-right'; // Corner: bottom-right
74
'bm': 'bottom-middle';// Edge: bottom-middle
75
'bl': 'bottom-left'; // Corner: bottom-left
76
'ml': 'middle-left'; // Edge: middle-left
77
}
78
```
79
80
**Usage Examples:**
81
82
```vue
83
<template>
84
<!-- Only corner handles -->
85
<vue-draggable-resizable
86
:handles="['tl', 'tr', 'br', 'bl']"
87
class-name-handle="corner-handle"
88
>
89
Corner resize only
90
</vue-draggable-resizable>
91
92
<!-- Only right and bottom handles -->
93
<vue-draggable-resizable
94
:handles="['mr', 'br', 'bm']"
95
>
96
Expand right and down only
97
</vue-draggable-resizable>
98
99
<!-- Custom handle slots -->
100
<vue-draggable-resizable :handles="['br']">
101
<template #br>
102
<div class="custom-handle">
103
<svg width="10" height="10">
104
<path d="M0,0 L10,10 M0,10 L10,0" stroke="black" />
105
</svg>
106
</div>
107
</template>
108
Custom handle appearance
109
</vue-draggable-resizable>
110
</template>
111
112
<style>
113
.corner-handle {
114
border-radius: 50%;
115
background: #ff6b6b;
116
}
117
118
.custom-handle {
119
display: flex;
120
align-items: center;
121
justify-content: center;
122
background: rgba(0, 0, 0, 0.7);
123
border-radius: 3px;
124
}
125
</style>
126
```
127
128
### Scale Factor Support
129
130
Handle parent element scaling transformations correctly.
131
132
```javascript { .api }
133
/**
134
* Scale factor configuration for transformed parent elements
135
*/
136
interface ScaleSupport {
137
/** Scale factor - single number or [scaleX, scaleY] array (default: 1) */
138
scale: number | [number, number];
139
}
140
```
141
142
**Usage Examples:**
143
144
```vue
145
<template>
146
<!-- Parent container with CSS transform scale -->
147
<div class="scaled-container">
148
<vue-draggable-resizable
149
:scale="0.75"
150
:w="200"
151
:h="150"
152
>
153
Handles parent scaling
154
</vue-draggable-resizable>
155
</div>
156
157
<!-- Different X and Y scale factors -->
158
<div class="stretched-container">
159
<vue-draggable-resizable
160
:scale="[0.8, 1.2]"
161
>
162
Different X/Y scaling
163
</vue-draggable-resizable>
164
</div>
165
</template>
166
167
<style>
168
.scaled-container {
169
transform: scale(0.75);
170
transform-origin: top left;
171
}
172
173
.stretched-container {
174
transform: scaleX(0.8) scaleY(1.2);
175
transform-origin: top left;
176
}
177
</style>
178
```
179
180
### Custom Drag Handles
181
182
Specify custom elements within the component that act as drag handles or prevent dragging.
183
184
```javascript { .api }
185
/**
186
* Custom drag handle configuration
187
*/
188
interface CustomDragHandles {
189
/** CSS selector for elements that act as drag handles */
190
dragHandle?: string;
191
192
/** CSS selector for elements that prevent dragging when clicked */
193
dragCancel?: string;
194
}
195
```
196
197
**Usage Examples:**
198
199
```vue
200
<template>
201
<!-- Custom drag handle -->
202
<vue-draggable-resizable
203
drag-handle=".drag-handle"
204
drag-cancel=".no-drag"
205
>
206
<div class="drag-handle" style="background: #eee; padding: 10px; cursor: move;">
207
π Drag me here
208
</div>
209
<div style="padding: 10px;">
210
<p>Main content area</p>
211
<button class="no-drag">Don't drag when clicking this button</button>
212
</div>
213
</vue-draggable-resizable>
214
215
<!-- Multiple drag handles -->
216
<vue-draggable-resizable drag-handle=".handle">
217
<div class="handle title-bar">Title Bar (drag here)</div>
218
<div>Content area</div>
219
<div class="handle status-bar">Status Bar (or here)</div>
220
</vue-draggable-resizable>
221
</template>
222
223
<style>
224
.drag-handle {
225
cursor: move;
226
user-select: none;
227
}
228
229
.title-bar {
230
background: #333;
231
color: white;
232
padding: 8px;
233
}
234
235
.status-bar {
236
background: #f0f0f0;
237
padding: 4px 8px;
238
font-size: 0.9em;
239
}
240
241
.no-drag {
242
cursor: pointer;
243
}
244
</style>
245
```
246
247
### Programmatic Control Methods
248
249
Methods for controlling component position and size programmatically.
250
251
```javascript { .api }
252
/**
253
* Programmatic control methods available on component instance
254
*/
255
interface ProgrammaticMethods {
256
/**
257
* Set horizontal position programmatically
258
* @param val - New X position in pixels
259
*/
260
moveHorizontally(val: number): void;
261
262
/**
263
* Set vertical position programmatically
264
* @param val - New Y position in pixels
265
*/
266
moveVertically(val: number): void;
267
268
/**
269
* Set width programmatically
270
* @param val - New width in pixels
271
*/
272
changeWidth(val: number): void;
273
274
/**
275
* Set height programmatically
276
* @param val - New height in pixels
277
*/
278
changeHeight(val: number): void;
279
}
280
```
281
282
**Usage Examples:**
283
284
```vue
285
<template>
286
<div>
287
<vue-draggable-resizable
288
ref="draggableElement"
289
:w="200"
290
:h="150"
291
>
292
Programmable element
293
</vue-draggable-resizable>
294
295
<div class="controls">
296
<button @click="moveToCenter">Center</button>
297
<button @click="resetSize">Reset Size</button>
298
<button @click="animateToCorner">Animate to Corner</button>
299
</div>
300
</div>
301
</template>
302
303
<script>
304
export default {
305
methods: {
306
moveToCenter() {
307
const container = this.$el;
308
const element = this.$refs.draggableElement;
309
310
const centerX = (container.offsetWidth - 200) / 2;
311
const centerY = (container.offsetHeight - 150) / 2;
312
313
element.moveHorizontally(centerX);
314
element.moveVertically(centerY);
315
},
316
317
resetSize() {
318
const element = this.$refs.draggableElement;
319
element.changeWidth(200);
320
element.changeHeight(150);
321
},
322
323
async animateToCorner() {
324
const element = this.$refs.draggableElement;
325
const steps = 20;
326
const targetX = 0;
327
const targetY = 0;
328
329
// Simple animation by stepping through positions
330
for (let i = 0; i <= steps; i++) {
331
const progress = i / steps;
332
const currentX = element.left * (1 - progress) + targetX * progress;
333
const currentY = element.top * (1 - progress) + targetY * progress;
334
335
element.moveHorizontally(currentX);
336
element.moveVertically(currentY);
337
338
await new Promise(resolve => setTimeout(resolve, 20));
339
}
340
}
341
}
342
}
343
</script>
344
```
345
346
### Grid Snapping
347
348
Configure grid-based snapping for precise positioning and sizing.
349
350
```javascript { .api }
351
/**
352
* Grid snapping configuration
353
*/
354
interface GridSnapping {
355
/** Grid intervals [x, y] in pixels (default: [1, 1]) */
356
grid: [number, number];
357
}
358
```
359
360
**Usage Examples:**
361
362
```vue
363
<template>
364
<!-- 20x20 pixel grid -->
365
<vue-draggable-resizable
366
:grid="[20, 20]"
367
:w="200"
368
:h="160"
369
>
370
Snaps to 20px grid
371
</vue-draggable-resizable>
372
373
<!-- Different X and Y grid sizes -->
374
<vue-draggable-resizable
375
:grid="[25, 15]"
376
>
377
25px horizontal, 15px vertical grid
378
</vue-draggable-resizable>
379
380
<!-- Fine grid for precision -->
381
<vue-draggable-resizable
382
:grid="[5, 5]"
383
>
384
Fine 5px grid
385
</vue-draggable-resizable>
386
</template>
387
```
388
389
### Slot System
390
391
Comprehensive slot system allowing content customization and custom handle designs.
392
393
```javascript { .api }
394
/**
395
* Available slots for content and handle customization
396
*/
397
interface SlotSystem {
398
/** Default slot for main component content */
399
default: Slot;
400
401
/** Named slots for each resize handle position */
402
'tl': Slot; // Top-left handle slot
403
'tm': Slot; // Top-middle handle slot
404
'tr': Slot; // Top-right handle slot
405
'mr': Slot; // Middle-right handle slot
406
'br': Slot; // Bottom-right handle slot
407
'bm': Slot; // Bottom-middle handle slot
408
'bl': Slot; // Bottom-left handle slot
409
'ml': Slot; // Middle-left handle slot
410
}
411
```
412
413
**Usage Examples:**
414
415
```vue
416
<template>
417
<!-- Custom handle designs -->
418
<vue-draggable-resizable :handles="['tl', 'br', 'mr']">
419
<!-- Default slot content -->
420
<div class="content">
421
<h3>Resizable Card</h3>
422
<p>Content goes here</p>
423
</div>
424
425
<!-- Custom corner handle -->
426
<template #tl>
427
<div class="corner-handle top-left">
428
<svg width="12" height="12">
429
<path d="M2,2 L10,2 L10,10" stroke="currentColor" fill="none" stroke-width="2"/>
430
</svg>
431
</div>
432
</template>
433
434
<!-- Custom corner handle -->
435
<template #br>
436
<div class="corner-handle bottom-right">
437
<svg width="12" height="12">
438
<path d="M2,10 L10,10 L10,2" stroke="currentColor" fill="none" stroke-width="2"/>
439
</svg>
440
</div>
441
</template>
442
443
<!-- Custom edge handle -->
444
<template #mr>
445
<div class="edge-handle">
446
<div class="handle-dots">
447
<span></span>
448
<span></span>
449
<span></span>
450
</div>
451
</div>
452
</template>
453
</vue-draggable-resizable>
454
</template>
455
456
<style>
457
.content {
458
padding: 16px;
459
background: white;
460
border: 1px solid #ddd;
461
border-radius: 4px;
462
height: 100%;
463
box-sizing: border-box;
464
}
465
466
.corner-handle {
467
display: flex;
468
align-items: center;
469
justify-content: center;
470
background: rgba(0, 123, 255, 0.1);
471
border: 2px solid #007bff;
472
border-radius: 6px;
473
color: #007bff;
474
cursor: nw-resize;
475
}
476
477
.corner-handle.bottom-right {
478
cursor: se-resize;
479
}
480
481
.edge-handle {
482
display: flex;
483
align-items: center;
484
justify-content: center;
485
background: #f8f9fa;
486
border: 1px solid #dee2e6;
487
border-radius: 4px;
488
cursor: ew-resize;
489
}
490
491
.handle-dots {
492
display: flex;
493
flex-direction: column;
494
gap: 2px;
495
}
496
497
.handle-dots span {
498
width: 3px;
499
height: 3px;
500
background: #6c757d;
501
border-radius: 50%;
502
}
503
</style>
504
```
505
506
**Themed Handle Examples:**
507
508
```vue
509
<template>
510
<!-- Dark theme handles -->
511
<vue-draggable-resizable class="dark-theme">
512
<div class="dark-content">Dark themed content</div>
513
514
<template #tl>
515
<div class="dark-handle corner">β</div>
516
</template>
517
<template #tr>
518
<div class="dark-handle corner">β</div>
519
</template>
520
<template #bl>
521
<div class="dark-handle corner">β</div>
522
</template>
523
<template #br>
524
<div class="dark-handle corner">β</div>
525
</template>
526
</vue-draggable-resizable>
527
528
<!-- Minimal handles -->
529
<vue-draggable-resizable :handles="['br']">
530
<div class="minimal-content">Minimal resize</div>
531
532
<template #br>
533
<div class="minimal-handle">
534
<div class="resize-icon">β€’</div>
535
</div>
536
</template>
537
</vue-draggable-resizable>
538
</template>
539
540
<style>
541
.dark-theme {
542
background: #343a40;
543
border: 1px solid #495057;
544
}
545
546
.dark-content {
547
color: white;
548
padding: 16px;
549
}
550
551
.dark-handle {
552
background: #495057;
553
color: #adb5bd;
554
border: 1px solid #6c757d;
555
border-radius: 3px;
556
font-size: 12px;
557
display: flex;
558
align-items: center;
559
justify-content: center;
560
}
561
562
.minimal-handle {
563
background: transparent;
564
color: #6c757d;
565
display: flex;
566
align-items: flex-end;
567
justify-content: flex-end;
568
cursor: se-resize;
569
}
570
571
.resize-icon {
572
font-size: 14px;
573
line-height: 1;
574
}
575
</style>
576
```
577
578
### Touch Device Support
579
580
Built-in support for touch devices with optimized touch event handling.
581
582
```javascript { .api }
583
/**
584
* Touch device support is automatically enabled
585
* Component handles both mouse and touch events seamlessly
586
*/
587
interface TouchSupport {
588
/** Touch events are automatically detected and handled */
589
touchEnabled: true;
590
591
/** Enhanced touch targets on mobile devices via CSS media queries */
592
mobileFriendly: true;
593
}
594
```
595
596
**Usage Examples:**
597
598
```vue
599
<template>
600
<!-- Works automatically on touch devices -->
601
<vue-draggable-resizable
602
:w="250"
603
:h="200"
604
class="touch-optimized"
605
>
606
Touch and drag on mobile
607
608
<!-- Larger handles for better touch experience -->
609
<template #br>
610
<div class="touch-handle">
611
<div class="touch-indicator"></div>
612
</div>
613
</template>
614
</vue-draggable-resizable>
615
</template>
616
617
<style>
618
.touch-optimized {
619
/* Component automatically includes mobile-friendly handle sizing */
620
}
621
622
.touch-handle {
623
width: 20px;
624
height: 20px;
625
background: rgba(0, 123, 255, 0.2);
626
border: 2px solid #007bff;
627
border-radius: 4px;
628
display: flex;
629
align-items: center;
630
justify-content: center;
631
}
632
633
.touch-indicator {
634
width: 8px;
635
height: 8px;
636
background: #007bff;
637
border-radius: 2px;
638
}
639
640
/* Additional mobile optimizations */
641
@media (max-width: 768px) {
642
.touch-optimized {
643
min-width: 100px;
644
min-height: 80px;
645
}
646
647
.touch-handle {
648
width: 24px;
649
height: 24px;
650
}
651
}
652
</style>
653
```