0


react+ ts实现双小球滑动交叉以及碰撞

tsx代码:

import React, { Component, createRef, RefObject } from 'react'
import './index.less'

interface iProps { }
interface iState { }
export default class Ddd extends Component<iProps, iState> {
    // 获取父盒子
    Parent = createRef<HTMLDivElement>()
    // 获取线
    Line = createRef<HTMLDivElement>()
    constructor(props: iProps) {
        super(props)
        this.state = {}
    }
    // 初始位置
    DisX: number = 0
    // 要移动的位置
    Distance: number = 0
    // 是否为球
    iSball: boolean = false
    // 元素
    Operatingelement?: HTMLDivElement
    // 线宽
    LineWidth: number = 0
    // parent宽
    ParentWidth: number = 0
    // 球宽
    BallWidth: number = 0
    // 左球
    Lball?: HTMLDivElement
    // 右球
    Rball?: HTMLDivElement

    FnElement(element: RefObject<HTMLDivElement>) {
        return element.current as HTMLDivElement
    }

    componentDidMount() {
        this.FnElement(this.Parent).ontouchstart = this.FnStart.bind(this)
        this.ParentWidth = this.FnElement(this.Parent).clientWidth
    }

    FnStart(ev: TouchEvent) {

        // 当前操作的元素
        this.Operatingelement = ev.target as HTMLDivElement
        // 操作元素是否为小球
        this.iSball = this.Operatingelement.classList.contains('ball')
        // 获取球宽
        this.BallWidth = this.Operatingelement.clientWidth
        if (this.iSball) {
            // 记录初始位置
            this.DisX = ev.changedTouches[0].pageX - this.Operatingelement.offsetLeft
            // 移动事件
            document.ontouchmove = this.FnMove.bind(this)
        }
    }

    FnMove(ev: TouchEvent) {
        // 当前操作的元素
        this.Operatingelement = ev.target as HTMLDivElement
        // 操作元素是否为小球
        this.iSball = this.Operatingelement.classList.contains('ball')

        if (this.iSball) {
            // 移动位置
            this.Distance = ev.targetTouches[0].pageX - this.DisX
            // 左球右球
            this.Lball = this.FnElement(this.Parent).children[0] as HTMLDivElement
            this.Rball = this.FnElement(this.Parent).children[1] as HTMLDivElement

            // 触边
            if (this.Distance < 0) {
                this.Distance = 0
            } else if (this.Distance >= this.ParentWidth - this.BallWidth) {
                this.Distance = this.ParentWidth - this.BallWidth
            }

            // 设置位置
            this.Operatingelement.style.left = this.Distance + 'px'
            // 设置线宽
            this.FnElement(this.Line).style.width = this.LineWidth + 'px'
            // 设置线的样式
            if (this.Operatingelement.className === 'ball') {
                this.FnElement(this.Line).style.left = this.Operatingelement.offsetLeft + this.BallWidth * 0.5 + 'px'
            }

            // 获取线宽
            this.LineWidth = Math.abs(this.Rball.offsetLeft - this.Lball.offsetLeft)

            //交叉
            if (this.Rball.offsetLeft < this.Lball.offsetLeft) {
                this.FnElement(this.Line).style.left = this.Rball.offsetLeft + this.BallWidth * 0.5 + 'px'
            } else {
                // 交叉后触边
                if (this.Lball.offsetLeft >= this.ParentWidth - this.BallWidth * 2) {
                    this.Lball.style.left = this.ParentWidth - this.BallWidth * 2 + 'px'
                    this.FnElement(this.Line).style.left = this.Lball.offsetLeft + this.BallWidth * 0.5 + 'px'
                }
                if (this.Rball.offsetLeft <= this.BallWidth) {
                    this.Rball.style.left = this.BallWidth + 'px'
                }
            }
            // 交叉结束

            // 碰撞
            // if(this.LineWidth <= this.BallWidth){
            //     this.LineWidth = this.BallWidth
            // }
            // if (this.LineWidth <= this.BallWidth) {
            //     if (this.Operatingelement.classList.contains('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.FnElement(this.Line).style.left = this.BallWidth / 2 + 'px'
            //         }
            //     } else {
            //         // 左边
            //         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'
            //             this.FnElement(this.Line).style.left = this.ParentWidth - this.BallWidth * 1.5 + 'px'
            //         }
            //     }
            //     this.FnElement(this.Line).style.left = this.Lball.offsetLeft + this.BallWidth / 2 + 'px'
            // }            
            // 碰撞结束
        }

    }
    render() {
        return (
            <div className='ddd' ref={this.Parent}>
                <div className="ball"></div>
                <div className="ball ac"></div>
                <div className="line" ref={this.Line}></div>
            </div>
        )
    }
}

less代码:

.ddd {
    width: 400px;
    height: 10px;
    background-color: #ccc;
    position: relative;
    margin: 0 auto;
    margin-top: 50px;

    .ball {
        width: 40px;
        height: 40px;
        border-radius: 50%;
        background-color: chocolate;
        position: absolute;
        left: 0;
        top: 0;
        bottom: 0;
        margin: auto;
        z-index: 2;

        &.ac {
            left: 360px;
            background-color:dodgerblue;
        }
    }

    .line {
        width: 400px;
        height: 10px;
        position: absolute;
        left: 0;
        background-color: aquamarine;
    }

}

本文转载自: https://blog.csdn.net/igrdg/article/details/125446933
版权归原作者 .星辰... 所有, 如有侵权,请联系我们删除。

“react+ ts实现双小球滑动交叉以及碰撞”的评论:

还没有评论