鼠标悬停元素外的反向径向渐变 SVG 动画
Reverse radialGradient SVG animation on mouseout on hovered element
我希望 radialGradient 动画仅应用于您悬停在其上的单个六边形,然后 onmouseout 我希望动画反转。
如何在悬停的六边形(不是所有六边形)上触发 radialGradient,然后在 mouseout/mouseleave 上反转动画?谢谢。
我尝试添加
{ fill: url(#myRadialGradient4);}
至
.filter-class
但是很明显,一旦发生鼠标移出,class 就会被删除,从而停止鼠标移出时的平滑反向动画。
我试过这个:
https://codepen.io/daneli84/pen/OJVZmeJ
//
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, 19, {
attr: {
stdDeviation: 0.5
}
}, {
attr: {
stdDeviation: 1
},
ease: Power1.easeInOut
});
}
flag.onmouseleave = function() {
flag.classList.remove('filter-class')
}
})
}
startPage();
/* grid styling */
use {-webkit-transition: 5s;
-webkit-transition: all 5s ease;
transition: all 5s ease;
}
use:hover {
cursor: pointer;
}
g { fill: url(#myRadialGradient4);}
#pod { -webkit-transition: all 5s ease;
transition: all 5s ease;}
text{pointer-events:none;color:white!important;}
.filter-class {
filter: url(#filter-1);
}
/* other styling */
svg {
width: 800px!important;
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/1.18.0/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.2.6/gsap.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg viewBox="0 0 100 100">
<defs>
<radialGradient id="myRadialGradient4"
fx="15%" fy="5%" r="65%"
spreadMethod="pad">
<stop offset="0%" stop-color="#fff" ></stop>
<stop offset="100%" stop-color="#50287C" ></stop>
<animate attributeName="fy" dur="2s" from="90%" to="0%" begin="pod.mouseover" end="pod.mouseout;indefinite" fill="freeze"/>
<animate attributeName="fy" dur="2s" from="0%" to="90%" begin="pod.mouseout" end="pod.mousover;indefinite" fill="freeze"/>
</radialGradient>
<filter id="innershadow" x0="20%" y0="5%" width="200%" height="200%">
<feGaussianBlur in="SourceAlpha" stdDeviation="1" result="blur"></feGaussianBlur>
<feOffset dy="0.2" dx="-0.1"></feOffset>
<feComposite in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowDiff"></feComposite>
<feFlood flood-color="#E5E5C5" flood-opacity="-15"></feFlood>
<feComposite in2="shadowDiff" operator="in"></feComposite>
<feComposite in2="SourceGraphic" operator="over" result="firstfilter"></feComposite>
<feGaussianBlur in="firstfilter" stdDeviation="0.9" result="blur2"></feGaussianBlur>
<feOffset dy="0.1" dx="0.1"></feOffset>
<feComposite in2="firstfilter" operator="arithmetic" k2="-1" k3="1" result="shadowDiff"></feComposite>
<feFlood flood-color="#fff" flood-opacity="0.5"></feFlood>
<feComposite in2="shadowDiff" operator="in"></feComposite>
<feComposite in2="firstfilter" operator="over"></feComposite>
</filter>
</linearGradient>
<linearGradient id="grad2" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:rgb(20,0,12);stop-opacity:1;" />
<stop offset="100%" style="stop-color:rgb(8,20,128);stop-opacity:1" />
</linearGradient>
<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="1" class="flag-blur" in="shadowOffsetOuter1" result="shadowBlurOuter1">
</feGaussianBlur>
<feColorMatrix values="200 150 255 0 0 255 255 200 0 0 255 0 0 0 0 0 0 0 1 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="0.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">
<g transform="translate(65, 68)" filter="url(#innershadow)">
<use xlink:href="#pod" class="h1 flag">
</use>
<text class="h1" alignment-baseline="middle" text-anchor="middle" font-family="Verdana" font-size="2.3" fill="white">TRANSPORT</text>
</g>
<g transform="translate(50, 41)" filter="url(#innershadow)">
<use xlink:href="#pod" class="h1 flag">
</use>
<text class="h1" alignment-baseline="middle" text-anchor="middle" font-family="Verdana" font-size="5" fill="white">CNI</text>
</g>
<g transform="translate(35, 50)" filter="url(#innershadow)" >
<use xlink:href="#pod" class="h1 flag">
</use>
<text class="h1" alignment-baseline="middle" text-anchor="middle" font-family="Verdana" font-size="5" fill="white">CNI</text>
</g>
<g transform="translate(65, 50)" filter="url(#innershadow)">
<use xlink:href="#pod" class="h1 flag">
</use>
<text class="h1" alignment-baseline="middle" text-anchor="middle" font-family="Verdana" font-size="5" fill="white">CNI</text>
</g>
<g transform="translate(50, 59)" filter="url(#innershadow)">
<use xlink:href="#pod" class="h1 flag">
</use>
<text class="h1" alignment-baseline="middle" text-anchor="middle" font-family="Verdana" font-size="5" fill="white">CNI</text>
</g>
</g>
</svg>
您正在制作动画的径向渐变需要与您用于其余六边形的径向渐变不同。
悬停时,您将切换到备用渐变并通过在其上调用 beginElement()
来启动 <animation>
。您可能还需要第三个 <animation>
用于反向动画。
但是这种方法比较复杂,我认为不会产生非常令人满意的结果。
一种不同的方法
我会推荐一种不同的方法。
- 将每个六边形的背景设为应用了渐变的矩形
- 然后在鼠标悬停时为该背景制作动画
- 在该矩形上使用六边形剪切路径
你可以用纯 CSS 做到这一点。而且简单多了。
注意:在下面的示例中,我删除了过滤器以使此示例更容易理解。
.pod-bg {
-webkit-transition: 5s;
-webkit-transition: all 5s ease;
transition: all 5s ease;
}
.pod-bg:hover {
transform: translate(0, -16px);
}
.h1.flag {
fill: url(#myRadialGradient4);
}
.pod-stroke {
stroke: #000000;
stroke-width: 0.1;
fill: none;
pointer-events: none;
cursor: pointer;
}
text {
pointer-events: none;
color: white;
}
/* other styling */
svg {
width: 800px!important;
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/1.18.0/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.2.6/gsap.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg viewBox="0 0 100 100">
<defs>
<radialGradient id="myRadialGradient4h" fx="15%" fy="45%" r="65%" spreadMethod="pad">
<stop offset="0%" stop-color="#fff" ></stop>
<stop offset="100%" stop-color="#50287C" ></stop>
</radialGradient>
<polygon id="pod" points="5,-9 -5,-9 -10,0 -5,9 5,9 10,0" />
<!-- a rect the same width and double the height of a pod hexagon -->
<rect id="bg-rect" x="-10" y="-9" width="20" height="36" fill="url(#myRadialGradient4h)"/>
<!-- a clipping path version of the pod hexagon -->
<clipPath id="pod-clip">
<use xlink:href="#pod"></use>
</clipPath>
</defs>
<g class="pod-wrap">
<g transform="translate(65, 68)">
<g clip-path="url(#pod-clip)">
<use xlink:href="#bg-rect" class="pod-bg"/>
</g>
<use xlink:href="#pod" class="pod-stroke"></use>
<text class="h1" alignment-baseline="middle" text-anchor="middle" font-family="Verdana" font-size="2.3" fill="white">TRANSPORT</text>
</g>
<g transform="translate(50, 41)">
<g clip-path="url(#pod-clip)">
<use xlink:href="#bg-rect" class="pod-bg"/>
</g>
<use xlink:href="#pod" class="pod-stroke"></use>
<text class="h1" alignment-baseline="middle" text-anchor="middle" font-family="Verdana" font-size="5" fill="white">CNI</text>
</g>
<g transform="translate(35, 50)">
<g clip-path="url(#pod-clip)">
<use xlink:href="#bg-rect" class="pod-bg"/>
</g>
<use xlink:href="#pod" class="pod-stroke"></use>
<text class="h1" alignment-baseline="middle" text-anchor="middle" font-family="Verdana" font-size="5" fill="white">CNI</text>
</g>
<g transform="translate(65, 50)">
<g clip-path="url(#pod-clip)">
<use xlink:href="#bg-rect" class="pod-bg"/>
</g>
<use xlink:href="#pod" class="pod-stroke"></use>
<text class="h1" alignment-baseline="middle" text-anchor="middle" font-family="Verdana" font-size="5" fill="white">CNI</text>
</g>
<g transform="translate(50, 59)">
<g clip-path="url(#pod-clip)">
<use xlink:href="#bg-rect" class="pod-bg"/>
</g>
<use xlink:href="#pod" class="pod-stroke"></use>
<text class="h1" alignment-baseline="middle" text-anchor="middle" font-family="Verdana" font-size="5" fill="white">CNI</text>
</g>
</g>
</svg>
我希望 radialGradient 动画仅应用于您悬停在其上的单个六边形,然后 onmouseout 我希望动画反转。
如何在悬停的六边形(不是所有六边形)上触发 radialGradient,然后在 mouseout/mouseleave 上反转动画?谢谢。
我尝试添加
{ fill: url(#myRadialGradient4);}
至
.filter-class
但是很明显,一旦发生鼠标移出,class 就会被删除,从而停止鼠标移出时的平滑反向动画。
我试过这个:
https://codepen.io/daneli84/pen/OJVZmeJ
//
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, 19, {
attr: {
stdDeviation: 0.5
}
}, {
attr: {
stdDeviation: 1
},
ease: Power1.easeInOut
});
}
flag.onmouseleave = function() {
flag.classList.remove('filter-class')
}
})
}
startPage();
/* grid styling */
use {-webkit-transition: 5s;
-webkit-transition: all 5s ease;
transition: all 5s ease;
}
use:hover {
cursor: pointer;
}
g { fill: url(#myRadialGradient4);}
#pod { -webkit-transition: all 5s ease;
transition: all 5s ease;}
text{pointer-events:none;color:white!important;}
.filter-class {
filter: url(#filter-1);
}
/* other styling */
svg {
width: 800px!important;
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/1.18.0/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.2.6/gsap.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg viewBox="0 0 100 100">
<defs>
<radialGradient id="myRadialGradient4"
fx="15%" fy="5%" r="65%"
spreadMethod="pad">
<stop offset="0%" stop-color="#fff" ></stop>
<stop offset="100%" stop-color="#50287C" ></stop>
<animate attributeName="fy" dur="2s" from="90%" to="0%" begin="pod.mouseover" end="pod.mouseout;indefinite" fill="freeze"/>
<animate attributeName="fy" dur="2s" from="0%" to="90%" begin="pod.mouseout" end="pod.mousover;indefinite" fill="freeze"/>
</radialGradient>
<filter id="innershadow" x0="20%" y0="5%" width="200%" height="200%">
<feGaussianBlur in="SourceAlpha" stdDeviation="1" result="blur"></feGaussianBlur>
<feOffset dy="0.2" dx="-0.1"></feOffset>
<feComposite in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowDiff"></feComposite>
<feFlood flood-color="#E5E5C5" flood-opacity="-15"></feFlood>
<feComposite in2="shadowDiff" operator="in"></feComposite>
<feComposite in2="SourceGraphic" operator="over" result="firstfilter"></feComposite>
<feGaussianBlur in="firstfilter" stdDeviation="0.9" result="blur2"></feGaussianBlur>
<feOffset dy="0.1" dx="0.1"></feOffset>
<feComposite in2="firstfilter" operator="arithmetic" k2="-1" k3="1" result="shadowDiff"></feComposite>
<feFlood flood-color="#fff" flood-opacity="0.5"></feFlood>
<feComposite in2="shadowDiff" operator="in"></feComposite>
<feComposite in2="firstfilter" operator="over"></feComposite>
</filter>
</linearGradient>
<linearGradient id="grad2" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:rgb(20,0,12);stop-opacity:1;" />
<stop offset="100%" style="stop-color:rgb(8,20,128);stop-opacity:1" />
</linearGradient>
<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="1" class="flag-blur" in="shadowOffsetOuter1" result="shadowBlurOuter1">
</feGaussianBlur>
<feColorMatrix values="200 150 255 0 0 255 255 200 0 0 255 0 0 0 0 0 0 0 1 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="0.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">
<g transform="translate(65, 68)" filter="url(#innershadow)">
<use xlink:href="#pod" class="h1 flag">
</use>
<text class="h1" alignment-baseline="middle" text-anchor="middle" font-family="Verdana" font-size="2.3" fill="white">TRANSPORT</text>
</g>
<g transform="translate(50, 41)" filter="url(#innershadow)">
<use xlink:href="#pod" class="h1 flag">
</use>
<text class="h1" alignment-baseline="middle" text-anchor="middle" font-family="Verdana" font-size="5" fill="white">CNI</text>
</g>
<g transform="translate(35, 50)" filter="url(#innershadow)" >
<use xlink:href="#pod" class="h1 flag">
</use>
<text class="h1" alignment-baseline="middle" text-anchor="middle" font-family="Verdana" font-size="5" fill="white">CNI</text>
</g>
<g transform="translate(65, 50)" filter="url(#innershadow)">
<use xlink:href="#pod" class="h1 flag">
</use>
<text class="h1" alignment-baseline="middle" text-anchor="middle" font-family="Verdana" font-size="5" fill="white">CNI</text>
</g>
<g transform="translate(50, 59)" filter="url(#innershadow)">
<use xlink:href="#pod" class="h1 flag">
</use>
<text class="h1" alignment-baseline="middle" text-anchor="middle" font-family="Verdana" font-size="5" fill="white">CNI</text>
</g>
</g>
</svg>
您正在制作动画的径向渐变需要与您用于其余六边形的径向渐变不同。
悬停时,您将切换到备用渐变并通过在其上调用 beginElement()
来启动 <animation>
。您可能还需要第三个 <animation>
用于反向动画。
但是这种方法比较复杂,我认为不会产生非常令人满意的结果。
一种不同的方法
我会推荐一种不同的方法。
- 将每个六边形的背景设为应用了渐变的矩形
- 然后在鼠标悬停时为该背景制作动画
- 在该矩形上使用六边形剪切路径
你可以用纯 CSS 做到这一点。而且简单多了。
注意:在下面的示例中,我删除了过滤器以使此示例更容易理解。
.pod-bg {
-webkit-transition: 5s;
-webkit-transition: all 5s ease;
transition: all 5s ease;
}
.pod-bg:hover {
transform: translate(0, -16px);
}
.h1.flag {
fill: url(#myRadialGradient4);
}
.pod-stroke {
stroke: #000000;
stroke-width: 0.1;
fill: none;
pointer-events: none;
cursor: pointer;
}
text {
pointer-events: none;
color: white;
}
/* other styling */
svg {
width: 800px!important;
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/1.18.0/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.2.6/gsap.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg viewBox="0 0 100 100">
<defs>
<radialGradient id="myRadialGradient4h" fx="15%" fy="45%" r="65%" spreadMethod="pad">
<stop offset="0%" stop-color="#fff" ></stop>
<stop offset="100%" stop-color="#50287C" ></stop>
</radialGradient>
<polygon id="pod" points="5,-9 -5,-9 -10,0 -5,9 5,9 10,0" />
<!-- a rect the same width and double the height of a pod hexagon -->
<rect id="bg-rect" x="-10" y="-9" width="20" height="36" fill="url(#myRadialGradient4h)"/>
<!-- a clipping path version of the pod hexagon -->
<clipPath id="pod-clip">
<use xlink:href="#pod"></use>
</clipPath>
</defs>
<g class="pod-wrap">
<g transform="translate(65, 68)">
<g clip-path="url(#pod-clip)">
<use xlink:href="#bg-rect" class="pod-bg"/>
</g>
<use xlink:href="#pod" class="pod-stroke"></use>
<text class="h1" alignment-baseline="middle" text-anchor="middle" font-family="Verdana" font-size="2.3" fill="white">TRANSPORT</text>
</g>
<g transform="translate(50, 41)">
<g clip-path="url(#pod-clip)">
<use xlink:href="#bg-rect" class="pod-bg"/>
</g>
<use xlink:href="#pod" class="pod-stroke"></use>
<text class="h1" alignment-baseline="middle" text-anchor="middle" font-family="Verdana" font-size="5" fill="white">CNI</text>
</g>
<g transform="translate(35, 50)">
<g clip-path="url(#pod-clip)">
<use xlink:href="#bg-rect" class="pod-bg"/>
</g>
<use xlink:href="#pod" class="pod-stroke"></use>
<text class="h1" alignment-baseline="middle" text-anchor="middle" font-family="Verdana" font-size="5" fill="white">CNI</text>
</g>
<g transform="translate(65, 50)">
<g clip-path="url(#pod-clip)">
<use xlink:href="#bg-rect" class="pod-bg"/>
</g>
<use xlink:href="#pod" class="pod-stroke"></use>
<text class="h1" alignment-baseline="middle" text-anchor="middle" font-family="Verdana" font-size="5" fill="white">CNI</text>
</g>
<g transform="translate(50, 59)">
<g clip-path="url(#pod-clip)">
<use xlink:href="#bg-rect" class="pod-bg"/>
</g>
<use xlink:href="#pod" class="pod-stroke"></use>
<text class="h1" alignment-baseline="middle" text-anchor="middle" font-family="Verdana" font-size="5" fill="white">CNI</text>
</g>
</g>
</svg>