Refine Harbor brand mode hover animation
This commit is contained in:
@@ -74,12 +74,27 @@ function DurationPart({ name, children }) {
|
||||
}
|
||||
|
||||
function HarborBrand({ isGateway, gatewayAvailable, gatewayDirect, busy, onSetGatewayAuto }) {
|
||||
const [modeAnimating, setModeAnimating] = useState(false);
|
||||
const stopModeAnimationRef = useRef(false);
|
||||
const product = isGateway ? 'Gateway' : 'Connect';
|
||||
const switchable = !isGateway && gatewayAvailable;
|
||||
const label = gatewayDirect
|
||||
? 'Игнорировать Harbor Gateway и использовать локальный VPN'
|
||||
: 'Использовать обнаруженный Harbor Gateway';
|
||||
|
||||
function startModeAnimation() {
|
||||
stopModeAnimationRef.current = false;
|
||||
setModeAnimating(true);
|
||||
}
|
||||
|
||||
function finishModeAnimation() {
|
||||
if (matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
||||
setModeAnimating(false);
|
||||
return;
|
||||
}
|
||||
stopModeAnimationRef.current = true;
|
||||
}
|
||||
|
||||
const content = <div className="harbor-brand-content">
|
||||
<svg viewBox="0 0 32 32" aria-hidden="true">
|
||||
<circle cx="16" cy="6" r="3" />
|
||||
@@ -111,12 +126,22 @@ function HarborBrand({ isGateway, gatewayAvailable, gatewayDirect, busy, onSetGa
|
||||
return (
|
||||
<div className={`harbor-brand is-${product.toLowerCase()}${switchable ? ` is-switchable${gatewayDirect ? ' is-gateway-active' : ''}` : ''}`}>
|
||||
{switchable ? <button
|
||||
className="harbor-brand-control"
|
||||
className={`harbor-brand-control${modeAnimating ? ' is-mode-animating' : ''}`}
|
||||
type="button"
|
||||
aria-label={label}
|
||||
aria-describedby="harbor-mode-tooltip"
|
||||
aria-pressed={gatewayDirect}
|
||||
disabled={busy}
|
||||
onPointerEnter={startModeAnimation}
|
||||
onPointerLeave={finishModeAnimation}
|
||||
onFocus={startModeAnimation}
|
||||
onBlur={finishModeAnimation}
|
||||
onAnimationIteration={(event) => {
|
||||
if (event.animationName === 'harbor-mode-float-front' && stopModeAnimationRef.current) {
|
||||
stopModeAnimationRef.current = false;
|
||||
setModeAnimating(false);
|
||||
}
|
||||
}}
|
||||
onClick={() => onSetGatewayAuto(!gatewayDirect)}
|
||||
>
|
||||
{content}
|
||||
|
||||
@@ -246,23 +246,19 @@ p {
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.harbor-brand-control:hover .harbor-mode-connect,
|
||||
.harbor-brand-control:focus-visible .harbor-mode-connect {
|
||||
.harbor-brand-control.is-mode-animating .harbor-mode-connect {
|
||||
animation: harbor-mode-float-front 1500ms ease-in-out infinite;
|
||||
}
|
||||
|
||||
.harbor-brand-control:hover .harbor-mode-gateway,
|
||||
.harbor-brand-control:focus-visible .harbor-mode-gateway {
|
||||
.harbor-brand-control.is-mode-animating .harbor-mode-gateway {
|
||||
animation: harbor-mode-float-back 1500ms ease-in-out infinite;
|
||||
}
|
||||
|
||||
.harbor-brand.is-gateway-active .harbor-brand-control:hover .harbor-mode-connect,
|
||||
.harbor-brand.is-gateway-active .harbor-brand-control:focus-visible .harbor-mode-connect {
|
||||
.harbor-brand.is-gateway-active .harbor-brand-control.is-mode-animating .harbor-mode-connect {
|
||||
animation-name: harbor-mode-float-back;
|
||||
}
|
||||
|
||||
.harbor-brand.is-gateway-active .harbor-brand-control:hover .harbor-mode-gateway,
|
||||
.harbor-brand.is-gateway-active .harbor-brand-control:focus-visible .harbor-mode-gateway {
|
||||
.harbor-brand.is-gateway-active .harbor-brand-control.is-mode-animating .harbor-mode-gateway {
|
||||
animation-name: harbor-mode-float-front;
|
||||
}
|
||||
|
||||
@@ -357,13 +353,11 @@ p {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.harbor-brand-control:hover .harbor-mode-swap .is-connect path,
|
||||
.harbor-brand-control:focus-visible .harbor-mode-swap .is-connect path {
|
||||
.harbor-brand-control.is-mode-animating .harbor-mode-swap .is-connect path {
|
||||
animation: harbor-arrow-float-right 1500ms ease-in-out infinite;
|
||||
}
|
||||
|
||||
.harbor-brand-control:hover .harbor-mode-swap .is-gateway path,
|
||||
.harbor-brand-control:focus-visible .harbor-mode-swap .is-gateway path {
|
||||
.harbor-brand-control.is-mode-animating .harbor-mode-swap .is-gateway path {
|
||||
animation: harbor-arrow-float-left 1500ms ease-in-out infinite;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user