79 lines
2.2 KiB
TypeScript
79 lines
2.2 KiB
TypeScript
import * as React from 'react'
|
|
import { Theme, withStyles } from '@material-ui/core'
|
|
|
|
interface State {
|
|
enabled: boolean
|
|
target: {x: number, y: number}
|
|
position: {x: number, y: number}
|
|
stepSizeX: number,
|
|
stepSizeY: number,
|
|
}
|
|
|
|
class Demo extends React.Component<{}, State> {
|
|
private timer: any
|
|
private frameInterval = 20
|
|
|
|
constructor(props: any) {
|
|
super(props)
|
|
this.state = { enabled: false, target: { x: 0, y: 0 }, position: { x: 0, y: 0 }, stepSizeX: 1, stepSizeY: 1 }
|
|
}
|
|
|
|
public componentDidMount() {
|
|
(window as any).demo.enableMouse = () => {
|
|
this.setState({ enabled: true })
|
|
}
|
|
(window as any).demo.moveMouse = (x: number, y: number, animationTime: number) => {
|
|
const stepSizeX = Math.abs(this.state.position.x - x) / (animationTime / this.frameInterval)
|
|
const stepSizeY = Math.abs(this.state.position.y - y) / (animationTime / this.frameInterval)
|
|
this.setState({ stepSizeX, stepSizeY, enabled: true, target: { x, y } })
|
|
this.moveCloser()
|
|
}
|
|
}
|
|
|
|
private moveCloser(steps: number = 0) {
|
|
const steSizeX = Math.min(this.state.stepSizeX, Math.abs(this.state.position.x - this.state.target.x))
|
|
const steSizeY = Math.min(this.state.stepSizeY, Math.abs(this.state.position.y - this.state.target.y))
|
|
const dirX = this.state.position.x > this.state.target.x ? -1 : 1
|
|
const dirY = this.state.position.y > this.state.target.y ? -1 : 1
|
|
|
|
if (steSizeX <= 0.1 && steSizeY <= 0.1) {
|
|
this.timer && clearTimeout(this.timer)
|
|
return
|
|
}
|
|
|
|
this.setState({
|
|
position: {
|
|
x: this.state.position.x + (dirX * steSizeX),
|
|
y: this.state.position.y + (dirY * steSizeY),
|
|
},
|
|
})
|
|
|
|
this.timer = setTimeout(() => {
|
|
this.moveCloser(steps + 1)
|
|
}, this.frameInterval)
|
|
}
|
|
|
|
public render() {
|
|
if (!this.state.enabled) {
|
|
return null
|
|
}
|
|
const style = {
|
|
width: '32px',
|
|
height: '32px',
|
|
position: 'fixed' as 'fixed',
|
|
zIndex: 1000000,
|
|
filter: 'invert(100%)',
|
|
left: this.state.position.x + 2,
|
|
top: this.state.position.y + 2,
|
|
}
|
|
|
|
return (
|
|
<img src="../cursor.png" style={style} />
|
|
)
|
|
}
|
|
}
|
|
|
|
const style = (theme: Theme) => {}
|
|
|
|
export default withStyles(style)(Demo)
|