Можно ли создать glow эффект в SVG?

133
15 августа 2019, 18:40

Я изучаю SVG, и я хотел бы знать, возможно ли создать такой эффект свечения с SVG, в интерактивном режиме, как в следующем примере- наведение вызывает эффект - пример

Дело в том, что мне интересно, как заставить свет загораться и затухать, преимущество SVG было бы более точным эффектом с лучшей формой следования, и такого рода преимуществом. Возможно ли это сделать с помощью SVG?

body { 
  background-color: #222222; 
  background: repeating-linear-gradient(45deg, #2b2b2b 0%, #2b2b2b 10%, #222222 0%, #222222 50%) 0 / 15px 15px; 
} 
 
#container { 
  width: 500px; 
  margin: auto; 
} 
 
/*Neon*/ 
p { 
  text-align: center; 
  font-size: 7em; 
  margin: 20px 0 20px 0; 
} 
 
a { 
  text-decoration: none; 
  -webkit-transition: all 0.5s; 
  -moz-transition: all 0.5s; 
  transition: all 0.5s; 
} 
 
p:nth-child(1) a { 
  color: #fff; 
  font-family: Monoton; 
  -webkit-animation: neon1 1.5s ease-in-out infinite alternate; 
  -moz-animation: neon1 1.5s ease-in-out infinite alternate; 
  animation: neon1 1.5s ease-in-out infinite alternate; 
} 
 
p:nth-child(1) a:hover { 
  color: #FF1177; 
  -webkit-animation: none; 
  -moz-animation: none; 
  animation: none; 
} 
 
p:nth-child(2) a { 
  font-size: 1.5em; 
  color: #228DFF; 
  font-family: Iceland; 
} 
 
p:nth-child(2) a:hover { 
  -webkit-animation: neon2 1.5s ease-in-out infinite alternate; 
  -moz-animation: neon2 1.5s ease-in-out infinite alternate; 
  animation: neon2 1.5s ease-in-out infinite alternate; 
} 
 
p:nth-child(3) a { 
  color: #FFDD1B; 
  font-family: Pacifico; 
} 
 
p:nth-child(3) a:hover { 
  -webkit-animation: neon3 1.5s ease-in-out infinite alternate; 
  -moz-animation: neon3 1.5s ease-in-out infinite alternate; 
  animation: neon3 1.5s ease-in-out infinite alternate; 
} 
 
p:nth-child(4) a { 
  color: #B6FF00; 
  font-family: "Press Start 2P"; 
  font-size: 0.8em; 
} 
 
p:nth-child(4) a:hover { 
  -webkit-animation: neon4 1.5s ease-in-out infinite alternate; 
  -moz-animation: neon4 1.5s ease-in-out infinite alternate; 
  animation: neon4 1.5s ease-in-out infinite alternate; 
} 
 
p:nth-child(5) a { 
  color: #FF9900; 
  font-family: Audiowide; 
} 
 
p:nth-child(5) a:hover { 
  -webkit-animation: neon5 1.5s ease-in-out infinite alternate; 
  -moz-animation: neon5 1.5s ease-in-out infinite alternate; 
  animation: neon5 1.5s ease-in-out infinite alternate; 
} 
 
p:nth-child(6) a { 
  color: #BA01FF; 
  font-family: Vampiro One; 
} 
 
p:nth-child(6) a:hover { 
  -webkit-animation: neon6 1.5s ease-in-out infinite alternate; 
  -moz-animation: neon6 1.5s ease-in-out infinite alternate; 
  animation: neon6 1.5s ease-in-out infinite alternate; 
} 
 
p a:hover { 
  color: #ffffff; 
} 
/*glow for webkit*/ 
 
@-webkit-keyframes neon1 { 
  from { 
    text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #FF1177, 0 0 70px #FF1177, 0 0 80px #FF1177, 0 0 100px #FF1177, 0 0 150px #FF1177; 
  } 
  to { 
    text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #FF1177, 0 0 35px #FF1177, 0 0 40px #FF1177, 0 0 50px #FF1177, 0 0 75px #FF1177; 
  } 
} 
 
@-webkit-keyframes neon2 { 
  from { 
    text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #228DFF, 0 0 70px #228DFF, 0 0 80px #228DFF, 0 0 100px #228DFF, 0 0 150px #228DFF; 
  } 
  to { 
    text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #228DFF, 0 0 35px #228DFF, 0 0 40px #228DFF, 0 0 50px #228DFF, 0 0 75px #228DFF; 
  } 
} 
 
@-webkit-keyframes neon3 { 
  from { 
    text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #FFDD1B, 0 0 70px #FFDD1B, 0 0 80px #FFDD1B, 0 0 100px #FFDD1B, 0 0 150px #FFDD1B; 
  } 
  to { 
    text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #FFDD1B, 0 0 35px #FFDD1B, 0 0 40px #FFDD1B, 0 0 50px #FFDD1B, 0 0 75px #FFDD1B; 
  } 
} 
 
@-webkit-keyframes neon4 { 
  from { 
    text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #B6FF00, 0 0 70px #B6FF00, 0 0 80px #B6FF00, 0 0 100px #B6FF00, 0 0 150px #B6FF00; 
  } 
  to { 
    text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #B6FF00, 0 0 35px #B6FF00, 0 0 40px #B6FF00, 0 0 50px #B6FF00, 0 0 75px #B6FF00; 
  } 
} 
 
@-webkit-keyframes neon5 { 
  from { 
    text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #FF9900, 0 0 70px #FF9900, 0 0 80px #FF9900, 0 0 100px #FF9900, 0 0 150px #FF9900; 
  } 
  to { 
    text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #FF9900, 0 0 35px #FF9900, 0 0 40px #FF9900, 0 0 50px #FF9900, 0 0 75px #FF9900; 
  } 
} 
 
@-webkit-keyframes neon6 { 
  from { 
    text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #ff00de, 0 0 70px #ff00de, 0 0 80px #ff00de, 0 0 100px #ff00de, 0 0 150px #ff00de; 
  } 
  to { 
    text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #ff00de, 0 0 35px #ff00de, 0 0 40px #ff00de, 0 0 50px #ff00de, 0 0 75px #ff00de; 
  } 
} 
/*glow for mozilla*/ 
 
@-moz-keyframes neon1 { 
  from { 
    text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #FF1177, 0 0 70px #FF1177, 0 0 80px #FF1177, 0 0 100px #FF1177, 0 0 150px #FF1177; 
  } 
  to { 
    text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #FF1177, 0 0 35px #FF1177, 0 0 40px #FF1177, 0 0 50px #FF1177, 0 0 75px #FF1177; 
  } 
} 
 
@-moz-keyframes neon2 { 
  from { 
    text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #228DFF, 0 0 70px #228DFF, 0 0 80px #228DFF, 0 0 100px #228DFF, 0 0 150px #228DFF; 
  } 
  to { 
    text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #228DFF, 0 0 35px #228DFF, 0 0 40px #228DFF, 0 0 50px #228DFF, 0 0 75px #228DFF; 
  } 
} 
 
@-moz-keyframes neon3 { 
  from { 
    text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #FFDD1B, 0 0 70px #FFDD1B, 0 0 80px #FFDD1B, 0 0 100px #FFDD1B, 0 0 150px #FFDD1B; 
  } 
  to { 
    text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #FFDD1B, 0 0 35px #FFDD1B, 0 0 40px #FFDD1B, 0 0 50px #FFDD1B, 0 0 75px #FFDD1B; 
  } 
} 
 
@-moz-keyframes neon4 { 
  from { 
    text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #B6FF00, 0 0 70px #B6FF00, 0 0 80px #B6FF00, 0 0 100px #B6FF00, 0 0 150px #B6FF00; 
  } 
  to { 
    text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #B6FF00, 0 0 35px #B6FF00, 0 0 40px #B6FF00, 0 0 50px #B6FF00, 0 0 75px #B6FF00; 
  } 
} 
 
@-moz-keyframes neon5 { 
  from { 
    text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #FF9900, 0 0 70px #FF9900, 0 0 80px #FF9900, 0 0 100px #FF9900, 0 0 150px #FF9900; 
  } 
  to { 
    text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #FF9900, 0 0 35px #FF9900, 0 0 40px #FF9900, 0 0 50px #FF9900, 0 0 75px #FF9900; 
  } 
} 
 
@-moz-keyframes neon6 { 
  from { 
    text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #ff00de, 0 0 70px #ff00de, 0 0 80px #ff00de, 0 0 100px #ff00de, 0 0 150px #ff00de; 
  } 
  to { 
    text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #ff00de, 0 0 35px #ff00de, 0 0 40px #ff00de, 0 0 50px #ff00de, 0 0 75px #ff00de; 
  } 
} 
/*glow*/ 
 
@keyframes neon1 { 
  from { 
    text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #FF1177, 0 0 70px #FF1177, 0 0 80px #FF1177, 0 0 100px #FF1177, 0 0 150px #FF1177; 
  } 
  to { 
    text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #FF1177, 0 0 35px #FF1177, 0 0 40px #FF1177, 0 0 50px #FF1177, 0 0 75px #FF1177; 
  } 
} 
 
@keyframes neon2 { 
  from { 
    text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #228DFF, 0 0 70px #228DFF, 0 0 80px #228DFF, 0 0 100px #228DFF, 0 0 150px #228DFF; 
  } 
  to { 
    text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #228DFF, 0 0 35px #228DFF, 0 0 40px #228DFF, 0 0 50px #228DFF, 0 0 75px #228DFF; 
  } 
} 
 
@keyframes neon3 { 
  from { 
    text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #FFDD1B, 0 0 70px #FFDD1B, 0 0 80px #FFDD1B, 0 0 100px #FFDD1B, 0 0 150px #FFDD1B; 
  } 
  to { 
    text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #FFDD1B, 0 0 35px #FFDD1B, 0 0 40px #FFDD1B, 0 0 50px #FFDD1B, 0 0 75px #FFDD1B; 
  } 
} 
 
@keyframes neon4 { 
  from { 
    text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #B6FF00, 0 0 70px #B6FF00, 0 0 80px #B6FF00, 0 0 100px #B6FF00, 0 0 150px #B6FF00; 
  } 
  to { 
    text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #B6FF00, 0 0 35px #B6FF00, 0 0 40px #B6FF00, 0 0 50px #B6FF00, 0 0 75px #B6FF00; 
  } 
} 
 
@keyframes neon5 { 
  from { 
    text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #FF9900, 0 0 70px #FF9900, 0 0 80px #FF9900, 0 0 100px #FF9900, 0 0 150px #FF9900; 
  } 
  to { 
    text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #FF9900, 0 0 35px #FF9900, 0 0 40px #FF9900, 0 0 50px #FF9900, 0 0 75px #FF9900; 
  } 
} 
 
@keyframes neon6 { 
  from { 
    text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #ff00de, 0 0 70px #ff00de, 0 0 80px #ff00de, 0 0 100px #ff00de, 0 0 150px #ff00de; 
  } 
  to { 
    text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #ff00de, 0 0 35px #ff00de, 0 0 40px #ff00de, 0 0 50px #ff00de, 0 0 75px #ff00de; 
  } 
} 
/*REEEEEEEEEEESPONSIVE*/ 
 
@media (max-width: 650px) { 
  #container { 
    width: 100%; 
  } 
  p { 
    font-size: 3.5em; 
  } 
}
<div id="container"> 
 
    <p><a href="https://en.wikipedia.org/wiki/Red"> 
        RED 
    </a></p> 
 
    <p><a href="https://en.wikipedia.org/wiki/Blue"> 
        BLUE 
    </a></p> 
 
    <p><a href="https://en.wikipedia.org/wiki/Yellow"> 
        Yellow 
    </a></p> 
 
    <p><a href="https://en.wikipedia.org/wiki/Green"> 
        GREEN 
    </a></p> 
 
    <p><a href="https://en.wikipedia.org/wiki/Orange_(colour)"> 
        ORANGE 
    </a></p> 
 
    <p><a href="https://en.wikipedia.org/wiki/Violet_(color)"> 
        VIOLET 
    </a></p> 
 
</div> 
 
<div id="linkBack" style="position:absolute;right:0px;top:0px;background-color:#333;margin:0;width:60px;padding:5px"><a href="http://www.f-rilling.com/projects/" target="_blank" style="font-size:14px;text-decoration:none;color:#fff;padding:0 0 0 5px;font-family:sans-serif">My Site</a></div>

Answer 1

Вот базовая настройка:

<svg width="100%" height="300"> 
  <filter id="neon"> 
    <feFlood flood-color="rgb(255,255,128)" flood-opacity="0.5" in="SourceGraphic" /> 
    <feComposite operator="in" in2="SourceGraphic" /> 
    <feGaussianBlur stdDeviation="10" /> 
    <feComponentTransfer result="glow1"> 
      <feFuncA type="linear" slope="4" intercept="0" /> 
    </feComponentTransfer> 
    <feMerge> 
       <feMergeNode in="glow1" /> 
       <feMergeNode in="SourceGraphic" /> 
    </feMerge> 
  </filter> 
  <rect width="100%" height="100%" fill="black" /> 
  <text text-anchor="middle" font-size="100" font-family="sans-serif" x="50%" y="200" fill="yellow" filter="url(#neon)">NEON</text> 
</svg>

  • 'Flood-Color' - это цвет свечения.
  • stdDeviation - приблизительный размер, более высокие значения означают меньшую интенсивность
  • slope усиливает свечение и противодействует разбавлению размытия по Гауссу. flood-opacity` делает то же самое, но имеет верхний предел 1
  • если вы хотите получить свечение перед буквами, измените порядок с <feMergeNode>s
  • если вы хотите наложить несколько слоев свечения, как в примере на codepen, повторите примитивы фильтра, кроме последнего <feMerge>, и добавьте их результат в том порядке, в котором вы хотите, чтобы они <feMerge>

Источник ответа:@ccprog

Answer 2

Да, это возможно.

Основная идея состоит в том, чтобы использовать фильтр, чтобы размыть форму, закрасить размытую форму неоновым цветом, а затем поместить его за исходный текст.

Однако, чтобы добиться лучшего неонового свечения, вам нужно повозиться с цветами и интенсивностью свечения. В следующем примере я использовал серию пятен разного количества, сложенных вместе, чтобы добиться лучшего эффекта. Это похожий подход к кодовому блоку, с которым вы связаны. Но будут и другие способы сделать это.

Обратите внимание, что для простоты конкретное определение фильтра, использованное здесь, предполагает, что исходная форма (текст) будет белой. Это может не работать с другими цветами. Но фильтр можно настроить, чтобы обойти эту проблему.

svg { 
  background-color: black; 
  width: 400px; 
} 
 
text { 
  font-family: Helvetica, Arial, sansserif; 
  font-size: 100px; 
  font-weight: 900; 
  fill: white; 
  filter: url(#red-glow); 
}
<svg viewBox="0 0 400 400"> 
  <defs> 
    <filter id="red-glow" filterUnits="userSpaceOnUse" 
            x="-50%" y="-50%" width="200%" height="200%"> 
       <!-- blur the text at different levels--> 
      <feGaussianBlur in="SourceGraphic" stdDeviation="5" result="blur5"/> 
      <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur10"/> 
      <feGaussianBlur in="SourceGraphic" stdDeviation="20" result="blur20"/> 
      <feGaussianBlur in="SourceGraphic" stdDeviation="30" result="blur30"/> 
      <feGaussianBlur in="SourceGraphic" stdDeviation="50" result="blur50"/> 
      <!-- merge all the blurs except for the first one --> 
      <feMerge result="blur-merged"> 
        <feMergeNode in="blur10"/> 
        <feMergeNode in="blur20"/> 
        <feMergeNode in="blur30"/> 
        <feMergeNode in="blur50"/> 
      </feMerge> 
      <!-- recolour the merged blurs red--> 
      <feColorMatrix result="red-blur" in="blur-merged" type="matrix" 
                     values="1 0 0 0 0 
                             0 0.06 0 0 0 
                             0 0 0.44 0 0 
                             0 0 0 1 0" /> 
      <feMerge> 
        <feMergeNode in="red-blur"/>       <!-- largest blurs coloured red --> 
        <feMergeNode in="blur5"/>          <!-- smallest blur left white --> 
        <feMergeNode in="SourceGraphic"/>  <!-- original white text --> 
      </feMerge> 
    </filter> 
  </defs> 
 
  <text x="200" y="200" text-anchor="middle">RED</text> 
</svg>

Источник ответа:@aul LeBeau

READ ALSO
Что такое и для чего сделано &ldquo;var carElement = $(carHtml);&rdquo;?

Что такое и для чего сделано “var carElement = $(carHtml);”?

Я новичок в JS и jQueryЧитаю "JavaScript для детей"

119
Почему переменная undefined в функции?

Почему переменная undefined в функции?

Объясните, пожалуйста, почему в переменная a в функции makeDiv получает undefined?

126
Вынесение констант actions в отдельный файл

Вынесение констант actions в отдельный файл

Разбираю тему модульности в vuex на примере приложения с аутентификацией (статья, репозиторий на гитхабе), переписываю с нуля по-своему, сравниваю...

123