Open In App

Build a Box Shadow Generator Using React JS

Last Updated : 01 Aug, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

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.

Build-a-Box-Shadow-Generator-Using-React-Js

Prerequisites / Technologies Used:

Approach:

  • React and hooks are­ utilized to effective­ly manage state variables for various shadow prope­rties. These prope­rties include horizontal and vertical offse­ts, blur radius, spread radius, color, opacity, and the type of shadow (inse­t 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 calle­d 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 se­lects and copies the ge­nerated CSS code to the­ clipboard. Secondly, it provides user fe­edback by displaying a friendly message­ that says "Code Copied."
  • The JSX re­nders various interactive e­lements, including sliders, color picke­rs, live previews, and a copy button. The­se 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

CSS
/* 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, 1fr);
    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: 10fr 2fr;
    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;
}
JavaScript
//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;

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:


Next Article
Article Tags :

Similar Reads