1.В первом примере показывается влияние атрибута markerUnits на габаритные размеры самого маркера в зависимости от толщины (stroke-width) линии, к которой он присоединен. Если атрибут маркера установлен в значение: markerUnits=”strokeWidth”, то при увеличении толщины линии пропорционально увеличиваются габаритные размеры маркера.
Обратите внимание, что у второго маркера, который выполнен в виде красного круга, габаритные размеры не увеличиваются, так как для него установлено значение атрибута markerUnits=”userSpaceOnUse” (см. строку 28) в листинге ниже. Важно помнить об этом, так как значение markerUnits по умолчанию равно “strokeWidth”.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
<?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 width="250" height="250" version="1.1" viewBox="0 0 250 250" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" > <title>example animation marker</title> <desc>animation attributes marker http://svg-art.ru </desc> <defs> <pattern id="newpattern" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" > <g fill="#85D2FF" stroke-width="1px" stroke="none" fill-opacity="1"> <rect x="0" y="0" width="10" height="10" /> <rect x="10" y="10" width="10" height="10" /> </g> </pattern> <marker id="MarkerArrow" viewBox="0 0 20 20" refX="2" refY="10" markerUnits="strokeWidth" orient="auto" markerWidth="20" markerHeight="20"> <polyline id="markerPoly1" points="0,0 20,10 0,20 2,10" fill="orange" fill-opacity="0.9" /> </marker> <marker id="MarkerCircle" viewBox="0 0 10 10" refX="0" refY="5" markerUnits="userSpaceOnUse" markerWidth="10" markerHeight="10"> <circle cx="5" cy="5" r="5" fill="crimson" /> </marker> </defs> <!-- area fill pattern --> <rect x="0" y="0" width="100%" height="100%" style="stroke: #000000; fill: url(#newpattern);" /> <!-- control button animation - "Start" --> <g id="startButton"> <rect x="20" y="210" width="54px" height="20px" rx="5px" ry="5px" fill="dodgerblue" stroke="lightyellow" /> <text x="27px" y="225px" font-size="18" font-weight="bold" font-family="serif" fill="lightyellow">Start</text> </g> <!-- line with markers attached --> <line x1="20" y1="125" x2="110" y2="125" style=" marker-start: url(#MarkerCircle); marker-end: url(#MarkerArrow); fill:none; stroke:green; stroke-width:1;" > <animate attributeName="stroke-width" begin="startButton.click" from="1px" to="6px" dur="6s" repeatCount="2" fill="freeze" /> </line> <!-- The heading marker attributes --> <rect x="15" y="11" width="214px" height="20px" rx="5px" ry="5px" fill="dodgerblue" stroke="lightyellow" /> <g font-size="16" font-weight="bold" font-family="serif" fill="lightyellow" > <text x="25" y="25">markerUnits="strokeWidth"</text> </g> </svg> |
2. В этом примере для анимации используется атрибут маркера “orient”, отвечающий за поворот маркера относительно линии. К линии присоединены начальный маркер marker-start: url(#MarkerArrowLeft); и конечный marker-end: url(#MarkerArrowRight);
Значение параметра “orient” для обоих маркеров одновременно изменняется от 0 градусов до 180 в течение 5 секунд. См. строки листинга 23,24 и 31,32. По завершению поворота маркеров begin=”animLeft.end” и begin=”animRight.end” линия с маркерами перемещается вправо. См. строки листинга 47,48.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
<?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 width="150" height="150" version="1.1" viewBox="0 0 150 150" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" > <title>marker attribute "orient"</title> <desc>Animation marker attribute "orient" http://svg-art.ru </desc> <defs> <pattern id="newpattern" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" > <g fill="#85D2FF" stroke-width="1px" stroke="none" fill-opacity="0.5"> <rect x="0" y="0" width="10" height="10" /> <rect x="10" y="10" width="10" height="10" /> </g> </pattern> <marker id="MarkerArrowRight" viewBox="0 0 20 20" refX="2" refY="10" markerUnits="userSpaceOnUse" orient="0" markerWidth="20" markerHeight="20"> <polyline points="0,0 20,10 0,20 2,10" fill="crimson" /> <animate id="animRight" attributeName="orient" from="0" to="180" begin="startButton.click" dur="5s" repeatCount="1" fill="freeze" /> </marker> <marker id="MarkerArrowLeft" viewBox="0 0 20 20" refX="2" refY="10" markerUnits="userSpaceOnUse" orient="0" markerWidth="20" markerHeight="20"> <polyline points="20,0 0,10 20,20 18,10" fill="crimson" /> <animate id="animLeft" attributeName="orient" from="0" to="180" begin="startButton.click" dur="5s" repeatCount="1" fill="freeze" /> </marker> </defs> <!-- area fill pattern --> <rect x="0" y="0" width="100%" height="100%" style="stroke: #000000; fill: url(#newpattern);" /> <!-- control button animation - "Start" --> <g id="startButton"> <rect x="50" y="120" width="54px" height="20px" rx="5px" ry="5px" fill="dodgerblue" stroke="lightyellow" /> <text x="57px" y="135px" font-size="18" font-weight="bold" font-family="serif" fill="lightyellow">Start</text> </g> <!-- line with markers attached --> <line x1="20" y1="80" x2="120" y2="80" style=" marker-start: url(#MarkerArrowLeft); marker-end: url(#MarkerArrowRight); fill:none; stroke:green; stroke-width:2;"> <animate attributeName="x1" from="20" to ="30" begin="animLeft.end" dur="1.5s" repeatCount="1" fill="freeze"/> <animate attributeName="x2" from="120" to ="130" begin="animRight.end" dur="1.5s" repeatCount="1" fill="freeze"/> </line> </svg> |
3.В этом примере используется комбинированная анимация: перемещение маркеров навстречу друг другу вдоль линии. При этом используется атрибут маркера “refX” и затем поворот обоих маркеров, в этом случае используется атрибут “orient”.
В листинге ниже строки отвечающие за эти действия выделены цветом: 25,26,35,36 – перемещение; 27,28 – поворот;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
<?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 width="150" height="150" version="1.1" viewBox="0 0 150 150" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" > <title>combined animation marker</title> <desc> combined animation marker: move along the line and turn http://svg-art.ru </desc> <defs> <pattern id="newpattern" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" > <g fill="#85D2FF" stroke-width="1px" stroke="none" fill-opacity="0.5"> <rect x="0" y="0" width="10" height="10" /> <rect x="10" y="10" width="10" height="10" /> </g> </pattern> <marker id="MarkerArrow" viewBox="0 0 20 20" refX="0" refY="10" markerUnits="userSpaceOnUse" orient="auto" markerWidth="20" markerHeight="20"> <polyline id="markerPoly1" points="0,0 20,10 0,20 2,10" fill="crimson" /> <animate id="refX1" attributeName ="refX" from ="0px" to="100px" begin="startButton.click" dur = "5s" repeatCount="1" restart="whenNotActive" /> <animate id="orientX" attributeName ="orient" from ="0" to="180" begin= "refX1.end" dur = "5s" repeatCount="1" fill="freeze" restart="whenNotActive" /> </marker> <marker id="MarkerCircle" viewBox="0 0 10 10" refX="0" refY="5" markerUnits="userSpaceOnUse" markerWidth="10" markerHeight="10"> <circle cx="5" cy="5" r="5" fill="crimson" /> <animate id="refX2" attributeName = "refX" from ="0px" to ="-90px" begin="startButton.click" dur="5s" repeatCount="1" fill="freeze" restart="whenNotActive" /> </marker> </defs> <!-- area fill pattern --> <rect x="0" y="0" width="100%" height="100%" style="stroke: #000000; fill: url(#newpattern);" /> <!-- control button animation - "Start" --> <g id="startButton"> <rect x="50" y="120" width="54px" height="20px" rx="5px" ry="5px" fill="dodgerblue" stroke="lightyellow" /> <text x="57px" y="135px" font-size="18" font-weight="bold" font-family="serif" fill="lightyellow">Start</text> </g> <!-- line with markers attached --> <line x1="20" y1="80" x2="110" y2="80" style=" marker-start: url(#MarkerCircle); marker-end: url(#MarkerArrow); fill:none; stroke:green; stroke-width:2; "/> </svg> |
4. Анимацию 4-х маркеров я уже приводил в этой статье. Но там был только фрагмент кода, здесь привожу его полностью.
Напомню, что запускает анимацию наведение мышки на мужской силуэт и останавливает анимацию – женский силуэт.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
<?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 width="255" height="250" version="1.1" viewBox="0 0 255 250" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" > <title>animation marker</title> <desc> the animation of the four markers http://svg-art.ru </desc> <defs> <style type="text/css"><![CDATA[ #man:hover { stroke:green; opacity: 0.5; } #woman:hover{ fill:red; opacity: 0.5; } ]]> </style> <pattern id="newpattern" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" > <g fill="#85D2FF" stroke-width="1px" stroke="none" fill-opacity="0.5"> <rect x="0" y="0" width="10" height="10" /> <rect x="10" y="10" width="10" height="10" /> </g> </pattern> <marker id="end-circle" markerUnits="userSpaceOnUse" markerWidth="40" markerHeight="40" refX="10" refY="2" orient="auto"> <rect x="0" y="0" width="40" height="20" stroke="black" fill="grey" fill-opacity="0.5"/> <circle cx="10" cy="10" r="10" style="fill:lime; stroke-width:2px; stroke:tomato;" /> </marker> </defs> <g transform="scale(1)"> <!-- the filling pattern of the entire working area --> <rect x="0" y="0" width="100%" height="100%" style="stroke: #000000; fill: url(#newpattern);" /> <!-- tower mill --> <line x1="120" y1="250" x2="120" y="0" stroke="black" /> <path d="M80,250 L80,100 L120,20 160,100 160,250 M80,100 L160,100" fill="silver" stroke="black" /> <!--window mill --> <g stroke="silver"> <path d="M100,80 L110,60 L130,60 L140,80z" fill="yellow" /> <rect x="123" y="150" width="36" height="30" stroke="grey" fill="yellow" /> <line x1="120" y1="250" x2="120" y2="100" /> <line x1="120" y1="170" x2="160" y2="170" /> <line x1="120" y1="160" x2="160" y2="160" /> <line x1="110" y1="80" x2="110" y2="60" /> <line x1="120" y1="80" x2="120" y2="60" /> <line x1="130" y1="80" x2="130" y2="60" /> </g> <!-- flag --> <path d="M120,2 L140,2 L133,7 L140,12 L120,12z" stroke="orange" fill="crimson" /> <!-- stairs and curbs --> <path d="M160,220 h10 v10 h10 v10 h10 v10 h-30z" fill="silver" stroke="black" /> <line x1="80" y1="102" x2="160" y2="102" stroke-width="5px" stroke="slategray" stroke-dasharray="6,2" /> <line x1="80" y1="240" x2="160" y2="240" stroke-width="5px" stroke="slategray" stroke-dasharray="6,2" /> <line x1="85" y1="245" x2="160" y2="245" stroke-width="5px" stroke="slategray" stroke-dasharray="6,2" /> <!-- Four rotating marker blades of the windmill --> <g style=" fill:none; stroke:green; stroke-width:4; marker-end: url(#end-circle);"> <desc>the animation of the four markers </desc> <line x1="120" y1="110" x2="120" y2="40" /> <line x1="130" y1="120" x2="200" y2="120" /> <line x1="120" y1="130" x2="120" y2="200" /> <line x1="110" y1="120" x2="40" y2="120" /> <animateTransform attributeType="xml" attributeName="transform" type="rotate" from="0 120 120" to="360 120 120" begin="man.mouseover" end="woman.mouseover" dur="2.5s" repeatCount="indefinite" fill="freeze"/> <!-- the Central circles of the blades of the mill --> <circle cx="120" cy="120" r="10" fill="limegreen" stroke="green" /> <circle cx="120" cy="120" r="3" fill="green" /> </g> <!-- the control unit buton -"Start" --> <g transform="translate(135, 145)"> <g id="man" style="fill: #ccf; stroke: black;"> <circle cx="85" cy="56" r="10"/> <line x1="85" y1="66" x2="85" y2="80"/> <polyline points="76 104, 85 80, 94 104" /> <polyline points="76 70, 85 76, 94 70" /> </g> <!-- the control unit buton -"Stop" --> <g id="woman" style="fill: #ffffcc; stroke: black;"> <circle cx="110" cy="56" r="10" /> <polyline points="110 66, 110 80, 100 90, 120 90, 110 80" /> <line x1="104" y1="104" x2="108" y2="90" /> <line x1="112" y1="90" x2="116" y2="104"/> <line x1="112" y1="90" x2="116" y2="104"/> </g> </g> <g font-size="18" font-weight="bold" font-family="serif" text-anchor="middle" fill="crimson" > <text x="250" y="155" transform="rotate(-90 250,155)" >Stop </text> <text x="225" y="155" transform="rotate(-90 225,155)" >Start </text> </g> </g> </svg> |
Примечание к 3 примеру.
Анимация параметров маркера “refX”, “refY”, которые отвечают за коррекцию положения маркера относительно линии корректно работает только в Mozilla Firefox. В Opera, GoogleChrom, Yandex и Safari работает довольно странно: анимация refY не работает и подменяется значениями из refX.
В статике во всех этих браузерах “refX” и “refY” работают нормально.
Внедрение SVG в современных браузерах идёт поэтапно, поэтому надеюсь, что это будет работать везде нормально.