文件
OmniCard/mpuniapp/pages/component/global-events/touch-events.uvue

174 行
4.3 KiB
Plaintext

<template>
<scroll-view style="flex: 1">
<page-head title="拖拽图标测试相关事件"></page-head>
<view class="uni-padding-wrap uni-common-mt" style="bottom: 20px;">
<navigator url="/pages/component/global-events/touch-events-case" hover-class="none">
<button type="default">
stopPropagation / preventDefault
</button>
</navigator>
</view>
<view class="container">
<view class="view-box" @touchstart="onViewTouchStart">
<image class="icon" id="icon" src="../image/logo.png" @touchstart="onTouchStart" @touchcancel="onTouchCancel"
@touchmove="onTouchMove" @touchend="onTouchEnd"></image>
</view>
</view>
<view v-if="touchEvent !== null">
<text class="title1">touches: </text>
<template v-for="(touch, index) in touchEvent!.touches" :key="index">
<text class="title2">touch[{{ index }}]:</text>
<text>identifier: {{touch.identifier}}</text>
<text>pageX: {{ touch.pageX }}, pageY: {{ touch.pageY }}</text>
<text>clientX: {{ touch.clientX }}, clientY: {{ touch.clientY }}</text>
<text>screenX: {{ touch.screenX }}, screenY: {{ touch.screenY }}</text>
</template>
</view>
</scroll-view>
</template>
<script setup lang="uts">
type DataType = {
touchTargets: string,
touchTargetsCount: number,
iconRect: DOMRect | null,
}
const move = ref(false)
const posX = ref(0)
const posY = ref(0)
const lastX = ref(0)
const lastY = ref(0)
const dragTouchId = ref(-1)
const touchEvent = ref(null as TouchEvent | null)
const icon = ref(null as UniElement | null)
const data = reactive({
touchTargets: "",
touchTargetsCount: 0,
iconRect: null as DOMRect | null,
} as DataType)
function onViewTouchStart(e : TouchEvent) {
data.touchTargets += e.target!.tagName + e.currentTarget!.tagName
data.touchTargetsCount++
}
function findTouchByIdentifier(touches : Touch[], identifier : number) : Touch | null {
for (let i = 0; i < touches.length; i++) {
const touch = touches[i]
if (touch.identifier == identifier) {
return touch
}
}
return null
}
function onTouchStart(e : TouchEvent) {
data.touchTargetsCount++
data.touchTargets += e.target!.tagName + e.currentTarget!.tagName
touchEvent.value = e
if (!move.value) {
const startTouch = e.changedTouches.length > 0 ? e.changedTouches[0] : e.touches[0]
if (startTouch == null) {
return
}
move.value = true
dragTouchId.value = startTouch.identifier
posX.value = startTouch.screenX
posY.value = startTouch.screenY
lastX.value = startTouch.screenX
lastY.value = startTouch.screenY
}
}
function onTouchMove(e : TouchEvent) {
e.preventDefault()
touchEvent.value = e
let p = findTouchByIdentifier(e.changedTouches, dragTouchId.value)
if (p == null) {
p = findTouchByIdentifier(e.touches, dragTouchId.value)
}
if (p == null) {
return
}
if (p.screenX == lastX.value && p.screenY == lastY.value) {
return
}
let x = p.screenX - posX.value
let y = p.screenY - posY.value
lastX.value = p.screenX
lastY.value = p.screenY
icon.value?.style?.setProperty('transform', 'translate(' + x + 'px,' + y + 'px)')
}
function resetIcon() {
move.value = false;
posX.value = 0;
posY.value = 0;
lastX.value = 0;
lastY.value = 0;
dragTouchId.value = -1;
icon.value?.style?.setProperty('transform', 'translate(0px,0px)')
}
function onTouchEnd(e : TouchEvent) {
if (findTouchByIdentifier(e.changedTouches, dragTouchId.value) != null) {
resetIcon()
touchEvent.value = null
}
}
function onTouchCancel(event : TouchEvent) {
resetIcon()
touchEvent.value = null
}
onReady(() => {
icon.value = uni.getElementById("icon")
// #ifdef APP-IOS || APP-HARMONY
data.iconRect = icon.value?.getBoundingClientRect() ?? null
// 加上导航栏及状态栏高度
if (data.iconRect != null) {
data.iconRect.y += uni.getSystemInfoSync().safeArea.top + 44
}
// #endif
})
defineExpose({
data
})
</script>
<style>
.container {
width: 100%;
flex-direction: column;
align-items: center;
}
.view-box {
width: 300px;
height: 300px;
align-items: center;
justify-content: center;
border-style: solid;
}
.icon {
width: 100px;
height: 100px;
}
.title1 {
margin-top: 10px;
font-size: 18px;
}
.title2 {
margin-top: 5px;
font-size: 16px;
}
</style>