@codaworks/react-glow
Version:
Add a mouse-tracing glow effect to React components
139 lines (135 loc) • 5.73 kB
JavaScript
"use client";
import React, { useRef, useEffect } from 'react';
function _extends() {
_extends = Object.assign ? Object.assign.bind() : function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function _objectWithoutPropertiesLoose(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for (i = 0; i < sourceKeys.length; i++) {
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
var _excluded = ["className", "size"],
_excluded2 = ["className", "style", "children", "color", "debug"];
var GlowCapture = function GlowCapture(props) {
var _props$className = props.className,
className = _props$className === void 0 ? '' : _props$className,
_props$size = props.size,
size = _props$size === void 0 ? 400 : _props$size,
rest = _objectWithoutPropertiesLoose(props, _excluded);
var element = useRef(null);
useEffect(function () {
var _element$current3, _element$current4;
var move = function move(e) {
if (e.pointerType === 'mouse') {
requestAnimationFrame(function () {
if (!element.current) return;
var bounds = element.current.getBoundingClientRect();
var x = e.clientX - bounds.left;
var y = e.clientY - bounds.top;
element.current.style.setProperty('--glow-x', x + "px");
element.current.style.setProperty('--glow-y', y + "px");
});
}
};
var leave = function leave() {
var _element$current, _element$current2;
(_element$current = element.current) == null || _element$current.style.removeProperty('--glow-x');
(_element$current2 = element.current) == null || _element$current2.style.removeProperty('--glow-y');
};
(_element$current3 = element.current) == null || _element$current3.addEventListener('pointermove', move, {
passive: true
});
(_element$current4 = element.current) == null || _element$current4.addEventListener('pointerleave', leave, {
passive: true
});
return function () {
var _element$current5, _element$current6;
(_element$current5 = element.current) == null || _element$current5.removeEventListener('pointermove', move);
(_element$current6 = element.current) == null || _element$current6.removeEventListener('pointerleave', leave);
};
}, []);
return React.createElement("div", Object.assign({
ref: element,
className: "glow-capture " + className,
style: {
position: 'relative',
'--glow-size': size + "px"
}
}, rest));
};
var mask = "\nradial-gradient(var(--glow-size) var(--glow-size) at calc(var(--glow-x, -99999px) - var(--glow-left, 0px))\ncalc(var(--glow-y, -99999px) - var(--glow-top, 0px)), #000000 1%, transparent 50%)\n";
var Glow = function Glow(props) {
var _props$className2 = props.className,
className = _props$className2 === void 0 ? '' : _props$className2,
style = props.style,
children = props.children,
_props$color = props.color,
color = _props$color === void 0 ? '#f50057' : _props$color,
_props$debug = props.debug,
debug = _props$debug === void 0 ? false : _props$debug,
rest = _objectWithoutPropertiesLoose(props, _excluded2);
var element = useRef(null);
useEffect(function () {
var _element$current7, _element$current8, _element$current9, _element$current10;
(_element$current7 = element.current) == null || _element$current7.style.setProperty('--glow-top', ((_element$current8 = element.current) == null ? void 0 : _element$current8.offsetTop) + "px");
(_element$current9 = element.current) == null || _element$current9.style.setProperty('--glow-left', ((_element$current10 = element.current) == null ? void 0 : _element$current10.offsetLeft) + "px");
});
useEffect(function () {
var _element$current15;
var observer = new ResizeObserver(function () {
requestAnimationFrame(function () {
var _element$current11, _element$current12, _element$current13, _element$current14;
(_element$current11 = element.current) == null || _element$current11.style.setProperty('--glow-top', ((_element$current12 = element.current) == null ? void 0 : _element$current12.offsetTop) + "px");
(_element$current13 = element.current) == null || _element$current13.style.setProperty('--glow-left', ((_element$current14 = element.current) == null ? void 0 : _element$current14.offsetLeft) + "px");
});
});
var capture = (_element$current15 = element.current) == null ? void 0 : _element$current15.closest('.glow-capture');
if (capture) observer.observe(capture);
return function () {
return observer.disconnect();
};
}, []);
return React.createElement("div", {
ref: element,
className: 'glow',
style: {
display: 'grid'
}
}, React.createElement("div", Object.assign({
className: className,
style: _extends({}, style, {
gridArea: '1/1/1/1'
})
}, rest), children), React.createElement("div", Object.assign({
className: "glow-mask " + className,
// @ts-ignore
glow: 'true',
style: _extends({}, style, {
'--glow-color': color,
gridArea: '1/1/1/1',
pointerEvents: 'none',
mask: debug ? undefined : mask,
WebkitMask: debug ? undefined : mask
})
}, rest), children));
};
export { Glow, GlowCapture };
//# sourceMappingURL=react-glow.esm.js.map