Maxim Leyzerovich hat mit einigen ausgesprochen einfachen SVG-Elementen den Marching Ants-Effekt erstellt.
Siehe den Pen SVG Marching Ants von Maxim Leyzerovich (@round) auf CodePen.
Lassen Sie uns das Stück für Stück zerlegen und sehen, wie all die kleinen Teile zusammenkommen.
Schritt 1: Zeichne ein verdammt Rechteck
Wir können unser SVG als Quadrat einrichten, aber das Seitenverhältnis ignorieren lassen und es in jedes gewünschte Rechteck einpassen.
<svg viewbox='0 0 40 40' preserveAspectRatio='none'>
<rect width='40' height='40' />
</svg>
Sofort werden wir daran erinnert, dass das Koordinatensystem innerhalb eines SVG einheitenlos ist. Hier sagen wir: "Dieses SVG ist ein 40x40-Raster. Zeichne jetzt ein Rechteck, das das gesamte Raster abdeckt." Wir können das gesamte SVG aber immer noch mit CSS skalieren. Zwingen wir es dazu, genau die Hälfte des Viewports zu sein
svg {
position: absolute;
width: 50vw;
height: 50vh;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
}
Schritt 2: Kämpfe gegen die Quetschung
Da wir die Box und das Raster so flexibel gestaltet haben, wird es zu einer gewissen Quetschung kommen, die wir wahrscheinlich vorhergesehen haben könnten. Sagen wir, wir haben einen Strich, der in unserem Koordinatensystem 2 breit ist. Wenn das SVG schmal ist, muss es diesen schmalen Raum immer noch in 40 Einheiten aufteilen. Das bedeutet, dass der Strich ziemlich schmal sein wird.
Das können wir verhindern, indem wir dem Strich sagen, dass er nicht skaliert werden soll.
rect {
fill: none;
stroke: #000;
stroke-width: 10px;
vector-effect: non-scaling-stroke;
}
Jetzt verhält sich der Strich eher wie ein Rand eines HTML-Elements.
Schritt 3: Zeichne die Kreuzlinien
In Maxims Demo zeichnet er die Linien in der Mitte mit vier Pfadelementen. Denken Sie daran, wir haben ein 40x40-Koordinatensystem, daher ist die Mathematik großartig
<path d='M 20,20 L 40,40' />
<path d='M 20,20 L 00,40 '/>
<path d='M 20,20 L 40,0' />
<path d='M 20,20 L 0,0' />
Das sind vier Linien, die genau in der Mitte (20,20) beginnen und zu jeder Ecke gehen. Warum vier Linien anstelle von zwei, die von Ecke zu Ecke gehen? Ich vermute, es liegt daran, dass die Marching Ants-Animation später irgendwie cooler aussieht, wenn alle Ameisen vom Zentrum ausgehen, anstatt sich zu kreuzen.
Ich liebe die schöne Syntax von Pfaden, aber wir verwenden nur zwei Linien, um anders zu sein
<line x1="0" y1="0" x2="40" y2="40"></line>
<line x1="0" y1="40" x2="40" y2="0"></line>
Wenn wir unseren Strich auf unser rect und line anwenden, funktioniert es! Aber wir sehen ein leicht seltsames Problem
rect, line {
fill: none;
stroke: #000;
stroke-width: 1px;
vector-effect: non-scaling-stroke;
}

Die äußere Linie erscheint dünner als die inneren Linien, und der Grund dafür ist, dass das äußere Rechteck genau außerhalb des SVG liegt. Infolgedessen wird alles außerhalb davon abgeschnitten. Es ist ziemlich frustrierend, aber Striche in SVG straddeln immer die Pfade, auf denen sie liegen, sodass genau die Hälfte des äußeren Strichs (0,5px) verborgen ist. Wir können das Rechteck verdoppeln, um es zu "beheben"
rect, line {
fill: none;
stroke: #000;
stroke-width: 1px;
vector-effect: non-scaling-stroke;
}
rect {
stroke-width: 2px;
}

Maxim fügt auch shape-rendering: geometricPrecision; hinzu, weil es auf Nicht-Retina-Displays angeblich ein wenig aufräumt.
Schritt 3: Ameisen sind gestrichelt
Abgesehen von der seltsamen Sache mit dem Straddeln der Linie bieten SVG-Striche weitaus mehr Kontrolle als CSS-Ränder. CSS hat zum Beispiel gestrichelte und gepunktete Randstile, bietet aber keine Kontrolle darüber. In SVG haben wir dank stroke-dasharray Kontrolle über die Länge der Striche und den Abstand dazwischen
rect, line {
...
/* 8px dashes with 2px spaces */
stroke-dasharray: 8px 2px;
}
Wir können es sogar richtig verrückt machen

Aber die Ameisen sehen gut aus mit 4px Strichen und 4px Abstand dazwischen, daher können wir eine Kurzform von stroke-dasharray: 4px; verwenden.
Schritt 5: Animieren Sie die Ameisen!
Der "Marching"-Teil von "Marching Ants" kommt von der Animation. SVG-Striche können auch um eine bestimmte Distanz versetzt werden. Wenn wir eine Distanz wählen, die genau so lang ist wie der Strich und der Abstand zusammen, und dann den Versatz dieser Distanz animieren, können wir eine flüssige Bewegung des Strichdesigns erzielen. Wir haben dies sogar schon einmal behandelt, um den Effekt eines sich selbst zeichnenden SVG zu erzeugen.
rect, line {
...
stroke-dasharray: 4px;
stroke-dashoffset: 8px;
animation: stroke 0.2s linear infinite;
}
@keyframes stroke {
to {
stroke-dashoffset: 0;
}
}
Hier ist unsere Nachbildung und das Original
Siehe den Pen SVG Marching Ants von Maxim Leyzerovich (@round) auf CodePen.
Wieder einmal ist vielleicht mein Lieblingsteil hier die klaren 1px Linien, die überhaupt nicht durch Größe oder Seitenverhältnis eingeschränkt sind, und wie wenig Code es braucht, um alles zusammenzubringen.
bezüglich des "dünneren" äußeren Strichs, man kann auch
overflow: visiblezu den SVG-Stilen hinzufügen, um es vollständig anzuzeigen!Funktioniert einwandfrei!
Es könnte erwähnenswert sein, dass
vector-effect: non-scaling-strokeimmer noch keine Unterstützung in IE und Edge hat, siehe https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7326047/