PixiJS案例——顺逆时钟判断

简介:

关于手势进行顺/逆时钟滑动的判断,此方案不局限于使用 PixiJs 才能完成,只要能够获取到手势坐标即可。

思路:

  1. 在页面上默认设置一个中心点

  1. 利用 touch 事件的特性,在 touchmove 触发时,计算手势的触摸点到中心点连线与上次触发时二者夹角变化值,并进行记录

  1. 在触发结束时进行统计或者计算,进而判断方向

核心部分:

  1. 关于 touch 事件的触发机制(80行到110行)

  1. 夹角、角度的计算

代码:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta content="a1z51.23600852" name="spm-id" />
    <title>
        判断顺逆时钟
    </title>
    <script src="./lib/zepto.min.js?t=1500513648235"></script>
    <script src="./lib/vue.min.js?t=1502325746688"></script>
    <script src="./lib/veryless.js?t=1502325746688"></script>
    <script src="./lib/pixi.js?t=1502325746688"></script>
    <style>
        html,
        body {
            position: relative;
            height: 100%;
        }

        body {
            background: #eee;
            font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
            font-size: 1rem;
            color: #000;
            margin: 0;
            padding: 0;
        }

        canvas {
            width: 100%;
            height: 100%;

        }
    </style>
</head>

<body>
    <div id="app">
        <div class="title_name">PIXI 判断顺逆时钟</div>
        <div class="piximove" id="pixijs"></div>
        <div class="direction_01">第一种模式:{{direction_01}}</div>
        <div class="direction_02">第二种模式:{{direction_02}}</div>
        <button class="test_01" @click="test()">测试</button>
    </div>
    <script>
        //vue
        $(document).ready(() => {
            var app = new Vue({
                el: "#app",
                data() {
                    return {
                        frameStage: null, //舞台
                        direction_01:true,
                        direction_02:true,
                    }
                },
                methods: {
                    //初始化方法
                    Application() {
                        //创建一个Application,设置长宽
                        this.frameStage = new PIXI.Application({
                            width: 600,
                            height: 600,
                            // backgroundColor: 0x55FF55,
                            backgroundAlpha: 1, //是否透明
                            antialias: true //设置抗锯齿
                            // forceCanvas: true //阻止选择WebGL渲染器
                        });

                        console.log(this.frameStage);

                        //将舞台添加到DOM元素中
                        document.getElementById("pixijs").appendChild(this.frameStage.view);

                        // 添加一个操作矩形 用来操作
                        const graphics = new PIXI.Graphics();

                        graphics.beginFill(0x55FF55);
                        graphics.drawCircle(300, 300, 250);
                        graphics.endFill();

                        // **************************** //
                        // 需要定义的变量
                        let angle = 0; // 记录角度
                        let angleArr = []; // 记录角度变化

                        graphics.interactive = true;
                        graphics.on('touchstart', async (ev) => {
                            // 需要取到合理的坐标点和原点
                            angleArr = [];
                            angle = this.getAngle(300, 300, ev.screen.x, ev.screen.y);
                        });
                        graphics.on('touchmove', async (ev) => {
                            // 需要取到合理的坐标点和原点
                            let now_angle = this.getAngle(300, 300, ev.screen.x, ev.screen.y);
                            angleArr.push(this.getDifferenceAngle(now_angle, angle))
                            angle = now_angle
                        });
                        graphics.on('touchend', async (ev) => {
                            // 需要取到合理的坐标点和原点
                            let now_angle = this.getAngle(300, 300, ev.screen.x, ev.screen.y);
                            angleArr.push(this.getDifferenceAngle(now_angle, angle));
                            console.log('是否为顺时钟:', this.judgeDirection(angleArr));
                        });

                        // **************************** //

                        this.frameStage.stage.addChild(graphics);
                        // console.log(this.getAngle(300,300,300,500))
                        // let a = this.getDifferenceAngle(-20, 45);
                        // console.log(a);
                    },
                    test() {
                        // this.frameStage.destroy(true, true);
                        // this.frameStage.renderer.transparent = true;
                        // this.frameStage.renderer.reset();
                        // console.log(this.frameStage.renderer.transparent)
                        // this.frameStage.renderer.backgroundColor = '0x550fff';
                        this.test1(12, "xx", "11", "222")
                    },
                    // 计算两个点组成直线的角度 x1,y1 为原点
                    getAngle(x1, y1, x2, y2) {
                        return Math.atan2((y2 - y1), (x2 - x1)) * (180 / Math.PI);
                    },
                    // 计算出两个角度之间的小差值 angle1为现在的角度 angle2为之前的角度
                    getDifferenceAngle(angle1, angle2) {
                        let difference = (angle1 + 360) % 360 - (angle2 + 360) % 360;
                        if (difference <= -180) difference += 360;
                        if (difference > 180) difference -= 360;
                        return difference;
                    },
                    // 判断顺逆时钟
                    // 第一种判断模式:变化率个数累计(这种方式有一定的漏洞在里面.例如:先快速的逆时钟,然后慢慢的顺时针往回走,最终不超过原来的位置,这里的逻辑会错误的判断为顺时钟)
                    // 第二种判断模式:变化率大小累计
                    judgeDirection(arr) {
                        let clockwise = 0; // 顺时钟
                        let counterclockwise = 0; // 逆时钟
                        let change = 0
                        arr.forEach(item => {
                            change += item;
                            if (item >= 0) clockwise += 1;
                            if (item < 0) counterclockwise += 1;
                        });
                        // 第一种模式
                        let direction_01 = clockwise >= counterclockwise ? true : false;
                        // 第二种模式
                        let direction_02 = change >= 0 ? true : false;
                        this.direction_01 = direction_01;
                        this.direction_02 = direction_02;
                        console.log(`判断顺逆时钟:模式一 ${direction_01} 模式二 ${direction_02}`)
                        return direction_01;
                    },
                    test1() {
                        
                    }
                },
                mounted() {
                    this.Application();
                }

            })
        })
    </script>

    <style>
        .piximove {
            position: absolute;
            height: 8rem;
            width: 8rem;
            left: 1rem;
            top: 1rem;
            background-color: red;
        }
        .direction_01{
            position: absolute;
            width: 6rem;
            height: 1rem;
            top: 10rem;
            left: 2rem;
            text-align: center;
            font-size: 0.5rem;
            line-height: 1rem;
            background-color: rgba(255, 0, 0, .8);
        }
        .direction_02{
            position: absolute;
            width: 6rem;
            height: 1rem;
            top: 12rem;
            left: 2rem;
            text-align: center;
            font-size: 0.5rem;
            line-height: 1rem;
            background-color: rgba(255, 0, 0, .8);
        }

        .test_01 {
            position: absolute;
            width: 2rem;
            height: 1rem;
            bottom: 0rem;
            left: 0rem;
            text-align: center;
            font-size: 0.5rem;
            /*color: rgba(255,0,0,.8);*/
            line-height: 1rem;
            background-color: rgba(255, 0, 0, .8);
        }

        .test_02 {
            position: absolute;
            width: 2rem;
            height: 1rem;
            bottom: 0rem;
            left: 3rem;
            text-align: center;
            font-size: 0.5rem;
            /*color: rgba(255,0,0,.8);*/
            line-height: 1rem;
            background-color: rgba(255, 255, 0, .8);
        }

        .test_03 {
            position: absolute;
            width: 2rem;
            height: 1rem;
            bottom: 0rem;
            left: 6rem;
            text-align: center;
            font-size: 0.5rem;
            /*color: rgba(255,0,0,.8);*/
            line-height: 1rem;
            background-color: rgba(0, 255, 0, .8);
        }

        .test_04 {
            position: absolute;
            width: 2rem;
            height: 1rem;
            bottom: 2rem;
            left: 6rem;
            text-align: center;
            font-size: 0.5rem;
            /*color: rgba(255,0,0,.8);*/
            line-height: 1rem;
            background-color: rgba(0, 255, 0, .8);
        }

        .title_name {
            position: absolute;
            width: 10rem;
            height: 1rem;
            left: 0;
            top: 0;
            background-color: rgba(255, 255, 255, 0.2);
            font-size: 0.5rem;
            line-height: 1rem;
            text-align: center;
        }
    </style>

</body>

</html>

异常:

在整个案例中有一个漏洞,那就是我们默认了,从 a 角度到 b 角度永远走的是短的路径(假如从0度变化到90度,我们永远默认时顺时针走了90度,不会理解为是逆时钟走了270度)

代码:

代码已经上传,审核中后续会同步地址

https://download.csdn.net/download/xiechao_5800/87387729

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

幻蝶Love

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值