Related
I'm trying to animate along a path based on this post: move SVG group on path trail based on percentage of whole path trail
It works beautifully in all browsers but Internet Explorer. I've read lots of posts about the lack of support in IE but I still have enough users that use it that I need to consider it. Can I convert this to another method?
Here is my code (simplified icon here, more complex icon in CodePen):
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Jeep Test 5</title>
<style type="text/css">
#carRight{visibility: visible;}
#carLeft{visibility: hidden;}
#carRightIsoBack {visibility: hidden;}
#carRightIsoFront {visibility: hidden;}
#carLeftIsoBack {visibility: hidden;}
#carLeftIsoFront {visibility: hidden;}
</style>
<script src="../SiteAssets/js/jquery-1.8.1.min.js"></script>
</head>
<body>
<input type="range" id="theRange" value="0"/>
<div id="percentage"></div>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 459 257" style="enable-background:new 0 0 459 257;" xml:space="preserve">
<style type="text/css">
#percentage{border:1px solid red; padding: 5px;}
svg{border:1px solid;overflow:visible; width:95vh; display:block; margin:1em auto;}
.st0{fill:none;stroke:#F1EA0D;stroke-width:5;stroke-miterlimit:10;}
.st1{fill:#1A1A1A;}
.st2{fill:#FF0000;}
</style>
<defs>
<g id="carRight" transform="translate(-90, -240)">
<circle class="st3" cx="134.5" cy="215.2" r="12"/>
</g>
</defs>
<path id="path" class="st0" d="M20.5,249.5c0,0,27,0,54,1s47.36-5,61-13c40.32-23.66,50.1-50.05,3-82c-35.12-23.83-65-19-97-44
c-22.4-17.5-21.92-28.85-1-41c31-18,101.15-43.54,158-27c55,16,48,30,45,61s-8,39-13,60s5.09,40.12,17,56c18,24,56.49,26.8,81,17
c10-4,33-17,29-48c-3.36-26.03-15-34-30-53s-4.97-25.67,7-27c18-2,32.57-1.81,59,7c24,8,54,9,65,4s1-22-9-32s-14-17-30-24
s-34-8-53-3s-28,11-44,14s-26-10-18-25s22-28,42-38c4-2,9-4,9-4"/>
<use id="theUse_car_right" transform="translate(0,20)" xlink:href="#carRight" />
</svg>
<script type="text/javascript">
let pathlength = path.getTotalLength();
let pos = path.getPointAtLength(0);
theUse_car_right.setAttributeNS(null,"x", pos.x);
theUse_car_right.setAttributeNS(null,"y", pos.y);
document.getElementById("percentage").textContent = "Completion=0%";
theRange.addEventListener("input", ()=>{
let perc = parseInt(theRange.value);
let leng = pathlength * perc/100;
pos = path.getPointAtLength(leng);
theUse_car_right.setAttributeNS(null,"x", pos.x);
theUse_car_right.setAttributeNS(null,"y", pos.y);
document.getElementById("percentage").textContent = "Completion=" + perc + "%";
})
</script>
</body>
</html>
Demo'd here: https://codepen.io/mrsgorgon/pen/ExNbEPN
The issue of your code is in the JavaScript.
Arrow function => is not supported in IE. You need to use the traditional function expression.
The input event on input range won't be triggerrd in IE. You need to use change event to monitor the change of the input range. But change event won't be triggered in other modern browsers, so we need to combine the two event handlers.
I define the function as moveit and combine the two event handlers like this:
<input type="range" id="theRange" value="0" oninput="moveit()" onchange="moveit()" />
The complete sample code is like this:
let pathlength = path.getTotalLength();
let pos = path.getPointAtLength(0);
theUse_car_right.setAttributeNS(null, "x", pos.x);
theUse_car_right.setAttributeNS(null, "y", pos.y);
document.getElementById("percentage").textContent = "Completion=0%";
function moveit() {
let perc = parseInt(theRange.value);
let leng = pathlength * perc / 100;
pos = path.getPointAtLength(leng);
theUse_car_right.setAttributeNS(null, "x", pos.x);
theUse_car_right.setAttributeNS(null, "y", pos.y);
document.getElementById("percentage").textContent = "Completion=" + perc + "%";
}
#carRight {
visibility: visible;
}
#carLeft {
visibility: hidden;
}
#carRightIsoBack {
visibility: hidden;
}
#carRightIsoFront {
visibility: hidden;
}
#carLeftIsoBack {
visibility: hidden;
}
#carLeftIsoFront {
visibility: hidden;
}
#percentage {
border: 1px solid red;
padding: 5px;
}
svg {
border: 1px solid;
overflow: visible;
width: 95vh;
display: block;
margin: 1em auto;
}
.st0 {
fill: none;
stroke: #F1EA0D;
stroke-width: 5;
stroke-miterlimit: 10;
}
.st1 {
fill: #1A1A1A;
}
.st2 {
fill: #FF0000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<input type="range" id="theRange" value="0" oninput="moveit()" onchange="moveit()" />
<div id="percentage"></div>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 459 257" style="enable-background:new 0 0 459 257;" xml:space="preserve">
<defs>
<g id="carRight" transform="translate(-90, -240)">
<circle class="st3" cx="134.5" cy="215.2" r="12" />
</g>
</defs>
<path id="path" class="st0" d="M20.5,249.5c0,0,27,0,54,1s47.36-5,61-13c40.32-23.66,50.1-50.05,3-82c-35.12-23.83-65-19-97-44
c-22.4-17.5-21.92-28.85-1-41c31-18,101.15-43.54,158-27c55,16,48,30,45,61s-8,39-13,60s5.09,40.12,17,56c18,24,56.49,26.8,81,17
c10-4,33-17,29-48c-3.36-26.03-15-34-30-53s-4.97-25.67,7-27c18-2,32.57-1.81,59,7c24,8,54,9,65,4s1-22-9-32s-14-17-30-24
s-34-8-53-3s-28,11-44,14s-26-10-18-25s22-28,42-38c4-2,9-4,9-4" />
<use id="theUse_car_right" transform="translate(0,20)" xlink:href="#carRight" />
</svg>
I am creating animated calligraphy using the stroke-dashoffset technique, applying the stroke as an animated mask on top of an SVG. This works on most browsers, but I would like to apply the same mask on top of a PNG instead. That way, even if the browser has trouble with both SVG and mask (IE...), at least it will just display the PNG as-is.
Here is a codepen of the working calligraphy with pure SVG:
https://codepen.io/benviatte/pen/PMzmYB
Here is the codepen of the non-working calligraphy where I put an image instead of the base SVG. It just displays blank, unless I remove the "mask-image" property, in which case it doesn't animate:
https://codepen.io/benviatte/pen/eqzWzJ
Finally, here is the code of the PNG version that just displays blank:
HTML:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 354.33071 248.03149">
<mask id="mask" maskUnits="userSpaceOnUse">
<path d="M 92.81613,118.88531 C 92.79077,113.54067 89.77774,108.7899 89.336626,103.42689 96.06007,89.146492 85.818314,62.350762 62.06357,80.661632 c -5.787226,7.87329 -12.023557,16.43904 -12.784729,26.500038 -0.404099,5.34115 3.084547,9.85663 7.361464,12.76814 9.170344,6.24271 20.057653,10.0779 27.888503,18.14154 4.373535,4.50356 2.810446,11.25662 2.004789,16.78827 -1.093846,7.51033 -10.89645,19.36241 -18.314927,21.84098 -9.433311,3.81749 -18.936726,-10.31651 -25.709437,-30.06406" />
</mask>
</svg>
<img src="http://thehermitcrab.org/imgs/S2.png"/>
CSS:
mask path {
fill: none;
stroke: white;
stroke-width: 22;
stroke-dasharray: 237 237;
stroke-dashoffset: 237;
animation: brush 1s cubic-bezier(.6,.3,.3,.9);
animation-fill-mode: forwards;
}
#keyframes brush {
0% { stroke-dashoffset: 237; }
20% { stroke-dashoffset: 237; }
80% { stroke-dashoffset: 0; }
100% { stroke-dashoffset: 0; }
}
img, svg{
width: 300px;
position: absolute;
top: 0;
left: 0;
}
img {
-webkit-mask-image: url(#mask);
mask-image: url(#mask);
}
Thank you so much!!!
You can fill the masked path with an image like so:
I hope this is what you were asking.
mask path {
fill: none;
stroke: white;
stroke-width: 22;
stroke-dasharray: 237 237;
stroke-dashoffset: 237;
animation: brush 5s cubic-bezier(.6,.3,.3,.9);
animation-fill-mode: forwards;
}
#keyframes brush {
0% { stroke-dashoffset: 237; }
20% { stroke-dashoffset: 237; }
80% { stroke-dashoffset: 0; }
100% { stroke-dashoffset: 0; }
}
svg {
width: 300px;
height: 300px;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 354.33071 248.03149">
<defs>
<pattern id="img" patternUnits="userSpaceOnUse" width="100" height="100">
<image xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/darwin300.jpg" x="0" y="0" width="100" height="100" />
</pattern>
<mask id="mask" maskUnits="userSpaceOnUse">
<path d="M 92.81613,118.88531 C 92.79077,113.54067 89.77774,108.7899 89.336626,103.42689 96.06007,89.146492 85.818314,62.350762 62.06357,80.661632 c -5.787226,7.87329 -12.023557,16.43904 -12.784729,26.500038 -0.404099,5.34115 3.084547,9.85663 7.361464,12.76814 9.170344,6.24271 20.057653,10.0779 27.888503,18.14154 4.373535,4.50356 2.810446,11.25662 2.004789,16.78827 -1.093846,7.51033 -10.89645,19.36241 -18.314927,21.84098 -9.433311,3.81749 -18.936726,-10.31651 -25.709437,-30.06406" />
</mask>
</defs>
<path mask="url(#mask)" fill="url(#img)" d="m 84.347106,72.730822 c -6.700057,0.41349 -13.536192,0.895 -20.004337,2.74122 -8.269143,3.35101 -15.144649,10.28592 -18.335113,18.62393 -1.745059,4.7139 -2.424554,9.829858 -1.055133,14.737138 0.971246,7.85177 6.591277,14.03623 12.594733,18.68723 4.899213,3.10976 10.516595,4.80935 15.88174,6.85728 3.598383,2.16843 7.853428,4.63947 9.276845,8.8059 0.995595,7.43174 -3.283258,14.41911 -7.577125,20.14167 -2.859338,3.25041 -7.082956,5.7682 -11.428016,6.06759 -2.76877,-0.88985 -4.676886,-3.50515 -6.467732,-5.66664 -0.8438,-2.84582 -0.503218,-6.25249 -2.88424,-8.50648 -2.356943,-2.51972 -6.848373,-3.89583 -9.901785,-1.90687 -1.783614,1.60567 -1.978665,4.29248 -0.431156,6.14634 0.628015,2.58248 4.330039,1.06794 4.996601,3.36938 -0.140661,3.29536 -3.415289,5.93264 -3.011822,9.2671 1.471965,3.46591 3.011956,7.79888 7.009623,8.93583 2.779476,2.56577 6.811098,1.17952 10.184223,1.15628 7.753544,-0.82418 15.439311,-4.27064 20.776362,-10.01337 3.918376,-5.23506 6.686713,-11.29125 9.19183,-17.29292 0.679648,-4.33031 0.214675,-8.76706 0.319579,-13.12674 -4.685098,-7.44203 -12.013326,-12.8652 -20.16128,-15.99596 -4.833407,-2.57162 -11.582728,-2.85294 -14.441374,-8.15604 -4.638062,-7.39166 -5.929022,-17.810038 -0.40541,-25.114328 3.085422,-4.36163 7.883758,-8.71782 13.633176,-8.01843 4.028691,-0.21996 8.250498,0.0932 11.561718,2.63603 2.904262,1.44386 1.746882,5.41774 0.879004,7.79388 -2.021102,4.66617 -3.832398,9.978878 -2.737189,15.088588 0.62468,1.45971 1.572558,3.02113 2.790336,3.97665 2.563411,1.00256 5.41245,0.65028 7.526616,-1.1464 2.393394,-1.33047 7.187979,-2.70727 6.367699,-6.21466 -1.29931,-1.67133 -4.660058,0.16306 -5.006198,-2.59652 -0.718456,-6.014858 3.485958,-11.212508 3.846428,-17.152098 0.2919,-3.79706 1.28679,-8.45196 -1.339374,-11.64839 -3.199638,-2.55035 -7.777181,-2.43209 -11.649229,-2.47619 z" />
</svg>
I tried to adapt a codepen thing for waves with svgs.
Works just fine in Chrome, Safari and Edge, but not in Firefox (and IE, but I don't care too much about that).
I suspect some Syntax problem with the svg. The animation works just fine, but the svgs are not displayed correctly. In Firefox it's just a straight line instead of waves.
Anyone out there, that has an idea about that?
Thanks a lot in advance.
.waves {
width: 100%;
height: 7em;
position: relative;
overflow: hidden;
background-color: #f6f9fc;
}
.wave
{
width:calc( 100% + 4em );
height:100%;
position:absolute;
left:-2em;
background:bottom center repeat-x;
animation-iteration-count:infinite;
animation-timing-function:linear;
}
/* Individual wave layers */
.wave_1
{
animation-name:wave_1;
animation-duration:3400ms;
animation-delay:-1200ms;
z-index:2;
opacity: 1;
background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="600" height="2000" viewBox="0 0 600 2000"><path fill-rule="evenodd" clip-rule="evenodd" fill="#fff" d="M600 2000c-100.8 0-141.6-39.892-240-39.892S98.4 2000 0 2000V0h6000v2000z"/></svg>');
background-position:bottom left;
background-color: #e0e7f1;
top: -3em;
}
.wave_2
{
z-index:1;
opacity: 1;
background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="600" height="2000" viewBox="0 0 600 2000"><path fill-rule="evenodd" clip-rule="evenodd" fill="#e0e7f1" d="M600 2000c-100.8 0-141.6-39.892-240-39.892S98.4 2000 0 2000V0h6000v2000z"/></svg>');
background-position:bottom left;
background-color: #245aa6;
top: 0em;
}
#keyframes wave_1
{
from { transform: rotate(0deg) translatey(-0.61em) rotate(0deg) ; }
to { transform: rotate(360deg) translatey(-0.61em) rotate(-360deg) ; }
}
<div class="waves">
<div class="wave wave_1"></div>
<div class="wave wave_2"></div>
</div>
h1 everyone, i'm trying to make a cross-browser animation based on svg mask for svg elements. At first, I caught a bug with css, in firefox mask doesn't work with css 'width' and 'height', only with inline properties. So, next question - how to animate mask for firefox, nothing harder that 'width resize'. https://codepen.io/flyby/pen/KmYOgb
<div id='cont'>
<svg>
<defs>
<mask id='rectMask' maskUnits='userSpaceOnUse' maskContentUnits='userSpaceOnUse' transform='scale(1)'>
<rect x='0' y='0' id='maskRect' width='700' height='850'/>
</mask>
</defs>
<path id='maskedPath' d='m 0,0 l 650,0 -100,850 -550,0 z' mask='url(#rectMask)'/>
<path id='riverPath' d='m 653,0 l -100,850' mask='url(#rectMask)'/>
<path id='notMaskedPath' d='m 655,0 l 650,0 0,850 -750,0 z'/>
</svg>
</div>
CSS:
body {
margin:0;
padding:0;
overflow:hidden;
}
#cont {
width:100vw;
height:100vh;
background-color:rgb(50,50,50);
}
svg {
width:100%;
height:100%;
}
#maskedPath {
stroke:none;
fill:rgb(230,230,230);
}
#notMaskedPath {
stroke:none;
fill:rgb(230,230,230);
}
#riverPath {
stroke:rgb(50,160,240);
stroke-width:8;
fill:none;
}
#maskRect {
width:0px;
height:850px;
fill:white;
stroke:none;
animation: resize 3s linear infinite;
}
#-moz-keyframes resize {
50% {width: 700px !important;}
0%,100% {width: 0px !important;}
}
Like you have discovered, your can't (yet) set geometric properties, like width and height of SVG elements in Firefox. It's not a bug. It's just an SVG 2 thing that Firefox has not implemented yet, but Chrome has.
The solution is to use the built-in SVG ("SMIL") animation elements, instead of CSS animation.
body {
margin:0;
padding:0;
overflow:hidden;
}
#cont {
width:100vw;
height:100vh;
background-color:rgb(50,50,50);
}
svg {
width:100%;
height:100%;
}
#maskedPath {
stroke:none;
fill:rgb(230,230,230);
}
#notMaskedPath {
stroke:none;
fill:rgb(230,230,230);
}
#riverPath {
stroke:rgb(50,160,240);
stroke-width:8;
fill:none;
}
#maskRect {
fill:white;
stroke:none;
}
<!--this animation doesn't work in FIREFOX, and not tested in IE11 ad Edge YET, WILL BE FIXED SOON (I HOPE)-->
<div id='cont'>
<svg>
<defs>
<mask id='rectMask' maskUnits='userSpaceOnUse' maskContentUnits='userSpaceOnUse' transform='scale(1)'>
<rect x='0' y='0' width="0" height="850" id='maskRect'>
<animate attributeName="width"
keyTimes="0; 0.4; 0.5; 1"
values="0; 670; 670; 0"
dur="4s" repeatCount="indefinite"/>
</rect>
</mask>
</defs>
<path id='maskedPath' d='m 0,0 l 650,0 -100,850 -550,0 z' mask='url(#rectMask)'/>
<path id='riverPath' d='m 653,0 l -100,850' mask='url(#rectMask)'/>
<path id='notMaskedPath' d='m 655,0 l 650,0 0,850 -750,0 z'/>
</svg>
</div>
I have a light gray SVG button in a label with black background. The SVG button seems 'blurry' / 'bolder' on the edges. This is not something I can notice when using a white background.
I suppose it is related to the high contrast between background and asset colour.
How can I get this better?
Btw, I'm using the SVG has background image of a div and respecting the original size of image.
CSS code of the div containing the SVG asset:
position: absolute;
z-index: 2;
width: 42px;
height: 42px;
padding: 0px;
border: 0px;
top: 20px;
right: 20px;
background-image: url(/assets/images/icons/create-document-close-button.svg);
background-repeat: no-repeat;
background-color: transparent;
background-size: 36px 36px;
background-position: center center;
transition: all 100ms ease-in-out;
The SVG code:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="36px" height="36px" viewBox="0 0 36 36" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs></defs>
<g id="States" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Buttons-&-States-(Documents-Steps)" transform="translate(-104.000000, -138.000000)">
<g id="Close-Button" transform="translate(104.000000, 138.000000)">
<g>
<circle id="circle" fill="#E9EEF2" cx="18" cy="18" r="18"></circle>
<polygon id="X" fill="#9FADB5" transform="translate(17.868000, 17.808000) rotate(-45.000000) translate(-17.868000, -17.808000) " points="16.968 23.616 18.768 23.616 18.768 18.672 23.736 18.672 23.736 16.944 18.768 16.944 18.768 12 16.968 12 16.968 16.944 12 16.944 12 18.672 16.968 18.672"></polygon>
</g>
</g>
</g>
</g>