@nutui/nutui
Version:
京东风格的轻量级移动端 Vue2、Vue3 组件库(支持小程序开发)
194 lines (193 loc) • 6.11 kB
JavaScript
import { ref, reactive, onMounted, onActivated, onDeactivated, openBlock, createElementBlock, renderSlot } from "vue";
import { c as createComponent } from "../component-DQf3CENX.js";
import { r as requestAniFrame } from "../raf-c01wDYCo.js";
import { _ as _export_sfc } from "../_plugin-vue_export-helper-1tPrXgE0.js";
const { create } = createComponent("drag");
const _sfc_main = create({
props: {
attract: {
type: Boolean,
default: false
},
direction: {
type: String,
default: "all"
},
boundary: {
type: Object,
default: () => {
return {
top: 0,
left: 0,
right: 0,
bottom: 0
};
}
}
},
setup(props) {
const myDrag = ref();
const state = reactive({
keepAlive: false,
elWidth: 0,
elHeight: 0,
screenWidth: 0,
screenHeight: 0,
startTop: 0,
startLeft: 0,
nx: 0,
ny: 0,
xPum: 0,
yPum: 0,
position: { x: 0, y: 0 },
boundary: {
top: 0,
left: 0,
right: 0,
bottom: 0
}
});
function getInfo() {
const domElem = document.documentElement;
state.elWidth = myDrag.value.offsetWidth;
state.elHeight = myDrag.value.offsetHeight;
state.screenWidth = domElem.clientWidth || 375;
state.screenHeight = domElem.clientHeight || 667;
}
function goLeft(target) {
if (state.boundary.left) {
if (+target.style.left.split("px")[0] > state.boundary.left) {
target.style.left = +target.style.left.split("px")[0] - 10 + "px";
requestAniFrame(() => {
goLeft(target);
});
} else {
target.style.left = `${state.boundary.left}px`;
}
} else {
if (+target.style.left.split("px")[0] > 10) {
target.style.left = +target.style.left.split("px")[0] - 10 + "px";
requestAniFrame(() => {
goLeft(target);
});
} else {
target.style.left = "0px";
}
}
}
function goRight(target, rightLocation) {
if (rightLocation - parseInt(target.style.left.split("px")[0]) > 10) {
target.style.left = parseInt(target.style.left.split("px")[0]) + 10 + "px";
requestAniFrame(() => {
goRight(target, rightLocation);
});
} else {
target.style.left = rightLocation + "px";
}
}
function touchMove(e) {
e.preventDefault();
const target = e.currentTarget;
if (e.targetTouches.length === 1) {
const touch = e.targetTouches[0];
state.nx = touch.clientX - state.position.x;
state.ny = touch.clientY - state.position.y;
state.xPum = state.startLeft + state.nx;
state.yPum = state.startTop + state.ny;
const rightLocation = state.screenWidth - state.elWidth - state.boundary.right;
if (Math.abs(state.xPum) > rightLocation) {
state.xPum = rightLocation;
} else if (state.xPum <= state.boundary.left) {
state.xPum = state.boundary.left;
}
if (state.yPum < state.boundary.top) {
state.yPum = state.boundary.top;
} else if (state.yPum > state.screenHeight - state.elHeight - state.boundary.bottom) {
state.yPum = state.screenHeight - state.elHeight - state.boundary.bottom;
}
if (props.direction != "y") {
target.style.left = state.xPum + "px";
}
if (props.direction != "x") {
target.style.top = state.yPum + "px";
}
}
}
function touchEnd(e) {
const target = e.currentTarget;
const touch = e.changedTouches[0];
let currX = touch.clientX;
const rightLocation = state.screenWidth - state.elWidth - state.boundary.right;
if (currX > rightLocation) {
currX = rightLocation;
} else if (currX < state.boundary.left) {
currX = state.boundary.left;
} else {
currX = currX < state.screenWidth / 2 ? state.boundary.left : rightLocation;
}
if (props.direction != "y" && props.attract) {
if (currX < state.screenWidth / 2) {
requestAniFrame(() => {
goLeft(target);
});
} else {
requestAniFrame(() => {
goRight(target, rightLocation);
});
}
}
if (props.direction != "x") {
target.style.top = state.yPum + "px";
}
}
function touchStart(e) {
const target = e.currentTarget;
const touches = e.touches[0];
const touch = e.targetTouches[0];
state.startTop = target.offsetTop;
state.startLeft = target.offsetLeft;
state.position.x = touches.clientX;
state.position.y = touches.clientY;
state.nx = touch.clientX - state.position.x;
state.ny = touch.clientY - state.position.y;
state.xPum = state.startLeft + state.nx;
state.yPum = state.startTop + state.ny;
}
onMounted(() => {
getInfo();
state.boundary = props.boundary;
});
onActivated(() => {
if (state.keepAlive) {
state.keepAlive = false;
}
});
onDeactivated(() => {
state.keepAlive = true;
myDrag.value.removeEventListener("touchstart", touchStart);
myDrag.value.removeEventListener("touchmove", touchMove);
myDrag.value.removeEventListener("touchend", touchEnd);
});
return {
myDrag,
touchStart,
touchMove,
touchEnd
};
}
});
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return openBlock(), createElementBlock("view", {
ref: "myDrag",
class: "nut-drag",
onTouchstart: _cache[0] || (_cache[0] = ($event) => _ctx.touchStart($event)),
onTouchmove: _cache[1] || (_cache[1] = ($event) => _ctx.touchMove($event)),
onTouchend: _cache[2] || (_cache[2] = ($event) => _ctx.touchEnd($event))
}, [
renderSlot(_ctx.$slots, "default")
], 544);
}
const index = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
export {
index as default
};