@stianlarsen/react-fade-effects
Version:
A collection of React components for smooth fade-in animations, starting with FadeWords. Easily add fade effects to your UI elements with customizable options.
187 lines (182 loc) • 7.44 kB
JavaScript
;
"use client";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.tsx
var index_exports = {};
__export(index_exports, {
FadedWords: () => FadedWords
});
module.exports = __toCommonJS(index_exports);
// src/components/fadedWords.tsx
var import_framer_motion = require("framer-motion");
var import_react = require("react");
// #style-inject:#style-inject
function styleInject(css, { insertAt } = {}) {
if (!css || typeof document === "undefined") return;
const head = document.head || document.getElementsByTagName("head")[0];
const style = document.createElement("style");
style.type = "text/css";
if (insertAt === "top") {
if (head.firstChild) {
head.insertBefore(style, head.firstChild);
} else {
head.appendChild(style);
}
} else {
head.appendChild(style);
}
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
}
// src/css/fadeEffects.css
styleInject(".sl-fade-textEffectWrapper {\n display: inline-block;\n vertical-align: inherit;\n text-align: inherit;\n text-decoration: inherit;\n text-wrap: inherit;\n font-size: inherit;\n font-weight: inherit;\n font-style: inherit;\n font-family: inherit;\n line-height: inherit;\n letter-spacing: inherit;\n color: inherit;\n background-color: inherit;\n border: inherit;\n border-radius: inherit;\n}\n.sl-fade-textEffectWrapper .sl-fade-word {\n display: inline-block;\n opacity: 0;\n color: inherit;\n vertical-align: inherit;\n text-align: inherit;\n text-decoration: inherit;\n text-wrap: inherit;\n font-size: inherit;\n font-weight: inherit;\n font-style: inherit;\n font-family: inherit;\n line-height: inherit;\n letter-spacing: inherit;\n background-color: inherit;\n border: inherit;\n border-radius: inherit;\n will-change:\n transform,\n opacity,\n filter;\n backface-visibility: hidden;\n -webkit-backface-visibility: hidden;\n transform: translateZ(0);\n contain: layout style;\n}\n.sl-fade-renderWordsWrapper {\n display: block;\n text-align: inherit;\n text-decoration: inherit;\n text-wrap: inherit;\n font-size: inherit;\n font-weight: inherit;\n font-style: inherit;\n font-family: inherit;\n line-height: inherit;\n letter-spacing: inherit;\n color: inherit;\n background-color: inherit;\n border: inherit;\n border-radius: inherit;\n}\n");
// src/components/fadedWords.tsx
var import_jsx_runtime = require("react/jsx-runtime");
var GPU_BLUR_PX = 8;
var FadedWords = ({
words,
className,
filter = true,
duration = 1,
staggerTime = 0.1,
delay = 0.2,
variant = "default",
scaleSize = void 0,
once = true,
translateAmount = void 0,
splitChar = " ",
includeSpaces = true
}) => {
const [scope, animate] = (0, import_framer_motion.useAnimate)();
const isInViewContainer = (0, import_react.useRef)(null);
const isInView = (0, import_framer_motion.useInView)(isInViewContainer, {
once,
amount: 0.5
});
const tokensArray = (0, import_react.useMemo)(() => {
if (Array.isArray(words)) {
return words.map((word) => ({ value: word, isDelimiter: false }));
}
let delimiterRegex;
if (splitChar instanceof RegExp) {
delimiterRegex = splitChar;
} else {
delimiterRegex = new RegExp(escapeRegex(splitChar), "g");
}
return tokenize(words, delimiterRegex);
}, [words, splitChar]);
const initialStyle = (0, import_react.useMemo)(
() => getInitialStyleObject(variant, filter, scaleSize, translateAmount),
[variant, filter, scaleSize, translateAmount]
);
(0, import_react.useEffect)(() => {
if (!isInView || !isInViewContainer.current || !scope.current) return;
const timeoutId = setTimeout(() => {
animate(
".singleWord",
{
opacity: 1,
filter: filter ? "blur(0px)" : "none",
transform: "translateY(0px) translateX(0px) scale(1)"
},
{
duration,
delay: (0, import_framer_motion.stagger)(staggerTime),
ease: [0.25, 0.1, 0.25, 1]
}
);
}, delay * 1e3);
return () => clearTimeout(timeoutId);
}, [isInView, animate, delay, duration, filter, staggerTime]);
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: isInViewContainer, className: "sl-fade-renderWordsWrapper", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_framer_motion.motion.span,
{
ref: scope,
className: `${className || ""} sl-fade-textEffectWrapper`,
children: tokensArray.map((token, idx) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
import_framer_motion.motion.span,
{
className: "sl-fade-word singleWord",
style: initialStyle,
children: [
token.value,
includeSpaces && !token.isDelimiter && idx < tokensArray.length - 1 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: "\xA0" }) : null
]
},
token.value + idx
))
}
) });
};
var getInitialStyleObject = (variant, filter, scaleSize, translateAmount) => {
let translateY = "0px";
let translateX = "0px";
switch (variant) {
case "up":
translateY = `${translateAmount !== void 0 ? translateAmount : 15}px`;
break;
case "down":
translateY = `${translateAmount !== void 0 ? -translateAmount : -15}px`;
break;
case "left":
translateX = `${translateAmount !== void 0 ? translateAmount : 15}px`;
break;
case "right":
translateX = `${translateAmount !== void 0 ? -translateAmount : -15}px`;
break;
}
const scale = scaleSize !== void 0 ? scaleSize : 1;
return {
opacity: 0,
filter: filter ? `blur(${GPU_BLUR_PX}px)` : "none",
display: "inline-block",
transform: `translateY(${translateY}) translateX(${translateX}) scale(${scale})`
};
};
var tokenize = (str, delimiterRegex) => {
const tokens = [];
let lastIndex = 0;
const regex = new RegExp(delimiterRegex, "g");
let match;
while ((match = regex.exec(str)) !== null) {
if (match.index > lastIndex) {
tokens.push({
value: str.slice(lastIndex, match.index),
isDelimiter: false
});
}
tokens.push({ value: match[0], isDelimiter: true });
lastIndex = regex.lastIndex;
}
if (lastIndex < str.length) {
tokens.push({ value: str.slice(lastIndex), isDelimiter: false });
}
return tokens;
};
var escapeRegex = (str) => {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
FadedWords
});
//# sourceMappingURL=index.cjs.map