react-cardflee-anim
Version:
A react animated card component that flee away from mouse.
91 lines (90 loc) • 3.39 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { Component } from 'react';
import './styles.css';
export class CardFlee extends Component {
mouseLeaveDelay = undefined;
background;
id;
halfWidth;
halfHeight;
sensitivity;
senseY;
cardCss;
constructor(props) {
super(props);
this.background =
(props.image && {
backgroundImage: `url("${props.image}")`,
}) ||
{};
this.halfWidth = (props.width && props.width / 2) || 100;
this.halfHeight = (props.height && props.height / 2) || 150;
this.id = `card-${props.id}`;
this.sensitivity = props.sensitivity || 12;
this.senseY = -(this.sensitivity * 0.8);
this.cardCss = {
width: (this.props.width && this.props.width + "px") || "300px",
height: (this.props.height && this.props.height + "px") || "500px",
};
this.state = {
mouseX: 0,
mouseY: 0,
tX: 0,
tY: 0,
rX: 0,
rY: 0,
cardStyle: {
transform: `rotateY(0deg) rotateX(0deg)`,
},
cardBgTransform: {
transform: `translateX(0px) translateY(0px)`,
},
};
}
mousePX = () => {
return (this.state.mouseX - this.halfWidth) / this.halfWidth;
};
mousePY = () => {
return (this.state.mouseY - this.halfHeight) / this.halfHeight;
};
handleMouseMove = (e) => {
const card = document.getElementById(this.id);
if (!card) {
return;
}
let { x, y } = card.getBoundingClientRect();
this.setState({
mouseX: e.clientX - x,
mouseY: e.clientY - y,
tX: this.mousePX() * this.sensitivity,
tY: this.mousePY() * this.senseY,
rX: this.mousePX() * this.sensitivity,
rY: this.mousePY() * this.senseY,
cardStyle: {
transform: `rotateY(${this.state.rX}deg) rotateX(${this.state.rY}deg)`,
},
cardBgTransform: {
transform: `translateX(${this.state.tX}px) translateY(${this.state.tY}px)`,
},
});
console.log(this);
};
handleMouseEnter = () => {
clearTimeout(this.mouseLeaveDelay);
};
handleMouseLeave = () => {
this.mouseLeaveDelay = setTimeout(() => {
this.setState({
cardStyle: {
transform: `rotateY(0deg) rotateX(0deg)`,
},
cardBgTransform: {
transform: `translateX(0px) translateY(0px)`,
},
});
}, 1000);
};
render() {
return (_jsx("div", { className: "card-wrap", onMouseMove: this.handleMouseMove, onMouseEnter: this.handleMouseEnter, onMouseLeave: this.handleMouseLeave, children: _jsxs("div", { id: this.id, className: "card", style: { ...this.cardCss, ...this.state.cardStyle }, children: [_jsx("div", { className: "card-bg", style: { ...this.background, ...this.state.cardBgTransform }, children: " " }), _jsxs("div", { className: "card-info", children: [_jsx("slot", { name: "header", children: this.props.head }), _jsx("slot", { name: "content", children: this.props.content })] })] }) }));
}
}