直接上代码
index.tsx代码
import React, { Component, createElement, createRef } from 'react'
import './index.less'
interface iProps { }
interface iState { arr: string[], num: number }
export default class Addcart extends Component<iProps, iState> {
constructor(props: iProps) {
super(props)
this.state = {
arr: ['商品1', '商品2', '商品3', '商品4', '商品5', '商品6', '商品7', '商品8', '商品9', '商品10'],
// 初始值
num: 0
}
}
// 获取收藏盒子
collect = createRef<HTMLDivElement>()
Getcollect = () => this.collect.current as HTMLDivElement
nums: number = 0
// 给每个span绑定点击事件
Fnstart(e: React.TouchEvent) {
this.nums++
// 获取当前span的x和y的值
let x = e.changedTouches[0].clientX
let y = e.changedTouches[0].clientY
// 点击一次让state中的num+1
this.setState({
num: this.nums
})
// 调用函数把x和y当参数传过去
this.createBall(x, y)
// 判断收藏的数量不为0的时候让收藏盒子显示
if (this.nums != 0) {
this.Getcollect().style.opacity = '1'
}
}
// 创建小球添加动画
createBall(left: number, top: number) {
// 创建div元素
let Ball = document.createElement('div')
// 给div定位
Ball.style.position = "absolute";
// div的left和span的left是一样的
Ball.style.left = left + 'px'
// div的top和span的top是一样的
Ball.style.top = top + 'px'
Ball.style.width = '20px'
Ball.style.height = '20px'
Ball.style.borderRadius = '50%'
Ball.style.backgroundColor = 'red'
// 贝塞尔曲线
Ball.style.transition = "left .6s linear, top .6s cubic-bezier(0.5, -0.5, 1, 1)";
// 向父元素最后添加
document.body.appendChild(Ball);
// 添加动画属性
setTimeout(() => {
Ball.style.left = this.Getcollect().offsetLeft + this.Getcollect().offsetWidth / 2 + "px";
Ball.style.top = this.Getcollect().offsetTop + "px";
}, 0);
//动画结束后,删除自己
// ontransitionend事件 是在 transition过度完之后执行的
Ball.ontransitionend = function () {
Ball.remove();
};
}
render() {
return (
<div className='Addcart'>
<div className='box'>
{this.state.arr.map((item, index) => (
<div className='div' key={index}>
{item}
<span onTouchStart={this.Fnstart.bind(this)}>+</span>
</div>
))}
<div className='collect' ref={this.collect}>
<span>数量</span> : {this.state.num}
</div>
</div>
</div>
)
}
}
css样式
index.less
.Addcart {
width: 100%;
height: 100%;
.box {
width: 100%;
height: 100%;
.div {
display: flex;
align-items: center;
justify-content: space-between;
margin: 0 20px;
height: 100px;
color: black;
font-size: 30px;
span {
text-align: center;
font-size: 30px;
color: black;
width: 40px;
height: 40px;
border-radius: 50%;
border: 1px solid #000;
line-height: 40px;
}
}
// 收藏
.collect {
opacity: 0;
margin: 100px 0 0 20px;
width: 150px;
height: 150px;
border: 1px solid #ccc;
border-top: none;
text-align: center;
line-height: 150px;
font-size: 30px;
span{
color: blue;
}
}
}
}