javascriptsvgsvg-filtersgsapsvg-animationelements

Trigger Tween for individually hovered over SVG hexagons


I want the Tween animation to be triggered for the hexagon you are hovering over only. At the moment only the top hexagon triggers the blurred reddish outline animation around the hexagon.

Each individual hexagon should have the filter applied to itself only.

Thanks in advance for advice.

https://codepen.io/daneli84/pen/OJVZmeJ

HTML

    <svg viewBox="0 0 100 100">
  <defs>
         <filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="filter-1">
            <feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
            <feGaussianBlur stdDeviation="0" class="flag-blur" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
            <feColorMatrix values="0 0 0 0 1   0 0 0 0 0   0 0 0 0 0  0 0 0 0.4 0" in="shadowBlurOuter1" type="matrix" result="shadowMatrixOuter1"></feColorMatrix>
            <feMerge>
                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
                <feMergeNode in="SourceGraphic"></feMergeNode>
            </feMerge>
        </filter>

    <g id="pod">
      <polygon stroke="#000000" stroke-width="1" points="5,-9 -5,-9 -10,0 -5,9 5,9 10,0" />
    </g>

        <!-- a transparent grey drop-shadow that blends with the background colour -->

  </defs>

  <g class="pod-wrap" ">
    <use xlink:href="#pod" transform="translate(50, 41)" class="flag" />
    <use xlink:href="#pod" transform="translate(35, 50)" class="flag"  />
    <use xlink:href="#pod" transform="translate(65, 50)" class="flag" />
    <use xlink:href="#pod" transform="translate(50, 59)" class="flag"  />
  </g>
</svg>

<a href="http://www.mathopenref.com/coordpolycalc.html" target="_blank">point calculator</a>

CSS

/* grid styling */
use {
  transition: 0.1s;
  cursor: pointer;
  fill: transparent;
}

use {filter: url(#filter-1);}




/* other styling */
svg {
  width: 700px;
  flex: 1;
}
body {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  margin: 0;
  height: 100vh;
  font-weight: 700;
  font-family: sans-serif;
}
a {
  color: #ccc;
  padding: 10px;
  text-decoration: none;
  transition: color 0.4s;
}

JS

// 
var flagBlur = document.querySelector('.flag-blur');
var flag = document.querySelector('.flag');



function startPage() {

  // 
  flag.onmouseover = function() {
    TweenMax.to(flagBlur, 0.9, {
      attr:{stdDeviation: 0.9},
      ease: Power1.easeInOut
    });
  };

  flag.onmouseleave = function() {
    TweenMax.to(flagBlur, 0.35, {
      attr:{stdDeviation: 0},
      ease: Power1.easeInOut
    });
  };
}

startPage();

Solution

  • There are 2 corrections:

    1. Use document.querySelectorAll(".flag") to add a listener on all four hexagons.

    2. Use a separate class for the blur filter and add/remove it to the hexagon you are interacting with. Also remove transition from use

    Check the code below:

    // переменные
    var flagBlur = document.querySelector('.flag-blur');
    var flags = document.querySelectorAll('.flag');
    
    // наведение курсора на флаги
    function startPage() {
      flags.forEach(flag => {
        flag.onmouseover = function() {
          flag.classList.add('filter-class')
          TweenMax.fromTo(flagBlur, 0.9, {
            attr: {
              stdDeviation: 0
            }
          }, {
            attr: {
              stdDeviation: 0.9
            },
            ease: Power1.easeInOut
          });
        }
    
        flag.onmouseleave = function() {
          flag.classList.remove('filter-class')
        }
      })
    }
    
    startPage();
    /* grid styling */
    use {
      cursor: pointer;
      fill: transparent;
    }
    
    .filter-class {
      filter: url(#filter-1);
    }
    
    /* other styling */
    svg {
      width: 700px;
      flex: 1;
    }
    
    body {
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: column;
      margin: 0;
      height: 100vh;
      font-weight: 700;
      font-family: sans-serif;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.2.4/gsap.min.js"></script>
    <svg viewBox="0 0 100 100">
      <defs>
             <filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="filter-1">
                <feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
                <feGaussianBlur stdDeviation="0" class="flag-blur" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
                <feColorMatrix values="0 0 0 0 1   0 0 0 0 0   0 0 0 0 0  0 0 0 0.4 0" in="shadowBlurOuter1" type="matrix" result="shadowMatrixOuter1"></feColorMatrix>
                <feMerge>
                    <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
                    <feMergeNode in="SourceGraphic"></feMergeNode>
                </feMerge>
            </filter>
        
        <g id="pod">
          <polygon stroke="#000000" stroke-width="1" points="5,-9 -5,-9 -10,0 -5,9 5,9 10,0" />
        </g>
            
            <!-- a transparent grey drop-shadow that blends with the background colour -->
            
      </defs>
      
      <g class="pod-wrap">
        <use xlink:href="#pod" transform="translate(50, 41)" class="flag h1" />
        <use xlink:href="#pod" transform="translate(35, 50)" class="flag h2"  />
        <use xlink:href="#pod" transform="translate(65, 50)" class="flag h3" />
        <use xlink:href="#pod" transform="translate(50, 59)" class="flag h4"  />
      </g>
    </svg>