Ich habe neulich meinen Anwendungsordner durchgesehen und gehofft, etwas aufzuräumen. Dabei bin ich auf eine App gestoßen, die ich früher liebte, aber schon ewig nicht mehr benutzt habe: Simple Desktops. Es ist eine App, um ab und zu das Hintergrundbild durch ein zufälliges, einfaches, klassisches Design zu ersetzen. Eines davon sah so aus:

Ich hatte gerade Lust dazu und habe mich daran gemacht, es mit Frontend-Code nachzubauen.
Du weißt, was gut im Zeichnen von Kreisen ist?
SVG ist es. Ich dachte, der einfachste Weg, konzentrische Kreise zu zeichnen, wäre das
<svg viewBox="-50 -50 100 100">
<!-- first circle -->
<circle cx="0" cy="0" radius="20" />
</svg>
Ich wusste, dass ich fünf Kreisgruppen wollte und dass jeder Kreis fünf Kreise enthalten sollte. Das wäre mühsam von Hand zu schreiben und noch mühsamer zu optimieren. Also griff ich zu unserem programmatischen Freund, der for-Schleife.
Aber wie schreibt man eine for-Schleife in SVG?
Verwenden Sie einen HTML-Präprozessor! Ich habe mich für Pug entschieden. Eine einfache Pug-Schleife sieht so aus:
- for (var x = 1; x < 6; x++)
p Print stuff five times.
Unsere Schleifen werden nur geringfügig komplizierter, da es zwei verschachtelte gibt. Und was sich in der Schleife befindet, ist ein
- for (var y = 1; y < 6; y++)
<svg viewBox="-50 -50 100 100">
- for (var x = 1; x < 6; x++)
circle&attributes({
"cx": 0,
"cy": 0,
"r": 60-(x*10)
})
</svg>
Das sieht ein wenig seltsam aus. Besonders das &attributes-Bit. Das nennen sie "exploded" Attribute. Aber ich mag es. Attribute in diesem Format eines JavaScript-Objekts zu setzen, ist irgendwie nett.
Wenn das kompiliert wird, sieht es so aus:

Ich bin sicher, Sie können sehen, wie einfach es wäre, den Code in diesen Schleifen anzupassen, um viele Dinge schnell zu ändern.
Unglaublich einfache Zentrierung und Layout mit Flexbox
Die 5 <svg>s nebeneinander anzuordnen ist sehr einfach. In unserem kleinen Demo reicht es aus, den <body> zu einem Flex-Container zu machen.
Die vertikale Zentrierung geschieht automatisch, wenn wir ihre Höhe mit flex: 1 erweitern. Standardmäßig macht SVG seinen Zeichenbereich zentriert und so groß wie möglich innerhalb des Bereichs, den die
html, body {
height: 100%;
overflow: hidden;
}
body {
display: flex;
padding: 0 50px;
}
svg {
flex: 1;
padding: 20px;
}
Wir besorgen uns schöne Farbpaletten
Es gibt eine clevere Methode, um in JavaScript eine zufällige Farbe (Hex-Code) zu generieren.
'#'+Math.floor(Math.random()*16777215).toString(16);
Zufällige Farben sind jedoch normalerweise nicht sehr ansprechend, besonders wenn fünf zufällige Farben zusammenkommen.
Es gibt eine nette kleine Bibliothek namens Please.js, die wir verwenden könnten, um ansprechende Farben zu erhalten. Sie haben sogar eine API für Paletten.
Please.make_scheme({
scheme_type: 'analogous'
});

Aber… das ist immer noch vielleicht nicht so schön wie eine handgemachte und von der Community kuratierte Farbpalette. Und genau das hat COLOURlovers.

Und glücklicherweise haben sie eine API. Der Gedankengang zur Nutzung ist ungefähr so:
1. Wir wollen speziell Paletten, also
http://www.colourlovers.com/api/palettes
2. Wir wollen speziell gute, also
http://www.colourlovers.com/api/palettes/top
3. Wir wollen sie in JavaScript verwenden, also wäre JSON nett, also
http://www.colourlovers.com/api/palettes/top?format=json
4. Wir wollen genau 5 davon, also
http://www.colourlovers.com/api/palettes/top?format=json&numResults=5
5. Wir wollen jedes Mal andere Ergebnisse, also
Das ist etwas kniffliger. Glücklicherweise unterstützt ihre API einen "Offset", was bedeutet, dass wir unsere fünf Ergebnisse ab einem beliebigen Punkt in ihrer Reihenfolge erhalten können. Also randomisieren wir das.
Lassen Sie uns eine Zahl zwischen 1 und 50 generieren.
var rand = Math.floor(Math.random() * (50 - 1)) + 1;
Dann können wir das am Ende der URL, die wir erstellen, anhängen.
var url = “http://www.colourlovers.com/api/palettes/top?format=json&numResults=5&resultOffset=” + rand;
Wir wollen das im Browser verwenden, also
Das bedeutet, diese API-Anfrage mit Ajax durchzuführen. Dabei unterliegen wir den Cross-Domain-Beschränkungen des Browsers. Diese können vom API-Anbieter aufgehoben werden, indem sogenannte CORS-Header gesetzt werden, aber aus irgendeinem Grund setzt COLOURlovers diese nicht. Eine andere klassische Methode, dies zu umgehen, ist "JSONP", aber wir gehen jetzt nicht darauf ein.
Stattdessen verwenden wir einen Proxy-Server, um die Daten abzurufen und sie uns mit richtigen CORS-Headern erneut bereitzustellen. crossorigin.me ist dafür nützlich. Sie stellen einfach ihre URL der URL voran, die wir gerade erstellen.
var url = "http://crossorigin.me/http://www.colourlovers.com/api/palettes/top?format=json&numResults=5&resultOffset=" + rand;
Farbcodes abrufen
Nachdem wir nun die URL haben, die die benötigten Daten zurückgibt, verwenden wir eine jQuery-Ajax-Methode, um sie abzurufen.
$.getJSON("http://crossorigin.me/http://www.colourlovers.com/api/palettes/top?format=json&numResults=5&resultOffset=" + rand, function(data) {
console.log(data);
});
Habe sie!

Die SVGs einfärben
Das Datenobjekt enthält alles, was wir zur Einfärbung benötigen. Wir werden über alle <svg>s und alle darin enthaltenen <circle>s in einer verschachtelten Schleife iterieren.
jQuerys .each() ist dafür nützlich, was uns auch einen Parameter zum Verfolgen von Iterationen gibt. Wir werden diese verwenden, um einzelne Farben aus den Arrays zu extrahieren und sie als fill-Attribut auf die <circle>s anzuwenden.
$("svg").each(function(x) {
// x will be 0, 1, 2, etc.
$(this)
.find("circle")
.each(function(y) {
// y will be 0, 1, 2, etc.
$(this).attr("fill", "#" + data[x].colors[y]);
});
console.log("Palette #" + x + ": " + data[x].colors)
// "Palette #1: 351330,424254,64908A,E8CAA4,CC2A41"
});
Tada!
Siehe den Pen
Color Palette Circles von Chris Coyier (@chriscoyier)
auf CodePen.