代码奉上
css:
html,body{
height: 100%;
}
#root,.App,.wrap{
height: 100%;
width: 100%;
}
.ball{
width: 60px;
height: 60px;
border-radius: 50%;
position: absolute;
background-color: tomato;
transition: left 1s linear, top 1s linear;
display: none;
}
.aim{
width: 100px;
height: 100px;
border: 1px solid #000;
position: absolute;
bottom: 0;
right: 0;
}
tsx代码:
import React, { Component, createRef } from 'react'
import './index.css'
interface IProp { }
interface IsState { }
export default class index extends Component<IsState, IProp> {
ball = createRef<HTMLDivElement>()
wrap = createRef<HTMLDivElement>()
flag: boolean = false
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
constructor(props: IProp) {
super(props);
}
FnStart(e: TouchEvent) {
if (!this.flag) {
this.flag = true
// 小球元素
const ball = this.ball.current as HTMLDivElement;
// 显示小球
ball.style.display = 'block';
// 操纵定位
ball.style.left = e.changedTouches[0].pageX + 'px';
ball.style.top = e.changedTouches[0].pageY + 'px';
// 落脚点元素
const wrap = this.wrap.current as HTMLDivElement;
// 小球的落脚点的距离页面顶端的距离
const H = wrap.offsetTop;
// 小球落脚点的距离页面左边的位置
const L = wrap.offsetLeft;
// 动画过渡时 给小球赋值
setTimeout(() => {
ball.style.top = H + 'px';
ball.style.left = L + 'px';
ball.style.transition = 'left 1s linear, top 1s cubic-bezier(0.4, -0.29, 0.7, 0.1)';
}, 50)
// 小球过渡结束事件
ball.addEventListener("transitionend", () => {
// 过度结束小球隐藏
ball.style.display = "none";
this.flag = false
})
}
}
componentDidMount() {
document.ontouchstart = this.FnStart.bind(this)
}
render() {
return (
<div className='wrap'>
<div ref={this.wrap} className="aim"></div>
<div ref={this.ball} className="ball"></div>
</div>
)
}
}