Can I make a transition on an SVG attribute that is not CSS?
As Robert Longson commented you can use SMIL animations: Inside the line #move
there are 2 <animate>
elements: the first for the mouseover
and the second for mouseleave
.
The first animation is changing the value of the x2 attribute of the line from="96.1" to="26"
. The second element has no from
attribute but is animating the value of the y2 to="96.1"
The duration of both animations is dur="1s"
and fill="freeze"
is similar to the animation-fill-mode: forwards
from CSS.
I hope it helps.
.st2 {
fill: #e5caca;
}
.st3 {
fill: none;
stroke: #ddd;
stroke-width: 17;
stroke-linecap: round;
stroke-miterlimit: 10;
}
<svg viewBox="0 0 1000 1000" style="enable-background:new 0 0 1000 1000;">
<g id="Layer_2">
<line class="st3" x1="500" y1="142" x2="500" y2="95"/>
<line id="move" class="st3" x1="518.2" y1="142.9" x2="521.8" y2="96.1">
<animate
attributeType="XML"
attributeName="y2"
from="96.1" to="26"
begin="mouseover"
dur="1s"
fill="freeze" />
<animate
attributeType="XML"
attributeName="y2"
to="96.1"
begin="mouseleave"
dur="1s"
fill="freeze" />
</line>
<line id="stretch" class="st3" x1="536" y1="144.7" x2="544" y2="98.3"/>
</g>
</svg>
css transition animation doesn't work on svg path's d' attribute change
Transitions can only be applied to presentation Attributes, and a few other attributes such as x, y, cx,cy ...
a list of supported attributes can be found here http://dev.w3.org/SVG/proposals/css-animation/animation-proposal.html
Unfortunately d isn't one of them...
as this is still not supported reliably across browsers, you can use SMIL animations to achieve the same result.
var type = true;
setInterval(function() {
$("#path").attr('from', type ? "M 0 0 L 50 100" : "M 0 0 L 100 50");
$("#path").attr('to', type ? "M 0 0 L 100 50" : "M 0 0 L 50 100");
$("#path")[0].beginElement()
$("#circle").attr('from', type ? "40" : "10");
$("#circle").attr('to', type ? "10" : "40");
$("#circle")[0].beginElement()
type = !type;
}, 1000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg>
<path stroke="#000000" stroke-width="5" d="M 0 0 L 100 50" >
<animate id="path" attributeName="d" from="M 0 0 L 100 50" to="M 0 0 L 50 100" dur="1s" fill="freeze"/>
</path>
<circle fill="#0000FF" cx="10" cy="50" r="10" >
<animate id="circle" attributeName="cx" from="10" to="40" dur="1s" fill="freeze"/>
</circle>
</svg>
SVG, animate a line from x1,y1 to x2,y2?
This works (tested in Opera):
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="480" height="320" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<g style="stroke:black" >
<line x1="0" y1="0" x2="50" y2="50" style="stroke:rgb(0,0,0);stroke-width:20;" >
<animate attributeName="x2" from="50" to="100" begin="1s" dur="2s" />
<animate attributeName="y2" from="50" to="100" begin="1s" dur="2s" />
</line>
</g>
</svg>
I see two major problems in your code:
- The line is outside the image (width: 480, x1: 585)
- Obscure time values (you are using hundredths of seconds there!!!)
Animating SVGs Via CSS
Only presentation attributes have their counter-parts in CSS.
As of today, here is the list of these attributes:
Properties with a presentation attribute Elements that support the presentation attribute cx, cy ‘circle’ and ‘ellipse’ height, width, x, y ‘foreignObject’, ‘image’, ‘rect’, ‘svg’, ‘symbol’, and ‘use’ r ‘circle’ rx, ry ‘ellipse’ and ‘rect’ d ‘path’ fill Any element in the SVG namespace except for animation elements, which have a different ‘fill’ attribute. transform For historical reasons, the transform property gets represented by different presentation attributes depending on the SVG element it applies to:
- transform
Any element in the SVG namespace with the exception of the ‘pattern’, ‘linearGradient’ and ‘radialGradient’ elements.
- ‘patternTransform’
‘pattern’. ‘patternTransform’ gets mapped to the transform CSS property[css-transforms-1].
- ‘gradientTransform’
‘linearGradient’ and ‘radialGradient’ elements.
‘gradientTransform’ gets mapped to the transform CSS property [css-transforms-1].alignment-baseline, baseline-shift, clip-path, clip-rule, color, color-interpolation, color-interpolation-filters, cursor, direction, display, dominant-baseline, fill-opacity, fill-rule, filter, flood-color, flood-opacity, font-family, font-size, font-size-adjust, font-stretch, font-style, font-variant, font-weight, glyph-orientation-horizontal, glyph-orientation-vertical, image-rendering, letter-spacing, lighting-color, marker-end, marker-mid, marker-start, mask, mask-type, opacity, overflow, paint-order, pointer-events, shape-rendering, stop-color, stop-opacity, stroke, stroke-dasharray, stroke-dashoffset, stroke-linecap, stroke-linejoin, stroke-miterlimit, stroke-opacity, stroke-width, text-anchor, text-decoration, text-overflow, text-rendering, transform-origin, unicode-bidi, vector-effect, visibility, white-space, word-spacing, writing-mode Any element in the SVG namespace. SVG line animation 2
The simplest way is to change the first line of your SVG as follows:
<svg width="100%" height="100%" viewBox="0 0 100 100">
Then the SVG will scale to the size of your
<div>
. So all you then need to do is style the div to 24px:.sv_btn {
position: relative;
width: 24px;
height: 24px;
margin: 200px;
}.sv_btn {
position: relative;
width: 24px;
height: 24px;
margin: 200px;
}
.sv_btn .text {
width: 100%;
height: 100%;
text-align: center;
position: absolute;
display: flex;
justify-content: center;
flex-direction: column;
font-size: 16px;
color: whitesmoke;
}
.sv_btn svg {
position: absolute;
top: 0;
left: 0;
}
.sv_btn line {
stroke-width: 5;
stroke: #000;
fill: none;
stroke-dasharray: 100px;
transition: transform .6s;
}
.sv_btn:hover svg line.top {
transform: translateX(-200px);
}
.sv_btn:hover svg line.bottom {
transform: translateX(200px);
}
.sv_btn:hover svg line.left {
transform: translateY(200px);
}
.sv_btn:hover svg line.right {
transform: translateY(-200px);
}<div class="sv_btn">
<svg width="100%" height="100%" viewBox="0 0 100 100">
<line class="top" x1="0" y1="0" x2="600" y2="0" />
<line class="left" x1="0" y1="100" x2="0" y2="-200" />
<line class="bottom" x1="100" y1="100" x2="-200" y2="100" />
<line class="right" x1="100" y1="0" x2="100" y2="600" />
</svg>
</div>Animate SVG straight line by CSS transition
The easiest way to animate a circle and a line synchronously is to use the circle as a marker.
In this case, the circle will always be attached to the line and will animate along with it.
const state = {
x: 75,
y: 75
};
const line = document.getElementsByTagName('line')[0];
const circle = document.getElementsByTagName('circle')[0];
setInterval(() => {
state.x = Math.floor(Math.random() * 150);
state.y = Math.floor(Math.random() * 150);
line.setAttribute("x2", state.x);
line.setAttribute("y2", state.y);
}, 2000)<svg height="160" width="160" style="border: 1px solid black">
<defs>
<marker id="markEnd" viewBox="0 0 22 22" refX="10" refY="10" markerUnits="userSpaceOnUse" markerWidth="22" markerHeight="22">
<circle r="10" cx="10" cy="10" fill="none" stroke="blue" />
</marker>
</defs>
<line
x1="0"
y1="0"
x2="75"
y2="75"
stroke="red"
marker-end="url(#markEnd)"
>
</line>
</svg>
Related Topics
Create Line After Text with CSS
CSS Image Layouting Before Image Loaded
CSS Selector When :Target Empty
Center Overflowing Div Inside Smaller Div
Is There a CSS File Size Limit in IE9
Should I Avoid Using "Text-Align: Justify;"
How to Change Navbar/Container Width? Bootstrap 3
"Vw" CSS Units in Calc in Chrome Not Working
Box Shadows on Multiple Elements at Same Level But Without Overlap
Leaving Certain Values Unchanged When Using CSS Shorthand Properties
Overriding Placeholder Font CSS in All Browsers
:First-Letter Selector Doesn't Work for Link
Bootstrap 4 Row Height Set by Specific Col - Not Highest One