UNPKG

@arolariu/components

Version:

🎨 60+ beautiful, accessible React components built on Radix UI. TypeScript-first, tree-shakeable, SSR-ready. Perfect for modern web apps, design systems & rapid prototyping. Zero config, maximum flexibility! ⚡

361 lines (360 loc) • 14.5 kB
"use client"; "use strict"; var __webpack_require__ = {}; (()=>{ __webpack_require__.d = (exports1, definition)=>{ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { enumerable: true, get: definition[key] }); }; })(); (()=>{ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); })(); (()=>{ __webpack_require__.r = (exports1)=>{ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { value: 'Module' }); Object.defineProperty(exports1, '__esModule', { value: true }); }; })(); var __webpack_exports__ = {}; __webpack_require__.r(__webpack_exports__); __webpack_require__.d(__webpack_exports__, { HoleBackground: ()=>HoleBackground }); const jsx_runtime_namespaceObject = require("react/jsx-runtime"); const external_react_namespaceObject = require("react"); const react_namespaceObject = require("motion/react"); const utils_cjs_namespaceObject = require("../../lib/utils.cjs"); const HoleBackground = /*#__PURE__*/ external_react_namespaceObject.forwardRef(({ strokeColor = "#737373", numberOfLines = 50, numberOfDiscs = 50, particleRGBColor = [ 255, 255, 255 ], className, children, ...props }, ref)=>{ const canvasRef = external_react_namespaceObject.useRef(null); external_react_namespaceObject.useImperativeHandle(ref, ()=>canvasRef.current); const animationFrameIdRef = external_react_namespaceObject.useRef(0); const stateRef = external_react_namespaceObject.useRef({ discs: [], lines: [], particles: [], clip: {}, startDisc: {}, endDisc: {}, rect: { width: 0, height: 0 }, render: { width: 0, height: 0, dpi: 1 }, particleArea: {}, linesCanvas: null }); const linear = (p)=>p; const easeInExpo = (p)=>0 === p ? 0 : Math.pow(2, 10 * (p - 1)); const tweenValue = external_react_namespaceObject.useCallback((start, end, p, ease = null)=>{ const delta = end - start; const easeFn = "inExpo" === ease ? easeInExpo : linear; return start + delta * easeFn(p); }, []); const tweenDisc = external_react_namespaceObject.useCallback((disc)=>{ const { startDisc, endDisc } = stateRef.current; disc.x = tweenValue(startDisc.x, endDisc.x, disc.p); disc.y = tweenValue(startDisc.y, endDisc.y, disc.p, "inExpo"); disc.w = tweenValue(startDisc.w, endDisc.w, disc.p); disc.h = tweenValue(startDisc.h, endDisc.h, disc.p); }, [ tweenValue ]); const setSize = external_react_namespaceObject.useCallback(()=>{ const canvas = canvasRef.current; if (!canvas) return; const rect = canvas.getBoundingClientRect(); stateRef.current.rect = { width: rect.width, height: rect.height }; stateRef.current.render = { width: rect.width, height: rect.height, dpi: window.devicePixelRatio || 1 }; canvas.width = stateRef.current.render.width * stateRef.current.render.dpi; canvas.height = stateRef.current.render.height * stateRef.current.render.dpi; }, []); const setDiscs = external_react_namespaceObject.useCallback(()=>{ const { width, height } = stateRef.current.rect; stateRef.current.discs = []; stateRef.current.startDisc = { x: 0.5 * width, y: 0.45 * height, w: 0.75 * width, h: 0.7 * height }; stateRef.current.endDisc = { x: 0.5 * width, y: 0.95 * height, w: 0, h: 0 }; let prevBottom = height; stateRef.current.clip = {}; for(let i = 0; i < numberOfDiscs; i++){ const p = i / numberOfDiscs; const disc = { p, x: 0, y: 0, w: 0, h: 0 }; tweenDisc(disc); const bottom = disc.y + disc.h; if (bottom <= prevBottom) stateRef.current.clip = { disc: { ...disc }, i }; prevBottom = bottom; stateRef.current.discs.push(disc); } const clipPath = new Path2D(); const disc = stateRef.current.clip.disc; clipPath.ellipse(disc.x, disc.y, disc.w, disc.h, 0, 0, 2 * Math.PI); clipPath.rect(disc.x - disc.w, 0, 2 * disc.w, disc.y); stateRef.current.clip.path = clipPath; }, [ tweenDisc ]); const setLines = external_react_namespaceObject.useCallback(()=>{ const { width, height } = stateRef.current.rect; stateRef.current.lines = []; const linesAngle = 2 * Math.PI / numberOfLines; for(let i = 0; i < numberOfLines; i++)stateRef.current.lines.push([]); stateRef.current.discs.forEach((disc)=>{ for(let i = 0; i < numberOfLines; i++){ const angle = i * linesAngle; const p = { x: disc.x + Math.cos(angle) * disc.w, y: disc.y + Math.sin(angle) * disc.h }; stateRef.current.lines[i].push(p); } }); const offCanvas = document.createElement("canvas"); offCanvas.width = width; offCanvas.height = height; const ctx = offCanvas.getContext("2d"); if (!ctx) return; stateRef.current.lines.forEach((line)=>{ ctx.save(); let lineIsIn = false; line.forEach((p1, j)=>{ if (0 === j) return; const p0 = line[j - 1]; if (!lineIsIn && (ctx.isPointInPath(stateRef.current.clip.path, p1.x, p1.y) || ctx.isPointInStroke(stateRef.current.clip.path, p1.x, p1.y))) lineIsIn = true; else if (lineIsIn) ctx.clip(stateRef.current.clip.path); ctx.beginPath(); ctx.moveTo(p0.x, p0.y); ctx.lineTo(p1.x, p1.y); ctx.strokeStyle = strokeColor; ctx.lineWidth = 2; ctx.stroke(); ctx.closePath(); }); ctx.restore(); }); stateRef.current.linesCanvas = offCanvas; }, [ strokeColor ]); const initParticle = external_react_namespaceObject.useCallback((start = false)=>{ const sx = stateRef.current.particleArea.sx + stateRef.current.particleArea.sw * Math.random(); const ex = stateRef.current.particleArea.ex + stateRef.current.particleArea.ew * Math.random(); const dx = ex - sx; const y = start ? stateRef.current.particleArea.h * Math.random() : stateRef.current.particleArea.h; const r = 0.5 + 4 * Math.random(); const vy = 0.5 + Math.random(); return { x: sx, sx, dx, y, vy, p: 0, r, c: `rgba(${particleRGBColor[0]}, ${particleRGBColor[1]}, ${particleRGBColor[2]}, ${Math.random()})` }; }, []); const setParticles = external_react_namespaceObject.useCallback(()=>{ const { width, height } = stateRef.current.rect; stateRef.current.particles = []; const disc = stateRef.current.clip.disc; stateRef.current.particleArea = { sw: 0.5 * disc.w, ew: 2 * disc.w, h: 0.85 * height }; stateRef.current.particleArea.sx = (width - stateRef.current.particleArea.sw) / 2; stateRef.current.particleArea.ex = (width - stateRef.current.particleArea.ew) / 2; const totalParticles = 100; for(let i = 0; i < totalParticles; i++)stateRef.current.particles.push(initParticle(true)); }, [ initParticle ]); const drawDiscs = external_react_namespaceObject.useCallback((ctx)=>{ ctx.strokeStyle = strokeColor; ctx.lineWidth = 2; const outerDisc = stateRef.current.startDisc; ctx.beginPath(); ctx.ellipse(outerDisc.x, outerDisc.y, outerDisc.w, outerDisc.h, 0, 0, 2 * Math.PI); ctx.stroke(); ctx.closePath(); stateRef.current.discs.forEach((disc, i)=>{ if (i % 5 !== 0) return; if (disc.w < stateRef.current.clip.disc.w - 5) { ctx.save(); ctx.clip(stateRef.current.clip.path); } ctx.beginPath(); ctx.ellipse(disc.x, disc.y, disc.w, disc.h, 0, 0, 2 * Math.PI); ctx.stroke(); ctx.closePath(); if (disc.w < stateRef.current.clip.disc.w - 5) ctx.restore(); }); }, [ strokeColor ]); const drawLines = external_react_namespaceObject.useCallback((ctx)=>{ if (stateRef.current.linesCanvas) ctx.drawImage(stateRef.current.linesCanvas, 0, 0); }, []); const drawParticles = external_react_namespaceObject.useCallback((ctx)=>{ ctx.save(); ctx.clip(stateRef.current.clip.path); stateRef.current.particles.forEach((particle)=>{ ctx.fillStyle = particle.c; ctx.beginPath(); ctx.rect(particle.x, particle.y, particle.r, particle.r); ctx.closePath(); ctx.fill(); }); ctx.restore(); }, []); const moveDiscs = external_react_namespaceObject.useCallback(()=>{ stateRef.current.discs.forEach((disc)=>{ disc.p = (disc.p + 0.001) % 1; tweenDisc(disc); }); }, [ tweenDisc ]); const moveParticles = external_react_namespaceObject.useCallback(()=>{ stateRef.current.particles.forEach((particle, idx)=>{ particle.p = 1 - particle.y / stateRef.current.particleArea.h; particle.x = particle.sx + particle.dx * particle.p; particle.y -= particle.vy; if (particle.y < 0) stateRef.current.particles[idx] = initParticle(); }); }, [ initParticle ]); const tick = external_react_namespaceObject.useCallback(()=>{ const canvas = canvasRef.current; if (!canvas) return; const ctx = canvas.getContext("2d"); if (!ctx) return; ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.save(); ctx.scale(stateRef.current.render.dpi, stateRef.current.render.dpi); moveDiscs(); moveParticles(); drawDiscs(ctx); drawLines(ctx); drawParticles(ctx); ctx.restore(); animationFrameIdRef.current = requestAnimationFrame(tick); }, [ moveDiscs, moveParticles, drawDiscs, drawLines, drawParticles ]); const init = external_react_namespaceObject.useCallback(()=>{ setSize(); setDiscs(); setLines(); setParticles(); }, [ setSize, setDiscs, setLines, setParticles ]); external_react_namespaceObject.useEffect(()=>{ const canvas = canvasRef.current; if (!canvas) return; init(); tick(); const handleResize = ()=>{ setSize(); setDiscs(); setLines(); setParticles(); }; window.addEventListener("resize", handleResize); return ()=>{ window.removeEventListener("resize", handleResize); cancelAnimationFrame(animationFrameIdRef.current); }; }, [ init, tick, setSize, setDiscs, setLines, setParticles ]); return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", { className: (0, utils_cjs_namespaceObject.cn)("relative size-full overflow-hidden", 'before:content-[""] before:absolute before:top-1/2 before:left-1/2 before:block before:size-[140%] dark:before:[background:radial-gradient(ellipse_at_50%_55%,transparent_10%,black_50%)] before:[background:radial-gradient(ellipse_at_50%_55%,transparent_10%,white_50%)] before:[transform:translate3d(-50%,-50%,0)]', 'after:content-[""] after:absolute after:z-[5] after:top-1/2 after:left-1/2 after:block after:size-full after:[background:radial-gradient(ellipse_at_50%_75%,#a900ff_20%,transparent_75%)] after:[transform:translate3d(-50%,-50%,0)] after:mix-blend-overlay', className), children: [ children, /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("canvas", { ref: canvasRef, className: "absolute inset-0 block size-full dark:opacity-20 opacity-10", ...props }), /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(react_namespaceObject.motion.div, { className: (0, utils_cjs_namespaceObject.cn)("absolute top-[-71.5%] left-1/2 z-[3] w-[30%] h-[140%] rounded-b-full blur-3xl opacity-75 dark:mix-blend-plus-lighter mix-blend-plus-darker [transform:translate3d(-50%,0,0)] [background-position:0%_100%] [background-size:100%_200%]", "dark:[background:linear-gradient(20deg,#00f8f1,#ffbd1e20_16.5%,#fe848f_33%,#fe848f20_49.5%,#00f8f1_66%,#00f8f160_85.5%,#ffbd1e_100%)_0_100%_/_100%_200%] [background:linear-gradient(20deg,#00f8f1,#ffbd1e40_16.5%,#fe848f_33%,#fe848f40_49.5%,#00f8f1_66%,#00f8f180_85.5%,#ffbd1e_100%)_0_100%_/_100%_200%]"), animate: { backgroundPosition: "0% 300%" }, transition: { duration: 5, ease: "linear", repeat: 1 / 0 } }), /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", { className: "absolute top-0 left-0 z-[7] size-full dark:[background:repeating-linear-gradient(transparent,transparent_1px,white_1px,white_2px)] mix-blend-overlay opacity-50" }) ] }); }); exports.HoleBackground = __webpack_exports__.HoleBackground; for(var __webpack_i__ in __webpack_exports__)if (-1 === [ "HoleBackground" ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; Object.defineProperty(exports, '__esModule', { value: true }); //# sourceMappingURL=hole-background.cjs.map