the codepen link
Hi everyone
I'm having issue with my cabins rotation.
they tend to go outside the wheel
/*svg colors */
.cls-1 {
fill: #e8f3e2;
}
.cls-2 {
fill: #faf4a8;
}
.cls-3 {
fill: #cac277;
}
.cls-4 {
fill: #f3ca76;
}
.cls-5 {
fill: #fdf387;
}
.cls-6 {
fill: #c2e4d8;
}
.cls-7 {
fill: #aedccd;
}
.cls-8 {
opacity: 0.5;
}
.cls-10,
.cls-16,
.cls-17,
.cls-22,
.cls-32,
.cls-38,
.cls-39,
.cls-48,
.cls-50,
.cls-56,
.cls-9 {
fill: none;
}
.cls-16,
.cls-17,
.cls-9 {
stroke: #dab6c4;
}
.cls-10,
.cls-18,
.cls-19,
.cls-32,
.cls-38,
.cls-39,
.cls-48,
.cls-50,
.cls-56,
.cls-9 {
stroke-miterlimit: 10;
}
.cls-10 {
stroke: #e6d0d8;
}
.cls-11 {
fill: #e7d0d8;
}
.cls-12 {
fill: #dab6c4;
}
.cls-13,
.cls-18 {
fill: #b5d780;
}
.cls-14 {
fill: #9cb17e;
}
.cls-15 {
fill: #f16a83;
}
.cls-16,
.cls-17 {
stroke-linejoin: bevel;
stroke-width: 2px;
}
.cls-17 {
stroke-dasharray: 14.92 4.97;
}
.cls-18 {
stroke: #b5d780;
}
.cls-18,
.cls-19 {
stroke-width: 0.25px;
}
.cls-19,
.cls-21 {
fill: #aec58b;
}
.cls-19 {
stroke: #aec58b;
}
.cls-20 {
fill: #7d8a71;
}
.cls-23 {
fill: #f69eac;
}
.cls-24 {
fill: #c38f98;
}
.cls-25 {
fill: #816872;
}
.cls-26 {
fill: #6d6066;
}
.cls-27 {
fill: #806871;
}
.cls-28 {
fill: #dbbf53;
}
.cls-29 {
fill: #bfcf30;
}
.cls-30 {
fill: #b29ea7;
}
.cls-31 {
fill: #8d6876;
}
.cls-32,
.cls-48 {
stroke: #8d6876;
}
.cls-32 {
opacity: 0.6;
}
.cls-33 {
fill: #d2a849;
}
.cls-34 {
fill: #e0b24d;
}
.cls-35 {
fill: #bf6872;
}
.cls-36 {
fill: #f0bf53;
}
.cls-37 {
fill: #c6c49e;
}
.cls-38 {
stroke: #f69eac;
}
.cls-39 {
stroke: #c38f98;
}
.cls-40 {
fill: #c5c072;
}
.cls-41 {
fill: #fdf164;
}
.cls-42 {
fill: #dbedd1;
}
.cls-43 {
fill: #b2beaf;
}
.cls-44 {
fill: #feeb19;
}
.cls-45 {
fill: #9998c8;
}
.cls-46 {
fill: #fef5b1;
}
.cls-47 {
fill: #fac1c4;
}
.cls-49 {
fill: #bfa264;
}
.cls-50 {
stroke: #806871;
}
.cls-51 {
fill: #ce9d2b;
}
.cls-52 {
fill: #c06975;
}
.cls-53 {
fill: #e0efd3;
}
.cls-54 {
fill: #b9e1d2;
}
.cls-55 {
fill: #fff;
}
.cls-56 {
stroke: #231f20;
}
.cls-57 {
fill: #ffefb8;
}
.cls-58 {
fill: #dfedc9;
}
.cls-59 {
fill: #f6d695;
}
.cls-60 {
fill: #fcd6d9;
}
.cls-61 {
fill: #a48691;
}
.cls-62 {
fill: #eddee3;
}
.cls-63 {
fill: #fcf8ca;
}
.cls-64 {
fill: #b8b2d8;
}
.cls-65 {
fill: #eff7ea;
}
.cls-66 {
fill: #fef7b7;
}
.cls-67 {
fill: #fee9a0;
}
.cls-99 {
fill: #ddd162;
}
body {max-width: 1440px;}
#needles {
-webkit-animation: rotate 5s linear infinite;
animation: rotate 5s linear infinite;
-webkit-transform-origin: center;
-ms-transform-origin: center;
transform-origin: center;
transform-box: fill-box;
}
#-webkit-keyframes rotate {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg)
}
100% {
-webkit-transform: rotate(-180deg);
transform: rotate(-180deg)
}
}
#keyframes rotate {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg)
}
100% {
-webkit-transform: rotate(-180deg);
transform: rotate(-180deg)
}
}
#arms {
-webkit-animation: rotate-out 5s linear infinite;
animation: rotate-out 5s linear infinite;
-webkit-transform-origin: center;
-ms-transform-origin: center;
transform-origin: center;
transform-box: fill-box;
}
#-webkit-keyframes rotate-out {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg)
}
100% {
-webkit-transform: rotate(180deg);
transform: rotate(180deg)
}
}
#keyframes rotate-out {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg)
}
100% {
-webkit-transform: rotate(180deg);
transform: rotate(180deg)
}
}
#cabins {
-webkit-animation: cabin-transit 5s linear infinite;
animation: cabin-transit 5s linear infinite;
-webkit-transform-origin: 648.22px 301.55px;
-ms-transform-origin: 648.22px 301.55px;
transform-origin: 648.22px 301.55px;
}
#-webkit-keyframes cabin-transit {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg)
}
100% {
-webkit-transform: rotate(180deg);
transform: rotate(180deg)
}
}
#keyframes cabin-transit {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg)
}
100% {
-webkit-transform: rotate(180deg);
transform: rotate(180deg)
}
}
.cabin {
-webkit-animation: cabin-transform 5s linear infinite;
animation: cabin-transform 5s linear infinite;
-webkit-transform-origin: center;
-ms-transform-origin: center;
transform-origin: center;
transform-box: fill-box;
}
#-webkit-keyframes cabin-transform {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(-180deg);
transform: rotate(-180deg)
}
}
#keyframes cabin-transform {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(-180deg);
transform: rotate(-180deg)
}
}
#balloon,
#bunch_of_balloons1,
#bunch_of_balloons {
-webkit-animation: balloon-anim 5s linear infinite;
animation: balloon-anim 5s linear infinite;
-webkit-transform-origin: center;
-ms-transform-origin: center;
transform-origin: center;
transform-box: fill-box;
}
#-webkit-keyframes balloon-anim {
0% {
-webkit-transform: rotate(0deg) translate(0);
transform: rotate(0deg) translate(0)
}
25% {
-webkit-transform: rotate(2deg) translateY(5px);
transform: rotate(2deg) translateY(5px)
}
50% {
-webkit-transform: rotate(-2deg) translateY(-5px);
transform: rotate(-2deg) translateY(-5px)
}
75% {
-webkit-transform: rotate(-2deg) translateY(5px);
transform: rotate(-2deg) translateY(5px)
}
100% {
-webkit-transform: rotate(0deg) translate(0);
transform: rotate(0deg) translate(0)
}
}
#keyframes balloon-anim {
0% {
-webkit-transform: rotate(0deg) translate(0);
transform: rotate(0deg) translate(0)
}
25% {
-webkit-transform: rotate(2deg) translateY(5px);
transform: rotate(2deg) translateY(5px)
}
50% {
-webkit-transform: rotate(-2deg) translateY(-5px);
transform: rotate(-2deg) translateY(-5px)
}
75% {
-webkit-transform: rotate(-2deg) translateY(5px);
transform: rotate(-2deg) translateY(5px)
}
100% {
-webkit-transform: rotate(0deg) translate(0);
transform: rotate(0deg) translate(0)
}
}
#clouds-front {
-webkit-animation: cloud-transit infinite ease-in-out 5s;
animation: cloud-transit infinite ease-in-out 5s;
}
#clouds-back {
-webkit-animation: cloud-transit-2 infinite ease-out 5s;
animation: cloud-transit-2 infinite ease-out 5s;
}
#-webkit-keyframes cloud-transit {
0% {
opacity: 0
}
50% {
opacity: 1;
}
100% {
-webkit-transform: translateX(-5%);
transform: translateX(-5%);
opacity: 0;
}
}
#keyframes cloud-transit {
0% {
opacity: 0
}
50% {
opacity: 1;
}
100% {
-webkit-transform: translateX(-5%);
transform: translateX(-5%);
opacity: 0;
}
}
#-webkit-keyframes cloud-transit-2 {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
-webkit-transform: translateX(5%);
transform: translateX(5%);
}
}
#keyframes cloud-transit-2 {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
-webkit-transform: translateX(5%);
transform: translateX(5%);
}
}
In the following example I'm simplifying your code letting only the main wheel and the cabins.
In fact I'm using only a cabin as a symbol. All the others cabins are use elements, a copy of the symbol. This is simplifying a lot the code.
Although in the beginning I intended to use css, I think using animateMotion is the easiest solution. In SVG <animateMotion> provides a way to define how an element moves along a motion path - in this case the path is a circle - the wheel.
Please observe that the motion path is different for each cabin. Although all the motion paths are drawing the same circle, each path starts in a different point - the point where the cabin start it's animation.
Also every <use> element has x="-17.5" y="0" so that the point by which the cabin hangs on the wheel is now in the point {x:0,y:0}.
In order to draw the wheel and the cabins I'm using javascript. If you don't want Javascript you can copy the code from the inspector.
const SVG_NS = "http://www.w3.org/2000/svg";
const SVG_XLINK = "http://www.w3.org/1999/xlink";
let cx = 648.22;
let cy = 301.55;
let r = 158.88;
let t = 0;
let a = Math.PI / 5;
for (let i = 0; i < 2 * Math.PI; i += a) {
t++;
let x = cx + r * Math.cos(i);
let _x = cx + r * Math.cos(i + Math.PI);
let y = cy + r * Math.sin(i);
let _y = cy + r * Math.sin(i + Math.PI);
let use = document.createElementNS(SVG_NS, "use");
use.setAttributeNS(SVG_XLINK, "xlink:href", "#cabin");
use.setAttribute("x", -17.5);
use.setAttribute("y", 0);
use.setAttribute("width", 35);
use.setAttribute("height", 53);
let aM = document.createElementNS(SVG_NS, "animateMotion");
aM.setAttribute(
"path",
`M${x},${y}
A${r},${r} 0 0 1 ${_x},${_y}
A${r},${r} 0 0 1 ${x},${y}`
);
aM.setAttribute("repeatCount", "indefinite");
aM.setAttribute("dur", "10s");
use.appendChild(aM);
cabins.appendChild(use);
}
<svg id="sky_day" data-name="sky day" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1295.87 804.79">
<symbol id="cabin" viewBox="779.8 357 35 53">
<path class="cls-40" d="M801.41,357.53a24.71,24.71,0,0,0-4.14-.35V361a26.34,26.34,0,0,1,2.79.15c7.3,0.88,12.21,10.6,12.14,17.29h0c0,6.77-5.32,10.87-12.26,10.74q-1.33-.06-2.67-0.06v20.1h3.83c7.51-.25,13.64-6.44,13.56-13.56V377.94C814.64,370.9,809.6,359.08,801.41,357.53Z" />
<path class="cls-41" d="M793.13,357.53a24.71,24.71,0,0,1,4.14-.35V361a26.34,26.34,0,0,0-2.79.15c-7.3.88-12.21,10.6-12.14,17.29h0c0,6.77,5.32,10.87,12.26,10.74q1.33-.06,2.67-0.06v20.1h-3.83c-7.51-.25-13.64-6.44-13.56-13.56V377.94C779.89,370.9,784.93,359.08,793.13,357.53Z" />
</symbol>
<g id="wheels">
<circle fill="none" stroke="black" cx="648.22" cy="301.55" r="158.88" />
</g>
<g id="cabins">
</g>
</svg>
Here is the code without javascript:
<svg id="sky_day" data-name="sky day" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1295.87 804.79">
<symbol id="cabin" viewBox="779.8 357 35 53">
<path class="cls-40" d="M801.41,357.53a24.71,24.71,0,0,0-4.14-.35V361a26.34,26.34,0,0,1,2.79.15c7.3,0.88,12.21,10.6,12.14,17.29h0c0,6.77-5.32,10.87-12.26,10.74q-1.33-.06-2.67-0.06v20.1h3.83c7.51-.25,13.64-6.44,13.56-13.56V377.94C814.64,370.9,809.6,359.08,801.41,357.53Z"></path>
<path class="cls-41" d="M793.13,357.53a24.71,24.71,0,0,1,4.14-.35V361a26.34,26.34,0,0,0-2.79.15c-7.3.88-12.21,10.6-12.14,17.29h0c0,6.77,5.32,10.87,12.26,10.74q1.33-.06,2.67-0.06v20.1h-3.83c-7.51-.25-13.64-6.44-13.56-13.56V377.94C779.89,370.9,784.93,359.08,793.13,357.53Z"></path>
</symbol>
<g>
<g id="wheels">
<circle fill="none" stroke="black" cx="648.22" cy="301.55" r="158.88"></circle>
</g>
<g id="cabins">
<use xlink:href="#cabin" x="-17.5" y="0" width="35" height="53">
<animateMotion path="M807.1,301.55A158.88,158.88 0 0 1 489.34000000000003,301.55A158.88,158.88 0 0 1 807.1,301.55" repeatCount="indefinite" dur="10s"></animateMotion>
</use>
<use xlink:href="#cabin" x="-17.5" y="0" width="35" height="53">
<animateMotion path="M776.7566200662917,394.93732088422814A158.88,158.88 0 0 1 519.6833799337084,208.16267911577188A158.88,158.88 0 0 1 776.7566200662917,394.93732088422814" repeatCount="indefinite" dur="10s"></animateMotion>
</use>
<use xlink:href="#cabin" x="-17.5" y="0" width="35" height="53">
<animateMotion path="M697.3166200662916,452.653859308974A158.88,158.88 0 0 1 599.1233799337084,150.44614069102602A158.88,158.88 0 0 1 697.3166200662916,452.653859308974" repeatCount="indefinite" dur="10s"></animateMotion>
</use>
<use xlink:href="#cabin" x="-17.5" y="0" width="35" height="53">
<animateMotion path="M599.1233799337084,452.653859308974A158.88,158.88 0 0 1 697.3166200662916,150.44614069102602A158.88,158.88 0 0 1 599.1233799337084,452.653859308974" repeatCount="indefinite" dur="10s"></animateMotion>
</use>
<use xlink:href="#cabin" x="-17.5" y="0" width="35" height="53">
<animateMotion path="M519.6833799337085,394.93732088422814A158.88,158.88 0 0 1 776.7566200662916,208.16267911577185A158.88,158.88 0 0 1 519.6833799337085,394.93732088422814" repeatCount="indefinite" dur="10s"></animateMotion>
</use>
<use xlink:href="#cabin" x="-17.5" y="0" width="35" height="53">
<animateMotion path="M489.34000000000003,301.55A158.88,158.88 0 0 1 807.1,301.54999999999995A158.88,158.88 0 0 1 489.34000000000003,301.55" repeatCount="indefinite" dur="10s"></animateMotion>
</use>
<use xlink:href="#cabin" x="-17.5" y="0" width="35" height="53">
<animateMotion path="M519.6833799337084,208.16267911577188A158.88,158.88 0 0 1 776.7566200662917,394.9373208842281A158.88,158.88 0 0 1 519.6833799337084,208.16267911577188" repeatCount="indefinite" dur="10s"></animateMotion>
</use>
<use xlink:href="#cabin" x="-17.5" y="0" width="35" height="53">
<animateMotion path="M599.1233799337084,150.44614069102602A158.88,158.88 0 0 1 697.3166200662918,452.653859308974A158.88,158.88 0 0 1 599.1233799337084,150.44614069102602" repeatCount="indefinite" dur="10s"></animateMotion>
</use>
<use xlink:href="#cabin" x="-17.5" y="0" width="35" height="53">
<animateMotion path="M697.3166200662916,150.44614069102602A158.88,158.88 0 0 1 599.1233799337084,452.653859308974A158.88,158.88 0 0 1 697.3166200662916,150.44614069102602" repeatCount="indefinite" dur="10s"></animateMotion>
</use>
<use xlink:href="#cabin" x="-17.5" y="0" width="35" height="53">
<animateMotion path="M776.7566200662916,208.16267911577185A158.88,158.88 0 0 1 519.6833799337085,394.93732088422814A158.88,158.88 0 0 1 776.7566200662916,208.16267911577185" repeatCount="indefinite" dur="10s"></animateMotion>
</use>
</g>
</g>
</svg>
Related
So, I have this SVG logo animated by increasing the stroke-dashoffset value
svg {
position: absolute; top: 50%; left: 50%;
transform: translateX(-50%) translateY(-50%);
width: 150px;
}
.cls-1,
.cls-2 {
fill:none;
stroke:#a9a9a9;
stroke-linecap:round;
stroke-linejoin:round;
stroke-width:10px;
}
.cls-1 {
stroke-dasharray: 496;
stroke-dashoffset: -496;
animation: firstLine 2s ease-out 0s infinite normal;
}
.cls-2 {
stroke-dasharray: 458;
stroke-dashoffset: -458;
animation: secondLine 2s ease-out 0s infinite normal;
}
#keyframes firstLine {
0% { stroke-dashoffset: -496; }
40% { stroke-dashoffset: 0; }
60% { stroke-dashoffset: 0; }
85% { stroke-dashoffset: 496; }
100% { stroke-dashoffset: 496; }
}
#keyframes secondLine {
0% { stroke-dashoffset: -458; }
45% { stroke-dashoffset: 0; }
60% { stroke-dashoffset: 0; }
90% { stroke-dashoffset: 458; }
100% { stroke-dashoffset: 458; }
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200.17 135"><path class="cls-1" d="M132.67,28.44a39.06,39.06,0,0,1,0,78.12H113.22V59.11A54.11,54.11,0,0,0,5,59.11v57.35a13.54,13.54,0,0,0,27.08,0v-9.9h27"/><path class="cls-2" d="M113.63,5h19a62.5,62.5,0,0,1,0,125H102.44a16.29,16.29,0,0,1-16.3-16.29V59.11a27,27,0,0,0-54.06,0V79.89h27"/></svg>
When opened on desktop browser, everything is fine. Same for Android. But on iOS, the animation is going so wrong. Is there some iOS specific bug stroke-dashoffset that I'm not aware of?
I have been looking for a solution for a long time how to replace negative stroke-dashoffset values with positive values in order to circumvent the restrictions that safari imposes.
Explanations are given for animating one line. For the second line, the calculation is similar.
The total length of the line is 496 px; therefore, the value of
stroke-dashoffset = "496"completely hides the line.
With double value stroke-dashoffset ="992" line is drawn
With triple value stroke-dashoffset =" 1488 ", the line is erased
again
CSS solution
svg {
position: absolute; top: 50%; left: 50%;
transform: translateX(-50%) translateY(-50%);
width: 150px;
}
.cls-1,
.cls-2 {
fill:none;
stroke:#a9a9a9;
stroke-linecap:round;
stroke-linejoin:round;
stroke-width:10px;
}
.cls-1 {
stroke-dasharray: 496;
stroke-dashoffset: 0;
animation: firstLine 2s ease-out 0s infinite normal;
}
.cls-2 {
stroke-dasharray: 458;
stroke-dashoffset: 0;
animation: secondLine 2s ease-out 0s infinite normal;
}
#keyframes firstLine {
0% { stroke-dashoffset: 496; }
40% { stroke-dashoffset: 992; }
60% { stroke-dashoffset: 992; }
85% { stroke-dashoffset: 1488; }
100% { stroke-dashoffset: 1488; }
}
#keyframes secondLine {
0% { stroke-dashoffset: 458; }
45% { stroke-dashoffset: 916; }
60% { stroke-dashoffset: 916; }
90% { stroke-dashoffset: 1374; }
100% { stroke-dashoffset: 1374; }
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200.17 135">
<path class="cls-1 " d="M132.67,28.44a39.06,39.06,0,0,1,0,78.12H113.22V59.11A54.11,54.11,0,0,0,5,59.11v57.35a13.54,13.54,0,0,0,27.08,0v-9.9h27" >
</path>
<path class="cls-2" d="M113.63,5h19a62.5,62.5,0,0,1,0,125H102.44a16.29,16.29,0,0,1-16.3-16.29V59.11a27,27,0,0,0-54.06,0V79.89h27" >
</path>
</svg>
Option with a shadow around the logo
Add shadow
<defs>
<filter id="shadow" x="-20%" y="-20%" width="200%" height="200%">
<feDropShadow dx="4" dy="8" stdDeviation="4"/>
</filter>
</defs>
body {
background: rgb(144,210,152);
background: linear-gradient(286deg, rgba(144,210,152,1) 29%, rgba(236,234,154,1) 69%);
}
svg {
position: absolute; top: 50%; left: 50%;
transform: translateX(-50%) translateY(-50%);
width: 150px;
}
.cls-1,
.cls-2 {
fill:none;
stroke:#a9a9a9;
stroke-linecap:round;
stroke-linejoin:round;
stroke-width:10px;
filter:url(#shadow);
}
.cls-1 {
stroke-dasharray: 496;
stroke-dashoffset: 0;
animation: firstLine 4s ease-out 0s infinite normal;
}
.cls-2 {
stroke-dasharray: 458;
stroke-dashoffset: 0;
animation: secondLine 4s ease-out 0s infinite normal;
}
#keyframes firstLine {
0% { stroke-dashoffset: 496; }
40% { stroke-dashoffset: 992; }
60% { stroke-dashoffset: 992; }
85% { stroke-dashoffset: 1488; }
100% { stroke-dashoffset: 1488; }
}
#keyframes secondLine {
0% { stroke-dashoffset: 458; }
45% { stroke-dashoffset: 916; }
60% { stroke-dashoffset: 916; }
90% { stroke-dashoffset: 1374; }
100% { stroke-dashoffset: 1374; }
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220.17 150">
<defs>
<filter id="shadow" x="-20%" y="-20%" width="200%" height="200%">
<feDropShadow dx="4" dy="8" stdDeviation="4"/>
</filter>
</defs>
<path class="cls-1 " d="M132.67,28.44a39.06,39.06,0,0,1,0,78.12H113.22V59.11A54.11,54.11,0,0,0,5,59.11v57.35a13.54,13.54,0,0,0,27.08,0v-9.9h27" >
</path>
<path class="cls-2" d="M113.63,5h19a62.5,62.5,0,0,1,0,125H102.44a16.29,16.29,0,0,1-16.3-16.29V59.11a27,27,0,0,0-54.06,0V79.89h27" >
</path>
</svg>
SVG solution
svg {
position: absolute; top: 50%; left: 50%;
transform: translateX(-50%) translateY(-50%);
width: 150px;
}
.cls-1,
.cls-2 {
fill:none;
stroke:#a9a9a9;
stroke-linecap:round;
stroke-linejoin:round;
stroke-width:10px;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200.17 135">
<path class="cls-1 " d="M132.67,28.44a39.06,39.06,0,0,1,0,78.12H113.22V59.11A54.11,54.11,0,0,0,5,59.11v57.35a13.54,13.54,0,0,0,27.08,0v-9.9h27" stroke-dasharray="496,496" stroke-dashoffset="496">
<animate id="an_offset"
attributeName="stroke-dashoffset"
begin="0s"
dur="3s"
values="496;992;992;1488"
fill="freeze"
repeatCount="indefinite" />
</path>
<path class="cls-2" d="M113.63,5h19a62.5,62.5,0,0,1,0,125H102.44a16.29,16.29,0,0,1-16.3-16.29V59.11a27,27,0,0,0-54.06,0V79.89h27" stroke-dasharray="458,458" stroke-dashoffset="458">
<animate id="an_offset2"
attributeName="stroke-dashoffset"
begin="0s"
dur="3s"
values="458;916;916;1374"
fill="freeze"
repeatCount="indefinite" />
</path>
</svg>
Additional example
Drawing from each line from its midpoint
To implement the animation, change the parameters of the stroke-dasharray attribute
With a total line length of 496px, half of it is` 248px
since the values of the parameters in order mean:
0 - line, 248 - space 0 - line, 248 - space.
Therefore, writing stroke-dasharray = "0,248 0,248" will completely hide the line
With stroke-dasharray = "0,0 496,0" the line will be fully visible.
svg {
position: absolute; top: 50%; left: 50%;
transform: translateX(-50%) translateY(-50%);
width: 150px;
}
.cls-1,
.cls-2 {
fill:none;
stroke:#a9a9a9;
stroke-linejoin:round;
stroke-width:10px;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200.17 135">
<path class="cls-1 " d="M132.67,28.44a39.06,39.06,0,0,1,0,78.12H113.22V59.11A54.11,54.11,0,0,0,5,59.11v57.35a13.54,13.54,0,0,0,27.08,0v-9.9h27" stroke-dasharray="496,496" stroke-dashoffset="496">
<animate id="an_array"
attributeName="stroke-dasharray"
begin="0s"
dur="4s"
values="0,248 0,248;0,0 496,0;0,0 496,0;0,248 0,248"
fill="freeze"
repeatCount="indefinite" />
</path>
<path class="cls-2" d="M113.63,5h19a62.5,62.5,0,0,1,0,125H102.44a16.29,16.29,0,0,1-16.3-16.29V59.11a27,27,0,0,0-54.06,0V79.89h27" stroke-dasharray="458,458" stroke-dashoffset="458">
<animate id="an_array2"
attributeName="stroke-dasharray"
begin="0s"
dur="4s"
values="0,229 0,229;0,0 458,0;0,0 458,0;0,229 0,229"
fill="freeze"
repeatCount="indefinite" />
</path>
As mentioned by #RobertLongson, it's a Safari bug where is does not support negative values for stroke-dashiffset
How do I convert this code so that the path with id #wires has the color #000 initially and then being colored by the pattern and keyframes as oppossed to no color at all? So essentially the star should be black and the gradient animation will creep up the star. How do I achieve this?
This was inspired by https://stackoverflow.com/a/42032657/5586359.
.fill {
animation-name: fillAction;
animation-iteration-count: infinite;
animation-timing-function: cubic-bezier(.26, .64, .8, .4);
animation-duration: 4s;
animation-fill-mode: forwards;
}
#waveShape {
animation-name: waveAction;
animation-iteration-count: infinite;
animation-timing-function: ease-out;
animation-duration: 0.5s;
width: 100%;
height: 50%;
}
#wires {
fill: url(#waveGradient);
}
svg {
width: 100%;
height: auto;
}
#keyframes fillAction {
0% {
transform: translate(0, 50%);
}
100% {
transform: translate(0, -1.6%);
}
}
#keyframes waveAction {
0% {
transform: translate(-0%, 0);
}
10% {
transform: translate(-5%, 0);
}
20% {
transform: translate(-10%, 0);
}
30% {
transform: translate(-15%, 0);
}
40% {
transform: translate(-20%, 0);
}
50% {
transform: translate(-15%, 0);
}
60% {
transform: translate(-10%, 0);
}
70% {
transform: translate(-5%, 0)
}
100% {
transform: translate(0%, 0);
}
}
<div class="banner">
<?xml version="1.0" standalone="no"?>
<!-- Generator: Gravit.io -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 250 250" width="250" height="250">
<defs>
<clipPath id="_clipPath_kDqJpeywA1tWpdDxczhcHinYaTsaw8EY"><rect width="250" height="250"/>
</clipPath>
<linearGradient id="gradient">
<stop offset="0%" stop-color="#333291"/>
<stop offset="30%" stop-color="purple"/>
<stop offset="100%" stop-color="#fb5b5d" stop-opacity="100" />
</linearGradient>
<pattern id='waveGradient' width="1" height="1" viewBox="0 0 100 100" preserveAspectRatio="none">
<g class="fill">
<path fill="url(#gradient)" id="waveShape" d="M300,300V2.5c0,0-0.6-0.1-1.1-0.1c0,0-25.5-2.3-40.5-2.4c-15,0-40.6,2.4-40.6,2.4
c-12.3,1.1-30.3,1.8-31.9,1.9c-2-0.1-19.7-0.8-32-1.9c0,0-25.8-2.3-40.8-2.4c-15,0-40.8,2.4-40.8,2.4c-12.3,1.1-30.4,1.8-32,1.9
c-2-0.1-20-0.8-32.2-1.9c0,0-3.1-0.3-8.1-0.7V300H300z"/>
</g>
</pattern>
</defs>
<g clip-path="url(#_clipPath_kDqJpeywA1tWpdDxczhcHinYaTsaw8EY)">
<path id="wires" d="M12.015.624L9.19 9.293H0l7.445 5.384-2.819 8.673L12 17.986l7.422 5.393-2.835-8.713L24 9.292h-9.162L12.015.622v.002z"/>
</g>
</svg>
</div>
One idea is to duplicate the path of the star and you fill it with the color you want. Both will be placed above each other and you will have the visual you want
.fill {
animation-name: fillAction;
animation-iteration-count: infinite;
animation-timing-function: cubic-bezier(.26, .64, .8, .4);
animation-duration: 4s;
animation-fill-mode: forwards;
}
#waveShape {
animation-name: waveAction;
animation-iteration-count: infinite;
animation-timing-function: ease-out;
animation-duration: 0.5s;
width: 100%;
height: 50%;
}
#wires {
fill: url(#waveGradient);
}
#empty {
fill:#000;
}
svg {
width: 100%;
height: auto;
}
#keyframes fillAction {
0% {
transform: translate(0, 50%);
}
100% {
transform: translate(0, -1.6%);
}
}
#keyframes waveAction {
0% {
transform: translate(-0%, 0);
}
10% {
transform: translate(-5%, 0);
}
20% {
transform: translate(-10%, 0);
}
30% {
transform: translate(-15%, 0);
}
40% {
transform: translate(-20%, 0);
}
50% {
transform: translate(-15%, 0);
}
60% {
transform: translate(-10%, 0);
}
70% {
transform: translate(-5%, 0)
}
100% {
transform: translate(0%, 0);
}
}
<div class="banner">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 250 250" width="250" height="250">
<defs>
<linearGradient id="gradient">
<stop offset="0%" stop-color="#333291"/>
<stop offset="30%" stop-color="purple"/>
<stop offset="100%" stop-color="#fb5b5d" stop-opacity="100" />
</linearGradient>
<pattern id='waveGradient' width="1" height="1" viewBox="0 0 100 100" preserveAspectRatio="none">
<g class="fill">
<path fill="url(#gradient)" id="waveShape" d="M300,300V2.5c0,0-0.6-0.1-1.1-0.1c0,0-25.5-2.3-40.5-2.4c-15,0-40.6,2.4-40.6,2.4
c-12.3,1.1-30.3,1.8-31.9,1.9c-2-0.1-19.7-0.8-32-1.9c0,0-25.8-2.3-40.8-2.4c-15,0-40.8,2.4-40.8,2.4c-12.3,1.1-30.4,1.8-32,1.9
c-2-0.1-20-0.8-32.2-1.9c0,0-3.1-0.3-8.1-0.7V300H300z"/>
</g>
</pattern>
</defs>
<g >
<path id="empty" d="M12.015.624L9.19 9.293H0l7.445 5.384-2.819 8.673L12 17.986l7.422 5.393-2.835-8.713L24 9.292h-9.162L12.015.622v.002z"/>
<path id="wires" d="M12.015.624L9.19 9.293H0l7.445 5.384-2.819 8.673L12 17.986l7.422 5.393-2.835-8.713L24 9.292h-9.162L12.015.622v.002z"/>
</g>
</svg>
</div>
I am trying to change the fill color of a path when I hover over it in an SVG. I can't seem to make it work. I am thinking it is a z-index issue.
I've tried every selector I can think of.
I've changed the order of the paths so they are the last elements in the svg.
I am trying to change the path's with the class .wedge
I've applied a global z-index using:
* {z-index: 1;}
Then on .wedge I increased the z-index:
.wedge {z-index: 10 !important;)
That didn't work.
Something I found interesting but not sure if it is relevant, I added a click function to change the fill color of one of the paths. That works and if you click it the hover will start working.
Here is a codepen:
Codepen
Any ideas?
Seems to be related to the
.st4 {
fill: none;
}
Changing that to:
.st4 {
fill: transparent;
}
and then using the regular :hover class of:
.wedge:hover {
fill: rgba(21, 255, 0, 0.5);
}
does the trick. Like this:
/*
* === CSS for SVG compass ===
*/
/*
* — Structural and appearance —
*/
* {
z-index: 1;
}
/* Contains compass and limits its size */
.compassWrap {
max-width: 40%;
margin: 0 auto;
}
/* probably needs adjusted */
/* SVG styles, no need to change */
.st0 {
fill: none;
stroke: #505050;
stroke-width: 4.11;
stroke-linecap: round;
stroke-miterlimit: 10;
}
/* don't change */
.st1 {
fill: none;
stroke: #808080;
stroke-width: 2.57;
stroke-linecap: round;
stroke-miterlimit: 10;
}
/* don't change */
.st2 {
fill: #505050;
}
/* don't change */
.st3 {
opacity: 0.5;
}
/* don't change */
.st4 {
fill: transparent;
}
/* don't change */
/*
* — Pie color classes —
Add the class to the path with the ID of the direction you want
Available path ID's
#nnwPie - north by north west
#wnwPie - west by north west
#wswPie - west by south west
#sswPie - south by south west
#ssePie - south by south east
#esePie - east by south east
#enePie - east by north east
#nnePie - north by north east
*/
.green {
fill: rgba(21, 255, 0, 0.5);
}
/* best wind */
.dgreen {
fill: rgba(12, 140, 0, 0.5);
}
/* less good wind */
.red {
fill: rgba(255, 42, 0, 0.5);
}
/* worst wind */
.dred {
fill: rgba(140, 23, 0, 0.5);
}
/* less bad wind */
.wedge {
z-index: 10 !important;
}
.wedge:hover {
fill: rgba(21, 255, 0, 0.5);
}
/* best wind */
/*
* === Arrow ===
*/
/* adjust the center point and make arrow wiggle at all times */
#arrow {
transform-origin: 50% 59.7%;
animation-name: wiggle;
animation-duration: 1s;
animation-fill-mode: forward;
animation-iteration-count: infinite;
}
/*
* === ADD CLASS TO #arrow to move to location and wiggle ===
*/
.north#arrow {
transform-origin: 50% 59.7%;
animation-name: spinNorth, wiggleNorth;
animation-delay: 0s, 1s;
animation-duration: 1s, 1s;
animation-iteration-count: 1, infinite;
}
.northEast#arrow {
transform-origin: 50% 59.7%;
animation-name: spinNorthEast, wiggleNorthEast;
animation-delay: 0s, 1s;
animation-duration: 1s, 1s;
animation-iteration-count: 1, infinite;
}
.east#arrow {
transform-origin: 50% 59.7%;
animation-name: spinEast, wiggleEast;
animation-delay: 0s, 1s;
animation-duration: 1s, 1s;
animation-iteration-count: 1, infinite;
}
.southEast#arrow {
transform-origin: 50% 59.7%;
animation-name: spinSouthEast, wiggleSouthEast;
animation-delay: 0s, 1s;
animation-duration: 1s, 1s;
animation-iteration-count: 1, infinite;
}
.south#arrow {
transform-origin: 50% 59.7%;
animation-name: spinSouth, wiggleSouth;
animation-delay: 0s, 1s;
animation-duration: 1s, 1s;
animation-iteration-count: 1, infinite;
}
.southWest#arrow {
transform-origin: 50% 59.7%;
animation-name: spinSouthWest, wiggleSouthWest;
animation-delay: 0s, 1s;
animation-duration: 1s, 1s;
animation-iteration-count: 1, infinite;
}
.west#arrow {
transform-origin: 50% 59.7%;
animation-name: spinWest, wiggleWest;
animation-delay: 0s, 1s;
animation-duration: 1s, 1s;
animation-iteration-count: 1, infinite;
}
.northWest#arrow {
transform-origin: 50% 59.7%;
animation-name: spinNorthWest, wiggleNorthWest;
animation-delay: 0s, 1s;
animation-duration: 1s, 1s;
animation-iteration-count: 1, infinite;
}
.wedge:hover {
fill: rgba(21, 255, 0, 0.5);
}
/*
* === Animations to make #arrow spin ===
*/
/* Spin north Animation */
#keyframes spinNorth {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(45deg);
}
}
/* Spin north east Animation */
#keyframes spinNorthEast {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(90deg);
}
}
/* Spin east Animation */
#keyframes spinEast {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(135deg);
}
}
/* Spin south east Animation */
#keyframes spinSouthEast {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(180deg);
}
}
/* Spin south Animation */
#keyframes spinSouth {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(225deg);
}
}
/* Spin south west Animation */
#keyframes spinSouthWest {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(270deg);
}
}
/* Spin west Animation */
#keyframes spinWest {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(315deg);
}
}
/* Spin north west Animation */
#keyframes spinNorthWest {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
/* 360 because this is the starting point of #arrow */
}
}
/*
* === WIGGLES for each direction ===
*/
/* Wiggle north Animation */
#keyframes wiggleNorth {
0% {
transform: rotate(46deg);
}
50% {
transform: rotate(44deg);
}
100% {
transform: rotate(46deg);
}
}
/* Wiggle north east Animation */
#keyframes wiggleNorthEast {
0% {
transform: rotate(91deg);
}
50% {
transform: rotate(89deg);
}
100% {
transform: rotate(91deg);
}
}
/* Wiggle east Animation */
#keyframes wiggleEast {
0% {
transform: rotate(136deg);
}
50% {
transform: rotate(134deg);
}
100% {
transform: rotate(136deg);
}
}
/* Wiggle south east Animation */
#keyframes wiggleSouthEast {
0% {
transform: rotate(181deg);
}
50% {
transform: rotate(179deg);
}
100% {
transform: rotate(181deg);
}
}
/* Wiggle south Animation */
#keyframes wiggleSouth {
0% {
transform: rotate(226deg);
}
50% {
transform: rotate(224deg);
}
100% {
transform: rotate(226deg);
}
}
/* Wiggle south west Animation */
#keyframes wiggleSouthWest {
0% {
transform: rotate(271deg);
}
50% {
transform: rotate(269deg);
}
100% {
transform: rotate(271deg);
}
}
/* Wiggle west Animation */
#keyframes wiggleWest {
0% {
transform: rotate(316deg);
}
50% {
transform: rotate(314deg);
}
100% {
transform: rotate(316deg);
}
}
/* Wiggle north west Animation */
#keyframes wiggleNorthWest {
0% {
transform: rotate(361deg);
}
50% {
transform: rotate(359deg);
}
100% {
transform: rotate(361deg);
}
}
/*
* === wiggle when no direction ===
*/
#keyframes wiggle {
0% {
transform: rotate(1deg);
}
50% {
transform: rotate(-1deg);
}
100% {
transform: rotate(1deg);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="compassWrap">
<svg version="1.1" id="Layer_4" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 116.3 144" style="enable-background:new 0 0 116.3 144;" xml:space="preserve">
<title>compass</title>
<line id="N" class="st0" x1="58.2" y1="31.3" x2="58.2" y2="49.6"/>
<line id="NW" class="st1" x1="18.5" y1="46.1" x2="31.4" y2="59"/>
<line id="W" class="st0" x1="3.6" y1="85.7" x2="21.9" y2="85.7"/>
<line id="SW" class="st1" x1="18.3" y1="125.5" x2="31.3" y2="112.5"/>
<line id="S" class="st0" x1="58" y1="140.3" x2="58" y2="122"/>
<line id="SE" class="st1" x1="97.7" y1="125.6" x2="84.8" y2="112.6"/>
<line id="E" class="st0" x1="113.4" y1="85.9" x2="95.1" y2="85.9"/>
<line id="NE" class="st1" x1="97.8" y1="46.2" x2="84.9" y2="59.1"/>
<path id="compass" class="st2" d="M69.6,28.8c6.7-6.3,7-16.9,0.7-23.6s-16.9-7-23.6-0.7s-7,16.9-0.7,23.6c0.2,0.2,0.4,0.5,0.7,0.7
c-31.5,6.3-51.9,37-45.6,68.5s37,51.9,68.5,45.6c31.5-6.3,51.9-37,45.6-68.5C110.6,51.4,92.6,33.4,69.6,28.8z M58.2,6.5
c5.6,0,10.2,4.6,10.2,10.2H48C48,11.1,52.6,6.5,58.2,6.5z M58.2,138.3c-29,0-52.5-23.5-52.5-52.5s23.5-52.5,52.5-52.5
c29,0,52.5,23.5,52.5,52.5c0,0,0,0,0,0C110.6,114.8,87.1,138.3,58.2,138.3z"/>
<path id="inner_compass" class="st2" d="M58.2,130.8c-24.9,0-45.2-20.2-45.2-45.2s20.2-45.2,45.2-45.2c24.9,0,45.2,20.2,45.2,45.1
c0,0,0,0,0,0C103.3,110.6,83.1,130.8,58.2,130.8z M58.2,43.8c-23.1,0-41.9,18.8-41.9,41.9s18.8,41.9,41.9,41.9s41.9-18.8,41.9-41.9
C100.1,62.6,81.3,43.8,58.2,43.8L58.2,43.8z"/>
<polygon id="arrow" class="st2" points="78.4,105.3 80.2,107.1 79.1,108.3 77.2,106.4 75.5,109.7 74.1,108.6 75.9,105.1 75.1,104.3
73.3,107.7 71.9,106.6 73.8,103 72.9,102.1 71.2,105.6 69.8,104.5 71.7,100.9 63.5,92.7 63.5,92.7 41.5,70.7 41.4,70.8 39,74.3
34.5,62.5 46.3,67.1 42.5,69.5 64.6,91.6 65.2,92.1 72.9,99.8 76.5,98 77.6,99.5 74.1,101.1 74.9,101.9 78.6,100 79.7,101.4
76.2,103.1 75.9,102.9 77.1,104 80.8,102.3 81.9,103.8 "/>
<path id="nnwPie" class="st4 wedge" d="M57.9,27.7v58.2l-41-41C27.8,33.9,42.5,27.7,57.9,27.7z"/>
<path id="wnwPie" class="st4 wedge" d="M57.9,85.8H0.2v-0.2c0-15.3,6-30,16.8-40.8L57.9,85.8z"/>
<path id="wswPie" class="st4 wedge" d="M57.9,85.8l-40.8,40.8c-10.8-10.8-16.9-25.5-17-40.8H57.9z"/>
<path id="sswPie" class="st4 wedge" d="M57.9,85.8v57.8c-15.3,0-30-6.2-40.8-17L57.9,85.8z"/>
<path id="ssePie" class="st4 wedge" d="M99,126.9c-10.8,10.8-25.5,16.8-40.8,16.8H58V85.8L99,126.9z"/>
<path id="esePie" class="st4 wedge" d="M116.2,85.8c0,15.4-6.2,30.2-17.2,41l-41-41H116.2z"/>
<path id="enePie" class="st4 wedge" d="M116.2,85.7v0.2H57.9l41.2-41.2C110.1,55.5,116.2,70.3,116.2,85.7z"/>
<path id="nnePie" class="st4 wedge" d="M99.1,44.6L57.9,85.8V27.7h0.2C73.5,27.6,88.3,33.7,99.1,44.6z"/>
</svg>
</div>
I have an SVG compass with an arrow in it. I want to be able to add a class to the arrow and have it rotate a certain degree then stay there and wiggle.
I have the rotation and wiggle working just not together. Not sure how to combine the two so they work together. Here is my code:
div {
max-width: 40%;
}
.st0 {
fill: none;
stroke: #505050;
stroke-width: 4.11;
stroke-linecap: round;
stroke-miterlimit: 10;
}
.st1 {
fill: none;
stroke: #808080;
stroke-width: 2.57;
stroke-linecap: round;
stroke-miterlimit: 10;
}
.st2 {
fill: #505050;
}
.st3 {
opacity: 0.5;
}
.st4 {
fill: none;
}
/* Fill Colors */
.green {
fill: rgba(21, 255, 0, 0.5);
}
.dgreen {
fill: rgba(12, 140, 0, 0.5);
}
.red {
fill: rgba(255, 42, 0, 0.5);
}
.dred {
fill: rgba(140, 23, 0, 0.5);
}
/* Arrow */
#arrow {
transform-origin: 50% 59.7%;
animation-name: wiggle;
animation-duration: 1s;
animation-fill-mode: forward;
-webkit-animation-fill-mode: forward;
-webkit-animation-iteration-count: infinite;
/* Safari 4.0 - 8.0 */
animation-iteration-count: infinite;
}
/* Rotations */
.north#arrow {
-webkit-transform: rotate(45deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.northEast#arrow {
-webkit-transform: rotate(90deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.west#arrow {
-webkit-transform: rotate(135deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.southWest#arrow {
-webkit-transform: rotate(180deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.south#arrow {
-webkit-transform: rotate(225deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.southWest#arrow {
-webkit-transform: rotate(270deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.west#arrow {
-webkit-transform: rotate(315deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.northWest#arrow {
-webkit-transform: rotate(0deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
/* Wiggle Animation */
/* safari and chrome */
#-webkit-keyframes wiggle {
0% {
-webkit-transform: rotate(4deg);
}
50% {
-webkit-transform: rotate(-4deg);
}
100% {
-webkit-transform: rotate(4deg);
}
}
/* firefox */
#-moz-keyframes wiggle {
0% {
-moz-transform: rotate(4deg);
}
50% {
-moz-transform: rotate(-4deg);
}
100% {
-moz-transform: rotate(4deg);
}
}
#keyframes wiggle {
0% {
transform: rotate(4deg);
}
50% {
transform: rotate(-4deg);
}
100% {
transform: rotate(4deg);
}
}
<div>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_4" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 116.3 144" style="enable-background:new 0 0 116.3 144;" xml:space="preserve">
<title>compass</title>
<line id="N" class="st0" x1="58.2" y1="31.3" x2="58.2" y2="49.6"/>
<line id="NW" class="st1" x1="18.5" y1="46.1" x2="31.4" y2="59"/>
<line id="W" class="st0" x1="3.6" y1="85.7" x2="21.9" y2="85.7"/>
<line id="SW" class="st1" x1="18.3" y1="125.5" x2="31.3" y2="112.5"/>
<line id="S" class="st0" x1="58" y1="140.3" x2="58" y2="122"/>
<line id="SE" class="st1" x1="97.7" y1="125.6" x2="84.8" y2="112.6"/>
<line id="E" class="st0" x1="113.4" y1="85.9" x2="95.1" y2="85.9"/>
<line id="NE" class="st1" x1="97.8" y1="46.2" x2="84.9" y2="59.1"/>
<path id="compass" class="st2" d="M69.6,28.8c6.7-6.3,7-16.9,0.7-23.6s-16.9-7-23.6-0.7s-7,16.9-0.7,23.6c0.2,0.2,0.4,0.5,0.7,0.7
c-31.5,6.3-51.9,37-45.6,68.5s37,51.9,68.5,45.6c31.5-6.3,51.9-37,45.6-68.5C110.6,51.4,92.6,33.4,69.6,28.8z M58.2,6.5
c5.6,0,10.2,4.6,10.2,10.2H48C48,11.1,52.6,6.5,58.2,6.5z M58.2,138.3c-29,0-52.5-23.5-52.5-52.5s23.5-52.5,52.5-52.5
c29,0,52.5,23.5,52.5,52.5c0,0,0,0,0,0C110.6,114.8,87.1,138.3,58.2,138.3z"/>
<path id="inner_compass" class="st2" d="M58.2,130.8c-24.9,0-45.2-20.2-45.2-45.2s20.2-45.2,45.2-45.2c24.9,0,45.2,20.2,45.2,45.1
c0,0,0,0,0,0C103.3,110.6,83.1,130.8,58.2,130.8z M58.2,43.8c-23.1,0-41.9,18.8-41.9,41.9s18.8,41.9,41.9,41.9s41.9-18.8,41.9-41.9
C100.1,62.6,81.3,43.8,58.2,43.8L58.2,43.8z"/>
<g id="NNW" class="st3">
<path id="nnwPie" class="st4 green" d="M57.9,27.7v58.2l-41-41C27.8,33.9,42.5,27.7,57.9,27.7z"/>
</g>
<g id="WNW" class="st3">
<path id="wnwPie" class="st4 dgreen" d="M57.9,85.8H0.2v-0.2c0-15.3,6-30,16.8-40.8L57.9,85.8z"/>
</g>
<g id="WSW">
<path id="wswPie" class="st4" d="M57.9,85.8l-40.8,40.8c-10.8-10.8-16.9-25.5-17-40.8H57.9z"/>
</g>
<g id="SSW">
<path id="sswPie" class="st4" d="M57.9,85.8v57.8c-15.3,0-30-6.2-40.8-17L57.9,85.8z"/>
</g>
<g id="SSE">
<path id="ssePie" class="st4 red" d="M99,126.9c-10.8,10.8-25.5,16.8-40.8,16.8H58V85.8L99,126.9z"/>
</g>
<g id="ESE">
<path id="esePie" class="st4 dred" d="M116.2,85.8c0,15.4-6.2,30.2-17.2,41l-41-41H116.2z"/>
</g>
<g id="ENE">
<path id="enePie" class="st4" d="M116.2,85.7v0.2H57.9l41.2-41.2C110.1,55.5,116.2,70.3,116.2,85.7z"/>
</g>
<g id="NNE">
<path id="nnePie" class="st4" d="M99.1,44.6L57.9,85.8V27.7h0.2C73.5,27.6,88.3,33.7,99.1,44.6z"/>
</g>
<polygon id="arrow" class="st2 west" points="78.4,105.3 80.2,107.1 79.1,108.3 77.2,106.4 75.5,109.7 74.1,108.6 75.9,105.1 75.1,104.3
73.3,107.7 71.9,106.6 73.8,103 72.9,102.1 71.2,105.6 69.8,104.5 71.7,100.9 63.5,92.7 63.5,92.7 41.5,70.7 41.4,70.8 39,74.3
34.5,62.5 46.3,67.1 42.5,69.5 64.6,91.6 65.2,92.1 72.9,99.8 76.5,98 77.6,99.5 74.1,101.1 74.9,101.9 78.6,100 79.7,101.4
76.2,103.1 75.9,102.9 77.1,104 80.8,102.3 81.9,103.8 "/>
</svg>
</div>
You need to chain animations together and use a delay between them so one plays after the other has finished.
You were previously using a transition and then an animation which are two separate things. Also browser prefixes are now pretty redundant for animations, I personally would use the non-prefixed syntax.
Here is one example where the arrow moves to the south and then wiggles, you will need to add in the others:
Example CSS
.wrap:hover #arrow {
transform-origin: 50% 59.7%;
animation-name: spinSouth, wiggleSouth;
animation-delay: 0s, 1s;
animation-duration: 1s, 1s;
animation-iteration-count: 1, infinite;
}
/* Spin south Animation */
#keyframes spinSouth {
0% {
transform: rotate(4deg);
}
100% {
transform: rotate(225deg);
}
}
/* Wiggle Animation */
#keyframes wiggleSouth {
0% {
transform: rotate(225deg);
}
50% {
transform: rotate(220deg);
}
100% {
transform: rotate(225deg);
}
}
Fiddle:
http://jsfiddle.net/5cn9sm99/
I think this may be a shorter solution with the code you already have. You could wrap your arrow in an arrow container like this:
<g id="arrowContainer">
<polygon id="arrow" class="st2 west" points="78.4,105.3 80.2,107.1 79.1,108.3 77.2,106.4 75.5,109.7 74.1,108.6 75.9,105.1 75.1,104.3
73.3,107.7 71.9,106.6 73.8,103 72.9,102.1 71.2,105.6 69.8,104.5 71.7,100.9 63.5,92.7 63.5,92.7 41.5,70.7 41.4,70.8 39,74.3
34.5,62.5 46.3,67.1 42.5,69.5 64.6,91.6 65.2,92.1 72.9,99.8 76.5,98 77.6,99.5 74.1,101.1 74.9,101.9 78.6,100 79.7,101.4
76.2,103.1 75.9,102.9 77.1,104 80.8,102.3 81.9,103.8 "/>
</g>
Then add this styles to center the pivot point of the container:
#arrowContainer{ transform-origin: 50% 50%; }
Now replace the Rotations to target the arrowContainer and use Javascript or jQuery to add the classes you already created. Here is the full code.
var changeDirection = function changeClass(myClass){
$('#compass').attr("class", myClass);
}
div {
max-width: 300px;
}
.st0 {
fill: none;
stroke: #505050;
stroke-width: 4.11;
stroke-linecap: round;
stroke-miterlimit: 10;
}
.st1 {
fill: none;
stroke: #808080;
stroke-width: 2.57;
stroke-linecap: round;
stroke-miterlimit: 10;
}
.st2 {
fill: #505050;
}
.st3 {
opacity: 0.5;
}
.st4 {
fill: none;
}
/* Fill Colors */
.green {
fill: rgba(21, 255, 0, 0.5);
}
.dgreen {
fill: rgba(12, 140, 0, 0.5);
}
.red {
fill: rgba(255, 42, 0, 0.5);
}
.dred {
fill: rgba(140, 23, 0, 0.5);
}
/* Arrow */
#arrowContainer{
transform-origin: 50% 50%;
}
#arrow {
transform-origin: 50% 59.7%;
animation-name: wiggle;
animation-duration: 1s;
animation-fill-mode: forward;
-webkit-animation-fill-mode: forward;
-webkit-animation-iteration-count: infinite;
/* Safari 4.0 - 8.0 */
animation-iteration-count: infinite;
}
/* Rotations */
.north #arrowContainer {
-webkit-transform: rotate(45deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.northEast #arrowContainer {
-webkit-transform: rotate(90deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.east #arrowContainer {
-webkit-transform: rotate(135deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.southEast #arrowContainer {
-webkit-transform: rotate(180deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.south #arrowContainer {
-webkit-transform: rotate(225deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.southWest #arrowContainer {
-webkit-transform: rotate(270deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.west #arrowContainer {
-webkit-transform: rotate(315deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.northWest #arrowContainer {
-webkit-transform: rotate(0deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
/* Wiggle Animation */
/* safari and chrome */
#-webkit-keyframes compass {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(0deg);
}
}
#-webkit-keyframes wiggle {
0% {
-webkit-transform: rotate(4deg);
}
50% {
-webkit-transform: rotate(-4deg);
}
100% {
-webkit-transform: rotate(4deg);
}
}
/* firefox */
#-moz-keyframes wiggle {
0% {
-moz-transform: rotate(4deg);
}
50% {
-moz-transform: rotate(-4deg);
}
100% {
-moz-transform: rotate(4deg);
}
}
#keyframes wiggle {
0% {
transform: rotate(4deg);
}
50% {
transform: rotate(-4deg);
}
100% {
transform: rotate(4deg);
}
}
/* Button Styles */
.buttons{
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="buttons">
<button onclick="changeDirection('north')">North</button>
<button onclick="changeDirection('northEast')">NorthEast</button>
<button onclick="changeDirection('east')">East</button>
<button onclick="changeDirection('southEast')">South East</button>
<button onclick="changeDirection('south')">South</button>
<button onclick="changeDirection('southWest')">South West</button>
<button onclick="changeDirection('west')">West</button>
<button onclick="changeDirection('northWest')">North West</button>
</div>
<div id="compass" class="addClassHere">
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_4" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 116.3 144" style="enable-background:new 0 0 116.3 144;" xml:space="preserve">
<title>compass</title>
<line id="N" class="st0" x1="58.2" y1="31.3" x2="58.2" y2="49.6"/>
<line id="NW" class="st1" x1="18.5" y1="46.1" x2="31.4" y2="59"/>
<line id="W" class="st0" x1="3.6" y1="85.7" x2="21.9" y2="85.7"/>
<line id="SW" class="st1" x1="18.3" y1="125.5" x2="31.3" y2="112.5"/>
<line id="S" class="st0" x1="58" y1="140.3" x2="58" y2="122"/>
<line id="SE" class="st1" x1="97.7" y1="125.6" x2="84.8" y2="112.6"/>
<line id="E" class="st0" x1="113.4" y1="85.9" x2="95.1" y2="85.9"/>
<line id="NE" class="st1" x1="97.8" y1="46.2" x2="84.9" y2="59.1"/>
<path id="compass" class="st2" d="M69.6,28.8c6.7-6.3,7-16.9,0.7-23.6s-16.9-7-23.6-0.7s-7,16.9-0.7,23.6c0.2,0.2,0.4,0.5,0.7,0.7
c-31.5,6.3-51.9,37-45.6,68.5s37,51.9,68.5,45.6c31.5-6.3,51.9-37,45.6-68.5C110.6,51.4,92.6,33.4,69.6,28.8z M58.2,6.5
c5.6,0,10.2,4.6,10.2,10.2H48C48,11.1,52.6,6.5,58.2,6.5z M58.2,138.3c-29,0-52.5-23.5-52.5-52.5s23.5-52.5,52.5-52.5
c29,0,52.5,23.5,52.5,52.5c0,0,0,0,0,0C110.6,114.8,87.1,138.3,58.2,138.3z"/>
<path id="inner_compass" class="st2" d="M58.2,130.8c-24.9,0-45.2-20.2-45.2-45.2s20.2-45.2,45.2-45.2c24.9,0,45.2,20.2,45.2,45.1
c0,0,0,0,0,0C103.3,110.6,83.1,130.8,58.2,130.8z M58.2,43.8c-23.1,0-41.9,18.8-41.9,41.9s18.8,41.9,41.9,41.9s41.9-18.8,41.9-41.9
C100.1,62.6,81.3,43.8,58.2,43.8L58.2,43.8z"/>
<g id="NNW" class="st3">
<path id="nnwPie" class="st4 green" d="M57.9,27.7v58.2l-41-41C27.8,33.9,42.5,27.7,57.9,27.7z"/>
</g>
<g id="WNW" class="st3">
<path id="wnwPie" class="st4 dgreen" d="M57.9,85.8H0.2v-0.2c0-15.3,6-30,16.8-40.8L57.9,85.8z"/>
</g>
<g id="WSW">
<path id="wswPie" class="st4" d="M57.9,85.8l-40.8,40.8c-10.8-10.8-16.9-25.5-17-40.8H57.9z"/>
</g>
<g id="SSW">
<path id="sswPie" class="st4" d="M57.9,85.8v57.8c-15.3,0-30-6.2-40.8-17L57.9,85.8z"/>
</g>
<g id="SSE">
<path id="ssePie" class="st4 red" d="M99,126.9c-10.8,10.8-25.5,16.8-40.8,16.8H58V85.8L99,126.9z"/>
</g>
<g id="ESE">
<path id="esePie" class="st4 dred" d="M116.2,85.8c0,15.4-6.2,30.2-17.2,41l-41-41H116.2z"/>
</g>
<g id="ENE">
<path id="enePie" class="st4" d="M116.2,85.7v0.2H57.9l41.2-41.2C110.1,55.5,116.2,70.3,116.2,85.7z"/>
</g>
<g id="NNE">
<path id="nnePie" class="st4" d="M99.1,44.6L57.9,85.8V27.7h0.2C73.5,27.6,88.3,33.7,99.1,44.6z"/>
</g>
<g id="arrowContainer">
<polygon id="arrow" class="st2 west" points="78.4,105.3 80.2,107.1 79.1,108.3 77.2,106.4 75.5,109.7 74.1,108.6 75.9,105.1 75.1,104.3
73.3,107.7 71.9,106.6 73.8,103 72.9,102.1 71.2,105.6 69.8,104.5 71.7,100.9 63.5,92.7 63.5,92.7 41.5,70.7 41.4,70.8 39,74.3
34.5,62.5 46.3,67.1 42.5,69.5 64.6,91.6 65.2,92.1 72.9,99.8 76.5,98 77.6,99.5 74.1,101.1 74.9,101.9 78.6,100 79.7,101.4
76.2,103.1 75.9,102.9 77.1,104 80.8,102.3 81.9,103.8 "/>
</g>
</svg>
</div>
I'm working on making a simple loading spinner element with SVG. It works excellently in Chrome, but not in other browsers. In IE, the animation doesn't work at all. More troubling, in FF, the animation works but the rotation is not centered at the right location.
What can I do to make it rotate correctly in FF? (Edit: It actually works correctly in FF 42alpha.) Is there anything I can do to get it to work in IE? (Targeting the current version of these browsers)
The snippet below contains the relevant CSS and HTML:
svg.spinner {
display: block;
width: 50px;
}
svg.spinner path {
fill-opacity: 0;
stroke-width: 11;
}
svg.spinner path.track {
stroke: rgba(92, 112, 128, 0.2);
}
svg.spinner path.head {
stroke: rgba(92, 112, 128, 0.5);
stroke-linecap: round;
/* -webkit-transform-origin: 50px 50px; */
-ms-transform-origin: 50px 50px;
transform-origin: 50px 50px;
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
}
#-webkit-keyframes spin {
from {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
#keyframes spin {
from {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
<svg class="spinner" viewBox="0 0 100 100">
<path class="track" d="M 50,50 m 0,-44.5 a 44.5,44.5 0 1 1 0,89 a 44.5,44.5 0 1 1 0,-89"></path>
<path class="head" d="M 91.81632162497291 65.21989637799226 A 44.5 44.5 0 0 0 50 5.5"></path>
</svg>
Newer versions of FF handle this more appropriately. Firefox 41 and up adds proper support for transform-origin with regards to SVG elements. It also adds the transform-box property. You can set this to view-box and it will use the SVG viewbox as a reference and correctly calculate the transform origin. FF 40 and older seem to calculate the position of the transform origin relative to the path element in question by default, and don't support any way to change this.
So good news for the future! However, this does not help with getting things working on the current version of FF or on IE.
This answer works on Firefox 40, Firefox 42 and Chrome.
svg.spinner {
display: block;
width: 50px;
}
svg.spinner path {
fill-opacity: 0;
stroke-width: 11;
}
svg.spinner path.track {
stroke: rgba(92, 112, 128, 0.2);
}
svg.spinner path.head {
stroke: rgba(92, 112, 128, 0.5);
stroke-linecap: round;
-ms-transform-origin: 50px 50px;
transform-origin: 50px 50px;
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
}
#-webkit-keyframes spin {
from {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
#keyframes spin {
from {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
<svg class="spinner" viewBox="-50 -50 100 100">
<g transform="translate(-50, -50)" >
<path class="track" d="M 50,50 m 0,-44.5 a 44.5,44.5 0 1 1 0,89 a 44.5,44.5 0 1 1 0,-89"></path>
<path class="head" d="M 91.81632162497291 65.21989637799226 A 44.5 44.5 0 0 0 50 5.5"></path>
</g>
</svg>
From #JKillian's answer there seem to be no way to fix it for older browsers.
There is another way to animate the element. :D
Im drawing to circle. No fill only stroke.
And animating the stroke to get the desired effect.
svg.spinner {
display: block;
width: 150px;
}
.circ {
fill: none;
stroke: #222;
stroke-width: 10;
}
#circ2 {
stroke: #999;
stroke-dasharray: 160, 100;
stroke-dashoffset: 0;
transition: stroke-dashoffset 2s;
}
svg:hover #circ2 {
stroke-dashoffset: 500;
}
<svg class="spinner" viewBox="0 0 100 100">
<circle class="circ" id="circ1" cx="50" cy="50" r="41" />
<circle class="circ" id="circ2" cx="50" cy="50" r="41" />
</svg>