使用hammerjs在区域内移动

2022-10-12 13:52:13 阅读:1 编辑

https://article.itxueyuan.com/vOkjra https://blog.csdn.net/kongjiea/article/details/43016085

下面这个官网功能可以查看源码 http://hammerjs.github.io/

下面(用于通过tap代替click,click需延时300ms才会被触发) https://github.com/hammerjs/hammer-time

<template>
    <div class="page">
        <div style="background-color:yellow;position: relative;width: 500px;height: 300px;overflow: hidden;">
            <div id="demoImg">
                <img src="https://zhyframe.fzh.fun/attachment/images/1023/2022/09/02d9610f22ac4c15877a043a3d481d83.png" class="demo-img" />
                <div style="background-color: red;width: 20px;height: 20px;font-size: 10px;" class="new_label" @click="click_label" data-id="A1">
                    A1
                </div>
                <div style="background-color: red;width: 20px;height: 20px;font-size: 10px;" class="new_label2"  @click="click_label" data-id="B2">
                    B2
                </div>
            </div>

        </div>

    </div>
</template>
<script>
    import Hammer from 'hammerjs'
   // import { setTimeout } from 'timers'
    export default {
        data () {
            return {
                config: {},
                id: null,
                mc: null,
                timer: false,
                translateX: 0,
                translateY: 0,
                scale: 1,
                firstTouch: true,
                relateX: 0,
                relateY: 0,
                oldX: 0,
                oldY: 0,
                oldScale: 1
            }
        },
        mounted () {
            this.$nextTick(() => {
                this.picInit()
            })
        },
        methods: {
            click_label(e){
                let id = e.currentTarget.dataset.id;
                alert("click id:" + id);
            },
            picInit () {
                this.id = document.getElementById('demoImg')
                this.mc = new Hammer(this.id)
                this.relateX = 0;//(document.body.clientWidth - this.id.offsetWidth) / 2
                this.relateY = 0;//(document.body.clientHeight - this.id.offsetHeight) / 2

                this.mc.add(new Hammer.Pan({
                    direction: Hammer.DIRECTION_ALL,
                    threshold: 0,
                    pointers: 0
                }))
                this.mc.add(new Hammer.Pinch({
                    threshold: 0
                })).recognizeWith(this.mc.get('pan'))

                this.mc.on('hammer.input', this.isFinal)
                this.mc.on('panstart panmove', this.onPan)
                this.mc.on('pinchstart pinchmove', this.onPinch)

                this.setPosition()
            },
            isFinal (ev) {
                if (ev.isFinal) {
                    this.oldX = this.translateX
                    this.oldY = this.translateY
                    this.oldScale = this.scale
                }
            },
            // 初始化图片位置及缩放
            setPosition () {
                this.selfPosition({
                    translateX: this.relateX,
                    translateY: this.relateY,
                    scale: this.scale
                })
            },
            // 单点触发 - 拖拉
            onPan (ev) {
                // console.log(this.firstTouch)
                if (this.firstTouch) {
                    this.oldX = this.relateX
                    this.oldY = this.relateY
                }
                // console.log(this.oldX)
                // console.log(this.oldY)
                this.translateX = this.oldX + ev.deltaX
                this.translateY = this.oldY + ev.deltaY
                const position = {
                    translateX: this.translateX,
                    translateY: this.translateY,
                    scale: this.scale
                }
                this.selfPosition(position)
                this.firstTouch = false
            },
            // 多点触发 - 缩放
            onPinch (ev) {
                this.scale = this.oldScale * ev.scale
                this.selfPosition({
                    translateX: this.translateX,
                    translateY: this.translateY,
                    scale: this.scale
                })
                // this.selfPosition(this.position)
            },
            selfPosition (pos) {
                return this.picAnimate()(() => this.tempPos(pos))
            },
            tempPos (pos) {
                let style = [
                    `translate3d(${pos.translateX}px, ${pos.translateY}px, 0)`,
                    `scale(${pos.scale}, ${pos.scale})`
                    // `scale(${pos.scale > 1.2 ? 1.2 : pos.scale}, ${pos.scale > 1.2 ? 1.2 : pos.scale})`
                ]
                style = style.join(' ')
                this.id.style.transform = style
            },
            picAnimate () {
                return window[Hammer.prefixed(window, 'requestAnimationFrame')] || function (callback) {
                    setTimeout(callback, 1000 / 60)
                }
            }
        }
    }
</script>
<style >
    .page {
        width: 600px;
        height: 100vh;
        background-color: red;
    }

    .demo-img {
        position: absolute;
        left: 0;
        top: 0;
        width: 260px;
        height: 260px;

    }
    .new_label{
        position: absolute;
        top: 100px;
        left: 100px;
    }
    .new_label2{
        position: absolute;
        top: 200px;
        left: 200px;
    }
</style>