广告位联系
返回顶部
分享到

JS实现简单的操作杆旋转示例介绍

JavaScript 来源:互联网 作者:佚名 发布时间:2023-09-26 22:06:22 人浏览
摘要

JS 简单的操作杆旋转实现 首先说明一下,请直接忽略背景图,这里主要实现的是杆旋转控制方向盘旋转。 鼠标移出控制区域,控制球复位 二、组成部分 创建ballOption.js文件,用以绑定

JS 简单的操作杆旋转实现

首先说明一下,请直接忽略背景图,这里主要实现的是杆旋转控制方向盘旋转。

鼠标移出控制区域,控制球复位

二、组成部分

创建 ballOption.js 文件,用以绑定控制球指定 dom,并初始化相关操作

创建 eleOption.js 文件,用以实现一些频繁的 dom 操作

主要是通过鼠标滑动事件控制“控制球”位置更改及获取以屏幕上方向为0度的角度计算,来控制“方向盘”进行旋转。

目标

1、监听鼠标滑动的事件,并判断 event 的 point 是否进入到控制球,如果进入,控制小球随着鼠标进行移动。

2、鼠标划出控制区域,控制球复位,旋转角度归零。

3、判断鼠标 point 点位置,通过反三角函数获取角度。

4、暴露控制球与控制区域中心形成的旋转角度,触发外界事件(方向盘旋转)

三、代码实现

1、操作控制

ballOption.js 文件

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

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 进行,控制球的初始化操作

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

<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 转换为旋转角度供外界使用


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • js二进制数据及其互相转化的实现
    file 在js中有很多二进制数据,有file,base64,Blob,ArrayBuffer,FileReader。这些二进制数据在文件导出和下载的时候是经常会用到的,我们这篇文章就
  • JS实现简单的操作杆旋转示例介绍

    JS实现简单的操作杆旋转示例介绍
    JS 简单的操作杆旋转实现 首先说明一下,请直接忽略背景图,这里主要实现的是杆旋转控制方向盘旋转。 鼠标移出控制区域,控制球复位
  • smartbanner.js实现可定制智能应用横幅使用示例
    smartbanner.js 适用于 iOS 和 Android 的可定制智能应用横幅(smart app banner)。简单易用,不依赖任何框架,怎么使用官方文档也写的很清楚,我就不
  • js的一些潜在规则使用介绍

    js的一些潜在规则使用介绍
    为什么开发中建议使用void 0 来代替undefined 因为 JavaScript 的代码 undefined 是一个变量,而并非是一个关键字,这是JavaScript 语言公认的设计失
  • 基于JavaScript实现图片滤镜效果介绍
    随着社交媒体的普及,人们对于图片的处理需求越来越高。图片滤镜效果成为了许多人喜爱的功能之一。在本文中,我们将学习如何使用
  • smartbanner.js实现可定制智能应用横幅使用介绍
    smartbanner.js 适用于 iOS 和 Android 的可定制智能应用横幅(smart app banner)。简单易用,不依赖任何框架,怎么使用官方文档也写的很清楚,我就不
  • 解决Element ui导航栏选中背景色刷新消失的问题
    Element ui导航栏选中背景色刷新消失 1 2 3 4 5 6 7 8 9 el-menu :is-collapse=isCollapse text-color=#fff active-text-color=#fff :default-active=activerouter :router=true /el
  • JS删除数组里的某个元素方法介绍
    删除数组指定的某个元素 一个包解决你所有的JS问题,点击获取 js删除数组中某一项或几项的几种方法https://www.jb51.net/article/154737.htm 首先可以
  • JS滚动到顶部踩坑解决记录
    一般在比较长的页面中会有一个滚动到顶部的按钮,用户点击一下 300ms 内,会滚动到顶部,有动画效果。 一开始我想,这不是很简单,一行
  • React-Router(V6)的权限控制实现
    在一个后台管理系统中,安全是很重要的。不光后端需要做权限校验,前端也需要做权限控制。 我们可以大致将权限分为3种:接口权限、页
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计