一、实现效果
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操作杆旋转的资料请关注编程网其它相关文章!