Tekenen met Two.js

Geavanceerde grafische afbeeldingen vormen tegenwoordig een groot deel van het web, maar er zijn een aantal verschillende renderers in de mix. Je zou natuurlijk canvas kunnen gebruiken; maar SVG en WebGL zijn ook opties. In deze zelfstudie bespreken we een relatief nieuwe tekenbibliotheek, two.js, die één API biedt die hetzelfde doet met alle drie van die renderers. Als je klaar bent, laten we het eens bekijken!


Stap 1 - Instellen

De eerste stap is het maken van een twee exemplaar en plaats het op de pagina. De Twee contstructor neemt een object met een aantal parameters:

 var two = new Two (fullscreen: true);

In dit geval gebruiken we de volledig scherm optie, waardoor het tekengebied het volledige browservenster beslaat. Als we wilden dat ons tekengebied een specifieke grootte had, zouden we de breedte en hoogte eigenschappen in plaats daarvan; deze nemen allebei een cijfer voor een pixelwaarde. Er is ook de automatische start parameter; als dit op true is ingesteld, worden alle animaties meteen uitgevoerd wanneer de pagina is geladen.

Er is ook de type parameter: dit bepaalt welke renderer zal worden gebruikt. U kunt kiezen tussen canvas, SVG en WebGl. Je typt niet alleen de naam: je gebruikt ook een soort bibliotheekconstante: een van beide Two.Types.canvas, Two.Types.svg, of Two.Types.webgl. Voor alle duidelijkheid: two.js gebruikt standaard SVG; het doet geen enkele vorm van functiedetectie om te zien wat de browser zal ondersteunen. Dat moet je alleen doen (en ik denk dat dat een goed idee is: kleine tools, één ding goed, en zo).

Dus, zodra we een hebben Twee Wat doen we er bijvoorbeeld mee? Eerst wil je het toevoegen aan de pagina. Het heeft een appendTo methode die een HTML-element als parameter gebruikt, dus laten we dit instellen:

 

Dan in main.js, we beginnen met dit:

 var el = document.getElementById ("main"), two = new Two (fullscreen: true); two.appendTo (el);

Met al deze instellingen zijn we klaar om een ​​paar vormen daadwerkelijk te tekenen.


Stap 2 - Basisvormen tekenen

We beginnen met basisvormen; terwijl we onze eigen complexe vormen kunnen maken met nieuwe Two.Polygon, de meeste eenvoudige vormen kunnen met een paar handige methoden worden gemaakt.

Laten we beginnen met cirkels. De makeCircle functie neemt drie parameters:

 var circle = two.makeCircle (110, 110, 100); circle.fill = "# 881111"; two.update ();

We zullen van onderaf bekijken: de oproep naar two.update updates zijn tekengebied en geven de inhoud daadwerkelijk weer. Een back-up maken naar de cirkel, de eerste twee parameters zijn de x- en y-coördinaten voor het middelpunt van de cirkel. Dan is de derde parameter de straal voor de cirkel. Al de two.make ... functies retourneren a Two.Polygon voorwerp. Terwijl we deze zelfstudie doorlopen, ziet u verschillende eigenschappen en methoden die u op deze shapes kunt gebruiken. Dit is de eerste: vullen. Zoals je misschien wel raadt, wordt de vulkleur ingesteld: elke geldige CSS doet het.

Het resultaat zou er als volgt uit moeten zien:

Hoe zit het met rechthoeken? De two.makeRectangle methode neemt vier parameters. Net als de cirkel markeren de eerste twee parameters de X en Y coördinaten voor het midden van de rechthoek. Dan is param drie breedte en param vier is de hoogte van de rechthoek.

 var rect = two.makeRectangle (115, 90, 150, 100); rect.fill = "oranje"; rect.opacity = 0,25; rect.noStroke (); two.update ();

Nogmaals, we gebruiken de vullen eigendom. We gebruiken ook de ondoorzichtigheid eigenschap, die een decimale waarde tussen 0 en 1 accepteert; we hebben hier de opaciteit van kwart. Ten slotte gebruiken we de noStroke methode, die de streek (rand) van de rechthoek verwijdert. Dit is wat we hebben:

Ellipsen zijn ook vrij eenvoudig: zoals je zou kunnen raden, zetten de eerste twee parameters het midden van de ellips. Dan hebben we breedte en hoogte:

 var ellips = two.makeEllipse (100, 40, 90, 30); ellipse.stroke = "# 112233"; ellipse.linewidth = 5; ellipse.noFill (); two.update ();

Voor nieuwe eigenschappen: we hebben beroerte, welke de kleur van de rand instelt; om de breedte van die rand in te stellen, gebruiken we de lijnbreedte eigendom. Onthoud dan noStroke? De geen vulling methode is hetzelfde, behalve dat de vulkleur voor onze vorm wordt verwijderd (zonder dat, onze vormen standaard op een witte vulling).

Natuurlijk zijn de eenvoudigste vormen lijnen.

 var line = two.makeLine (10, 10, 110, 210); line.linewidth = 10; line.stroke = "rgba (255, 0, 0, 0.5)";

De eerste twee parameters zijn de X en Y voor het ene uiteinde van de regel; de tweede set is voor het andere uiteinde.

Waarschijnlijk de meest ongemakkelijke vorm om te creëren is de curve. De two.makeCurve methode kost zoveel sets x, y parameters zoals je zou willen - elk paar is een punt waar de lijn zal buigen. Dan is de laatste parameter een boolean: maak het waar als de vorm open is, wat betekent dat de uiteinden geen verbinding maken. Als je wilt dat two.js een lijn tekent die de twee uiteinden van de curven verbindt, zou dat moeten zijn vals.

 var curve = two.makeCurve (110, 100, 120, 50, 140, 150, 160, 50, 180, 150, 190, 100, waar); curve.linewidth = 2; curve.scale = 1,75; curve.rotation = Math.PI / 2; // Kwartslag curve.noFill ();

Je weet wel lijnbreedte, maar hoe zit het met schaal? We kunnen dit gebruiken om onze vorm te verkleinen of uit te breiden; hier breiden we de vorm met 175% uit. Dan kunnen we gebruiken omwenteling om onze vorm te roteren door een aantal radialen; we doen 90 graden, wat half-PI-radialen is.

Eindelijk, je zou kunnen denken dat, omdat we vorm hebben opengemaakt, we geen vulling krijgen; maar dat is niet waar. Een niet-gesloten curve heeft nog steeds een vulling, dus we gebruiken geen vulling om de vulling te verwijderen en eindigt met alleen de curve.

Het laatste vormtype is de catch-all: het is de algemene polygoon. Eigenlijk is het vrijwel net als de curve, behalve dat de lijnen recht van punt naar punt gaan.

 var poly = two.makePolygon (110, 100, 120, 50, 140, 150, 160, 50, 180, 150, 190, 100); poly.linewidth = 4; poly.translation = new Two.Vector (60, 60); poly.stroke = "#cccccc"; poly.fill = "#ececec";

Net als bij de curve, hebben we zoveel paren coördinaten als we zouden willen, en dan de open boolean; hier plaatsen we het op vals, dus de vorm zal worden gesloten.

We stellen ook een vertaling hier; Hierdoor kunnen we de vorm naar links of rechts en omhoog of omlaag verplaatsen. We zetten de vertaling eigendom van een Two.Vector aanleg. De Two.Vector constructor neemt twee parameters: een X en een Y. Deze vormen uiteindelijk de coördinaten voor het midden van de vorm. U hoeft hiervoor eigenlijk geen nieuwe vector aan te maken; je kunt gewoon de X en Y waarden map:

 poly.translation.x = 60; poly.translation.y = 60;

Dit is wat we krijgen:


Stap 3 - Groepen maken

Tot nu toe hebben we gewerkt met objecten met individuele vormen; het is echter mogelijk om vormen samen te voegen en ermee samen te werken als één geheel.

Je kunt een groep maken met de two.makeGroup methode. Dan kunnen we het gebruiken toevoegen methode om een ​​vorm aan de groep toe te voegen.

 var group = two.makeGroup (), rect = two.makeRectangle (0, 0, 100, 100), circ = two.makeCircle (50, 50, 50);

rect.fill = "rood"; circ.fill = "blauw"; group.add (rect); group.add (circ); two.update ();

Als je dit uitvoert, is het vrij eenvoudig; net zoals je zou krijgen zonder de groep stukjes.

Maar dan kunnen we met de groep werken, met behulp van een van de transformaties die we kunnen doen op een individuele vorm. Bijvoorbeeld, wat dacht je van een vertaling?

 group.translation.x = 100; group.translation.y = 100; two.update ();

Net als bij reguliere vormen worden groepen van back-to-front besteld terwijl ze worden gemaakt. Als u echter een vorm aan een groep en vervolgens een andere groep toevoegt, wordt deze uit de eerste groep verwijderd. Dit is geweldig als je de volgorde van de vormen van voor naar achter bij het animeren moet veranderen (wat we zullen bereiken). Dus, als we hiermee beginnen:

 var topGroup = two.makeGroup (), bottomGroup = two.makeGroup (), rect = two.makeRectangle (100, 100, 100, 100), circ = two.makeCircle (150, 150, 50); rect.fill = "rood"; circ.fill = "blauw"; topGroup.add (rect); topGroup.add (circ); two.update ();

We hebben hetzelfde als hierboven:

Maar als we het toevoegen rect naar de bottomGroup in plaats daarvan…

 bottomGroup.add (rect);

Nu staat ons vierkant bovenaan.

Stap 4 - Animatie van vormen

Laten we tenslotte praten over animatie. Je weet al dat two.js de vormen weergeeft die je hebt gemaakt wanneer je belt two.update (). Als je belt two.play () in plaats daarvan is het net als bellen bijwerken() herhaaldelijk met behulp van Request Animation Frame. Elke keer dat dit gebeurt, start two.js een "update" -gebeurtenis. Dit is hoe we animatie kunnen produceren: luister naar de "update" -gebeurtenis; en wanneer dit gebeurt, voert u een functie uit om het volgende frame in te stellen.

Onze voorbeelden tot dusverre waren vrij eenvoudig, dus laten we de zaken een tandje bijsteken: we zullen een planeet in een baan om de aarde creëren met zijn eigen baan om de maan. Vergeet niet dat we beginnen met het maken van twee instanties:

 var el = document.getElementById ("main"), two = new Two (fullscreen: true). appendTo (el);

Vervolgens moeten we een aantal variabelen instellen.

 var earthAngle = 0, moonAngle = 0, distance = 30, radius = 50, padding = 100, orbit = 200, offset = baan + opvulling, banen = two.makeGroup ();

We zullen verhogen earthAngle en moonAngle om onze planeet en maan rond hun banen te krijgen. De afstand veranderlijk is hoe ver onze maan van onze aarde zal zijn. De radius is de raduis van onze planeet aarde, en de vulling is hoeveel ruimte onze planeet buiten zijn baan zal hebben. Die baan komt van de baan variabel. De compenseren variabele is hoe ver onze planeet zal worden verplaatst van de rand van het canvas. eindelijk, de banen groep houdt de twee baankringen vast, die ons in staat zullen stellen om ze naar believen te tonen of te verbergen. Maak je geen zorgen als je een beetje in de war bent; je zult zien hoe ze allemaal in een seconde samenwerken.

We beginnen met de baanbaan van de aarde. Dat is natuurlijk een simpele cirkel:

 var earthOrbit = two.makeCircle (offset, offset, baan); earthOrbit.noFill (); earthOrbit.linewidth = 4; earthOrbit.stroke = "#ccc"; orbits.add (earthOrbit); two.update ();

Er is hier niets nieuws. Dit is wat u zou moeten zien:

Dan moeten we een planeet creëren en deze in zijn baan plaatsen. Ten eerste hebben we een middel nodig om uit te zoeken waar in de baan de planeet moet worden geplaatst; en natuurlijk moet dit voor elk animatieframe veranderen. Laten we dus een functie maken die het centrum terugbrengt X en Y coördinaten voor de baan op basis van de huidige hoek voor positionering rond de cirkel en de straal van de baan:

 functie getPositions (hoek, baan) return x: Math.cos (hoek * Math.PI / 180) * baan, y: Math.sin (hoek * Math.PI / 180) * baan; 

Ja, het is een beetje trigonometrie, maar maak je niet al te veel zorgen: we converteren in feite de hoek (die een graad is) naar een radiaal, met behulp van de JavaScript sinus- en cosinus-methoden, en dan te vermenigvuldigen met de baan. Nu kunnen we deze functie gebruiken om de aarde aan de foto toe te voegen:

 var pos = getPositions (earthAngle ++, orbit), earth = two.makeCircle (pos.x + offset, pos.y + offset, radius); earth.stroke = "# 123456"; earth.linewidth = 4; earth.fill = "# 194878";

We beginnen met het verkrijgen van de positie voor de eerste earthAngle (waarde van 0, weet je nog?); dan maken we onze aarde gebaseerd op die posities (plus de offset) en kleur het op. Dit is wat we eindigen met:

Laten we deze planeet animeren. De bindende code van de gebeurtenis komt eigenlijk rechtstreeks van Backbone, dus het ziet er misschien bekend uit:

 two.bind ("update", functie (frameCount) var pos = getPositions (earthAngle ++, orbit); earth.translation.x = pos.x + offset; earth.translation.y = pos.y + offset;); two.play ();

Wat hier gebeurt, is dat elke keer dat het bijwerken gebeurtenis optreedt, we gebruiken de getPositions functie om de positie voor de volgende hoek op aarde te berekenen. Dan hoeven we alleen maar het midden van de aarde in te stellen op die nieuwe posities, plus de offset. Eindelijk bellen we two.play () om de update-evenementen te starten. Als je de pagina nu opnieuw laadt, zou je de aarde rond de baan moeten zien draaien.

Goed gedaan tot nu toe, nietwaar? Nu, wat dacht je van de maan en zijn baan in de baan; dit gaat boven de binden uitspraak.

 var moonOrbit = two.makeCircle (earth.translation.x, earth.translation.y, radius + distance); moonOrbit.noFill (); moonOrbit.linewidth = 4; moonOrbit.stroke = "#ccc"; orbits.add (moonOrbit); var pos = getPositions (moonAngle, radius + distance), moon = two.makeCircle (earth.translation.x + pos.x, earth.translation.y + pos.y, radius / 4); moonAngle + = 5; moon.fill = "# 474747";

Dit lijkt veel op de code voor de planeet: we centreren de cirkelbaan van de maan in het midden van de aarde met behulp van de vertaling eigenschappen; de straal is de straal van de aarde plus de afstand die de maan van de aarde verwijderd moet zijn. Nogmaals, we voegen het toe moonOrbit naar de banen groep.

Vervolgens creëren we de maan, door eerst de gewenste positie in te nemen en op die locatie een cirkel te creëren. Voor een straal gebruiken we een kwart van de straal die we voor de aarde hebben gebruikt. We zullen elke keer de hoek van de maan met 5 verrijken, dus het zal sneller bewegen dan de aarde.

De animatie uitschakelen (door de opmerkingen te plaatsen) two.bind verklaring), we krijgen dit:

Laatste stap: laat de maan animeren. Binnen datzelfde two.bind verklaring, voeg deze regels toe:

 var moonPos = getPositions (moonAngle, radius + distance); moon.translation.x = earth.translation.x + moonPos.x; moon.translation.y = earth.translation.y + moonPos.y; moonAngle + = 5; moonOrbit.translation.x = earth.translation.x; moonOrbit.translation.y = earth.translation.y;

Net als voorheen krijgen we de nieuwe positie voor de maan en positioneren deze ten opzichte van de aarde. Vervolgens verplaatsen we ook de baanring van de maan zodat deze gecentreerd blijft op de aarde.

Met dit alles op zijn plaats, is ons kleine voorbeeld compleet: hier is nog een shot van de actie:

Zoals ik al zei, we kunnen ook de banen verbergen. Omdat ze allebei in de banen groep, we kunnen de zichtbaar eigendom van de groep:

 orbits.visible = false;

En nu:


Conclusie

Wel, dat is een omslag in deze tutorial. Denk je dat je two.js in elk van je eigen projecten gaat gebruiken? Of misschien heb je een beter alternatief? Laten we erover horen in de reacties!