Related
I have been playing around with this for hours and trying to think up a solution.
In this... https://jsfiddle.net/WebFlair/nc0zyjdq/78/
<div class="bg">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="400.000000pt" height="400.000000pt" viewBox="0 0 400.000000 400.000000"
preserveAspectRatio="xMidYMid meet">
<path class="path" fill="none" stroke="#b0225e" stroke-linejoin="round" stroke-width="5" stroke-miterlimit="10" d="M23.742,10.709
c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
c19.17,28.697,49.512,49.927,78.596,67.591"/>
<path class="dashed" fill="none" stroke="white" stroke-width="7" stroke-linejoin="round" stroke-miterlimit="16" d="M23.742,10.709
c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
c19.17,28.697,49.512,49.927,78.596,67.591"/>
</svg>
</div>
<style>
.bg {background:#eee;}
.dashed{
stroke-dasharray: 14;
}
.path {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: dash 5s linear alternate forwards;
}
#keyframes dash {
from {
stroke-dashoffset: 1000;
}
to {
stroke-dashoffset: 0;
}
}
</style>
You will see a grey background and an animated white and pink dashed line.
Now I know this wont work in my example, but what I am trying to do is make the white part transparent so that it can be used on any background, keep the animation and the pink dashed line.
Can anyone think of a way to make that happen? I have gone over everything I can think of and always need the white part in order to keep the animation.
but what I am trying to do is make the white part transparent so that
it can be used on any background, keep the animation and the pink
dashed line.
The idea is as follows: use three layers
The first bottom layer will have a white path
The middle layer will have exactly the same pink path
There will be a masking path on the top layer, which will gradually
reveal the pink path
This uses the property of the mask when "stroke: white" shows the section of the pink path that is under it
And since the length of the masking path changes from zero to the maximum value (stroke-dashoffset decreases from the maximum 917 to zero), the growth of the pink path becomes visible
#keyframes dash {
from {
stroke-dashoffset: 917;
}
to {
stroke-dashoffset: 0;
}
Clarification the maximum path length is 917px
1. The first bottom layer will have a white path
.bg {background:#eee;}
#dashed {
stroke-dasharray: 14;
fill:none;
stroke:white;
stroke-width:7;
stroke-linejoin:round;
}
<div class="bg">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="400.000000pt" height="400.000000pt" viewBox="0 0 400.000000 400.000000"
preserveAspectRatio="xMidYMid meet">
<!-- Bottom layer dashed white line -->
<path id="dashed" d="M23.742,10.709
c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
c19.17,28.697,49.512,49.927,78.596,67.591"/>
</svg>
</div>
<script>
console.log(dashed.getTotalLength());
</script>
2. The middle layer will have exactly the same pink path
<style>
.bg {background:#eee;}
#dashed {
stroke-dasharray: 14;
fill:none;
stroke:white;
stroke-width:7;
stroke-linejoin:round;
}
#pink {
stroke-dasharray: 14;
fill:none;
stroke:#b0225e;
stroke-width:7;
stroke-linejoin:round;
mask:url(#msk);
}
<div class="bg">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="400.000000pt" height="400.000000pt" viewBox="0 0 400.000000 400.000000"
preserveAspectRatio="xMidYMid meet">
<!-- Bottom layer dashed white line -->
<path id="dashed" d="M23.742,10.709
c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
c19.17,28.697,49.512,49.927,78.596,67.591"/>
<!-- Middle layer dashed pink line -->
<path id="pink" d="M23.742,10.709
c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
c19.17,28.697,49.512,49.927,78.596,67.591"/>
</svg>
</div>
3. There will be a masking path on the top layer, which will gradually reveal the pink path
.bg {background:#eee;}
#dashed {
stroke-dasharray: 14;
fill:none;
stroke:white;
stroke-width:7;
stroke-linejoin:round;
}
#pink {
stroke-dasharray: 14;
fill:none;
stroke:#b0225e;
stroke-width:7;
stroke-linejoin:round;
mask:url(#msk);
}
#maskLine {
fill:none;
stroke:white;
stroke-width:7;
stroke-dasharray: 917;
stroke-dashoffset: 917;
animation: dash 5s linear alternate forwards;
}
#keyframes dash {
from {
stroke-dashoffset: 917;
}
to {
stroke-dashoffset: 0;
}
}
<div class="bg">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="400.000000pt" height="400.000000pt" viewBox="0 0 400.000000 400.000000"
preserveAspectRatio="xMidYMid meet">
<defs>
<mask id="msk">
<!-- A mask layer that reveals a dashed pink line -->
<path id="maskLine" d="M23.742,10.709
c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
c19.17,28.697,49.512,49.927,78.596,67.591"/>
</mask>
</defs>
<!-- Bottom layer dashed white line -->
<path id="dashed" d="M23.742,10.709
c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
c19.17,28.697,49.512,49.927,78.596,67.591"/>
<!-- Middle layer dashed pink line -->
<path id="pink" d="M23.742,10.709
c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
c19.17,28.697,49.512,49.927,78.596,67.591"/>
</svg>
</div>
UPDATE
Filling, clearing the path on repeated clicks on the button "Play"
var dash = true;
function play() {
var path = document.getElementById('maskLine');
path.style.strokeDashoffset = (dash) ? '0' : '917.00';
dash = !dash;
}
.bg {background:#eee;}
#dashed {
stroke-dasharray: 14;
fill:none;
stroke:white;
stroke-width:7;
stroke-linejoin:round;
}
#pink {
stroke-dasharray: 14;
fill:none;
stroke:#b0225e;
stroke-width:7;
stroke-linejoin:round;
mask:url(#msk);
}
#maskLine {
fill:none;
stroke:white;
stroke-width:7;
stroke-dasharray: 917;
stroke-dashoffset: 917;
transition: stroke-dashoffset 5s linear;
}
<button onclick="play();">Play</button>
<div class="bg">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="400.000000pt" height="400.000000pt" viewBox="0 0 400.000000 400.000000"
preserveAspectRatio="xMidYMid meet">
<defs>
<mask id="msk">
<!-- A mask layer that reveals a dashed pink line -->
<path id="maskLine" d="M23.742,10.709
c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
c19.17,28.697,49.512,49.927,78.596,67.591">
</path>
</path>
</mask>
</defs>
<!-- Bottom layer dashed white line -->
<path id="dashed" d="M23.742,10.709
c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
c19.17,28.697,49.512,49.927,78.596,67.591"/>
<!-- Middle layer dashed pink line -->
<path id="pink" d="M23.742,10.709
c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
c19.17,28.697,49.512,49.927,78.596,67.591"/>
</svg>
</div>
You can do it using a mask:
.bg {
background: #eee;
}
.dashed {
stroke-dasharray: 14;
}
.path {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: dash 5s linear alternate forwards;
}
#keyframes dash {
from {
stroke-dashoffset: 1000;
}
to {
stroke-dashoffset: 0;
}
}
<div class="bg">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="400.000000pt" height="400.000000pt" viewBox="0 0 400.000000 400.000000" preserveAspectRatio="xMidYMid meet">
<defs>
<path id="dashed" class="dashed" fill="none" stroke="white" stroke-width="7" stroke-linejoin="round" stroke-dasharray="14" stroke-miterlimit="16" d="M23.742,10.709
c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
c19.17,28.697,49.512,49.927,78.596,67.591"/>
<mask id="mask">
<use xlink:href="#dashed"/>
</mask>
</defs>
<path class="path" fill="none" stroke="#b0225e" stroke-linejoin="round" stroke-width="5" stroke-miterlimit="10" mask="url(#mask)" d="M23.742,10.709
c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
c19.17,28.697,49.512,49.927,78.596,67.591"/>
</svg>
</div>
You can also eliminate the duplicate path declaration by reusing the path defined in defs, but this would require additional changes, so, in order to not obfuscate things, I decided to not put that in my answer.
I'm using the "use xlink:ref" tag to render a polyline that's defined in the "defs" tag and animate it. I want to also use xlink:ref to render the same polyline, but without the animation, i.e., as just a static object. But all three instances of the "use xlink:ref" that I render animate, even though there's no animation associated with two of them!? How can I have only one of the three instances of it animate? I don't understand why SVG thinks I want the other 2 instances to animate. Thanks for any help!
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="600" height="600" viewBox="0 0 600 600">
<defs>
<marker id="mCircle" markerWidth="160" markerHeight="160" refX="80" refY="80" markerUnits="userSpaceOnUse">
<circle cx="80" cy="80" r="70" style="fill: red; stroke: black; stroke-width: 5px; opacity:0.2"/>
</marker>
<marker id="mMid" markerWidth="100" markerHeight="100" refX="50" refY="50" markerUnits="userSpaceOnUse" >
<circle cx="50" cy="50" r="6" style="fill: black; stroke: none; stroke-width:4px; opacity:1"/>
</marker>
<path d="M 0,0 60,0 120,0 180,0 240,0 300,0 360,0" id="linered" style="marker-start: url(#mCircle); marker-end: url(#mCircle); marker-mid: url(#mMid); stroke-width: 12; fill:none; stroke-linejoin:round; stroke-linecap:round; stroke-opacity: 0.6"/>
</defs>
<use xlink:href="#linered" transform="translate(120, 280)" style="stroke-dasharray:222; stroke-dashoffset:-70px; stroke:orange;"/>
<animate
xlink:href="#linered"
attributename="d"
dur="2s"
begin="1s;"
values= "M 0 0, 60 0, 120 0, 180 0, 240 0, 300 0, 360 0;
M 180 0, 60 40, 120 -30, 180 60, 240 220, 300 60, 180 0;
M 180 0, 60 -33, 120 60, 180 -90, 240 70, 300 0, 180 0;
M 180 0, 60 40, 120 -30, 180 60, 240 220, 300 60, 180 0;
M 0 0, 60 0, 120 0, 180 0, 240 0, 300 0, 360 0;"
keySplines= "0 0.8 0.3 1; 0 0.8 0.3 1; 0 0.8 0.3 1; 0 0.8 0.3 1;"
keyTimes= "0; 0.33; 0.5; 0.66; 1"
calcMode="spline"
repeatcount="4"
/>
<g transform="translate(300 280)">
<use id="static1" xlink:href="#linered" x="-180" y="0" transform="rotate(60)" style="stroke-dasharray:222; stroke-dashoffset:-70px; stroke:blue;"/>
<use id="static2" xlink:href="#linered" x="-180" y="0" transform="rotate(120)" style="stroke-dasharray:222; stroke-dashoffset:-70px; stroke:white;"/>
</g>
</svg>
First, there are a few errors in your code concerning upper case letters in attributes. While Chrome seems to be a bit more forgiving (as defined in SVG v2), other browsers still adhere to SVG v1.1, which is fully XML-compliant in this regard. So you should always use case-sensitive markerUnits, attributeName and repeatCount attributes.
Your main problem is what you are animating:
<animate xlink:href="#linered" attributeName="d" ... />
Your animation references the <path id="linered" /> element, which is the template from which each <use> is derived. Each of them copies the whole template, including its animation.
Please note that your <animate> tag is a sibling to the <use> tag it is positioned next to. Both are self-closing tags, and there is no connection between those two exept their placement in the source code next to each other - but that is incitental.
The connection between an element and its animation can only be established in two ways.
an <animate> element is the child of the animated element (do not use the xlink:href attribute for this syntax):
<path ...>
<animate ... />
</path>
an <animate> element, positioned anywhere in the same svg fragment, references the animated element:
<path id="target"... />
<!-- other content -->
<animate xlink:href="#target" ... />
If you want to animate one <use> element, but not the others, you need to animate that element. For example you could animate a transform attribute set on the <use> element. But the d attribute you want to animate is part of the referenced <path> element.
The <use> element is no stand-in for what it is referencing, but conceptually a container that hides a copy of its reference inside (in what is called a Shadow DOM). This copy cannot be referenced with a url, or a CSS selector. It cannot be animated individually.
The only solution is to write down the element to be animated seperately (note the id):
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="600" height="600" viewBox="0 0 600 600">
<defs>
<marker id="mCircle" markerWidth="160" markerHeight="160" refX="80" refY="80" markerUnits="userSpaceOnUse">
<circle cx="80" cy="80" r="70" style="fill: red; stroke: black; stroke-width: 5px; opacity:0.2"/>
</marker>
<marker id="mMid" markerWidth="100" markerHeight="100" refX="50" refY="50" markerUnits="userSpaceOnUse" >
<circle cx="50" cy="50" r="6" style="fill: black; stroke: none; stroke-width:4px; opacity:1"/>
</marker>
<path id="linered" d="M 0,0 60,0 120,0 180,0 240,0 300,0 360,0" style="marker-start: url(#mCircle); marker-end: url(#mCircle); marker-mid: url(#mMid); stroke-width: 12; fill:none; stroke-linejoin:round; stroke-linecap:round; stroke-opacity: 0.6"/>
</defs>
<path id="linered-animated" transform="translate(120, 280)" d="M 0,0 60,0 120,0 180,0 240,0 300,0 360,0" style="marker-start: url(#mCircle); marker-end: url(#mCircle); marker-mid: url(#mMid); stroke-width: 12; fill:none; stroke-linejoin:round; stroke-linecap:round; stroke-opacity: 0.6;stroke-dasharray:222; stroke-dashoffset:-70px; stroke:orange;"/>
<animate
xlink:href="#linered-animated"
attributeName="d"
dur="2s"
begin="1s;"
values= "M 0 0, 60 0, 120 0, 180 0, 240 0, 300 0, 360 0;
M 180 0, 60 40, 120 -30, 180 60, 240 220, 300 60, 180 0;
M 180 0, 60 -33, 120 60, 180 -90, 240 70, 300 0, 180 0;
M 180 0, 60 40, 120 -30, 180 60, 240 220, 300 60, 180 0;
M 0 0, 60 0, 120 0, 180 0, 240 0, 300 0, 360 0;"
keySplines="0 0.8 0.3 1; 0 0.8 0.3 1; 0 0.8 0.3 1; 0 0.8 0.3 1;"
keyTimes= "0; 0.33; 0.5; 0.66; 1"
calcMode="spline"
repeatCount="4"
/>
<g transform="translate(300 280)">
<use id="static1" xlink:href="#linered" x="-180" y="0" transform="rotate(60)" style="stroke-dasharray:222; stroke-dashoffset:-70px; stroke:blue;"/>
<use id="static2" xlink:href="#linered" x="-180" y="0" transform="rotate(120)" style="stroke-dasharray:222; stroke-dashoffset:-70px; stroke:white;"/>
</g>
</svg>
As a footnote only, it seems that the xlink:href attribute in an <animate> element has a bug in Firefox where the animation is never applied to a referencing <use> element.
I'm an SVG noob and am trying to animate this Squid. I can't understand why the right arm is keeps anchoring itself to the top left of the viewbox as well as anything that I animate. I've created a css animation property to try to counteract it but I feel like there is an underlying issue or a better way to do this/fix this.
I've changed the color of the right arm to red. I want it to do what the left arm is doing.
Hopefully you guys can help.
Here is my SVG Code
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
x="0px" y="0px" width="220px" height="192.8px" viewBox="0 0 80 192.8" style="enable-background:new 0 0 128 192.8;"
xml:space="preserve" preserveAspectRatio="xMidyMax meet">
<defs>
</defs>
<g class="squid">
<path id="left-arm" class="left-arm" d="M6,20.8c0,0,21.3,0,21.3,21.2c0,21.2-20.8,18.4-20.8,41.4c0,22.6,36.7,34.4,52.9-8.9"/>
<path id="right-arm" class="right-arm" d="M122,20.8c0,0-21.3,0-21.3,21.2c0,21.2,20.8,18.4,20.8,41.4c0,22.6-36.7,34.4-52.8-8.9"/>
<g>
<path id="lightning" class="lightning" d="M65.2,43.7L67.7,56l3.1,15.9L63.4,56L52.9,33.2l9.9-0.4l-5-27.6l17.3,38L65.2,43.7z"/>
</g>
<path id="left-mid-arm" class="left-mid-arm" d="M58.5,99.6c-31.1,25.5-50,28.7-50,50.8c0,15.8,10.2,22.9,16,26.6"/>
<path id="right-mid-arm" class="right-mid-arm" d="M69.7,99.6c31.1,25.5,50,28.7,50,50.8c0,15.8-10.2,22.9-16,26.6"/>
<g>
<g>
<path id="right-leg" class="right-leg" d="M68.5,108.9c4,2.5,8.9,8.6,7.2,21.3c-0.1,0.4-0.1,0.8-0.2,1.2"/>
<path id="right-foot" class="right-foot" d="M51.6,156.8c-2.3,3-3.8,6.8-3.8,12.1c0,5.1,1.4,8.8,3.1,11.5"/>
</g>
</g>
<path id="left-leg" class="left-leg" d="M63.8,107.6c0,0-14.3,0.3-11.6,20.6c2.8,20.8,27.9,19,27.9,40.6c0,14.6-11.2,18-11.2,18"/>
<g class="body">
<path id="body" d="M85.6,91.1c-0.9-0.7-1.4-1.4-1.7-1.9c-1.5-1.9-2.7-5.9-0.5-6h1.4c2.8,0,5-2.2,5-5v-0.4c0-4.5-5.1-5.2-5.2-5.3
c-2-0.8-3.4-2.7-3.4-5c0-2.3,1.5-4.3,3.5-5c0.1-0.1,5.1-1.5,5-5.1V5c0-2.8-2.2-5-5-5h-42c-2.8,0-5,2.2-5,5v52.4
c0,2.4,1.7,4.4,3.9,4.9c0.2,0,1.1,0.2,1.2,0.3c2,0.8,3.5,2.7,3.5,5c0,2.2-1.4,4.1-3.3,4.9c-0.1,0.1-5.4,1.2-5.3,5.3v0.4
c0,2.8,2.2,5,5,5h1.5c2.3,0,1.6,4.4,0,6c-0.8,0.8-1.7,2.1-3.6,3.5l23.4,8.9L85.6,91.1z M65,43.7L67.4,56l3.1,15.9L63.2,56
L52.7,33.2l9.9-0.4l-5-27.6l17.3,38L65,43.7z"/>
</g>
<animate
xlink:href="#left-arm"
attributeName="d"
dur="2s"
begin="0s"
repeatCount="indefinite"
values="
M6,20.8c0,0,21.3,0,21.3,21.2c0,21.2-20.8,18.4-20.8,41.4c0,22.6,36.7,34.4,52.9-8.9;
M37.9,6.8c0,0,2.8-5.8-6.5,13.3c-12.6,25.9-40.3,64-15,78c20.2,11.2,41-11.5,57.1-54.9;
M20.9,63.7c0,0,0,0-4.2,4.4c-5.2,5.5-21.2,30.8-0.2,40.5C44.5,121.4,62.7,49.3,78.9,6;
M37.9,6.8c0,0,2.8-5.8-6.5,13.3c-12.6,25.9-40.3,64-15,78c20.2,11.2,41-11.5,57.1-54.9;
M6,20.8c0,0,21.3,0,21.3,21.2c0,21.2-20.8,18.4-20.8,41.4c0,22.6,36.7,34.4,52.9-8.9;
Z;"/>
<animate
xlink:href="#right-arm"
attributeName="d"
dur="2s"
begin="0s"
repeatCount="indefinite"
values="
M122,20.8c0,0-21.3,0-21.3,21.2c0,21.2,20.8,18.4,20.8,41.4c0,22.6-36.7,34.4-52.8-8.9;
M40.3,6.2c0,0-2.3-3.1,10.4,14c12.7,17,44.3,62.7,22,78.3C49.9,114.5,22.2,86.7,6,43.4;
M64,63.7c0,0,0,0,4.2,4.4c5.2,5.5,21.2,30.8,0.2,40.5C40.4,121.4,22.2,49.3,6,6;
M40.3,6.2c0,0-2.3-3.1,10.4,14c12.7,17,44.3,62.7,22,78.3C49.9,114.5,22.2,86.7,6,43.4;
M122,20.8c0,0-21.3,0-21.3,21.2c0,21.2,20.8,18.4,20.8,41.4c0,22.6-36.7,34.4-52.8-8.9;
Z;"/>
</g>
</svg>
CSS
.left-arm,
.right-arm,
.right-leg,
.left-leg,
.right-foot,
.left-mid-arm,
.right-mid-arm{
fill:none;
stroke:#000000;
stroke-width:12;
stroke-linecap:round;
stroke-miterlimit:10;
}
g.squid {
margin-left:20px;
}
.lightning {
fill:white;
}
g.body {
fill:black;
}
.left-arm {
animation: left-arm 2s infinite;
}
.right-arm {
animation: right-arm 2s infinite;
}
#keyframes left-arm {
0% {transform: translate(0px,0px);}
20% {transform: translate(0px,0px);}
40% {transform: translate(-15px,50px);}
80% {transform: translate(0px,0px);}
100% {transform: translate(0px,0px);}
}
#keyframes right-arm {
0% {transform: translate(0px,0px);}
20% {transform: translate(0px,0px);}
40% {transform: translate(60px,50px);}
80% {transform: translate(0px,0px);}
100% {transform: translate(0px,0px);}
}
Here is a link to codepen
http://codepen.io/alcoven/pen/NbRNdd
So after a day of working at this I figured out that an elements position is specific to its surrounding elements. I was copying and pasting single paths from AI into a codepen and the actual vector information was aligned to the top left because the other shapes were not pasted along with it for reference. I ended up changing the actual vector numbers to align the shapes. The only one I had to change was the M#'s and the following number after the comma in front of each value.
<animate
xlink:href="#left-arm"
attributeName="d"
dur="1s"
begin="squid.mouseover"
end="squid.mouseout"
repeatCount="indefinite"
values="
M6,20.8c0,0,21.3,0,21.3,21.2c0,21.2-20.8,18.4-20.8,41.4c0,22.6,36.7,34.4,52.9-8.9;
M20,50.1c0,0,2.8-5.8-6.5,13.3c-12.6,25.9-40.3,64-15,78c20.2,11.2,41-11.5,57.1-54.9;
M-2,140.2c0,0,0,0-4.2,4.4c-5.2,5.5-21.2,30.8-0.2,40.5c27.9,12.8,46.2-59.2,62.3-102.5;
M6,216.7c0,0,0-1.3,0-5.4c0-5.7,0-1.7,0-11.4C6,146,46.2,124.7,62.4,81.3;
M10,216.7c0,0,0-1.3,0-5.4c0-5.7,0-1.7,0-11.4C6,146,46.2,124.7,62.4,81.3;
M6,216.7c0,0,0-1.3,0-5.4c0-5.7,0-1.7,0-11.4C6,146,46.2,124.7,62.4,81.3;
M-2,140.2c0,0,0,0-4.2,4.4c-5.2,5.5-21.2,30.8-0.2,40.5c27.9,12.8,46.2-59.2,62.3-102.5;
M20,50.1c0,0,2.8-5.8-6.5,13.3c-12.6,25.9-40.3,64-15,78c20.2,11.2,41-11.5,57.1-54.9;
M6,20.8c0,0,21.3,0,21.3,21.2c0,21.2-20.8,18.4-20.8,41.4c0,22.6,36.7,34.4,52.9-8.9;
Z;"/>
Here's my new pen
Hover on it.
http://codepen.io/alcoven/pen/mOrYBd?editors=1100
I've read Bostock's "Nested Selections" tutorial but I couldn't quite wrap my head around using nested data.
I've simplified my problem to a data set like this:
var data = [{
"id": "foo",
"row": 0,
"col": 0,
"row_size": 200,
"col_size": 100,
"modules": [{
"id": "foo1",
"row": 0,
"col": 0
}, {
"id": "foo2",
"row": 1,
"col": 0
}]
}, {
"id": "bar",
"row": 0,
"col": 1,
"row_size": 200,
"col_size": 100,
"modules": [{
"id": "bar1",
"row": 0,
"col": 1
}, {
"id": "bar2",
"row": 1,
"col": 1
}]
}]
And I'm trying to dynamically create a svg like this:
<svg width="500" height="500">
<g transform="translate(20,20)">
<g transform="translate(0,0)" class="outside_box">
<rect x="0" y="0" width="100" height="200" fill="white" stroke="red" stroke-width="10"></rect>
<text x="50" y="100" text-anchor="middle" alignment-baseline="central" font-size="50">foo</text>
<g class="inside_box">
<g transform="translate(0,0)">
<rect x="0" y="0" width="100" height="100" fill-opacity="0.5" stroke="blue"></rect>
<text x="50" y="50" text-anchor="middle" alignment-baseline="central">foo1</text>
</g>
<g transform="translate(0,100)">
<rect x="0" y="0" width="100" height="100" fill-opacity="0.5" stroke="blue"></rect>
<text x="50" y="50" text-anchor="middle" alignment-baseline="central">foo2</text>
</g>
</g>
</g>
<g transform="translate(100,0)" class="outside_box">
<rect x="0" y="0" width="100" height="200" fill="white" stroke="red" stroke-width="10"></rect>
<text x="50" y="100" text-anchor="middle" alignment-baseline="central" font-size="50">bar</text>
<g class="inside_box">
<g transform="translate(0,0)">
<rect x="0" y="0" width="100" height="100" fill-opacity="0.5" stroke="blue"></rect>
<text x="50" y="50" text-anchor="middle" alignment-baseline="central">bar1</text>
</g>
<g transform="translate(0,100)">
<rect x="0" y="0" width="100" height="100" fill-opacity="0.5" stroke="blue"></rect>
<text x="50" y="50" text-anchor="middle" alignment-baseline="central">bar2</text>
</g>
</g>
</g>
</g>
</svg>
The positioning, sizing, and color in my example is irrelevant (I just added extra attributes to make the SVG clear to understand); but the grouping of the <g>, <text>, and <rect> is very important. I also want to create the SVG from scratch (a blank canvas), so trying to do something like
d3.selectAll("g").data(data).enter().append("g")...
Thanks!
This should do it. I haven't tested it, so it's possible there are errors, but the overall structure is what you're after.
var svg = d3.select("body").append("svg") // here you'll also want to apply width and height .attr's
var mainG = svg.append("g") // this you'll also want to translate(20,20) as your mockup suggests
// Now bind the outer level, to produce a 2-element selection bound to 'data'
var gOuter = mainG.selectAll("g.outside_box").data(data)
var gOuterEnter = gOuter.enter().append("g")
.attr("class", "outside_box")
// also to this you can apply translation as you wish
gOuterEnter.append("rect") // and set the rect's attributes as needed
gOuterEnter.append("text") // and set the text's attributes and text as needed
gOuterEnter.append("g")
.attr("class", "inside_box")
// Now comes the work with the nested data:
var gModules = gOuterEnter.select(".inside_box").selectAll("g").data(function(d) {
// here d is the outer datum, and lets you access
// its nested 'modules' array, which is what you want
// to return, as instructed by Bostocks "Nested Selections" tutorial
return d.modules
})
var gModulesEnter = gModules.enter()
.append("g")
gModulesEnter.append("rect") // and set attributes
gModulesEnter.append("text")
.text(function(m) {
// here m is each module's datum, so you can return its id
// to set the text to what you want
return d.id
})
I'm making a simple spinner using the dash-offset animation technique. you can see what i have here. As you can see the polygon shape never closes. Is there any simple way to ensure the path completes the shape instead of leaving the miter corner at the top.
I could over shoot the path int he SVG so it overlaps to complete that final corner. Unfortunately you can see it overdraw in the animation which isn't ideal.
HTML
<div class="logo-container">
<svg class="is2-logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 243.514 195.632">
<path class="gray-path" fill="none" stroke="#9A9A9A" stroke-width="16" stroke-miterlimit="10" d="M121.71 64.26l106.08 61.04-106.08 61.033L15.724 125.3z"/>
<path class="blue-path" fill="none" stroke="#00B3E9" stroke-width="16" stroke-miterlimit="10" d="M121.71 9.225l106.08 61.04-106.08 61.032L15.724 70.265z"/>
</svg>
</div>
CSS
.logo-container {
width: 400px;
.is2-logo path {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
}
.blue-path {
animation: dash 2s linear forwards infinite;
}
.gray-path {
animation: dash 2s linear forwards infinite .5s;
}
}
#keyframes dash {
0% {
stroke-dashoffset: 1000;
}
50% {
stroke-dashoffset: 0;
}
100% {
stroke-dashoffset: -1000;
}
}
completes the shape instead of leaving the miter corner at the top.
Actually it's leaving butt line-caps at the top.
Why don't you just make the blue path have round line-caps like the grey one has?
.logo-container {
width: 400px;
}
.logo-container .is2-logo path {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
}
.logo-container .blue-path {
animation: dash 5s linear forwards infinite;
}
.logo-container .gray-path {
animation: dash 5s linear forwards infinite .5s;
}
#keyframes dash {
0% {
stroke-dashoffset: 1000;
}
50% {
stroke-dashoffset: 0;
}
100% {
stroke-dashoffset: -1000;
}
}
<div class="logo-container">
<svg class="is2-logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 243.514 195.632">
<path class="gray-path" fill="none" stroke="#9A9A9A" stroke-linecap="round" stroke-width="16" stroke-linejoin="round" stroke-miterlimit="10" d="M121.71 64.26l106.08 61.04-106.08 61.033L15.724 125.3z"/>
<path class="blue-path" fill="none" stroke="#00B3E9" stroke-width="16" stroke-linejoin="round" stroke-linecap="round" stroke-miterlimit="10" d="M121.71 9.225l106.08 61.04-106.08 61.032L15.724 70.265z"/>
</svg>
</div>
Why don't you just extend the path by another leg, leaving the dash offset the same:
<svg class="is2-logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 243.514 195.632">
<path class="gray-path" fill="none" stroke="#9A9A9A" stroke-linejoin="round" stroke-width="16" stroke-miterlimit="10" d="M121.71 64.26l106.08 61.04-106.08 61.033L15.724 125.3 l106.08 -61.04 106.08 61.04" marker-end="url(#gray-start)"/>
<path class="blue-path" fill="none" stroke="#00B3E9" stroke-linejoin="round" stroke-width="16" stroke-miterlimit="10" d="M121.71 9.225 l106.08 61.04 -106.08 61.032 L15.724 70.265 l106.08 -61.04 106.08 61.04"/>
</svg>