Определение анимации круга / дуги в SVG
кто-нибудь знает, как определить анимированную дугу / круг в SVG, так что дуга начинается с 0 градусов и заканчивается на 360 градусов?
7 ответов
вы можете нарисовать его "вручную", используя lineto пути и вычислить положение дуги:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
viewBox="0 0 1200 800"
preserveAspectRatio="xMidYMid"
style="width:100%; height:100%; position:absolute; top:0; left:0;"
onload="drawCircle();">
<script>
function drawCircle() {
var i = 0;
var circle = document.getElementById("arc");
var angle = 0;
var radius = 100;
window.timer = window.setInterval(
function() {
angle -=5;
angle %= 360;
var radians= (angle/180) * Math.PI;
var x = 200 + Math.cos(radians) * radius;
var y = 200 + Math.sin(radians) * radius;
var e = circle.getAttribute("d");
if(i==0) {
var d = e+ " M "+x + " " + y;
}
else {
var d = e+ " L "+x + " " + y;
}
if (angle === -5 && i !== 0) {
window.clearInterval(window.timer);
}
circle.setAttribute("d", d);
i++;
}
,10)
}
</script>
<path d="M200,200 " id="arc" fill="none" stroke="blue" stroke-width="2" />
</svg>
один из способов-использовать круг и анимировать stroke-dashoffset (вам тоже нужен "stroke-dasharray"). Пример такой анимации (не с кругом, но применяется тот же принцип) можно увидеть здесь.
другой вариант-использовать анимацию пути, и сегменты пути дуги, для анимации / морфинга между путями см. Это пример.
вы также можете нарисовать SVG вручную, используя circle
и следующая техника:
- дать
circle
astroke
. - сделать
stroke
dashed
С длиной штриха, равной окружности круга. - компенсировать
stroke
длиной, равной окружности круга. - анимировать ход.
HTML-код:
<svg width="200" height="200">
<circle class="path" cx="100" cy="100" r="96" stroke="blue" stroke-width="4" fill="none" />
</svg>
CSS:
circle {
stroke-dasharray: /* circumference */;
stroke-dashoffset: /* circumference */;
animation: dash 5s linear forwards;
}
@keyframes dash {
to {
stroke-dashoffset: /* length at which to stop the animation */;
}
}
или, возможно, вы могли бы раскрыть предварительно нарисованный круг, чтобы дать необходимый эффект:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000" width="400" height="400">
<rect x="0" y="0" width="1000" height="1000"/>
<circle cx="500" cy="500" r="500" fill="red"/>
<rect x="0" y="500" width="1000" height="500"/>
<rect x="0" y= "0" width="1000" height="500">
<animateTransform attributeName="transform" type="rotate" begin="0s" dur="5s" fill="freeze" from="0,500,500" to="180,500,500"/>
</rect>
</svg>
Я также был немного разочарован, что не смог просто сделать дугу круга с процентом или углом.
В настоящее время, когда мне нужна дуга, которая не является частью более длинного пути, я использую круг и strokeDasharray трюк, чтобы показать только часть этого круга.
svg {
outline: solid;
height: 100px;
width: 100px;
}
.arc {
fill: transparent;
stroke-width: 5;
stroke: red;
stroke-dasharray: 94.24778 219.91149;
}
<svg viewport="0 0 100 100">
<circle cx="50" cy="50" r="50" class="arc"></circle>
</svg>
Вы можете увидеть улучшенную версию здесь которые используют Sass для выполнения вычислений.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<link rel="stylesheet" href="">
</head>
<body>
</body>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
viewBox="0 0 1200 800"
preserveAspectRatio="xMidYMid"
style="width:100%; height:100%; position:absolute; top:0; left:0;"
onload="drawCircle();">
<script>
function drawCircle() {
// center point
var cX = 300,
cY = 300;
radius = 300,
p1 = {x: cX+radius, y: cY},
p2 = {x: cX-radius, y: cY},
circle = document.getElementById("arc"),
angle = 0;
window.timer = window.setInterval(
function() {
angle -= 5;
angle %= 360;
var radians= (angle/180) * Math.PI;
var x = cX + Math.cos(radians) * radius;
var y = cY + Math.sin(radians) * radius;
if (Math.abs(angle) < 180 && angle != 0)
d= 'M ' + p1.x + ',' + p1.y + ' A' + radius+ ',' + radius+ (Math.abs(angle)==180?' 0 1 0 ':' 0 0 0 ')+x+' '+y;
else
d= 'M ' + p1.x + ',' + p1.y + ' A' + radius+ ',' + radius+ ' 0 1 0 '+p2.x+' '+p2.y +
' M ' + p2.x + ',' + p2.y + ' A' + radius+ ',' + radius+ (Math.abs(angle)==0?' 0 1 0 ':' 0 0 0 ')+x+' '+y;
circle.setAttribute("d", d);
if (Math.abs(angle) == 0)
window.clearInterval(window.timer);
}
,10)
}
</script>
<path d="" id="arc" fill="none" stroke="blue" stroke-width="2" />
</svg>
</html>
Спасибо за ответы-вот немного больше информации о том, почему я хочу оживить круг в SVG:
У нас есть клиент-сервер приложение. Я планирую генерировать SVG-изображения для представления диаграмм (круговых диаграмм / гистограмм) на сервере и отправлять SVG клиентам. У нас есть клиенты Java и .NET. Я напишу клиентский код для анализа и визуализации SVG-изображений, полученных с сервера. Я планирую использовать только подмножество формата SVG - не больше того, что нам нужно представляйте наши графики, но анимация-это требование.
долгосрочный было бы неплохо иметь клиент ajax, который будет работать в браузерах без Java или .NET runtime. Именно поэтому я выбрал формат SVG.
для краткосрочного решения я теперь думаю, что добавлю свой собственный элемент в SVG, определяя дугу, используя начальные и углы развертки. Затем я могу легко определить требуемую анимацию, анимируя угол развертки, и делает мою реализацию простой.
долго термин-если мы действительно доберемся до imlpementing клиента AJAX / HTML - мне придется повторно реализовать и придерживаться стандарта SVG.