簡介:
關于手勢進行順/逆時鐘滑動的判斷,此方案不局限于使用 PixiJs 才能完成,隻要能夠擷取到手勢坐标即可。
思路:
- 在頁面上預設設定一個中心點
- 利用 touch 事件的特性,在 touchmove 觸發時,計算手勢的觸摸點到中心點連線與上次觸發時二者夾角變化值,并進行記錄
- 在觸發結束時進行統計或者計算,進而判斷方向
核心部分:
- 關于 touch 事件的觸發機制(80行到110行)
- 夾角、角度的計算
代碼:
<!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