目录
一、实现效果
JS 简单的操作杆旋转实现
首先说明一下,请直接忽略背景图,这里主要实现的是杆旋转控制方向盘旋转。
鼠标移出控制区域,控制球复位
二、组成部分
创建 ballOption.js 文件,用以绑定控制球指定 dom,并初始化相关操作
创建 eleOption.js 文件,用以实现一些频繁的 dom 操作
主要是通过鼠标滑动事件控制“控制球”位置更改及获取以屏幕上方向为0度的角度计算,来控制“方向盘”进行旋转。
目标
1、监听鼠标滑动的事件,并判断 event 的 point 是否进入到控制球,如果进入,控制小球随着鼠标进行移动。
2、鼠标划出控制区域,控制球复位,旋转角度归零。
3、判断鼠标 point 点位置,通过反三角函数获取角度。
4、暴露控制球与控制区域中心形成的旋转角度,触发外界事件(方向盘旋转)
三、代码实现
1、操作控制
ballOption.js 文件
class BallOption{ //添加操作dom ID eleId //el操作对象 eleOption //控制球对象 ball //控制球尺寸 ballWidth ballHeight ballOffX ballOffY //是否触碰过控制球 isTouchedBall = false //控制区域 optionRangeView optionRangeViewCenterPoint //上一次角度 lastDeg //角度回调 angleCallBack //初始化操作 constructor(eleId,angleCallBack){ this.eleId = eleId this.angleCallBack = angleCallBack this.eleOption = new EleOption(eleId) } //创建操作框 createOptionView(){ if(this.eleId != undefined){ this.createOptionRangeView() this.createOptionBallView() } } //绘制操作范围 createOptionRangeView(){ let width = this.eleOption.getEleWidth(this.eleOption.getCurrentEle()) let height = this.eleOption.getEleHeight(this.eleOption.getCurrentEle()) this.optionRangeView = this.eleOption.createEl('optionRangeViewEl') this.eleOption.addSubEl(this.eleOption.getCurrentEle(),this.optionRangeView) this.eleOption.setBackgroundColor(this.optionRangeView,'rgb(248,248,248)') this.eleOption.setWidth(this.optionRangeView,width) this.eleOption.setHeight(this.optionRangeView,height) this.eleOption.setCircle(this.optionRangeView) //添加拖拽事件 this.eleOption.addMoveEvent(optionRangeViewEl,this,this.makeBallFollowScroll,this.resetBall) } //控制球随鼠标滚 makeBallFollowScroll(point,ballOption){ let x = (point.x - ballOption.ballOffX) let y = (point.y - ballOption.ballOffY) let currentPoint = {x,y} if(ballOption.checkIsTouchControlBall(point)){ ballOption.eleOption.setCenter(ballOption.ball,currentPoint) ballOption.getCurrentAngle(point) } } //检测是否碰触过控制球 checkIsTouchControlBall(point){ if(!this.isTouchedBall){ let isTouchBall = ( point.x > this.optionRangeViewCenterPoint.x - this.ballWidth && point.x < this.optionRangeViewCenterPoint.x + this.ballWidth && point.y > this.optionRangeViewCenterPoint.y - this.ballHeight && point.y < this.optionRangeViewCenterPoint.y + this.ballHeight ) if(isTouchBall){ this.isTouchedBall = true this.eleOption.setTransparency(this.ball,100) } } return this.isTouchedBall } //鼠标移出事件 resetBall(ballOption){ ballOption.isTouchedBall = false ballOption.eleOption.setCenter(ballOption.ball,ballOption.optionRangeViewCenterPoint) ballOption.eleOption.setTransparency(ballOption.ball,40) if(ballOption.angleCallBack){ ballOption.lastDeg = 0 ballOption.angleCallBack(ballOption.lastDeg) } } //计算角度 getCurrentAngle(point){ let addX = (point.x - this.eleOption.getEleWidth(this.optionRangeView) / 2.0) let addY = (point.y - this.eleOption.getEleHeight(this.optionRangeView) / 2.0) if(addY != 0){ let tan = addX / addY let angle = Math.atan(tan) this.lastDeg = (angle / Math.PI) * 180 if(addX <= 0 && addY < 0){ this.lastDeg = this.lastDeg } else if(addX <= 0 && addY > 0){ this.lastDeg = (180 - Math.abs(this.lastDeg)) } else if(addX >= 0 && addY > 0){ this.lastDeg = 180 + Math.abs(this.lastDeg) } else if(addX >= 0 && addY < 0){ this.lastDeg = (360 - Math.abs(this.lastDeg)) } } if(this.angleCallBack){ this.angleCallBack(360 - this.lastDeg) } } //绘制球滚动 createOptionBallView(){ let scale = 3.2 this.ballWidth = this.eleOption.getEleWidth(this.eleOption.getCurrentEle()) / scale this.ballHeight = this.eleOption.getEleHeight(this.eleOption.getCurrentEle()) / scale this.ballOffX = this.ballWidth / 2.0 this.ballOffY = this.ballHeight / 2.0 this.ball = this.eleOption.createEl('optionBallViewEl') this.eleOption.addSubEl(this.eleOption.getCurrentEle(),this.ball) this.eleOption.setBackgroundColor(this.ball,'black') this.eleOption.setWidth(this.ball,this.ballWidth) this.eleOption.setHeight(this.ball,this.ballHeight) this.eleOption.setCircle(this.ball) this.eleOption.setSupCenter(this.ball) this.eleOption.cancleUserInreface(this.ball) this.eleOption.setTransparency(this.ball,40) //保存中心点坐标 this.optionRangeViewCenterPoint = this.eleOption.getCenterPoint({offX:this.ballOffX,offY:this.ballOffY}) } }
2、dom对象操作类
eleOption.js
class EleOption{ //添加操作dom ID eleId constructor(eleId){ this.eleId = eleId } //获取当前关联的el getCurrentEle(){ return document.getElementById(this.eleId) } //获取el宽度 getEleWidth(el){ return el.offsetWidth } //获取el高度 getEleHeight(el){ return el.offsetHeight } //设置背景颜色 setBackgroundColor(el,color){ el.style.backgroundColor = color } //设置宽度 setWidth(el,w){ el.style.width = w + 'px' } //设置高度 setHeight(el,h){ el.style.height = h + 'px' } //设置圆角 setCircle(el){ el.style.borderRadius = (this.getEleWidth(el) / 2.0 )+ 'px' } //设置绝对定位 setAbsolutePosition(el){ el.style.position = 'absolute' } //设置透明度 setTransparency(el,alpha){ el.style.opacity = alpha / 100 } //设置为父el中心位置 setSupCenter(el){ if(el.style.position != 'absolute'){ this.setAbsolutePosition(el) let superElWidth = this.getEleWidth(this.getSuperEl(el)) let superElHeight = this.getEleHeight(this.getSuperEl(el)) let width = this.getEleWidth(el) let height = this.getEleHeight(el) el.style.left = ((superElWidth - width) / 2.0) + 'px' el.style.top = ((superElHeight - height) / 2.0) + 'px' } } //设置中心位置 setCenter(el,point){ if(el.style.position != 'absolute'){ this.setAbsolutePosition(el) } el.style.left = point.x + 'px' el.style.top = point.y + 'px' } //获取父类el getSuperEl(el){ return el.parentNode } //获取el getElById(elId){ return document.getElementById(elId) } //创建el createEl(elId){ let el = document.createElement('div') if(elId){ el.setAttribute('id',elId) } return el } //添加子el addSubEl(superEl,subEl){ superEl.appendChild(subEl); } //取消交互 cancleUserInreface(el){ el.style.pointerEvents = 'none' } //添加move事件 addMoveEvent(el,ballOption,mcb,emcb){ //鼠标进入移动事件 el.onmousemove = (event)=>{ mcb(this.getMoveEventPoint(event,el),ballOption) } //鼠标移出事件 el.onmouseout = (_)=>{ emcb(ballOption) } } //move事件监听 getMoveEventPoint(event,el){ let x = event.clientX - this.getSuperEl(el).offsetLeft let y = event.clientY - this.getSuperEl(el).offsetTop return {x,y} } //获取中心点 getCenterPoint(off){ let x = this.getSuperEl(this.getCurrentEle()).offsetLeft + (this.getEleWidth(this.getCurrentEle()) / 2.0) - off.offX let y = this.getSuperEl(this.getCurrentEle()).offsetTop + (this.getEleHeight(this.getCurrentEle()) / 2.0) - off.offY return {x,y} } }
3、用法
初始化控制操作类即可,绑定相对应地 dom 进行,控制球的初始化操作
<script src="../js/eleOption.js"></script> <script src="../js/ballOption.js"></script> <body> <div id="optionDiv"></div> <div id="car"> <img src="../source/car.jpeg" alt=""> </div> <div id="target"> <img src="../source/circle.jpeg" alt=""> </div> </body> <script> //初始化控制操作类即可 let ballOption = new BallOption('optionDiv',(angle)=>{ let targetEl = document.getElementById('target') targetEl.style.transform = 'rotate(' + angle + 'deg)' }) ballOption.createOptionView() </script>
总结与思考
代码很简单,其中通过计算来控制小球的位置移动,并将时时的鼠标滑过的 point 转换为旋转角度供外界使用
以上就是JS实现简单的操作杆旋转示例详解的详细内容,更多关于JS操作杆旋转的资料请关注其它相关文章!