首頁 > 軟體

JS實現簡單的操作杆旋轉範例詳解

2023-01-16 14:02:00

一、實現效果

JS 簡單的操作杆旋轉實現

首先說明一下,請直接忽略背景圖,這裡主要實現的是杆旋轉控制方向盤旋轉。

滑鼠移出控制區域,控制球復位

二、組成部分

建立 ballOption.js 檔案,用以繫結控制球指定 dom,並初始化相關操作

建立 eleOption.js 檔案,用以實現一些頻繁的 dom 操作

主要是通過滑鼠滑動事件控制“控制球”位置更改及獲取以螢幕上方向為0度的角度計算,來控制“方向盤”進行旋轉。

目標

1、監聽滑鼠滑動的事件,並判斷 eventpoint 是否進入到控制球,如果進入,控制小球隨著滑鼠進行移動。

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操作杆旋轉的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com