import React, { Component } from "react";
import "./block.scss";
interface Props {}
interface state {
left1: number;
left2: number;
maxWidth: number;
}
class BlockDrog extends Component<Props, state> {
slideButton1: any = React.createRef();
slideButton2: any = React.createRef();
slideBar: any = React.createRef();
x1: number = 0;
x2: number = 0;
disX1: number = 10;
disX2: number = 200;
// 进度条
scaleArr: Array<number> = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100];
constructor(props: Props) {
super(props);
this.state = {
left1: 10,
left2: 200,
maxWidth: this.slideBar.offsetWidth ? this.slideBar.offsetWidth : 770,
};
}
componentDidMount() {
this.x1 = this.slideButton1.offsetLeft;
this.x2 = this.slideButton2.offsetLeft;
}
FnDown1(e: any) {
// 获取当前点击元素的起始点
this.disX1 = e.clientX - this.slideButton1.offsetLeft;
// 事件绑定和阻止默认事件
document.onmousemove = this.FnMove1.bind(this);
document.onmouseup = this.FnUp.bind(this);
e.preventDefault && e.preventDefault();
}
FnMove1(e: MouseEvent) {
// 移动的距离
this.x1 = e.clientX - this.disX1;
// 边界判断
if (this.x1 < 0) {
this.x1 = 0;
}
if (this.x1 > this.state.maxWidth) {
this.x1 = this.state.maxWidth;
}
// 交叉形式的 判断
if (
this.x1 >= 0 &&
this.x1 <= this.state.maxWidth
) {
// 碰撞形式的判断
/* if (
this.x1 >= 0 &&
this.x1 <= this.state.maxWidth - this.slideButton1.offsetWidth
) { */
this.setState({
left1: this.x1,
});
// 碰撞形式的判断
// if (
// this.x1 + this.slideButton1.offsetWidth >= this.x2 &&
// this.x1 + this.slideButton1.offsetWidth <= this.state.maxWidth
// ) {
// this.setState({
// left1: this.x1,
// left2: this.x1 + this.slideButton1.offsetWidth,
// });
// this.x2 = this.x1 + this.slideButton1.offsetWidth;
// }
}
}
FnDown2(e: any) {
this.disX2 = e.clientX - this.slideButton2.offsetLeft;
document.onmousemove = this.FnMove2.bind(this);
document.onmouseup = this.FnUp.bind(this);
e.preventDefault && e.preventDefault();
}
FnMove2(e: MouseEvent) {
this.x2 = e.clientX - this.disX2;
if (this.x2 < 0) {
this.x2 = 0;
}
if (this.x2 > this.state.maxWidth) {
this.x2 = this.state.maxWidth;
}
// 交叉形式的 判断
if (
this.x2 >= 0 &&
this.x2 <= this.state.maxWidth
) {
// 碰撞形式的判断
/* if (
this.x2 >= this.slideButton1.offsetWidth &&
this.x2 <= this.state.maxWidth
) { */
this.setState({
left2: this.x2,
});
// 碰撞形式的判断
// if (
// this.x2 - this.slideButton2.offsetWidth <= this.x1 &&
// this.x2 - this.slideButton2.offsetWidth >= 0
// ) {
// this.setState({
// left1: this.x2 - this.slideButton2.offsetWidth,
// left2: this.x2,
// });
// this.x1 = this.x2 - this.slideButton2.offsetWidth;
// }
}
}
FnUp() {
document.onmousemove = null;
}
render() {
return (
<div className="block-drog">
<div className="block">
<h2 className="block-title">双滑块</h2>
<div className="slider">
<div className="scale">
{this.scaleArr.map((item, index) => (
<div
key={index}
style={{
left: item + "%",
}}
>
{item}
</div>
))}
</div>
<div
className="slider-bar"
ref={(div: HTMLDivElement) => {
this.slideBar = div;
}}
style={{
width:
Math.floor(
Math.abs(this.state.left2 * 100 - this.state.left1 * 100) /
this.state.maxWidth
) + "%",
// left: Math.floor(Math.min(this.state.left2 , this.state.left1)),
}}
>
<div
className="slider-button-left"
style={{
width:
this.state.left1 < this.state.left2
? this.state.left1
: this.state.left2,
}}
>
<div
className="slider-button"
ref={(div: HTMLDivElement) => {
this.slideButton1 = div;
}}
onMouseDown={this.FnDown1.bind(this)}
style={{ left: this.state.left1 }}
>
{Math.floor((this.state.left1 / this.state.maxWidth) * 100)}
</div>
</div>
<div
className="slider-button-right"
style={{
width:
this.state.left2 > this.state.left1
? this.state.left2
: this.state.left1,
}}
>
<div
className="slider-button"
ref={(div: HTMLDivElement) => {
this.slideButton2 = div;
}}
onMouseDown={this.FnDown2.bind(this)}
style={{ left: this.state.left2 }}
>
{Math.floor((this.state.left2 / this.state.maxWidth) * 100)}
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default BlockDrog;
【react+ts】react+ts实现双滑块移动效果,包含交叉和碰撞
最新推荐文章于 2024-05-27 15:48:06 发布