Drag and Scale
Operate elements to move within the parent container and perform scaling.
Installation
INFO
If you need to use other components, please refer toFull Components Installation
To install this component individually, run the following command:
shell
npm install @havue/drag-and-scale --save
shell
yarn add @havue/drag-and-scale
shell
pnpm install @havue/drag-and-scale
Import
vue
<script>
import { HvDragAndScale } from 'havue'
// or
import { HvDragAndScale } from '@havue/components'
// or
import { HvDragAndScale } from '@havue/color-picker'
</script>
Examples
Set container actual dimensions to 1920x1080.
The first black element limits minimum size to 64x64, maintains aspect ratio, and restricts movement within the container.
The second gray element limits minimum size to 128x128 and maximum size to 512x300.
min: 64*64
keepRatio: true
inContaienr: true
min: 128*128
max: 512*300
keepRatio: false
inContaienr: false
Click to view code
vue
<template>
<div class="drag-area" ref="containerRef">
<DragAndScale
:container="containerRef"
:containerRealSize="containerRealSize"
:keepRatio="{
enable: true,
scaleCase: 'min'
}"
:limit="{ minWidth: 64, minHeight: 64 }"
:disabled="false"
class="drag-box"
@change="handleChange"
:style="dragStyle"
>
<div class="inner-box">
<div>min: 64*64</div>
<div>keepRatio: true</div>
<div>inContaienr: true</div>
</div>
</DragAndScale>
<DragAndScale
:container="containerRef"
:containerRealSize="containerRealSize"
:keepRatio="{
enable: false,
scaleCase: 'min'
}"
:limit="{ inContainer: false, minWidth: 128, minHeight: 128, maxWidth: 512, maxHeight: 300 }"
:disabled="false"
class="drag-box"
@change="handleChange2"
:style="dragStyle2"
>
<div class="inner-box">
<div>min: 128*128</div>
<div>max: 512*300</div>
<div>keepRatio: false</div>
<div>inContaienr: false</div>
</div>
</DragAndScale>
</div>
</template>
ts
<script setup lang="ts">
import type { DragAndScaleChangeResultType } from '@havue/drag-and-scale'
import { ref, computed } from 'vue'
// import { HvDragAndScale as DragAndScale } from '@havue/drag-and-scale'
import { HvDragAndScale as DragAndScale } from '@havue/components'
const containerRef = ref()
const dragPosition = ref({
x: 50,
y: 50,
width: 100,
height: 50
})
const dragPosition2 = ref({
x: 230,
y: 50,
width: 100,
height: 50
})
const containerRealSize = ref({ width: 1920, height: 1080 })
const dragStyle = computed(() => {
return {
top: `${dragPosition.value.y}px`,
left: `${dragPosition.value.x}px`,
width: `${dragPosition.value.width}px`,
height: `${dragPosition.value.height}px`
}
})
const dragStyle2 = computed(() => {
return {
top: `${dragPosition2.value.y}px`,
left: `${dragPosition2.value.x}px`,
width: `${dragPosition2.value.width}px`,
height: `${dragPosition2.value.height}px`,
background: 'gray'
}
})
function handleChange(params: DragAndScaleChangeResultType) {
Object.assign(dragPosition.value, {
x: params.elX,
y: params.elY,
width: params.elWidth,
height: params.elHeight
})
console.log(params)
}
function handleChange2(params: DragAndScaleChangeResultType) {
Object.assign(dragPosition2.value, {
x: params.elX,
y: params.elY,
width: params.elWidth,
height: params.elHeight
})
console.log(params)
}
</script>
scss
<style lang="scss" scoped>
.drag-area {
position: relative;
box-sizing: border-box;
width: 100%;
height: 400px;
overflow: hidden;
background-color: rgb(71 121 105);
.drag-box {
position: absolute;
background-color: rgb(26 24 24);
.inner-box {
width: 100%;
height: 100%;
overflow: hidden;
white-space: nowrap;
user-select: none;
}
}
}
</style>
To disable scaling while keeping dragging, add these styles:
css
.hv-drag-and-scale {
--scale-area-width: 0px;
border: none;
}
To disable dragging while keeping scaling, add these styles:
scss
.hv-drag-and-scale {
.hv-drag-and-scale__area-center {
pointer-events: none;
}
}
Props
TIP
Properties marked with '?' are optional.
Property | Description | Type | Default |
---|---|---|---|
container | Container element | HTMLElement | Ref<HTMLElement> | — |
containerRealSize? | Actual physical dimensions of container | object | — |
containerRealSize.width | Actual physical width | number | — |
containerRealSize.height | Actual physical height | number | — |
keepRatio? | Aspect ratio configuration | object | — |
keepRatio.enable | Whether to maintain aspect ratio | boolean | false |
keepRatio?.scaleCase | Use min/max delta when scaling | 'min' | 'max' | 'min' |
limit? | Size constraints | object | — |
limit?.inContainer | Restrict within parent | boolean | true |
limit?.minWidth | Minimum width limit | number | 0 |
limit?.minHeight | Minimum height limit | number | 0 |
limit?.maxWidth | Maximum width limit | number | Infinity |
limit?.maxHeight | Maximum height limit | number | Infinity |
disabled? | Disable interaction | boolean | false |
Events
Event | Description | Parameters |
---|---|---|
change | Triggered during drag/scale | (params: DragAndScaleChangeResultType) => void |
finish | Triggered after drag/scale ends | () => void |
ts
type DragAndScaleChangeResultType {
/** Operation type */
type: 'move' | 'scale'
/** Horizontal distance moved compared to last change event */
deltaX: number
/** Vertical distance moved compared to last change event */
deltaY: number
/** Element X position in container */
elX: number
/** Element Y position in container */
elY: number
/** Element width */
elWidth: number
/** Element height */
elHeight: number
/** Actual X coordinate converted via containerRealSize */
realX: number
/** Actual Y coordinate converted via containerRealSize */
realY: number
/** Actual width converted via containerRealSize */
realWidth: number
/** Actual height converted via containerRealSize */
realHeight: number
}
Slots
Slots | Description |
---|---|
default | Default content |