0

I have a container which has its borders moving around it which works fine. The last thing I need to do is to achieve a very bulb like glow effect. I will post an image of it below. I am not sure how to achieve that:

Desired glow effect

So far I have tried the following code where I set the color and the blur and brigtness effect but those do not achieve what I want. I am not sure how to apply multiple layers over each other as that might be possible the way to go. I hope you can help me out.

import React, { useState } from 'react';
import styled, { createGlobalStyle, keyframes } from 'styled-components';

const GlobalStyle = createGlobalStyle`
  *, *::before, *::after {
    box-sizing: border-box;
  }

  body {
    display: grid;
    place-content: center;
    gap: 2rem;
    min-height: 100vh;
    background-image: conic-gradient(
      at 125% 50%,
      #b78cf7,
      #ff7c94,
      #ffcf0d,
      #ff7c94,
      #b78cf7
    );
    font-family: system-ui;
  }
`;

const continuousDashOffsetAnimation = keyframes`
  from {
    stroke-dashoffset: 0;
  }
  to {
    stroke-dashoffset: -50px;
  }
`;

const Box = styled.div`
  cursor: pointer;
  font-size: 2rem;
  font-family: inherit;
  font-weight: 700;
  color: hsl(320, 40%, 40%);
  background-color: hsl(349 100% 95%);
  width: 510px;
  height: 100px;
  border: 0;
  border-radius: 1.25rem;
  display: flex;
  align-items: center;
  justify-content: center;

  --glow-line-color: #FFD600;
  --glow-line-thickness: 2px;
  --glow-line-length: ${props => (props.speed > 15 ? "30px" : "10px")};
  --glow-blur-color: #FFD600;
  --glow-blur-size: 5px;
  --glow-offset: 0px;
  --animation-speed: ${props => (props.speed > 15 ? "500ms" : "1500ms")};
  --container-offset: 100px;
  --intense-glow-size: 15px;
  position: relative;

  .glow-container {
    pointer-events: none;
    position: absolute;
    inset: calc(var(--container-offset) / -2);
    width: calc(100% + var(--container-offset));
    height: calc(100% + var(--container-offset));
    opacity: 1;
  }

  .glow-blur, .glow-line {
    width: calc(100% - var(--container-offset) + var(--glow-offset));
    height: calc(100% - var(--container-offset) + var(--glow-offset));
    x: calc((var(--container-offset) / 2) + calc(var(--glow-offset) / -2));
    y: calc((var(--container-offset) / 2) + calc(var(--glow-offset) / -2));
    fill: transparent;
    stroke: black;
    stroke-width: 5px;
    stroke-dasharray: var(--glow-line-length) calc(50px - var(--glow-line-length));
    animation: ${continuousDashOffsetAnimation} var(--animation-speed) linear infinite;
  }

  .glow-line {
    stroke: var(--glow-line-color);
    stroke-width: var(--glow-line-thickness);
  }

  .glow-blur {
    filter: 
      blur(var(--glow-blur-size)) 
      brightness(5.5); 
    stroke: var(--glow-blur-color);
    stroke-width: var(--glow-blur-size);
  }

  &:after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    border-radius: inherit;
    background: radial-gradient(ellipse at center, rgba(255,214,0,0.6) 0%, transparent 70%);
    filter: blur(var(--intense-glow-size));
    z-index: -1;
  }
`;

const App = () => {
  const [speed, setSpeed] = useState(10); // Initially set to 10 as an example
  
  return (
    <>
      <GlobalStyle />
      <Box speed={speed}>
        Hi there 
        <svg className="glow-container">
          <rect rx="1.25rem" pathLength="100" strokeLinecap="round" className="glow-blur"></rect>
          <rect rx="1.25rem" pathLength="100" strokeLinecap="round" className="glow-line"></rect>
        </svg>
        <button onClick={() => setSpeed(prevSpeed => (prevSpeed > 15 ? 10 : 20))}>
          Toggle Speed
        </button>
      </Box>
    </>
  );
}

export default App;
Angel Hadzhiev
  • 664
  • 2
  • 6
  • 20

1 Answers1

0
import React from 'react';
import styled, { createGlobalStyle, keyframes } from 'styled-components';

const GlobalStyle = createGlobalStyle`
  *, *::before, *::after {
    box-sizing: border-box;
  }

  body {
    display: grid;
    place-content: center;
    gap: 2rem;
    min-height: 100vh;
    background-image: conic-gradient(
      at 125% 50%,
      #b78cf7,
      #ff7c94,
      #ffcf0d,
      #ff7c94,
      #b78cf7
    );
    font-family: system-ui;
  }
`;

const Container = styled.div`
  position: relative;
  width: 200px;
  height: 200px;
`;

const GlowEffectContainer = styled.div`
  position: absolute;
  top: -20px;
  left: -20px;
  right: -20px;
  bottom: -20px;
  border-radius: 50%;
  background: radial-gradient(
    ellipse,
    rgba(255, 255, 255, 0.15),
    transparent 50%
  );
  opacity: 0.8;
  filter: blur(30px);
  animation: rotate 2s linear infinite, pulse 2s ease-in-out infinite;
`;

const Svg = styled.svg`
  display: block;
`;

const continuousDashOffsetAnimation = keyframes`
  from {
    stroke-dashoffset: 0;
  }
  to {
    stroke-dashoffset: -50px;
  }
`;

const GlowEffect = () => {
  return (
    <div>
      <GlobalStyle />
      <Container>
        <Svg width="200" height="100" xmlns="http://www.w3.org/2000/svg">
          <rect x="10" y="10" width="180" height="80" fill="blue" />
        </Svg>
        <GlowEffectContainer />
      </Container>
    </div>
  );
};

export default GlowEffect;

I've wrapped your existing SVG inside a Container component, and then added a GlowLayer component as an absolutely positioned element around the Svg. This GlowLayer applies the radial gradient and blur to achieve the desired glow effect.

You can adjust the positioning, size, blur, opacity, and other properties of the GlowLayer to achieve the exact look you want for the bulb-like glow effect. export default GlowEffect;

Rai Hassan
  • 599
  • 1
  • 12