In this article, We will create a box shadow generator using React Js. The application enables customization of various aspects of a box shadow, including position, size, color, opacity, and whether it should be inset or outset.
Preview of final output: Let us have a look at how the final output will look like.
Prerequisites / Technologies Used:
Approach:
- React and hooks are utilized to effectively manage state variables for various shadow properties. These properties include horizontal and vertical offsets, blur radius, spread radius, color, opacity, and the type of shadow (inset or outset).
- The useEffect hook monitors these state changes and invokes the generateShadow function. This function computes the box shadow CSS string based on user input.
- The function called hexToRgba serves the purpose of converting a chosen color into the RGBA format, which is commonly used
- The copyCode function performs two essential tasks. Firstly, it selects and copies the generated CSS code to the clipboard. Secondly, it provides user feedback by displaying a friendly message that says “Code Copied.”
- The JSX renders various interactive elements, including sliders, color pickers, live previews, and a copy button. These tools allow for seamless customization of box shadows.
Steps to Create the project:
Step 1: Create a react application by using this command
npx create-react-app box-shadow-generator
Step 2: After creating your project folder, i.e. box-shadow-generator, use the following command to navigate to it:
cd box-shadow-generator
Project Structure:
Package.json
"dependencies": {
"html-to-image": "^1.11.11",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
"react-scripts": "latest"
}
Example: Below is the implementation of the Box Shadow Generator using ReactJs
//App.js import React, { useState, useEffect } from "react" ;
import "./App.css" ;
function App() {
const [hShadow, setHShadow] = useState(0);
const [vShadow, setVShadow] = useState(0);
const [blurRadius, setBlurRadius] = useState(0);
const [
spreadRadius,
setSpreadRadius] = useState(0);
const [
shadowColor,
setShadowColor] = useState( "#0075ff" );
const [
shadowColorOpacity,
setShadowColorOpacity] = useState(1);
const [
shadowInset,
setShadowInset] = useState( false );
const [
boxShadow,
setBoxShadow] = useState( "" );
const [
copiedMessageVisible,
setCopiedMessageVisible] = useState( false );
useEffect(() => {
generateShadow();
}, [
hShadow,
vShadow,
blurRadius,
spreadRadius,
shadowColor,
shadowColorOpacity,
shadowInset,
]);
const generateShadow = () => {
const boxShadowValue = shadowInset
? `inset ${hShadow}px ${vShadow}px ${blurRadius}px
${spreadRadius}px rgba(${hexToRgba(
shadowColor, shadowColorOpacity
)})`
: `${hShadow}px ${vShadow}px ${blurRadius}px
${spreadRadius}px rgba(${hexToRgba(
shadowColor, shadowColorOpacity
)})`;
setBoxShadow(boxShadowValue);
};
const hexToRgba = (color, opacity) => {
const r = parseInt(color.slice(1, 3), 16);
const g = parseInt(color.slice(3, 5), 16);
const b = parseInt(color.slice(5, 7), 16);
return `${r},${g},${b},${opacity}`;
};
const copyCode = () => {
const codeElement = document.getElementById( "code" );
codeElement.select();
document.execCommand( "copy" );
setCopiedMessageVisible( true );
setTimeout(() => {
setCopiedMessageVisible( false );
}, 2000);
};
return (
<div className= "container" >
<div className= "result" >
<div id= "element"
style={{ boxShadow: boxShadow }}>
</div>
</div>
<div className= "sliders" >
<div className= "slider-wrapper" >
<label htmlFor= "h-shadow" >
Horizontal Shadow:
</label>
<input
type= "range"
id= "h-shadow"
max= "100"
min= "-100"
value={hShadow}
onChange={(e) =>
setHShadow(Number(e.target.value))}
/>
</div>
<div className= "slider-wrapper" >
<label htmlFor= "v-shadow" >
Vertical Shadow:
</label>
<input
type= "range"
id= "v-shadow"
max= "100"
min= "-100"
value={vShadow}
onChange={(e) =>
setVShadow(Number(e.target.value))}
/>
</div>
<div className= "slider-wrapper" >
<label htmlFor= "blur-radius" >
Blur Radius:
</label>
<input
type= "range"
id= "blur-radius"
max= "100"
min= "0"
value={blurRadius}
onChange={(e) =>
setBlurRadius(Number(e.target.value))}
/>
</div>
<div className= "slider-wrapper" >
<label htmlFor= "spread-radius" >
Spread Radius:
</label>
<input
type= "range"
id= "spread-radius"
max= "50"
min= "-50"
value={spreadRadius}
onChange={(e) =>
setSpreadRadius(Number(e.target.value))}
/>
</div>
<div className= "slider-wrapper" >
<label htmlFor= "shadow-color" >
Shadow Color:
</label>
<input
type= "color"
id= "shadow-color"
value={shadowColor}
onChange={(e) =>
setShadowColor(e.target.value)}
/>
</div>
<div className= "slider-wrapper" >
<label htmlFor= "shadow-color-opacity" >
Shadow Color Opacity:
</label>
<input
type= "range"
id= "shadow-color-opacity"
max= "1"
min= "0"
step= "0.1"
value={shadowColorOpacity}
onChange={(e) =>
setShadowColorOpacity(Number(e.target.value))}
/>
</div>
<div className= "input-wrapper" >
<label htmlFor= "shadow-inset" >
Inset Shadow:
</label>
<input
type= "checkbox"
id= "shadow-inset"
checked={shadowInset}
onChange={(e) =>
setShadowInset(e.target.checked)}
/>
</div>
</div>
<div className= "code-wrapper" >
<textarea
rows= "2"
id= "code"
readOnly
value={`box-shadow: ${boxShadow};`}
/>
<button onClick={copyCode}>Copy</button>
{copiedMessageVisible && (
<div className= "copy-message" >
Code Copied To Clipboard!!
</div>
)}
</div>
</div>
);
} export default App;
|
/* App.css */ * { margin : 0 ;
padding : 0 ;
box-sizing: border-box;
font-family : 'Poppins' , sans-serif ;
} body { background-color : #eee ;
} .container { background-color : #ffffff ;
padding : 30px ;
position : absolute ;
transform: translate( -50% , -50% );
left : 50% ;
top : 50% ;
width : 700px ;
border-radius: 10px ;
box-shadow: 0 20px 40px rgba( 2 , 42 , 83 , 0.2 );
} .result { padding : 150px 0 ;
} #element { height : 150px ;
width : 150px ;
position : relative ;
background-color : crimson;
margin : auto ;
border-radius: 15px ;
} .sliders { display : grid;
grid-template-columns: repeat ( 2 , 1 fr);
gap: 20px 15px ;
} .slider-wrapper { display : flex;
flex- direction : column;
justify- content : space-between;
} input[type= 'range' ] {
width : 100% ;
} .code-wrapper { display : grid;
grid-template-columns: 10 fr 2 fr;
gap: 5px ;
margin-top : 20px ;
} textarea { resize: none ;
border : 1px solid black ;
border-radius: 5px ;
padding : 15px ;
} .code-wrapper button { background-color : #0075ff ;
border-radius: 5px ;
border : none ;
color : #ffffff ;
cursor : pointer ;
} .copy-message { color : green ;
font-weight : bold ;
text-align : center ;
margin-top : 10px ;
font-family : 'Courier New' , Courier , monospace ;
} |
Steps to run the Application:
Step 1: Type the following command in the terminal:
npm start
Step 2: Type the following URL in the browser:
http://localhost:3000/
Output: