rotation border
This commit is contained in:
@@ -4,14 +4,53 @@ import "./rotationTestStyle.css";
|
||||
|
||||
// Web-only rotating gradient border container
|
||||
// Props:
|
||||
// - active: show rotating gradient when true (default)
|
||||
// - active: animate rotation (default true)
|
||||
// - colors: [primary, secondary] gradient colors
|
||||
// - duration: animation duration in seconds
|
||||
// - borderWidth: width of the gradient border (px)
|
||||
// - borderRadius: optional corner radius (px)
|
||||
// - fillColor: background color applied inside the border
|
||||
// - style, className: optional DOM styles/classes
|
||||
const RotationBorder = ({ children, style, className, active = true }) => {
|
||||
const classes = ["box", active ? "a" : null, className]
|
||||
const RotationBorder = ({
|
||||
children,
|
||||
style,
|
||||
className,
|
||||
active = true,
|
||||
colors = ["#F94697", "#7023F7"],
|
||||
duration = 5,
|
||||
borderWidth = 1,
|
||||
borderRadius,
|
||||
fillColor = "transparent",
|
||||
}) => {
|
||||
const classes = [
|
||||
"rotation-border",
|
||||
active ? "rotation-border--active" : "rotation-border--static",
|
||||
className,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" ");
|
||||
|
||||
const inlineStyle = { ...style };
|
||||
|
||||
inlineStyle["--rotation-border-width"] = `${borderWidth}px`;
|
||||
inlineStyle["--rotation-border-color-1"] = colors[0];
|
||||
inlineStyle["--rotation-border-color-2"] = colors[1] ?? colors[0];
|
||||
inlineStyle["--rotation-border-duration"] = `${duration}s`;
|
||||
inlineStyle["--rotation-border-fill"] = fillColor;
|
||||
|
||||
if (typeof borderRadius !== "undefined") {
|
||||
inlineStyle.borderRadius = borderRadius;
|
||||
}
|
||||
|
||||
if (typeof inlineStyle.borderRadius !== "undefined") {
|
||||
inlineStyle["--rotation-border-radius"] =
|
||||
typeof inlineStyle.borderRadius === "number"
|
||||
? `${inlineStyle.borderRadius}px`
|
||||
: inlineStyle.borderRadius;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes} style={style}>
|
||||
<div className={classes} style={inlineStyle}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,29 +1,36 @@
|
||||
.box {
|
||||
.rotation-border {
|
||||
--border-angle: 0deg;
|
||||
border-radius: 12px;
|
||||
width: 100%;
|
||||
height: 260px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
box-shadow: 0px 2px 4px hsl(0 0% 0% / 25%);
|
||||
animation: border-angle-rotate 5s infinite linear;
|
||||
border: 2px solid transparent;
|
||||
--rotation-border-width: 1px;
|
||||
--rotation-border-radius: 0px;
|
||||
--rotation-border-duration: 5s;
|
||||
--rotation-border-color-1: #f94697;
|
||||
--rotation-border-color-2: #7023f7;
|
||||
--rotation-border-fill: transparent;
|
||||
border: var(--rotation-border-width) solid transparent;
|
||||
border-radius: var(--rotation-border-radius);
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
position: relative;
|
||||
background: linear-gradient(
|
||||
var(--rotation-border-fill),
|
||||
var(--rotation-border-fill)
|
||||
)
|
||||
padding-box,
|
||||
conic-gradient(
|
||||
from var(--border-angle),
|
||||
var(--rotation-border-color-1),
|
||||
var(--rotation-border-color-2),
|
||||
var(--rotation-border-color-1)
|
||||
)
|
||||
border-box;
|
||||
}
|
||||
|
||||
&.a {
|
||||
background: linear-gradient(#11012f, #11012f) padding-box,
|
||||
conic-gradient(
|
||||
from var(--border-angle),
|
||||
oklch(0.6659 0.2211 304.21),
|
||||
oklch(0.6659 0.2211 304.21 / 0%),
|
||||
oklch(0.6659 0.2211 304.21),
|
||||
oklch(0.6659 0.2211 304.21 / 0%),
|
||||
oklch(0.6659 0.2211 304.21)
|
||||
|
||||
)
|
||||
border-box;
|
||||
}
|
||||
.rotation-border--active {
|
||||
animation: border-angle-rotate var(--rotation-border-duration) linear infinite;
|
||||
}
|
||||
|
||||
.rotation-border--static {
|
||||
animation: none;
|
||||
}
|
||||
|
||||
@keyframes border-angle-rotate {
|
||||
|
||||
Reference in New Issue
Block a user