更新记录
1.0.0(2025-06-24)
更新版本 1.0.0
功能特点
- 100%纯JS代码实现,依赖于CSS3 transform、transform-origin特性,性能高无卡顿;
- 双指缩放时,支持以双指中心点缩放元素,而不是以元素中心点缩放,聚焦缩放目标;
- 支持0.01~10比例缩放,scale值精确到两位小数,组件缩放更丝滑;
- 支持可移动区域边界距离设置,限制在边界距离区域以内才可移动;
- 兼容性支持:微信小程序、安卓、苹果、H5、鸿蒙(其他平台未测试理论上支持)。
平台兼容性
云端兼容性
uni-app(4.19)
Vue2 |
Vue3 |
Chrome |
Safari |
app-vue |
app-nvue |
Android |
iOS |
鸿蒙 |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
微信小程序 |
支付宝小程序 |
抖音小程序 |
百度小程序 |
快手小程序 |
京东小程序 |
鸿蒙元服务 |
QQ小程序 |
飞书小程序 |
快应用-华为 |
快应用-联盟 |
√ |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
其他
uniapp通用拖拽滑动或双指缩放组件
模拟实现了相较于系统自带movable-area, movable-view功能,但有以下几个优点。
功能特点
- 100%纯JS代码实现,依赖于CSS3 transform、transform-origin特性,性能高无卡顿;
- 双指缩放时,支持以双指中心点缩放元素,而不是以元素中心点缩放,聚焦缩放目标;
- 支持0.01~10比例缩放,scale值精确到两位小数,组件缩放更丝滑;
- 支持可移动区域边界距离设置,限制在边界距离区域以内才可移动;
- 兼容性支持:微信小程序、安卓、苹果、H5、鸿蒙(其他平台未测试理论上支持)。
一、使用示例
<template>
<view class='movable-area'>
<aux-movable-view ref="auxMovableView" direction='all' scale :out-of-bounds='false' :out-safe-distance='20' @scale='scaleChange'>
<view class='movable-view'>
我可以拖拽、双指放大
</view>
</aux-movable-view>
</view>
</template>
<script>
export default {
data(){
return {
scaleValue: 1
}
},
methods: {
scaleChange(event){
this.scaleValue = event.scale || 1;
}
}
}
</script>
<style>
.movable-area {
width: 100%;
height: 500px;
background-color: #ddd;
}
.movable-view {
width: 100px;
height: 100px;
background-color: blue;
color: #fff;
}
</style>
组件参数
配置 |
数据类型 |
默认参数 |
说明 |
direction |
String |
all |
movable-view的移动方向,属性值有all、vertical、horizontal、none |
scale |
Boolean |
true |
是否支持双指缩放,默认缩放手势生效区域是在movable-content内 |
scale-min |
Number |
0.1 |
定义缩放倍数最小值 |
scale-max |
Number |
10 |
定义缩放倍数最大值 |
out-of-bounds |
Boolean |
false |
可移动区域设置边界距离,限制在边界距离内区域移动 |
out-safe-distance |
Number |
0 |
限制超过区域边界N距离内(单位:像素),仍可以移动 |
inertia |
Boolean |
false |
移动元素时是否带有惯性 |
disabled |
Boolean |
false |
是否禁用 |
animation |
Boolean |
true |
是否使用动画 |
@change |
function |
拖动过程中触发的事件,event = {x: x, y: y, scale: value} |
@scale |
function |
缩放过程中触发的事件,event = {x: x, y: y, scale: value} |
组件方法
配置 |
数据类型 |
说明 |
this.$refs['auxMovableView'].setScale(2) |
function |
设置缩放值 |
this.$refs['auxMovableView'].setTranslate(10,10) |
function |
设置位移值 |
this.$refs['auxMovableView'].restLayout() |
function |
重置元素布局位置,并自适应缩放视图 |
DEMO案例
<template>
<view class="content">
<view class="movable-title">
示例 1
<text class="desc">限制在区域内移动</text>
</view>
<view class="movable-area">
<aux-movable-view ref="hiMovableView1" direction='all' :out-of-bounds='false' :out-safe-distance='0' @change="change($event)" @scale="scale($event)">
<view class='movable-view'></view>
</aux-movable-view>
</view>
<view>
<button type="primary" class="btn" @click="zoom('hiMovableView1', 2)">放大</button>
<button type="primary" class="btn" @click="zoom('hiMovableView1', 1)">缩小</button>
<button type="primary" class="btn" @click="translate('hiMovableView1', 100)">移动</button>
</view>
<view class="movable-title">
示例 2
<text class="desc">可超出边界外30px移动</text>
</view>
<view class="movable-area">
<aux-movable-view ref="hiMovableView2" direction='all' :out-of-bounds='false' :out-safe-distance='30' @change="change($event)" @scale="scale($event)">
<view class='movable-view'></view>
</aux-movable-view>
</view>
<view class="movable-title">
示例 3
<text class="desc">允许自由超出区域外移动</text>
</view>
<view class="movable-area">
<aux-movable-view ref="hiMovableView3" direction='all' :out-of-bounds='true' @change="change($event)" @scale="scale($event)">
<view class='movable-view'></view>
</aux-movable-view>
</view>
<view class="movable-title">
示例 4
<text class="desc">限制横向移动</text>
</view>
<view class="movable-area">
<aux-movable-view ref="hiMovableView4" direction='horizontal' :out-of-bounds='true' :out-safe-distance='30' @change="change($event)" @scale="scale($event)">
<view class='movable-view'></view>
</aux-movable-view>
</view>
<view class="movable-title">
示例 5
<text class="desc">限制纵向移动</text>
</view>
<view class="movable-area">
<aux-movable-view ref="hiMovableView5" direction='vertical' :out-of-bounds='true' @change="change($event)" @scale="scale($event)">
<view class='movable-view'></view>
</aux-movable-view>
</view>
<view class="movable-title">
示例 6
<text class="desc">带有惯性移动</text>
</view>
<view class="movable-area">
<aux-movable-view ref="hiMovableView6" direction='all' :inertia='true' :out-of-bounds='false' @change="change($event)" @scale="scale($event)">
<view class='movable-view'></view>
</aux-movable-view>
</view>
<view class="movable-title">
示例 7
<text class="desc">可以缩放</text>
</view>
<view class="movable-area" style="height: 400px;">
<aux-movable-view ref="hiMovableView7" direction='all' scale :max-scale="5" :out-of-bounds='true' @change="change($event)" @scale="scale($event)">
<view class='movable-view image'>
<image class="image" src="https://web-ext-storage.dcloud.net.cn/doc/uni-app-x-640.png"></image>
</view>
</aux-movable-view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: 'Hello'
}
},
onLoad() {
},
methods: {
scale(e){
// console.log('scale', e)
},
change(e){
// console.log('change', e)
},
zoom(refName, scale){
this.$refs[refName].setScale(scale);
},
translate(refName, value){
this.$refs[refName].setTranslate(100,10);
}
}
}
</script>
<style lang="scss">
.content {
padding: 10px;
}
.btn{
width: 100px;
font-size: 14px;
display: inline-block;
margin-left: 10px;
margin: 4px;
}
.movable-title{
margin-top: 20px;
margin-bottom: 2px;
.desc{
display: block;
color: gray;
font-size: $uni-font-size-base;
}
}
.movable-area {
width: 100%;
height: 200px;
background-color: #ddd;
}
.movable-view {
width: 80px;
height: 80px;
background-color: $uni-color-primary;
color: #fff;
&.image, .image{
width: 300px;
height: 180px;
}
}
</style>