@stianlarsen/react-light-beam
Advanced tools
Comparing version 1.0.2 to 1.0.3
import React from "react"; | ||
import { LightBeamProps } from "../types/types"; | ||
export declare const LightBeam: ({ className, colorLightmode, colorDarkmode, fullWidth, }: LightBeamProps) => React.JSX.Element; | ||
export declare const LightBeam: ({ className, colorLightmode, colorDarkmode, maskLightByProgress, fullWidth, invert, id, }: LightBeamProps) => React.JSX.Element; |
@@ -26,2 +26,5 @@ "use strict"; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -31,5 +34,6 @@ exports.LightBeam = void 0; | ||
const react_1 = __importStar(require("react")); | ||
const lightBeam_module_css_1 = __importDefault(require("./css/lightBeam.module.css")); | ||
const useDarkmode_1 = require("./hooks/useDarkmode"); | ||
const LightBeam = ({ className, colorLightmode = "rgba(0,0,0, 0.5)", colorDarkmode = "rgba(255, 255, 255, 0.5)", fullWidth = 1.0, // Default to full width | ||
}) => { | ||
const LightBeam = ({ className, colorLightmode = "rgba(0,0,0, 0.5)", colorDarkmode = "rgba(255, 255, 255, 0.5)", maskLightByProgress = false, fullWidth = 1.0, // Default to full width | ||
invert = false, id = undefined, }) => { | ||
const elementRef = (0, react_1.useRef)(null); | ||
@@ -40,2 +44,3 @@ const bodyRef = (0, react_1.useRef)(document.body); | ||
const { isDarkmode } = (0, useDarkmode_1.useIsDarkmode)(); | ||
const chosenColor = isDarkmode ? colorDarkmode : colorLightmode; | ||
(0, react_1.useEffect)(() => { | ||
@@ -49,4 +54,7 @@ const handleScroll = () => { | ||
// Calculate progress | ||
const progress = 1 - Math.max(adjustedFullWidth, Math.min(1, rect.top / windowHeight)); | ||
console.log("progress: ", progress); | ||
const progress = invert | ||
? 0 + | ||
Math.max(adjustedFullWidth, Math.min(1, rect.top / windowHeight)) | ||
: 1 - | ||
Math.max(adjustedFullWidth, Math.min(1, rect.top / windowHeight)); | ||
// Update motion values | ||
@@ -68,15 +76,19 @@ inViewProgress.set(progress); | ||
const backgroundPosition = (0, framer_motion_1.useTransform)(inViewProgress, [0, 1], [ | ||
"conic-gradient(from 90deg at 90% 0%, var(--colorTop), transparent 180deg) 0% 0% / 50% 150% no-repeat, conic-gradient(from 270deg at 10% 0%, transparent 180deg, var(--colorTop)) 100% 0% / 50% 100% no-repeat", | ||
"conic-gradient(from 90deg at 0% 0%, var(--colorTop), transparent 180deg) 0% 0% / 50% 100% no-repeat, conic-gradient(from 270deg at 100% 0%, transparent 180deg, var(--colorTop)) 100% 0% / 50% 100% no-repeat", | ||
`conic-gradient(from 90deg at 90% 0%, ${chosenColor}, transparent 180deg) 0% 0% / 50% 150% no-repeat, conic-gradient(from 270deg at 10% 0%, transparent 180deg, ${chosenColor}) 100% 0% / 50% 100% no-repeat`, | ||
`conic-gradient(from 90deg at 0% 0%, ${chosenColor}, transparent 180deg) 0% 0% / 50% 100% no-repeat, conic-gradient(from 270deg at 100% 0%, transparent 180deg, ${chosenColor}) 100% 0% / 50% 100% no-repeat`, | ||
]); | ||
const maskImageOpacity = (0, framer_motion_1.useTransform)(inViewProgress, [0, 1], [ | ||
`linear-gradient(to bottom, ${chosenColor} 0%, transparent 50%)`, | ||
`linear-gradient(to bottom, ${chosenColor} 0%, transparent 95%)`, | ||
]); | ||
const maskImage = maskLightByProgress | ||
? maskImageOpacity | ||
: `linear-gradient(to bottom, ${chosenColor} 25%, transparent 95%)`; | ||
return (react_1.default.createElement(framer_motion_1.motion.div, { style: { | ||
"--colorTop": `${isDarkmode ? colorDarkmode : colorLightmode}`, | ||
background: backgroundPosition, | ||
opacity: opacity, | ||
height: "100%", | ||
transition: "background 0.5s ease, opacity 0.5s ease", | ||
zIndex: -1, | ||
maskImage: `linear-gradient(to bottom, background 0%, transparent 98%)`, | ||
}, ref: elementRef, className: `Conic_conic__HBaxC ${className}` })); | ||
maskImage: maskImage, | ||
WebkitMaskImage: maskImage, | ||
}, ref: elementRef, id: id, className: `lightBeam ${className} ${lightBeam_module_css_1.default.react__light__beam}` })); | ||
}; | ||
exports.LightBeam = LightBeam; |
{ | ||
"name": "@stianlarsen/react-light-beam", | ||
"version": "1.0.2", | ||
"version": "1.0.3", | ||
"description": "A customizable React component that creates a light beam effect using conic gradients. Supports dark mode and various customization options.", | ||
@@ -9,3 +9,3 @@ "main": "dist/index.js", | ||
"test": "echo \"Error: no test specified\" && exit 1", | ||
"build": "rm -rf dist && tsc" | ||
"build": "rm -rf dist && tsc && shx mkdir -p dist/css/ && shx cp src/css/lightBeam.module.css dist/css/" | ||
}, | ||
@@ -49,2 +49,3 @@ "files": [ | ||
"@types/react-dom": "^18", | ||
"shx": "^0.3.4", | ||
"typescript": "^5.5.4" | ||
@@ -51,0 +52,0 @@ }, |
@@ -0,1 +1,2 @@ | ||
# @stianlarsen/react-light-beam | ||
@@ -22,4 +23,4 @@ | ||
```jsx | ||
import { LightBeam } from "@stianlarsen/react-light-beam"; | ||
import "your-css-file.css"; // Include the necessary styles | ||
import { LightBeam } from '@stianlarsen/react-light-beam'; | ||
import 'your-css-file.css'; // Include the necessary styles | ||
@@ -30,6 +31,9 @@ const App = () => { | ||
<LightBeam | ||
id="unique-lightbeam" | ||
className="your-lightbeam-class" | ||
colorDarkmode="hsl(var(--primary) / 1)" | ||
colorLightmode="hsl(var(--foreground) / 0.2)" | ||
colorDarkmode="rgba(255, 255, 255, 0.8)" | ||
colorLightmode="rgba(0, 0, 0, 0.2)" | ||
fullWidth={0.8} | ||
maskLightByProgress={true} | ||
invert={false} | ||
/> | ||
@@ -46,13 +50,57 @@ <YourContentHere /> | ||
| Prop Name | Type | Default Value | Description | | ||
| ---------------- | -------- | -------------------------- | -------------------------------------------------------------------------------------------- | | ||
| `className` | `string` | `undefined` | Optional string representing custom classes to be added to the LightBeam container. | | ||
| `colorLightmode` | `string` | `rgba(0,0,0, 0.5)` | Optional string representing the color of the light beam in light mode. | | ||
| `colorDarkmode` | `string` | `rgba(255, 255, 255, 0.5)` | Optional string representing the color of the light beam in dark mode. | | ||
| `fullWidth` | `number` | `1.0` | Optional number between `0` and `1` representing the maximum width the light beam can reach. | | ||
| Prop Name | Type | Default Value | Description | | ||
|---------------------|-----------|--------------------------------|-------------------------------------------------------------------------------------------------| | ||
| `id` | `string` | `undefined` | Optional string representing a unique ID for the LightBeam container. | | ||
| `className` | `string` | `undefined` | Optional string representing custom classes to be added to the LightBeam container. | | ||
| `colorLightmode` | `string` | `rgba(0,0,0, 0.5)` | Optional string representing the color of the light beam in light mode. | | ||
| `colorDarkmode` | `string` | `rgba(255, 255, 255, 0.5)` | Optional string representing the color of the light beam in dark mode. | | ||
| `fullWidth` | `number` | `1.0` | Optional number between `0` and `1` representing the maximum width the light beam can reach. | | ||
| `maskLightByProgress` | `boolean` | `false` | If `true`, the `mask-image`'s linear gradient will start with the chosen color at 0% and the transparent part starting at 50%. As the user scrolls, it will dynamically change to have the transparent part at 95%, reducing the glow effect. If `false`, it will default to `linear-gradient(to bottom, chosenColor 25%, transparent 95%)`. | | ||
| `invert` | `boolean` | `false` | Optional boolean to invert the scroll progress calculation. | | ||
### Customization | ||
### Default Configuration | ||
You can customize the appearance and behavior of the light beam by adjusting the props or by applying additional styles via the `className` prop. | ||
The component comes with the following default styles: | ||
```css | ||
.react__light__beam { | ||
height: 500px; | ||
width: 100vw; | ||
transition: all 0.5s ease; | ||
will-change: auto; | ||
} | ||
``` | ||
These default styles ensure that the component is immediately visible when added to your application. However, for more effective use, you might want to customize its position and behavior. | ||
### Recommended Usage | ||
For best results, it's recommended to position the `LightBeam` component as an absolutely positioned element within a relatively positioned container. This allows the light beam to cast light downwards over your content, creating a more dynamic and engaging visual effect. | ||
Example: | ||
```jsx | ||
<div className="container"> | ||
<LightBeam className="lightBeam"/> | ||
</div> | ||
``` | ||
And in your CSS or SCSS: | ||
```scss | ||
.container { | ||
position: relative; | ||
z-index: 1; | ||
.lightBeam { | ||
position: absolute; | ||
inset: 0; | ||
width: 100vw; | ||
height: 100%; // Important: Ensure the beam covers the entire height | ||
z-index: -1; | ||
margin-top: -300px; // Adjust as needed to position the light beam above the content | ||
} | ||
} | ||
``` | ||
### Dark Mode Support | ||
@@ -66,6 +114,9 @@ | ||
<LightBeam | ||
id="lightbeam-example" | ||
className="custom-lightbeam" | ||
colorDarkmode="hsl(210, 22%, 18%)" | ||
colorLightmode="hsl(0, 0%, 98%)" | ||
colorDarkmode="rgba(255, 255, 255, 0.8)" | ||
colorLightmode="rgba(0, 0, 0, 0.2)" | ||
fullWidth={0.5} | ||
maskLightByProgress={true} | ||
invert={true} | ||
/> | ||
@@ -72,0 +123,0 @@ ``` |
@@ -6,2 +6,5 @@ export type LightBeamProps = { | ||
colorDarkmode?: string; | ||
maskLightByProgress?: boolean; | ||
invert?: boolean; | ||
id?: string; | ||
}; |
13569
10
141
124
4