animation - logo - Definir una animación de círculo/arco en SVG
svg animation generator (7)
Gracias por las respuestas. Aquí hay un poco más de información sobre por qué quiero animar un círculo en SVG:
Tenemos una aplicación cliente-servidor. Planeo generar imágenes SVG para representar gráficos (gráficos circulares / gráficos de barras) en el servidor y enviar el SVG a los clientes. Tenemos clientes Java y .NET. Escribiré el código del lado del cliente para analizar y representar las imágenes SVG recibidas del servidor. Planeo usar solo un subconjunto del formato SVG, no más de lo que necesitamos para representar nuestros gráficos, pero la animación es un requisito.
A largo plazo, sería bueno tener un cliente ajax, que se ejecutará en navegadores sin Java o .NET runtime. Es por eso que he elegido el formato SVG.
Para una solución a corto plazo, ahora creo que agregaré mi propio elemento al SVG, definiendo un arco usando ángulos de inicio y barrido. Entonces puedo definir fácilmente la animación que necesito animando el ángulo de barrido, y hace que mi implementación sea simple.
A largo plazo, si realmente conseguimos imponer un cliente AJAX / HTML, tendré que volver a implementar y mantener el estándar SVG.
¿Alguien sabe cómo definir un arco / círculo animado en SVG, de manera que el arco comienza en 0 grados y termina en 360 grados?
Una forma es usar un círculo y animar el stroke-dashoffset (también se necesita ''stroke-dasharray''). Un ejemplo de dicha animación (no con un círculo, pero se aplica el mismo principio) se puede ver aquí .
La otra opción es usar una animación de ruta, y segmentos de ruta de arco , para animar / cambiar entre rutas ver este ejemplo .
puedes pintarlo "a mano" usando la línea del camino y calcular la posición del arco:
<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>
También me decepcionó un poco no poder simplemente hacer un círculo con un porcentaje, o un ángulo.
Hoy en día, cuando necesito un arco que no forma parte de un camino más largo, uso un círculo y un truco de Dharharray para mostrar solo una parte de este círculo.
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>
Puedes ver una versión mejorada aquí que usa Sass para hacer los cálculos.
<!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>
También puede dibujar el SVG a mano usando un circle
y la siguiente técnica:
- Dale al
circle
unstroke
. - Haga que el
stroke
dashed
con una longitud del tablero igual a la circunferencia del círculo. - Compense el
stroke
por una longitud igual a la circunferencia del círculo. - Anima el golpe.
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 */;
}
}
O tal vez podría descubrir un círculo pre dibujado para dar el efecto requerido:
<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>