I am new to working with SVG and animation. I am trying to simply make an animation where a hexagon draws itself starting from the topmost point. However, the animation starts from middle right point. What is the best solution to solve this problem?
.root {
background-color: black;
}
.shape {
fill: none;
stroke: #61fbde;
stroke-width: 3px;
stroke-dasharray: 1300px;
stroke-dashoffset: 1300px;
animation: move 3s linear forwards;
}
#keyframes move {
100% {
stroke-dashoffset: 0;
}
}
<div class="root">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="129.204 94.714 359.102 415.224" width="355.1" height="411.22"><defs><path class="shape" d="M485.31 197.76v206.12L307.76 506.94 130.2 403.88V197.76L307.76 95.71l177.55 102.05z" id="a"/></defs><use xlink:href="#a" fill-opacity="0" stroke="#61fbde"/></svg>
</div>
You will need to change the value of the d attribute so that the path begins where the animation need to begin
.root {
background-color: black;
}
.shape {
fill: none;
stroke: #61fbde;
stroke-width: 3px;
stroke-dasharray: 1300px;
stroke-dashoffset: 1300px;
animation: move 3s linear forwards;
}
#keyframes move {
100% {
stroke-dashoffset: 0;
}
}
<div class="root">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="129.204 94.714 359.102 415.224" width="355.1" height="411.22"><defs><path class="shape" d="
M307.76 95.71
L485.31 197.76
v206.12
L307.76 506.94 130.2 403.88
V197.76
L307.76 95.71
z" id="a"/></defs><use xlink:href="#a" fill-opacity="0" stroke="#61fbde"/></svg>
</div>
Another idea that allows you to start an animation from anywhere without redrawing the shape
Can be used for stroke-dasharray line drawing animation
Move animation start point with stroke-dashoffset
The total line length is 1232px
Completely hidden line -stroke-dasharray = "0, 1232"
The line is visible - stroke-dasharray =" 1232, 0 "
Therefore, for line drawing animations, it is necessary to increase the stroke length from zero to a maximum of -1232px
#keyframes move {
0% {
stroke-dasharray: 0, 1232;
}
100% {
stroke-dasharray: 1232,0;
}
}
In order to move the starting point of the animation to the top of
the hexagon
stroke-dashoffset="205.3"
.root {
width:25%;
height:25%;
background-color: black;
}
.shape {
fill: none;
stroke: #61fbde;
stroke-width: 5px;
stroke-dasharray: 0,1232px;
stroke-dashoffset: 205.3px;
animation: move 3s linear forwards;
}
#keyframes move {
0% {
stroke-dasharray: 0, 1232;
}
100% {
stroke-dasharray: 1232,0;
}
}
<div class="root">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="129.204 94.714 359.102 415.224" >
<defs>
<path class="shape" d="M485.31 197.76v206.12L307.76 506.94 130.2 403.88V197.76L307.76 95.71l177.55 102.05z" id="a" />
</defs>
<use xlink:href="#a" />
</svg>
</div>
Using this approach, you can start the animation from anywhere, for example, from the bottom vertex of the hexagon
Move the start point of the line animation to the bottom of the hexagon stroke-dashoffset: 821.3px;
.root {
width:25%;
height:25%;
background-color: black;
}
.shape {
fill: none;
stroke: #61fbde;
stroke-width: 5px;
stroke-dasharray: 0,1232px;
stroke-dashoffset: 821.3px;
animation: move 3s linear forwards;
}
#keyframes move {
0% {
stroke-dasharray: 0, 1232;
}
100% {
stroke-dasharray: 1232,0;
}
}
<div class="root">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="129.204 94.714 359.102 415.224" >
<defs>
<path class="shape" d="M485.31 197.76v206.12L307.76 506.94 130.2 403.88V197.76L307.76 95.71l177.55 102.05z" id="a" />
</defs>
<use xlink:href="#a" />
</svg>
</div>
An example of drawing from a single point with two symmetrical lines
.root {
width:25%;
height:25%;
background-color: black;
}
.shape {
fill: none;
stroke: #61fbde;
stroke-width: 5px;
stroke-dasharray: 0,1232px;
stroke-dashoffset: 821.3px;
}
<div class="root">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="129.204 94.714 359.102 415.224" >
<defs>
<path class="shape" d="M485.31 197.76v206.12L307.76 506.94 130.2 403.88V197.76L307.76 95.71l177.55 102.05z" id="a" >
<animate attributeName="stroke-dasharray" dur="4s" values="0,616 0,616;0,0 1232,0" repeatCount="indefinite" />
</path>
</defs>
<use xlink:href="#a" />
</svg>
</div>
Hexagon animation example with dicsrete drawing
.root {
width:25%;
height:25%;
background-color: black;
}
.shape {
fill: none;
stroke: #61fbde;
stroke-width: 5px;
stroke-dasharray: 0,1232px;
stroke-dashoffset: 205.3px;
}
<div class="root">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="129.204 94.714 359.102 415.224" >
<defs>
<path class="shape" d="M485.31 197.76v206.12L307.76 506.94 130.2 403.88V197.76L307.76 95.71l177.55 102.05z" id="a" >
<animate
attributeName="stroke-dasharray"
dur="3s"
values="
0,1232;
205.3,1027;
410.6,822;
616,616;
822,410.6;
1027.3,205.3;
1232,0"
calcMode="discrete"
repeatCount="indefinite" />
</path>
</defs>
<use xlink:href="#a" />
</svg>
</div>
Related
I'm trying to reproduce this piece of code (animated button using SVG and CSS):
https://codepen.io/jscottsmith/pen/azRObp/
To keep the code clean, I wanted to use xlink with that. My current code looks as follows:
#import "compass/css3";
body {background:violet}
#keyframes spin {
to { transform: rotate(360deg); }
}
.stroke-dotted {
opacity: 0;
stroke-dasharray: 4,5;
stroke-width: 1px;
transform-origin: 50% 50%;
animation: spin 4s infinite linear;
transition: opacity 1s ease,
stroke-width 1s ease;
}
.stroke-solid {
stroke-dashoffset: 0;
stroke-dashArray: 300;
stroke-width: 4px;
transition: stroke-dashoffset 1s ease,
opacity 1s ease;
}
.icon {
transform-origin: 50% 50%;
transition: transform 200ms ease-out;
}
#play:hover .stroke-dotted {
stroke-width: 4px;
opacity: 1;
}
#play:hover .stroke-solid {
opacity: 0;
stroke-dashoffset: 300;
}
#play:hover .icon {
transform: scale(1.05);
}
#PlayNow {
cursor: pointer;
position: absolute;
top: 50%;
left: 50%;
transform: translateY(-50%) translateX(-50%);
width:10em;
height:auto;
display:block;
}
<a href="#">
<svg xmlns="http://www.w3.org/2000/svg" id="PlayNow" viewBox="0 0 100 100" x="0px" y="0px" ><use xlink:href="#play" id="playTrailerButton" /></svg>
</a>
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="play" viewBox="0 0 100 100">
<path class="stroke-solid" fill="none" stroke="white" d="M49.9,2.5C23.6,2.8,2.1,24.4,2.5,50.4C2.9,76.5,24.7,98,50.3,97.5c26.4-0.6,47.4-21.8,47.2-47.7
C97.3,23.7,75.7,2.3,49.9,2.5"/>
<path class="stroke-dotted" fill="none" stroke="white" d="M49.9,2.5C23.6,2.8,2.1,24.4,2.5,50.4C2.9,76.5,24.7,98,50.3,97.5c26.4-0.6,47.4-21.8,47.2-47.7
C97.3,23.7,75.7,2.3,49.9,2.5"/>
<path class="icon" fill="white" d="M38,69c-1,0.5-1.8,0-1.8-1.1V32.1c0-1.1,0.8-1.6,1.8-1.1l34,18c1,0.5,1,1.4,0,1.9L38,69z"/>
</symbol>
</svg>
But the animation doesn't work.. Any ideas or hints - why? jsfiddle is here:
https://jsfiddle.net/4ztwr3c9/6
You have this:
#PlayNow {
cursor: pointer;
position: absolute;
top: 50%;
left: 50%;
transform: translateY(-50%) translateX(-50%);
width:10em;
height:auto;
display:block;
}
There is no element with the id #PlayNow. The example below has #PlayNow selector replaced by the original #play and your changes have been added, and I removed the Compass as well which I guess you can add it back, just be mindful of each change and retest so it's easier to debug and backtrack.
#keyframes spin {
to {
transform: rotate(360deg);
}
}
.stroke-dotted {
opacity: 0;
stroke-dasharray: 4, 5;
stroke-width: 1px;
transform-origin: 50% 50%;
animation: spin 4s infinite linear;
transition: opacity 1s ease, stroke-width 1s ease;
}
.stroke-solid {
stroke-dashoffset: 0;
stroke-dashArray: 300;
stroke-width: 4px;
transition: stroke-dashoffset 1s ease, opacity 1s ease;
}
.icon {
transform-origin: 50% 50%;
transition: transform 200ms ease-out;
}
#play:hover .stroke-dotted {
stroke-width: 4px;
opacity: 1;
}
#play:hover .stroke-solid {
opacity: 0;
stroke-dashoffset: 300;
}
#play:hover .icon {
transform: scale(1.05);
}
html {
height: 100%;
}
body {
height: 100%;
/*background-color: #30FF98;
background: radial-gradient(#71edb5, #30ff98);*/
}
#play {
cursor: pointer;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
/* Your Changes */
width:10em;
height:auto;
display:block;
}
body {background:violet}
<svg version="1.1" id="play" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" height="100px" width="100px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve">
<path class="stroke-solid" fill="none" stroke="white" d="M49.9,2.5C23.6,2.8,2.1,24.4,2.5,50.4C2.9,76.5,24.7,98,50.3,97.5c26.4-0.6,47.4-21.8,47.2-47.7
C97.3,23.7,75.7,2.3,49.9,2.5"/>
<path class="stroke-dotted" fill="none" stroke="white" d="M49.9,2.5C23.6,2.8,2.1,24.4,2.5,50.4C2.9,76.5,24.7,98,50.3,97.5c26.4-0.6,47.4-21.8,47.2-47.7
C97.3,23.7,75.7,2.3,49.9,2.5"/>
<path class="icon" fill="white" d="M38,69c-1,0.5-1.8,0-1.8-1.1V32.1c0-1.1,0.8-1.6,1.8-1.1l34,18c1,0.5,1,1.4,0,1.9L38,69z"/>
</svg>
You can change/override some properties of a <use> element - provided these are not already set in your <symbol> element (see first example).
Since you need to change the dash-array values for different elements you can use css variables, that could be changed on hover.
body {
background: violet;
}
#keyframes spin {
to {
transform: rotate(360deg);
}
}
:root {
--fill: #fff;
--strokeWidth: 4px;
--scale: 1;
--strokeDashOffset: 10;
--strokeDashArray: 4 5;
--opacity: 0;
--strokeDashArraySolid: 300;
--strokeDashOffsetSolid: 0;
--opacitySolid: 1;
}
.PlayNow {
display: inline-block;
height: 10em;
}
.PlayNow2 {
--fill: #ccc;
--strokeWidth: 6px;
--scale: 1.5;
}
.PlayNow:hover {
--scale: 1.05;
--strokeDashOffset: 10;
--strokeDashArray: 4 5;
--strokeDashArraySolid: 300;
--strokeDashOffsetSolid: 300;
--opacity: 1;
--opacitySolid: 0;
}
#playTrailerButtonSimple:hover {
fill: green!important;
stroke: green!important;
stroke-dasharray: 10 5;
}
<a href="#">
<svg class="PlayNow PlayNowSimple" xmlns="http://www.w3.org/2000/svg" id="PlayNowSimple" viewBox="0 0 100 100">
<use href="#playSimple" id="playTrailerButtonSimple" stroke-width="4" fill="red" stroke="red"/>
</svg> Simple icon
</a>
<a href="#">
<svg class="PlayNow" xmlns="http://www.w3.org/2000/svg" id="PlayNow" viewBox="0 0 100 100">
<use href="#play" id="playTrailerButton" />
</svg>
</a>
<a href="#">
<svg class="PlayNow PlayNow2" xmlns="http://www.w3.org/2000/svg" id="PlayNow2" viewBox="0 0 100 100">
<use href="#play" id="playTrailerButton" />
</svg>
</a>
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="circle">
<path fill="none" style="stroke:var(--fill)" d="M49.9,2.5C23.6,2.8,2.1,24.4,2.5,50.4C2.9,76.5,24.7,98,50.3,97.5c26.4-0.6,47.4-21.8,47.2-47.7 C97.3,23.7,75.7,2.3,49.9,2.5" />
</symbol>
<symbol id="play" viewBox="0 0 100 100">
<use href="#circle" transform-origin="center" class="stroke-solid" style="stroke-width: var(--strokeWidth); stroke-dasharray: var(--strokeDashArraySolid); stroke-dashoffset: var(--strokeDashOffsetSolid); opacity:var(--opacitySolid); transition: stroke-dashoffset 1s ease, opacity 1s ease;" />
<use href="#circle" transform-origin="center" class="stroke-dotted" style="stroke-width: var(--strokeWidth); stroke-dasharray: var(--strokeDashArray); stroke-dashoffset: var(--strokeDashOffset); opacity:var(--opacity); animation: spin 4s infinite linear; transition: opacity 1s ease, stroke-width 1s ease;" />
<path class="icon" transform-origin="center" style="fill:var(--fill);transform:scale(var(--scale));transition:0.3s" d="M38,69c-1,0.5-1.8,0-1.8-1.1V32.1c0-1.1,0.8-1.6,1.8-1.1l34,18c1,0.5,1,1.4,0,1.9L38,69z" />
</symbol>
</svg>
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="circle2">
<path fill="none" d="M49.9,2.5C23.6,2.8,2.1,24.4,2.5,50.4C2.9,76.5,24.7,98,50.3,97.5c26.4-0.6,47.4-21.8,47.2-47.7 C97.3,23.7,75.7,2.3,49.9,2.5" />
</symbol>
<symbol id="playSimple" viewBox="0 0 100 100">
<use href="#circle2" transform-origin="center" class="stroke-solid" />
<path stroke-width="0" class="icon" transform-origin="center" d="M38,69c-1,0.5-1.8,0-1.8-1.1V32.1c0-1.1,0.8-1.6,1.8-1.1l34,18c1,0.5,1,1.4,0,1.9L38,69z" />
</symbol>
</svg>
External <use> reference
To some extent, you could also use external svg files like so:
<a href="#">
<svg class="svgBtn" xmlns="http://www.w3.org/2000/svg" id="PlayNow" viewBox="0 0 100 100" x="0px" y="0px">
<use href="button.svg#play" id="playTrailerButton" style="transition:0.3s"/>
</svg>
</a>
** Drawback:** Your animations/transitions won#t work in most browsers (Firefox can render them)
I have followed this tutorial to get to where I am. So far, I have the animation working for the mask layer. The only issue is that I cannot change the .mask stroke color to #fff like the tutorial. Once I do that, the mask layer seems to disappear and nothing is animated.
Can someone help me understand why I can't make the lines in the "M" look like they are being drawn by the animation?
const masks = ["M"];
masks.forEach((mask, index, el) => {
const id = `#Mask-${mask}`;
let path = document.querySelector(id);
const length = path.getTotalLength();
path.style.strokeDasharray = length;
path.style.strokeDashoffset = length;
});
.Character {
cursor: pointer;
position: absolute;
fill: #000000;
left: 0;
top: 0;
}
#Char-M {
mask: url(#Mask-M);
}
.mask {
fill: none;
stroke: #333;
stroke-miterlimit: 10;
stroke-width: 171px;
stroke-linecap: round;
stroke-linejoin: bevel;
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
}
#keyframes strokeOffset {
to {
stroke-dashoffset: 0;
}
}
#Mask-M {
animation: strokeOffset 3s linear infinite;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 559.4 535.94">
>
<g id="Mask-Layer">
<g id="Mask">
<path id="Mask-M" class="mask" d="M90.89,534.25l-4-412c-.54-16.52-4.5-27.17,4-13l165.23,232.5A28.56,28.56,0,0,0,303,341.3L455.79,95.19c9.49-15.28,18.5-11.92,18.1,6.06l-6,433.5"/>
</g>
</g>
<g id="Character-Layer">
<g id="Character">
<path id="Char-M" data-name="M" d="M241.39,405.9H216L35.81,102.69V526.41H13.18V64.48H38.64Zm-183-236.54L81,207.58V526.41H58.45ZM292.59,405.9H266.87L64.39,64.48H90.17ZM103.72,245.75l22.67,38V526.41H103.72Zm420-143.1L343.58,405.9H317.8L115.66,64.48h25.47L331,384.75,520.56,64.53h25.83V526.41H523.76ZM149,322.22l22.63,37.94V526.41H149Zm151.52-17.57-13.2-21.2,130.77-219h25.78Zm26.09,43.79-12.89-20.92,155.93-263H495.1Zm61.3,9.48L410.54,320V526.41H387.9Zm45.27-77L455.81,243V526.41H433.17ZM478.44,205l22.63-38.21V526.41H478.44Z"/>
</g>
</g>
</svg>
Well, you don't necessarily need a mask, you can just progressively uncover the underlying character by moving the stroke-dasharray of a duplicate over-drawing. Here's a simplified version of yours showing how this would work.
There are some nasty drawing artifacts (in Chrome at least) - because very large strokes often have bad rendering artifacts when you combine them with stroke dash arrays and miters/end-caps. But it does work.
.mask {
stroke: #fff;
fill: none;
stroke-width: 171px;
stroke-dasharray: 1600 1600;
stroke-dashoffset: 3200;
}
#keyframes strokeOffset {
to {
stroke-dashoffset: 1600;
}
}
#Mask-M {
animation: strokeOffset 3s linear infinite;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 559.4 535.94">
<g id="Character-Layer">
<g id="Character">
<path id="Char-M" data-name="M" d="M241.39,405.9H216L35.81,102.69V526.41H13.18V64.48H38.64Zm-183-236.54L81,207.58V526.41H58.45ZM292.59,405.9H266.87L64.39,64.48H90.17ZM103.72,245.75l22.67,38V526.41H103.72Zm420-143.1L343.58,405.9H317.8L115.66,64.48h25.47L331,384.75,520.56,64.53h25.83V526.41H523.76ZM149,322.22l22.63,37.94V526.41H149Zm151.52-17.57-13.2-21.2,130.77-219h25.78Zm26.09,43.79-12.89-20.92,155.93-263H495.1Zm61.3,9.48L410.54,320V526.41H387.9Zm45.27-77L455.81,243V526.41H433.17ZM478.44,205l22.63-38.21V526.41H478.44Z"/>
</g>
</g>
<g id="Mask-Layer">
<g id="Mask">
<path id="Mask-M" class="mask" d="M90.89,534.25l-4-412c-.54-16.52-4.5-27.17,4-13l165.23,232.5A28.56,28.56,0,0,0,303,341.3L455.79,95.19c9.49-15.28,18.5-11.92,18.1,6.06l-6,433.5"/>
</g>
</g>
</svg>
How can I rotate 3 irregular SVG circles around same origin? They are written as a path and reused. I have set transform-origin to center, what else am I missing? They should all be in the same space and overlap in center like in this image
<svg width="900" height="500" viewBox="0 0 900 500">
<defs>
<path id="circle" d="m 43.467262,110.65774 c -2.81733,25.95379 9.663408,54.24201 33.479611,66.3315 12.768318,6.52194 29.493997,6.26667 40.854417,-3.07058 12.79824,-9.29014 25.48168,-19.76411 33.26937,-33.78136 4.54432,-8.49226 5.12542,-19.52979 -0.73083,-27.56368 C 142.27364,100.40343 128.56364,93.579328 115.25185,88.674523 98.350761,82.775856 78.939082,80.223234 62.116925,87.733369 52.940099,92.163321 45.975566,100.79364 43.467262,110.65774 Z" />
</defs>
<g class="group">
<use class="circle circle--1" xlink:href="#circle" />
<use class="circle circle--2" xlink:href="#circle" />
<use class="circle circle--3" xlink:href="#circle" />
</g>
</svg>
svg {
width: 900px;
path {
stroke: #333;
stroke-width: 3px;
fill: transparent;
}
}
g {
position: relative;
transform-origin: center center;
}
.circle {
transform-origin: 50% 50%;
perspective: 500px;
&--1 {
transform: rotateZ(60deg);
}
&--2 {
transform: rotateZ(120deg);
}
&--3 {
transform: rotateZ(180deg);
}
}
https://codepen.io/anon/pen/mQdLvX
You want transform-box: fill-box; i.e.
.circle {
transform-box: fill-box;
transform-origin: 50% 50%;
perspective: 500px;
&--1 {
transform: rotateZ(60deg);
}
&--2 {
transform: rotateZ(120deg);
}
&--3 {
transform: rotateZ(180deg);
}
}
When the svg draw is not centered on the canvas, this gets a bit more difficult. I've ajusted the SVG viewBox values, take a look at the following snippet:
svg {
border: 1px solid red;
}
svg path {
stroke: #333;
stroke-width: 3px;
fill: transparent;
}
.circle {
transform-origin: 50% 50%;
}
.circle--1 {
transform: rotateZ(90deg);
}
.circle--2 {
transform: rotateZ(160deg);
}
.circle--3 {
transform: rotateZ(270deg);
}
<svg width="900" height="500" viewBox="0 0 250 250">
<defs>
<path id="circle" d="m 43.467262,110.65774 c -2.81733,25.95379 9.663408,54.24201 33.479611,66.3315 12.768318,6.52194 29.493997,6.26667 40.854417,-3.07058 12.79824,-9.29014 25.48168,-19.76411 33.26937,-33.78136 4.54432,-8.49226 5.12542,-19.52979 -0.73083,-27.56368 C 142.27364,100.40343 128.56364,93.579328 115.25185,88.674523 98.350761,82.775856 78.939082,80.223234 62.116925,87.733369 52.940099,92.163321 45.975566,100.79364 43.467262,110.65774 Z" />
</defs>
<g class="group">
<use class="circle circle--1" xlink:href="#circle" />
<use class="circle circle--2" xlink:href="#circle" />
<use class="circle circle--3" xlink:href="#circle" />
</g>
</svg>
I'm working on SVG animations with CSS and I've noticed that with my line drawing animations, any SVG rect (#clipboard-border and #clipboard-clip-border) stroke always excludes a bit of the top-left corner, which makes it an incomplete rectangle.
I've tried adjusting the stroke-dasharray and stroke-dashoffset measurements within the CSS, as well as adjusting the sizes and pixel coordinated within the SVG code, but neither are the problem it seems. Help?
html,
body {
width: 100%;
height: 100%;
background-color: #CECECE;
}
div {
text-align: center;
}
svg {
display: inline-block;
width: 120px;
margin: 3% auto;
padding: 0px 100px;
}
/* ---------------------
SVG RULES
--------------------- */
/* All grey strokes */
#clipboard-border,
.clipboard-content,
.clipboard-borders,
.mech-pencil-borders {
fill: none;
stroke: #4D5152;
stroke-width: 6;
stroke-miterlimit: 10;
}
/* All things white */
#clipboard-paper-fill,
#mech-pencil-eraser-fill {
fill: #F3F7F6;
}
/* All things green */
#mech-pencil-point-fill,
#mech-pencil-top-fill {
fill: #25B686;
}
/* All things blue */
#clipboard-fill {
fill: #85D0D3;
}
/* All things yellow */
#clipboard-clip-fill,
#mech-pencil-grip {
fill: #FBFBCE;
}
#clipboard-knob-1,
#clipboard-knob-2,
#clipboard-knob-3,
#mech-pencil-bottom-btn,
#mech-pencil-top-btn {
stroke-dasharray: 8px;
stroke-dashoffset: 8px;
animation: trace .5s ease-out forwards;
}
/* ---------------------
ANIMATION KEYFRAMES
--------------------- */
#keyframes trace {
100% {
stroke-dashoffset: 0px;
}
}
#keyframes fill-it {
100% {
opacity: 1;
}
}
#keyframes grow {
0% {
transform: scale(0);
}
30% {
transform: scale(1.1);
}
60% {
transform: scale(.9);
}
}
/* ---------------------
SVG ANIMATION: INSIGHT & PLANNING ICON
--------------------- */
#clipboard-clip-border {
stroke-dasharray: 180px;
stroke-dashoffset: 180px;
animation: trace .2s ease-out forwards;
}
#clipboard-clip-fill {
opacity: 0;
animation: fill-it .2s .2s ease-in-out forwards;
}
#clipboard-border {
stroke-dasharray: 640px;
stroke-dashoffset: 640px;
animation: trace 1.25s ease-in-out forwards;
}
#clipboard-fill,
#mech-pencil-point-fill,
#mech-pencil-top-fill {
opacity: 0;
animation: fill-it .25s 1.25s ease-in-out forwards;
}
#clipboard-paper-border {
stroke-dasharray: 400px;
stroke-dashoffset: 400px;
animation: trace 1s ease-out forwards;
}
#clipboard-paper-fill,
#mech-pencil-eraser-fill,
#mech-pencil-grip {
opacity: 0;
animation: fill-it .75s 1s ease-in-out forwards;
}
#clipboard-content-line-1 {
stroke-dasharray: 30px;
stroke-dashoffset: 30px;
animation: trace .5s ease-out forwards;
}
#clipboard-content-line-7,
#clipboard-clip-detail {
stroke-dasharray: 52px;
stroke-dashoffset: 52px;
animation: trace .5s ease-out forwards;
}
#clipboard-content-line,
#clipboard-content-line-even,
#mech-pencil-eraser-border {
stroke-dasharray: 80px;
stroke-dashoffset: 80px;
animation: trace .75s ease-out forwards;
}
#mech-pencil-border-left,
#mech-pencil-border-right {
stroke-dasharray: 115px;
stroke-dashoffset: 115px;
animation: trace .75s ease-out forwards;
}
#mech-pencil-point-border {
stroke-dasharray: 60px;
stroke-dashoffset: 60px;
animation: trace .5s ease-out forwards;
}
#mech-pencil-tip,
#mech-pencil-top {
stroke-dasharray: 10px;
stroke-dashoffset: 10px;
animation: trace .4s ease-out forwards;
}
/* ---------------------
ANIMATION DELAYS
--------------------- */
#clipboard-knob-1,
#clipboard-knob-2 {
animation-delay: .25s;
}
#clipboard-clip-detail,
#clipboard-content-line,
#clipboard-content-line-7,
#clipboard-knob-2 {
animation-delay: .5s;
}
#mech-pencil-bottom-btn,
#mech-pencil-top-btn {
animation-delay: 1.25s;
}
<div class="wrapper">
<!-- INSIGHT & PLANNING ICON -->
<svg id="insight-planning" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="200px" height="200px" viewBox="0 0 200 200">
<g class="clipboard">
<rect id="clipboard-fill" x="15.015" y="11.44" width="132" height="182" />
<rect id="clipboard-paper-fill" x="30.753" y="11.44" width="100" height="151" />
<g class="clipboard-content">
<line id="clipboard-content-line-even" x1="46.491" y1="68.096" x2="115.738" y2="68.096" />
<line id="clipboard-content-line" x1="46.491" y1="80.687" x2="115.738" y2="80.687" />
<line id="clipboard-content-line-even" x1="46.491" y1="93.277" x2="115.738" y2="93.277" />
<line id="clipboard-content-line" x1="46.491" y1="105.867" x2="115.738" y2="105.867" />
<line id="clipboard-content-line-even" x1="46.491" y1="118.458" x2="115.738" y2="118.458" />
<line id="clipboard-content-line-7" x1="46.491" y1="131.048" x2="96.852" y2="131.048" />
<line id="clipboard-content-line-1" x1="115.738" y1="49.211" x2="90.557" y2="49.211" />
</g>
<rect id="clipboard-border" x="15.015" y="11.44" width="132" height="182" />
</g>
<g class="mech-pencil-fills">
<rect id="mech-pencil-grip" x="166.099" y="96.425" width="18" height="47" />
<rect id="mech-pencil-top-fill" x="166.099" y="30.325" width="18" height="66" />
<rect id="mech-pencil-eraser-fill" x="166.099" y="11.44" width="18" height="18" />
<polygon id="mech-pencil-point-fill" points="184.985,143.639 184.985,159.376 175.542,168.819 166.099,159.376 166.099,143.639" />
</g>
<g class="mech-pencil-borders">
<line id="mech-pencil-border-left" x1="166.099" y1="143.639" x2="166.099" y2="30.325" />
<line id="mech-pencil-border-right" x1="184.985" y1="30.325" x2="184.985" y2="145" />
<rect id="mech-pencil-eraser-border" x="166.099" y="11.44" width="18" height="18" />
<polygon id="mech-pencil-point-border" points="184.985,143.639 184.985,159.376 175.542,168.819 166.099,159.376 166.099,143.639" />
<line id="mech-pencil-top" x1="175.542" y1="11.44" x2="175.542" y2="1.997" />
<line id="mech-pencil-tip" x1="175.542" y1="168.819" x2="175.542" y2="175.114" />
<line id="mech-pencil-bottom-btn" x1="175.542" y1="127.901" x2="175.542" y2="121.605" />
<line id="mech-pencil-top-btn" x1="175.542" y1="115.31" x2="175.542" y2="109.015" />
</g>
<g class="clipboard-clip">
<rect id="clipboard-clip-fill" x="49.639" y="5.144" width="62" height="25" />
</g>
<g class="clipboard-borders">
<polyline id="clipboard-paper-border" points="131.476,11.44 131.476,162.524 30.753,162.524 30.753,11.44" />
<rect id="clipboard-clip-border" x="49.639" y="5.144" width="62" height="25" />
<line id="clipboard-clip-detail" x1="59.081" y1="17.735" x2="103.148" y2="17.735" />
<line id="clipboard-knob-1" x1="65.376" y1="178.262" x2="71.672" y2="178.262" />
<line id="clipboard-knob-2" x1="77.967" y1="178.262" x2="84.262" y2="178.262" />
<line id="clipboard-knob-3" x1="90.557" y1="178.262" x2="96.852" y2="178.262" />
</g>
</svg>
</div>
Also posted in Codepen.
Just add stroke-linecap: square; to the CSS declarations for the SVG object.
svg {
display: inline-block;
width: 120px;
margin: 3% auto;
padding: 0px 100px;
stroke-linecap: square; /* <-- Add this */
}
Example:
Here's an SVG with two paths (open, not closed). The path drawn with "butt" line endings has a bit missing in the top corner, but the other path (drawn with "square" line endings) doesn't have this issue.
<svg width="250" height="100" viewBox="0 0 250 100">
<path d="M10 10h80v80h-80v-80" style="stroke:#000; stroke-width:10px; fill:none; stroke-linecap: square;"/>
<text x="50" y="70" text-anchor="middle">Square</text>
<path d="M160 10h80v80h-80v-80" style="stroke:#000; stroke-width:10px; fill:none; stroke-linecap: butt;"/>
<text x="200" y="70" text-anchor="middle">Butt</text>
</svg>
P.S. I like your work, but next time please consider making a minimal, complete and verifiable example to illustrate the problem. That way people won't have to wade through reams of code to discover what's going wrong :-)
I have a hexagon shaped polygon with a stroke around it. I want to animate that stroke, which I've done, but I would love to have it start in a different place on the polygon.
This is the CSS that I have right now which works, I just want to change where the animation starts from.
.outline1 {
fill: none;
stroke: #0d72b9;
stroke-miterlimit: 10;
stroke-width: 3px;
}
g.icon .outline1 {
stroke-dasharray: 808;
stroke-dashoffset:808;
transition:all 300ms ease-in-out;
fill:transparent;
}
g.icon:hover .outline1{
stroke-dashoffset:0;
cursor: pointer;
}
This is the svg
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 764.87 535.94">
<g class="regional icon">
<polygon class="cls-3 outline1" points="113.52 134.89 229.99 67.64 346.47 134.89 346.47 269.38 229.99 336.62 113.52 269.38 113.52 134.89"/>
</g>
</svg>
The animation starts in the upper left corner but I'd like it to start in the bottom left.
The stroke starts where the path/polygon starts...change the start point.
svg {
height: 250px;
display: block;
margin: 1em auto;
border: 1px solid grey;
}
.outline1 {
fill: none;
stroke: #0d72b9;
stroke-miterlimit: 10;
stroke-width: 10px;
}
g.icon .outline1 {
stroke-dasharray: 808;
stroke-dashoffset: 808;
transition: all 1000ms ease-in-out;
fill: pink;
}
g.icon:hover .outline1 {
stroke-dashoffset: 0;
cursor: pointer;
}
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 764.87 535.94">
<g class="regional icon">
<polygon class="cls-3 outline1" points=" 113.52 269.38 113.52 134.89 229.99 67.64 346.47 134.89 346.47 269.38 229.99 336.62 113.52 269.38 " />
</g>
</svg>
You just need to change your start point.
Here it's a right way to do it.
.outline1 {
fill: none;
stroke: #0d72b9;
stroke-miterlimit: 10;
stroke-width: 3px;
}
g.icon .outline1 {
stroke-dasharray: 808;
stroke-dashoffset:808;
transition:all 300ms ease-in-out;
fill:transparent;
}
g.icon:hover .outline1{
stroke-dashoffset:0;
cursor: pointer;
}
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 764.87 535.94">
<g class="regional icon">
<polygon class="cls-3 outline1" points="113.52 202.135 113.52 134.89 229.99 67.64 346.47 134.89 346.47 269.38 229.99 336.62 113.52 269.38"/>
</g>
</svg>
For symmeterical shapes, it is much easier to add a CCS that directly rotate the shape.
.outline1 {
fill: none;
stroke: #0d72b9;
stroke-miterlimit: 10;
stroke-width: 3px;
}
g.icon .outline1 {
stroke-dasharray: 808;
stroke-dashoffset:808;
transition:all 300ms ease-in-out;
fill:transparent;
}
g.icon:hover .outline1{
stroke-dashoffset:0;
cursor: pointer;
}
.outline1 {
-ms-transform: rotate(60deg); /* IE 9 */
-ms-transform-origin: 50% 50%; /* IE 9 */
-webkit-transform: rotate(60deg); /* Chrome, Safari, Opera */
-webkit-transform-origin: 50% 50%; /* Chrome, Safari, Opera */
transform: rotate(60deg);
transform-origin: 50% 50%;
}
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 764.87 535.94">
<g class="regional icon">
<polygon class="cls-3 outline1" points="113.52 134.89 229.99 67.64 346.47 134.89 346.47 269.38 229.99 336.62 113.52 269.38 113.52 134.89"/>
</g>
</svg>