html - SVG animation properly not closing at the end(small Gap persists) -


i'm relatively new svg. trying implement hexagon loader, 90% has been completed @ end of animation hexagon not closing completely(a small gap persists). used adobe illustrator getting path coordinates.

link: jsfiddle.net/srigar/fhmbqtg7/1/

there several approaches can take. if don't mind rounded joins, can take @demonofthemists's approach.

but before demonstrate other approaches, going clean path. uses 15 path commands make hexagon. should need 6. has stray "-0" @ end nothing. cleaned css. finally, path 245.68 in length, dash array of 300 long and, consequence, not seeing effect of ease-in-out animation timing.

here's cleaned sample.

.loader path {    stroke-width: 10;    fill: none;  }    .loader #fill {    stroke:#4c83c4;    stroke-dasharray: 246;    animation: dash 5s ease-in-out infinite;  }  .loader #border {    stroke:#d6d5d5;  }  .loader svg {    width: 600px;    height: 300px;    display: block;    margin: 0 auto;    margin-bottom: 40px;    opacity: 0.5;    position: relative;  }    @keyframes dash {    0% {      stroke-dashoffset: 246;    }    100% {      stroke-dashoffset: 0;    }  }
<div class="loader">    <svg viewbox="0 -10 97.59 119.306">      <g>        <path id="border"              d="m43.3,8.1 l8,28.6 v41.2 l43.3,90.3 l78.6,69.8 v28.6 z"/>        <path id="fill"              d="m43.3,8.1 l8,28.6 v41.2 l43.3,90.3 l78.6,69.8 v28.6 z"/>      </g>    </svg>  </div>    <label>author: srigar</label>

okay, solutions.

1. "square"line caps , mask

you switch square line caps instead of round, result in caps extending outside of hexagon shape. fix using mask.

.loader path {    stroke-width: 10;    fill: none;  }    .loader #fill {    stroke:#4c83c4;    stroke-dasharray: 246;    stroke-linecap: square;    animation: dash 5s ease-in-out infinite;    mask: url(#loader-mask);  }  .loader #border {    stroke:#d6d5d5;  }  .loader svg {    width: 600px;    height: 300px;    display: block;    margin: 0 auto;    margin-bottom: 40px;    opacity: 0.5;    position: relative;  }    @keyframes dash {    0% {      stroke-dashoffset: 246;    }    100% {      stroke-dashoffset: 0;    }  }
<div class="loader">    <svg viewbox="0 -10 97.59 119.306">      <defs>        <mask id="loader-mask">          <rect width="100%" height="100%" fill="black"/>          <path d="m43.3,8.1 l8,28.6 v41.2 l43.3,90.3 l78.6,69.8 v28.6 z"                stroke="white"/>        </mask>      </defs>      <g>        <path id="border"              d="m43.3,8.1 l8,28.6 v41.2 l43.3,90.3 l78.6,69.8 v28.6 z"/>        <path id="fill"              d="m43.3,8.1 l8,28.6 v41.2 l43.3,90.3 l78.6,69.8 v28.6 z"/>      </g>    </svg>  </div>    <label>author: srigar</label>

unfortunately, doesn't @ start of path.

2. extend end of path, mask

another approach eschew line caps, , instead extend end of path past start point bit. of course, makes line longer, need make dash array value bigger also. , still need use mask, see parts of line extension want keep.

.loader path {    stroke-width: 10;    fill: none;  }    .loader #fill {    stroke:#4c83c4;    stroke-dasharray: 250;    animation: dash 5s ease-in-out infinite;    mask: url(#loader-mask);  }  .loader #border {    stroke:#d6d5d5;  }  .loader svg {    width: 600px;    height: 300px;    display: block;    margin: 0 auto;    margin-bottom: 40px;    opacity: 0.5;    position: relative;  }    @keyframes dash {    0% {      stroke-dashoffset: 250;    }    100% {      stroke-dashoffset: 0;    }  }
<div class="loader">    <svg viewbox="0 -10 97.59 119.306">      <defs>        <mask id="loader-mask">          <rect width="100%" height="100%" fill="black"/>          <path d="m43.3,8.1 l8,28.6 v41.2 l43.3,90.3 l78.6,69.8 v28.6 z"                stroke="white"/>        </mask>      </defs>      <g>        <path id="border"              d="m43.3,8.1 l8,28.6 v41.2 l43.3,90.3 l78.6,69.8 v28.6 z"/>        <path id="fill"              d="m43.3,8.1 l8,28.6 v41.2 l43.3,90.3 l78.6,69.8 v28.6 l-38.8,-22.6"/>      </g>    </svg>  </div>    <label>author: srigar</label>

so there couple of techniques started. fancier if want - example if wanted vertical start/end join, using couple of masks , splitting animation 2 parts. i'll leave things simple now, avoid making answer confusing.

update

3. neater start , end

.loader path {    stroke-width: 10;    fill: none;  }    .loader #fill-left,  .loader #fill-right {    stroke:#4c83c4;    animation: dash 5s ease-in-out infinite;  }    .loader #fill-left {    stroke-dasharray: 254;    mask: url(#left-mask);  }    .loader #fill-right {    stroke-dasharray: 168 254;    mask: url(#right-mask);  }    .loader #border {    stroke:#d6d5d5;  }  .loader svg {    width: 600px;    height: 300px;    display: block;    margin: 0 auto;    margin-bottom: 40px;    opacity: 0.5;    position: relative;  }    @keyframes dash {    0% {      stroke-dashoffset: 254;    }    100% {      stroke-dashoffset: 0;    }  }
<div class="loader">    <svg viewbox="0 -10 97.59 119.306">      <defs>        <mask id="left-mask">          <rect width="100%" height="100%" fill="black"/>          <path d="m43.3,8.1 l8,28.6 v41.2 l43.3,90.3 l78.6,69.8 v28.6 z"                stroke="white"/>          <rect x="43.3" width="100%" height="100%" fill="black"/>        </mask>        <mask id="right-mask">          <rect width="100%" height="100%" fill="black"/>          <path d="m43.3,8.1 l8,28.6 v41.2 l43.3,90.3 l78.6,69.8 v28.6 z"                stroke="white"/>          <rect width="43.3" height="100%" fill="black"/>        </mask>      </defs>      <g>        <path id="border"              d="m43.3,8.1 l8,28.6 v41.2 l43.3,90.3 l78.6,69.8 v28.6 z"/>        <path id="fill-left"              d="m46.8,6 l8,28.6 v41.2 l43.3,90.3 l78.6,69.8 v28.6 l-38.8,-22.6"/>        <path id="fill-right"              d="m8,69.8 l43.3,90.3 l78.6,69.8 v28.6 l-38.8,-22.6"/>      </g>    </svg>  </div>    <label>author: srigar</label>

how works.

as mentioned above, in ordere neater start , end, have split mask 2 halves. 1 left half can extend start line (like did end line) , make start point vertical. second can extend end line did earlier.

for clarity, left mask looks like.

.loader path {    stroke-width: 10;    fill: none;  }    .loader svg {    width: 600px;    height: 300px;  }
<div class="loader">    <svg viewbox="0 -10 97.59 119.306">      <rect width="100%" height="100%" fill="black"/>      <path d="m43.3,8.1 l8,28.6 v41.2 l43.3,90.3 l78.6,69.8 v28.6 z"            stroke="white"/>      <rect x="43.3" width="100%" height="100%" fill="black"/>    </svg>  </div>

and here right mask.

.loader path {    stroke-width: 10;    fill: none;  }    .loader svg {    width: 600px;    height: 300px;  }
<div class="loader">    <svg viewbox="0 -10 97.59 119.306">      <rect width="100%" height="100%" fill="black"/>      <path d="m43.3,8.1 l8,28.6 v41.2 l43.3,90.3 l78.6,69.8 v28.6 z"            stroke="white"/>      <rect width="43.3" height="100%" fill="black"/>    </svg>  </div>

if remove masking , make fill lines translucent, can see how arranged work masks.

.loader path {    stroke-width: 10;    fill: none;    stroke-opacity: 0.5;  }    .loader #fill-left,  .loader #fill-right {    stroke:#4c83c4;    animation: dash 5s ease-in-out infinite;  }    .loader #fill-left {    stroke-dasharray: 254;  }    .loader #fill-right {    stroke: red;    stroke-dasharray: 168 254;  }    .loader #border {    stroke:#d6d5d5;  }  .loader svg {    width: 600px;    height: 300px;    display: block;    margin: 0 auto;    margin-bottom: 40px;    opacity: 0.5;    position: relative;  }    @keyframes dash {    0% {      stroke-dashoffset: 254;    }    100% {      stroke-dashoffset: 0;    }  }
<div class="loader">    <svg viewbox="0 -10 97.59 119.306">      <g>        <path id="border"              d="m43.3,8.1 l8,28.6 v41.2 l43.3,90.3 l78.6,69.8 v28.6 z"/>        <path id="fill-left"              d="m46.8,6 l8,28.6 v41.2 l43.3,90.3 l78.6,69.8 v28.6 l-38.8,-22.6"/>        <path id="fill-right"              d="m8,69.8 l43.3,90.3 l78.6,69.8 v28.6 l-38.8,-22.6"/>      </g>    </svg>  </div>


Comments