I am about to write a SMIL animation that should morph from one path to another. The paths are created by Inkscape.
Although both shapes consist of 17 nodes (according to Inkscape) the SMIL animation doesn't quite work. After the defined 1 second it jumps right from one path to the other one without morphing the path between it. (Hover the border of the box) Additionally to that it also flickers in Chrome (but not in Firefox)
<svg width="34" height="34" version="1.1" viewBox="0 0 34 34" style="margin:2px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<path id="check" d="m 5,8.25 0,17.5 C 5,27 6.25,27 6.25,27 l 17.5,0 c 0,0 1.25,0 1.25,-1.25 L 25,8.25 C 25,7 23.75,7 23.75,7 L 12.976695,7 6.25,7 C 6.25,7 5,7 5,8.25 Z M 2.5,2 l 25,0 c 0,0 2.5,0 2.5,2.5 l 0,25 C 30,32 27.5,32 27.5,32 l -25,0 C 2.5,32 0,32 0,29.5 L 0,4.5 C 0,2 2.5,2 2.5,2 Z" id="boxUid">
<animate attributeName="d" to="m 5,18.1 0,0 7.5,8.9 0,0 12.5,-15.7 0,0 L 23.4,7 12.5,20.8 7,14.5 Z M 2.5,2 l 25,0 c 0,0 2.5,0 2.5,2.5 l 0,25 C 30,32 27.5,32 27.5,32 l -25,0 C 2.5,32 0,32 0,29.5 L 0,4.5 C 0,2 2.5,2 2.5,2 Z" dur="1s" fill="freeze" begin="check.mouseenter"/>
<animate attributeName="d" to="m 5,8.25 0,17.5 C 5,27 6.25,27 6.25,27 l 17.5,0 c 0,0 1.25,0 1.25,-1.25 L 25,8.25 C 25,7 23.75,7 23.75,7 L 12.976695,7 6.25,7 C 6.25,7 5,7 5,8.25 Z M 2.5,2 l 25,0 c 0,0 2.5,0 2.5,2.5 l 0,25 C 30,32 27.5,32 27.5,32 l -25,0 C 2.5,32 0,32 0,29.5 L 0,4.5 C 0,2 2.5,2 2.5,2 Z" dur="1s" fill="freeze" begin="check.mouseleave"/>
</path>
</svg>
Unfortunately I'm not able to count the nodes. In principle I'm aware of how the path element works. E.g. according to MDN m dx dy is the move command which moves to a certain position and generates a new point without connecting it to the old one. But what is m 5,18.1 0,0 7.5,8.9 0,0 12.5,-15.7 0,0 supposed to mean?
Because of apparent lack of knowledge I have to trust Inkscape which says that there are 17 nodes in each shape:
What is the reason Browsers don't do a proper animation? What do I have to change?
It seems that having the same amount of nodes in the two paths is not enough. They also have to have the same type. (e.g. straight lines vs. Bezier curves)
Here is a working example:
<svg width="34" height="34" version="1.1" viewBox="0 0 34 34" style="margin:2px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<path id="check" d="m 5,8.25 0,17.5 C 5,27 6.25,27 6.25,27 l 17.5,0 c 0,0 1.25,0 1.25,-1.25 L 25,8.25 C 25,7 23.75,7 23.75,7 L 12.976695,7 6.25,7 C 6.25,7 5,7 5,8.25 Z M 2.5,2 l 25,0 c 0,0 2.5,0 2.5,2.5 l 0,25 C 30,32 27.5,32 27.5,32 l -25,0 C 2.5,32 0,32 0,29.5 L 0,4.5 C 0,2 2.5,2 2.5,2 Z" id="boxUid">
<animate attributeName="d" to="m 5,18.1 7.347853,8.719452 C 12.5,27 12.5,27 12.5,27 L 24.897509,11.428728 c 0,0 0,0 0.0587,-0.07373 L 25,11.3 C 24.2,9.15 23.4,7 23.4,7 L 12.5,20.8 7,14.5 c 0,0 -1,1.8 -2,3.6 z M 2.5,2 l 25,0 c 0,0 2.5,0 2.5,2.5 l 0,25 C 30,32 27.5,32 27.5,32 l -25,0 C 2.5,32 0,32 0,29.5 L 0,4.5 C 0,2 2.5,2 2.5,2 Z" dur="0.3s" fill="freeze" begin="check.mouseenter"/>
<animate attributeName="d" to="m 5,8.25 0,17.5 C 5,27 6.25,27 6.25,27 l 17.5,0 c 0,0 1.25,0 1.25,-1.25 L 25,8.25 C 25,7 23.75,7 23.75,7 L 12.976695,7 6.25,7 C 6.25,7 5,7 5,8.25 Z M 2.5,2 l 25,0 c 0,0 2.5,0 2.5,2.5 l 0,25 C 30,32 27.5,32 27.5,32 l -25,0 C 2.5,32 0,32 0,29.5 L 0,4.5 C 0,2 2.5,2 2.5,2 Z" dur="0.3s" fill="freeze" begin="check.mouseleave"/>
</path>
</svg>
Related
I'm failing to understand why the observed path the shape is moving against doesn't match the path outlined by an actual circle shape drawn - despite them both having the same value for path: inside the d attributes for circle, and inside the offset-path attribute by the line.
What am I doing wrong?
Does this have something to do with the coordinate system? The expectation is such that the "line" path touches the circle and, if virtually extended, "comes out of the circle's center" (sorry, I'm not an native english speaker and not sure how to express this in proper "math/geometry english").
For context, I am trying to learn how SVG element positioning and animations work. In particular, currently I find margin-offset: path("...") to be quite promising when moving a shape, hoping that I can re-use the value of path for both the moving shape, and the path. However, I am apparently failing to do this even with the simplest shape possible, e.g. a <path> that represents a straight line.
The full HTML of my (currently failing) experiment can be see below:
body {
justify-content: center
}
.track {
stroke: #ccc
}
.marker {
offset-path: path('M 15 15 m -4, 0 a 4,4 0 1,0 8,0 a 4,4 0 1,0 -8,0');
animation: move 3s linear infinite;
}
#keyframes move {
100% {
offset-distance: 100%;
}
}
<svg viewbox="0,0 25,25" width="200px" height="200px">
<!-- the path to be animated along -->
<path
class="track"
fill="none"
stroke-width="0.25"
d="M 15 15 m -4, 0 a 4,4 0 1,0 8,0 a 4,4 0 1,0 -8,0"
/>
<!-- the mover -->
<path d="M1,1 L1,5" class="marker" stroke="red" stroke-width=0.25></path>
</svg>
Your moving/aligned element currently has the starting coordinates x:1 y:1
So these values will be added as offsets to the offset-path aligned coordinates (closely related to your previous question).
Just change your moving path's d attribute to M0 0 l0 4 or M0 0 v4 (using vertical shorthand)
body {
justify-content: center;
}
.track {
stroke: #ccc;
}
.marker2,
.marker {
offset-path: path("M 15 15 m -4, 0 a 4,4 0 1,0 8,0 a 4,4 0 1,0 -8,0");
animation: move 3s linear infinite;
}
.marker2{
transform: translateY(-4px);
}
#keyframes move {
100% {
offset-distance: 100%;
}
}
<svg viewBox="0 0 25 25" width="200px" height="200px">
<!-- the path to be animated along -->
<path class="track" fill="none" stroke-width="0.25" d="M 15 15 m -4, 0 a 4,4 0 1,0 8,0 a 4,4 0 1,0 -8,0" />
<!-- the mover -->
<path d="M0 0 v4" class="marker" stroke="red" stroke-width=0.25></path>
</svg>
<svg viewBox="0 0 25 25" width="200px" height="200px">
<!-- the path to be animated along -->
<path class="track" fill="none" stroke-width="0.25" d="M 15 15 m -4, 0 a 4,4 0 1,0 8,0 a 4,4 0 1,0 -8,0" />
<!-- the mover -->
<path d="M0 0 v4" class="marker2" stroke="red" stroke-width=0.25></path>
</svg>
Convert path d attribute to use relative commands
I've changed the commands to relative commands.
This way, you can easily apply or adjust x/y offsets by changing only the M commands coordinates. Also explained in Lea Verou's article: "Utility: Convert SVG path to all-relative or all-absolute commands"
Some web apps to convert path data to relative commands
yqnn's svg-path-editor
thednp's svg PathCommander
BTW: the viewBox attribute is case sensitive – always use the "camel case" notation viewBox.
I am trying to animate an svg <path> element. The initial <path> element has L(lineto) commands whereas the <path> that I'm trying to animate it to has C(cubic-bezier curve) commands. I've tried animating it but it doesn't really transition between the two paths. Is something like this possible?
<svg>
<path id="path" d="M0,50 L25,40 L50,60 L75,40 L100,60 L125,40 L150,50" fill="none" stroke-width="2" stroke="#000" />
<animate xlink:href="#path"
attributeName="d"
dur="3s"
from="M 0 50 L 25 40 L 50 60 L 75 40 L 100 60 L 125 40 L 150 50"
to="M 0 80 C 25 55 50 55 75 80 C 100 105 125 105 150 80"
repeatCount="indefinite" />
</svg>
As you found out, path data animations need to list the exact same sequence of commands and points to work. That said, you can divide a path into as many segments as you need, and a cubic bezier can describe a straight line if its control points are positioned in a straight line. For your example to work, you need to
rewrite each L segment as a C segment
divide each C segment into three C segments so that the curve is unchanged
Both tasks are best performed with a grafical editor like Inkscape that has appropriate tools.
<svg>
<path id="path" d="M0,50 L25,40 L50,60 L75,40 L100,60 L125,40 L150,50" fill="none" stroke-width="2" stroke="#000" />
<animate xlink:href="#path"
attributeName="d"
dur="3s"
from="M 0,50
C 12.5,45 12.5,45 25,40
37.5,50 37.5,50 50,60
62.5,50 62.5,50 75,40
87.5,50 87.5,50 100,60
112.5,50 112.5,50 125,40
137.5,45 137.5,45 150,50"
to="M 0,80
C 8.33333,71.6667 16.6667,66.1111 25,63.3333
33.3333,60.5556 41.6667,60.5556 50,63.3333
58.3333,66.1111 66.6667,71.6667 75,80
83.3333,88.3333 91.6667,93.8889 100,96.6667
108.333,99.4444 116.667,99.4444 125,96.6667
133.333,93.8889 141.667,88.3333 150,80"
repeatCount="indefinite" />
</svg>
I`m writing code on visual prolog 8,
I have to write Adder and half adder, using the table of truth and use a basis 2-AND-NOT
Schemes I made:
half adder
and a full adder
Have you got any ideas, how to make this work?
In ISO Prolog, you could do the following:
halfadd(X, Y, Z, C) :-
Z is X xor Y,
C is X /\ Y.
fulladd(X, Y, C, Z, D) :-
halfadd(X, Y, H, J),
halfadd(H, C, Z, K),
D is J \/ K.
Looks right to me:
X Y C|Z D
-----+---
0 0 0|0 0
0 0 1|1 0
0 1 0|1 0
0 1 1|0 1
1 0 0|1 0
1 0 1|0 1
1 1 0|0 1
1 1 1|1 1
I am trying to use the SVG animate tag to change the path from a half fill to a complete fill
<svg class="background-gradient" viewBox="0 0 100 100" preserveAspectRatio="none">
<defs>
<linearGradient id="grad">
<stop offset="0%" stop-color="rgba(82,181,244,.1)" stop-opacity="1"></stop>
<stop offset="100%" stop-color="rgba(70,215,255,.7)" stop-opacity="1"></stop>
</linearGradient>
</defs>
<path id="scroll-path" d="M0 0 H100 v 100" fill="url(#grad)">
<animate attributeName="d" from="M0 0 H100 v 100" to="M0 0 H100 L100 100 L0 100" dur="1s" repeatCount="indefinite" />
</path>
</svg>
Currently it just jumps from the beginning to the end of the animation and does not show the smooth fill I was hoping for in between.
Any ideas?
For an animation to be smooth the path must have the same number and types of commands.
Your first path has 3 commands M H v
Your second path has 4 commands M H L L
You'll need to write the first path using 2 L commands instead of the v or the second as a v instead of the two L commands.
I have the following svg and I am trying to animate the shape.
<svg class="svg" viewBox="0 0 100 100">
<path fill="white">
<animate id="close" begin="0s;open.end" attributeName="d" dur="1s"
from="..." to="..." />
<animate id="open" begin="close.end" attributeName="d" dur="1s"
from="..." to="...0" />
</path>
</svg>
The problem I am facing is that the 1st animation (#close) only happens once at the start then never again. The second animation (#open) repeats as normal.
Here's a codepen with my code and simpler animation I based mine off of (which works correctly)
http://codepen.io/dogoku/pen/yxKjs
Thanks for any help
One way would be to put it in the same animation
<animate id="close" begin="0s" repeatCount="indefinite" attributeName="d" dur="2s"
values="M 0,0 L 100,0 100,50 100,100 0,100 0,50; M 0,50 L 100,50 75,50 100,
50 0,50 25,50; M 0,50 L 100,50 75,50 100,50 0,50 25,50; M 0,0 L 100,0 100,
50 100,100 0,100 0,50" />