HarmonyOS - 基于ArkUI (JS) 实现图片旋转验证
Posted 开源基础软件社区官方
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HarmonyOS - 基于ArkUI (JS) 实现图片旋转验证相关的知识,希望对你有一定的参考价值。
作者:王少丽
前言
通过学习其他人的slider滑块组件衍生出的小组件, 本文主要结合HarmonyOS官网上的相关组件以及通用API,来实现一个图片的旋转验证 -- 需拖动滑块将图片旋转还原为正确,方可验证通过。
效果演示
实现原理
-
触发条件
基于HarmonyOS通用事件touchstart和touchmove,touchend,通过手指刚触摸屏幕时触发、手指触摸屏幕后移动时触发事件,手指触摸屏幕后结束时触发事件;
-
实现slider滑块效果
通过touches触摸事件的属性集合,返回屏幕触摸点的信息数组,拿到localX距离被触摸组件左上角横向距离,动态计算出子元素的宽度来实现slider滑块效果。
-
实现图片旋转效果
初始化随机生成360°以内的角度,设置图片原点,360°除以100就得到圆的步长比上滑动距离除滑块总长度,最后加上图片原点就等于旋转后的角度。
使用到的官方API
通用方法
getBoundingClientRect()
获取元素的大小及其相对于窗口的位置。
属性 | 类型 | 描述 |
---|---|---|
width | number | 该元素的宽度。 |
height | number | 该元素的高度。 |
left | number | 该元素左边界距离窗口的偏移。 |
top | number | 该元素上边界距离窗口的偏移。 |
通用事件
名称 | 参数 | 描述 | 是否支持冒泡 |
---|---|---|---|
touchstart | TouchEvent | 手指刚触摸屏幕时触发该事件。 | 是5+ |
touchmove | TouchEvent | 手指触摸屏幕后移动时触发该事件。 | 是5+ |
touchend | TouchEvent | 手指触摸屏幕后结束时触发该事件。 | 是5+ |
属性 | 类型 | 说明 |
---|---|---|
touches | Array<TouchInfo> | 触摸事件时的属性集合,包含屏幕触摸点的信息数组。 |
属性 | 类型 | 说明 |
---|---|---|
globalX | number | 距离屏幕左上角(不包括状态栏)横向距离。屏幕的左上角为原点。 |
globalY | number | 距离屏幕左上角(不包括状态栏)纵向距离。屏幕的左上角为原点。 |
localX | number | 距离被触摸组件左上角横向距离。组件的左上角为原点。 |
localY | number | 距离被触摸组件左上角纵向距离。组件的左上角为原点。 |
实现过程
1. htm部分
<div class="slider-wrapper" style="flex-direction: column;">
<div style="width: 100%;padding-top: 40px;">
<text class="title" >
<span>请</span>
<span style="color: #F56A00;">
拖动
</span>
<span>滑块旋转至正确位置</span>
</text>
</div>
<div for=" item in imagesArr " tid="id" class="imagesArr">
<div class="img">
<image src=" item.src "></image>
</div>
<div class="pic">
<image src="item.duan" style="transform: rotate(numdeg);" id="rotatepic"></image>
</div>
</div>
<div class="content" style="width: 300px;flex-direction: row;" >
<div id="slider" @touchstart="boxChoose" @touchmove="boxChoose" @touchend="Chooseend" style="width: 280px;background-color: #0fbda0;">
<div class="slider-main" style="width: width ;background-color: #73E9C5;" ></div>
<text class="text" show=" done ">
请拖动至正确位置
</text>
<text class="success text" show=" success ">
验证通过
</text>
<text class="fail text" show=" fail ">
验证失败,请重试
</text>
</div>
<div class="dot" style ="left : dotLeft;background-color: #0fbda0;height: 60px;" show=" textblock " >
<text style="color: white;font-size: 20px;">
>>>
</text>
</div>
<div class="dot" style ="left : dotLeft;height: 60px;background-color: #10A68D;" show=" textblock2 ">
<text style="color: white;font-size: 20px;">
>>>
</text>
</div>
<div show=" imageblock " class="imageblock" >
<image src="../../common/images/succes.jpg"></image>
</div>
</div>
</div>
2. css部分
.slider-wrapper
width: 100%;
display: flex;
align-items: center;
flex-direction: column;
background-color: bisque;
position: relative;
.title
width: 100%;
font-size: 20px;
text-align: center;
.imagesArr
width: 90%;
.img
height: 200px;
.pic
height: 200px;
width: 200px;
position: absolute;
left: 62px;
top: 0;
.content
width: 360px;
display: flex;
align-items: center;
flex-direction: row;
position: relative;
margin-top: 50px;
position: relative;
#slider
width: 300px;
height: 50px;
background-color: #0fbda0;
display: flex;
justify-content: center;
.text
font-size: 15px;
.fail
color: red;
.success
color: black;
.slider-main
background-color: #73E9C5;
width: 0;
height: 100%;
position: absolute;
left: 0;
top: 0;
border: 1px solid #d9f3ef;
.dot
width: 50px;
height: 50px;
background-color: #0fbda0;
position: absolute;
bottom: -5px;
border-radius: 5px;
.dot text
text-align: center;
padding-left: 5px;
color:#A69E9E;
.imageblock
height: 50px;
width: 50px;
position: absolute;
right: 10px;
3. js部分
export default
data:
progress:0,
width: 0,
step1: 1,
dotLeft:0,
img:../../common/images/succes.jpg,
imageblock:false,
textblock:true,
success:false,
fail:false,
done:true,
numdeg:Math.round(Math.random()*360),// 初始化的随机角度
startNumdeg: 0,
textblock2:false,
imagesArr:[
src:common/images/ro.jpg,duan:common/images/ro.png,
],
,
onInit()
this.startNumdeg = this.numdeg;
,
//控制点击结束后的样式
Chooseend( )
if(this.success && this.imageblock)
return
if (!this.textblock )
this.disable = true
console.log(Chooseend==this.startNumdeg == + this.startNumdeg + ===this.numdeg=== + this.numdeg)
if (this.width &&Math.abs(this.numdeg-360)<=5)
this.width = 240;
this.progress = 100;
this.textblock = false;
this.fail = false;
this.success =true;
this.done =false;
this.textblock2 =false;
this.dotLeft = 0;
this.numdeg = 0
this.imageblock = true;
else
this.width = 0;
this.progress = 0;
this.fail = true;
this.success =false;
this.done =false;
this.textblock2 = true;
this.textblock = false
this.dotLeft =0
this.numdeg = this.startNumdeg + (360/100) * (this.width / 240)*100
,
boxChoose(e)
if(this.success && this.imageblock)
return
let slider = this.$element(slider)
let width = e.touches[0].localX // 获取点击时距离容器左边位置
this.dotLeft = width
let elementWidth = slider.getBoundingClientRect().width //元素的宽度
// 正方形的偏移量临界值
if ( this.dotLeft >= elementWidth )
this.dotLeft = 240
let compare = elementWidth / (100 / this.step1) // 根据步长计算每一步宽度 2.4
this.width = Math.ceil(width / compare) * compare //滑动距离
this.width = this.width < 0 ? 0 : (this.width > 240 ? 240 : this.width)
this.numdeg = this.startNumdeg + 360 * (this.width / 240) //图像处理
this.progress = Math.abs(this.width / elementWidth *100) //slider滑块
if (this.width>0)
this.fail = false;
this.done = true
if (this.width>=240)
this.width = 280
,
总结
这篇文章是我通过对slider滑块的一个延伸练习,也算是一个比较常用的组件,后续部分功能还需完善,比如在样式、功能及代码优化方面等等,还有很多不足之处,大家有想法的可以提出来,我们一起学习,共同进步!
更多原创内容请关注:中软国际 HarmonyOS 技术团队
入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。
以上是关于HarmonyOS - 基于ArkUI (JS) 实现图片旋转验证的主要内容,如果未能解决你的问题,请参考以下文章
HarmonyOS - 基于ArkUI(JS)实现彩带飘动特效
#夏日挑战赛# HarmonyOS - 基于ArkUI(JS)实现打地鼠游戏
HarmonyOS - 基于ArkUI(JS)实现信件弹出效果
#打卡不停更# HarmonyOS - 基于ArkUI(JS)实现虚拟摇杆组件