La transformación SVG rota 90, 180 o 270 grados y no funciona en círculo en Safari iOS 10
mobile-safari ios10 (3)
Quiero crear un gráfico de dona usando un elemento de círculo SVG al establecer stroke-dasharray
y variando stroke-dashoffset
. El elemento SVG debe girarse 270 (o -90) grados para que la "barra" del gráfico comience en la parte superior. Aquí está el código:
El ángulo de rotación se especifica con el primer número en transform="rotate(270, 80, 80)"
.
El problema es: cuando se ve en Safari en iOS 10, esta rotación no se aplica. De hecho, establecer la rotación de 90, 180 o 270 grados no tiene ningún efecto. Los mismos ángulos pero negativos (por ejemplo -90) tampoco se aplican.
Aquí hay una captura de pantalla del violín anterior en Safari en iOS 10.0.1:
Y aquí está el mismo violín en Safari en iOS 9.3.5:
Como solución, descubrí que el uso de algo así como 270.1 grados resuelve el problema; sin embargo, me gustaría saber por qué 270 no funciona y si hay una mejor manera de solucionarlo.
Lo he experimentado dolorosamente en iOS 10.1 y Safari 10.0.1. El error definitivamente se desencadena por cualquier valor de rotate
que compute a un valor divisible en 90 grados.
Pero se vuelve más extraño.
Vea esta demostración / serie de casos de prueba mínimos que reuní (versión jsFiddle aquí ). Lo mejor es ejecutar el fragmento y luego expandirlo a la página completa:
svg {
height: 80px;
width: 80px;
}
circle {
fill: none;
stroke-dasharray: 150;
stroke-width: 4px;
stroke: #6fdb6f;
transform-origin: center center;
}
.degrot {
transform: rotate(-90deg);
}
.degrot-offset {
transform: rotate(-90.1deg);
}
.degrot-offset-more {
transform: rotate(-92deg);
}
.turnrot {
transform: rotate(-0.25turn);
}
.turnrot-offset {
transform: rotate(-0.251turn);
}
svg[viewBox] circle {
stroke-dasharray: 300;
stroke-width: 8px;
}
svg[viewBox].scaledown circle {
stroke-dasharray: 300;
stroke-width: 8px;
}
svg[viewBox].noscale circle {
stroke-dasharray: 150;
stroke-width: 4px;
}
svg[viewBox].scaleup circle {
stroke-dasharray: 75;
stroke-width: 2px;
}
.wc {
will-change: transform;
}
/* Demo prettification */
p:last-child {
margin-bottom: 0;
}
td {
padding: 10px;
}
tr td:first-of-type {
width: 80px;
min-height: 80px;
}
tr + tr td {
border-top: 1px solid #dcdcdc;
}
<table>
<tr><td colspan="2">In Safari 10.0.1 and iOS 10.1, strange behavior can be observed on SVG shapes with <code>rotate</code> values not divisible by 90 degrees, when <code>transform-origin: center center;</code></td></tr>
<tr>
<td>
<svg xmlns="http://www.w3.org/2000/svg">
<circle class="degrot" r="35" cy="40" cx="40" />
</svg>
</td>
<td>
<code>transform: rotate(-90deg);</code>
<p>The stroke improperly begins <a href="https://www.w3.org/TR/SVG11/shapes.html#CircleElement">at 3:00</a>, as if the <code>transform</code> rule hadn''t been applied.</p>
</td>
</tr>
<tr>
<td>
<svg xmlns="http://www.w3.org/2000/svg">
<circle class="degrot-offset" r="35" cy="40" cx="40" />
</svg>
</td>
<td>
<code>transform: rotate(-90.1deg);</code>
<p>The stroke begins at (twelve seconds before) 12:00, as expected.</p>
</td>
</tr>
<tr>
<td>
<svg xmlns="http://www.w3.org/2000/svg">
<circle class="turnrot" r="35" cy="40" cx="40" />
</svg>
</td>
<td>
<code>transform: rotate(-0.25turn);</code>
<p>The same bug applies to any <code>rotate</code> value which computes to a multiple of 90 degrees.</p>
</td>
</tr>
<tr>
<td>
<svg xmlns="http://www.w3.org/2000/svg">
<circle class="turnrot-offset" r="35" cy="40" cx="40" />
</svg>
</td>
<td>
<code>transform: rotate(-0.251turn);</code>
<p>43 seconds before noon.</p>
</td>
</tr>
<tr><td colspan="2">But when the SVG element specifies a <code>viewBox</code> which is being scaled down, things can get weird:</td></tr>
<tr>
<td>
<svg viewBox="0 0 160 160" xmlns="http://www.w3.org/2000/svg">
<circle class="degrot" r="70" cy="80" cx="80" />
</svg>
</td>
<td>
<code>transform: rotate(-90deg);</code>
<p>So far, so the same.</p>
</td>
</tr>
<tr>
<td>
<svg viewBox="0 0 160 160" xmlns="http://www.w3.org/2000/svg">
<circle class="degrot-offset" r="70" cy="80" cx="80" />
</svg>
</td>
<td>
<code>transform: rotate(-90.1deg);</code>
<p>But now, offsetting by a little bit doesn''t work, <em>unless</em> you zoom in the page in past a certain zoom threshold (either via pinching, or <code>View > Zoom</code> and/or keyboard shortcut). Try it; it''s unsetting!</p>
<p>This is probably because of some rounding of that the zooming engine performs, because...</p>
</td>
</tr>
<tr>
<td>
<svg viewBox="0 0 160 160" class="scaledown" xmlns="http://www.w3.org/2000/svg">
<circle class="degrot-offset-more" r="70" cy="80" cx="80" />
</svg>
</td>
<td>
<code>transform: rotate(-92deg);</code>
<p>offsetting by a larger amount restores expected behavior.</p>
</td>
</tr>
<tr><td colspan="2">If the SVG element is not being scaled <em>down</em>, behavior identical to the first section resumes. Zooming has no effect:</td></tr>
<tr>
<td>
<svg viewBox="0 0 80 80" class="noscale" xmlns="http://www.w3.org/2000/svg">
<circle class="degrot" r="35" cy="40" cx="40" />
</svg>
<svg viewBox="0 0 40 40" class="scaleup" xmlns="http://www.w3.org/2000/svg">
<circle class="degrot" r="17.5" cy="20" cx="20" />
</svg>
</td>
<td>
<code>transform: rotate(-90deg);</code>
<p>
Top: No scaling (viewBox dimensions match parent element''s)<br><br>
Bottom: Scaling up (viewBox dimensions half of parent element''s)
</p>
</td>
</tr>
<tr>
<td>
<svg viewBox="0 0 80 80" class="noscale" xmlns="http://www.w3.org/2000/svg">
<circle class="degrot-offset" r="35" cy="40" cx="40" />
</svg>
<svg viewBox="0 0 40 40" class="scaleup" xmlns="http://www.w3.org/2000/svg">
<circle class="degrot-offset" r="17.5" cy="20" cx="20" />
</svg>
</td>
<td>
<code>transform: rotate(-90.1deg);</code>
<p>
Top: No scaling (viewBox dimensions match parent element''s)<br><br>
Bottom: Scaling up (viewBox dimensions half of parent element''s)
</p>
</td>
</tr>
<tr><td colspan="2">But there is one exception:</td></tr>
<tr>
<td>
<svg class="degrot wc" xmlns="http://www.w3.org/2000/svg">
<circle r="35" cy="40" cx="40" />
</svg>
</td>
<td>
<p>On the parent <code>svg</code> element:</p>
<code>transform: rotate(-90deg);<br>will-change: transform;</code>
<p>Iff the the the rotation is applied to a <em>parent</em> of the SVG shape (including the SVG element itself) along with the rule <code>will-change: transform</code>, all rotation values work as expected.</p>
</td>
</tr>
<tr><td colspan="2">All these behaviors have been observed in Safari 10.0.1 and iOS 10.1. They appear to be fixed as of iOS 10.2 Beta 2.</td></tr>
</table>
Como se indica en la demostración, parece estar corregido en iOS 10.2, al menos en la versión beta pública que acabo de descargar. Presumiblemente, un arreglo de Safari también llegará a su debido tiempo.
iOS 10.1
iOS 10.2 (Public Beta 2)
Esto me está sucediendo a mí también, me decidí a usar una rotación casi imposible de ser divisible 90 grados para evitar esto mientras tanto.
De hecho, establezca la transformación de rotación en algo así como 90.1deg resuelve el problema ...
He probado muchas cosas, informadas aquí: https://codepen.io/KevinNTH/pen/ZBgKdG
<!-- workaround ios -->
<svg class="wka-ios">
<g transform="rotate(-90.1 30 30)">
<circle cx="25" cy="25" r="15"/>
</g>
</svg>