tsx代码:
import React, { Component, createRef } from 'react'
import './index.less'
interface iProps { }
interface iState { }
export default class Eee extends Component<iProps, iState> {
constructor(props: iProps) {
super(props)
this.state = {}
}
// 初始位置
disX: number = 0
// 要移动的位置
X: number = 0
// 线宽
LineWidth: number = 0
// 球宽
BallWidth: number = 0
// parent宽
ParentWidth: number = 0
// 获取父元素box
Parent = createRef<HTMLDivElement>()
// 获取线
Line?: HTMLDivElement
// 获取左球
Lball?: HTMLDivElement
// 获取右球
Rball?: HTMLDivElement
// 获取操作元素
Element?: HTMLDivElement
// 转html
FnParent() {
return this.Parent.current as HTMLDivElement
}
// 事件
FnStart(ev: React.TouchEvent) {
// 获取操作元素
this.Element = ev.target as HTMLDivElement
// 记录初始位置
this.disX = ev.changedTouches[0].pageX - this.Element.offsetLeft
// 移动事件
document.ontouchmove = this.FnMove.bind(this)
}
// 移动事件
FnMove(ev: TouchEvent) {
// 获取操作元素
this.Element = ev.target as HTMLDivElement
// 要移动的位置
this.X = ev.changedTouches[0].pageX - this.disX
// 获取左球,右球,线
this.Lball = this.FnParent().children[0] as HTMLDivElement
this.Rball = this.FnParent().children[1] as HTMLDivElement
this.Line = this.FnParent().children[2] as HTMLDivElement
// 球宽
this.BallWidth = this.Lball.clientWidth
// 获取parent
this.ParentWidth = this.FnParent().clientWidth
// 判断小球出边
if (this.X <= 0) this.X = 0
if (this.X >= this.ParentWidth - this.Element.clientWidth) this.X = this.ParentWidth - this.Element.clientWidth
// 设置小球位置
if (this.Element.classList.contains('ball')) {
this.Element.style.left = this.X + 'px'
}
// 设置线宽
this.Line.style.width = this.LineWidth + 'px'
// 获取线宽
this.LineWidth = Math.abs(this.Rball.offsetLeft - this.Lball.offsetLeft)
if (this.Element.className === 'ball') {
this.Line.style.left = this.Lball.offsetLeft + this.BallWidth / 2 + 'px'
}
if (this.LineWidth < this.BallWidth) {
this.LineWidth = this.BallWidth
}
// 碰撞
if (this.LineWidth <= this.BallWidth) {
if (this.Element.className === 'ball') {
this.Rball.style.left = this.Lball.offsetLeft + this.BallWidth + 'px'
if (this.Rball.offsetLeft >= this.ParentWidth - this.BallWidth) {
this.Lball.style.left = this.ParentWidth - this.BallWidth * 2 + 'px'
this.Rball.style.left = this.ParentWidth - this.BallWidth + 'px'
}
} else if (this.Element.className === 'ball ac') {
this.Lball.style.left = this.Rball.offsetLeft - this.BallWidth + 'px'
if (this.Lball.offsetLeft <= 0) {
this.Lball.style.left = 0 + 'px'
this.Rball.style.left = this.BallWidth + 'px'
}
}
this.Line.style.left = this.Lball.offsetLeft + this.BallWidth / 2 + 'px'
}
}
render() {
return (
<div className='eee' ref={this.Parent}>
<div className="ball" onTouchStart={this.FnStart.bind(this)}></div>
<div className="ball ac" onTouchStart={this.FnStart.bind(this)}></div>
<div className="line"></div>
</div>
)
}
}
less代码:
.eee {
width: 400px;
height: 20px;
background-color: #ccc;
position: relative;
margin: 0 auto;
.ball {
width: 40px;
height: 40px;
background-color: red;
border-radius: 50%;
position: absolute;
left: 0;
bottom: 0;
top: 0;
margin: auto;
z-index: 2;
}
.ac {
left: 360px;
}
.line {
width: 400px;
height: 20px;
position: absolute;
background-color: #ff0;
left: 0;
}
}