123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- <template>
- <view
- id="drag-button"
- class="drag-container"
- :class="{transition: autoDocking && !moving }"
- :style="{
- left: `${left}px`,
- top: `${top}px`,
- width: `${size}rpx`,
- height: `${size}rpx`,
- zIndex: zIndex
- }"
- @touchend="touchend"
- @touchmove.stop.prevent="touchmove"
- >
- <slot />
- </view>
- </template>
- <script>
- export default {
- name: 'DragButton',
- props: {
- /**
- * 按钮大小
- */
- size: {
- type: Number,
- default: 200
- },
- /**
- * 层级
- */
- zIndex: {
- type: Number,
- default: 999
- },
- /**
- * x轴边界限制
- */
- xEdge: {
- type: Number,
- default: 0
- },
- /**
- * y轴边界限制
- */
- yEdge: {
- type: Number,
- default: 0
- },
- /**
- * 自动停靠
- */
- autoDocking: {
- type: Boolean,
- default: true
- },
- // 是否开启沿袭拖动位置
- isAutoPosition: {
- type: Boolean,
- default: true
- },
- // 超出左右边界长度
- exceedBorderLength: {
- type: Number,
- default: 0
- }
- },
- data() {
- return {
- top: 500,
- left: 300,
- width: 0,
- height: 0,
- moving: true,
- }
- },
- mounted() {
- this.init()
- },
- methods: {
- init() {
- // 获取窗口尺寸
- const { windowWidth, windowHeight, windowTop } = uni.getSystemInfoSync()
- this._windowWidth = windowWidth
- this._windowHeight = windowHeight
- if (windowTop) {
- this._windowHeight += windowTop
- }
- // 计算按钮初始位置
- const query = uni.createSelectorQuery().in(this)
- query.select('#drag-button').boundingClientRect(data => {
- if (!data) return
- console.log(data);
- const { width, height } = data
- this.width = width
- this.height = height
- this._offsetWidth = width / 2
- this._offsetHeight = height / 2
- let positionStorage = uni.getStorageSync('dragBtn');
- if (this.isAutoPosition && positionStorage){
- this.left = positionStorage.left;
- this.top = positionStorage.top;
- }else {
- this.left = (this._windowWidth - this.width - this.xEdge) > 0 ? this._windowWidth - this.width - this.xEdge + this.exceedBorderLength : 0 - this.exceedBorderLength
- this.top = (this._windowHeight - this.height - this.yEdge) > 0 ? this._windowHeight - this.height - this.yEdge : 0
- if (this.isAutoPosition){
- uni.setStorageSync('dragBtn', {
- top: this.top,
- left: this.left
- });
- }
- }
- }).exec()
- },
- // 拖动
- touchmove({ touches }) {
- if (touches.length !== 1) return false
- this.moving = true
- const { clientX, clientY } = touches[0]
- this.left = clientX - this._offsetWidth
- let _clientY = clientY - this._offsetHeight
- // #ifdef H5
- _clientY += this.height
- // #endif
- this.top = _clientY
- },
- // 松手
- touchend() {
- // 左右边界,松手自动停靠
- if (this.autoDocking) {
- const rigthEdge = this._windowWidth - this.width - this.xEdge
- if (this.left < this._windowWidth / 2 - this._offsetWidth) {
- this.left = this.xEdge - this.exceedBorderLength
- } else {
- this.left = rigthEdge + this.exceedBorderLength
- }
- }
- // 上下边界
- const bottomEdge = this._windowHeight - this.height - this.yEdge
- if (this.top < this.yEdge) {
- this.top = this.yEdge
- } else if (this.top > bottomEdge) {
- this.top = bottomEdge
- }
-
- // 记录位置变化
- if (this.isAutoPosition){
- uni.setStorageSync('dragBtn', {
- top: this.top,
- left: this.left
- });
- }
-
- console.log(uni.getStorageSync('dragBtn'))
-
- this.moving = false
- },
- }
- }
- </script>
- <style lang="scss" scoped>
- .drag-container {
- display: flex;
- justify-content: center;
- align-items: center;
- border-radius: 50%;
- position: fixed;
- &.transition {
- transition: all .3s ease;
- }
- }
- </style>
|