Opret supereffektive SVG-tegn med localStorage

Forfatter: Peter Berry
Oprettelsesdato: 15 Juli 2021
Opdateringsdato: 12 Kan 2024
Anonim
Opret supereffektive SVG-tegn med localStorage - Kreativ
Opret supereffektive SVG-tegn med localStorage - Kreativ

Indhold

  • Viden nødvendig: Mellemliggende Javascript, grundlæggende Illustrator
  • Kræver: Prototype.js og nogle SVG
  • Projekt tid: 1-2 timer og tegningstid

Download kildefiler

Se demo

SVG er en fantastisk måde at male og animere skalerbar vektorgrafik af høj kvalitet på nettet. Det er en form for XML og kan let eksporteres fra vektorpakker, såsom Illustrator, til brug på dit websted. Når den er gengivet, kan den skaleres til enhver størrelse uden at miste kvalitet og animeres eller manipuleres som en samling af DOM-objekter.

På twiDAQ har vi brugt SVG til at skabe vores animerede spilkarakter. Hver spiller i spillet har en imaginær aktiemægler, Jim, der giver sig bedre, smartere tøj og tilbehør, når spillerens portefølje udvikler sig. Hver karakter er derfor lidt forskellig for hver spiller. Her er min mægler for eksempel.

Fordi han er ret detaljeret, og der er mange forskellige tilbehør og udstyr, er den fulde SVG-fil ret stor (~ 2 MB).Så vi har brug for en måde at downloade så lidt af SVG som muligt, samtidig med at vi undgår at downloade nogen af ​​de komponenter eller sprites, der kræves for at opbygge hver karakter mere end en gang nogensinde.


For at opnå dette udnytter vi browserens localStorage til at gemme eventuelle SVG-sprite-data, vi downloader. Vi kan derefter bruge localStorage til at få adgang til SVG-dataene næste gang vi har brug for det og male tegnet på skærmen ved hjælp af localStorage-dataene i stedet for at downloade disse sprites fra serveren igen.

Desuden når vi støder på en ny karakter, eller når spilleren får en opgradering, genbruger vi så meget data som muligt og downloader kun de nye sprites, vi ikke kender til; radikalt reducere mængden af ​​data, der kræves fra serveren over tid.

Oversigt

Hver karakter beskrives som en streng af sprites, der gives os en del af hver spillers JSON-objekt indsamlet via API:

  1. {jim: "bukser skjorte blå-slips frakke"}

Når vi har brug for at male et tegn, skal vi se i localStorage for hver af de krævede sprites og holde en liste over eventuelle sprites, der mangler.


Hvis der mangler sprites, beder vi dem fra et API-slutpunkt, der er oprettet til at betjene alle SVG-sprites, vi har brug for. SVG er en form for XML, så hver sprite sendes som en JSON-streng, der indeholder de XML-data, der kræves for at tegne den pågældende komponent; en arm, et grønt slips eller en sko.

Vi gemmer de nye sprites i localStorage, hvis vi har brug for dem igen i fremtiden, og endelig, nu har vi alt, hvad vi har brug for, vi maler vores karakter til siden ved hjælp af et SVG-objekt eller i tilfælde af IE8, i Flash via svgweb.

localStorage og JSON

localStorage er en simpel nøgle / værdipar-database, der giver dig mulighed for at gemme omkring 5 MB data pr. domæne. Da det ikke indbygget understøtter lagring af JSON-objekter, bliver vi nødt til at serialisere vores data for at gemme dem og deserialisere dem, når vi vil bruge dem. Sådan får vi og indstiller vi vores data i localStorage.

  1. // Butik
  2. localStorage.setItem ('hat', JSON.stringify (sprite));
  3. // Hent
  4. sprite = JSON.parse (localStorage.getItem (’hat’));

Objektet sprite er et json-objekt, der indeholder en streng XML fra API'en.


API-slutpunktet

Slutpunktet tager en kommasepareret liste over sprites og returnerer dem som et JSON-objekt, der indeholder navnet og referencen for sprite og selve sprite XML.

  1. // Tag SVG fra databasen
  2. $ oSprites = dbo :: get (’SELECT * FRA svg HVOR kode I (?)’, $ _GET [’dele’]);
  3. // Konstruer vores json
  4. $ oJson = array ();
  5. foreach ($ oSprites som $ oSprite) {
  6. $ oJson [$ oSprite-> code] = array (
  7. ’Navn’ => $ oSprite-> navn,
  8. ’Kode’ => $ oSprite-> kode,
  9. ’Xml’ => $ oSprite-> xml,
  10. );
  11. }
  12. // Returner vores json
  13. udskriv json_encode ($ oJson);

At fremsætte følgende anmodning til slutpunktet ville give os SVG til karakterens hat og slips.

Sørg for, at vi har alt, hvad vi har brug for

En grundlæggende karakter består af et dusin eller flere sprites, der skal males for at de skal lagres korrekt. Vi beskriver vores karakter som en pladsafgrænset streng, der deles ved hjælp af prototype.js's $ w (); fungere.

Når vi først har en liste over karaktersprites, bygger vi en liste over mangler, henter dem og prøver derefter igen.

  1. funktion build_character () {
  2. // En stak til de manglende sprites ..
  3. var mangler = [];
  4. // Find manglende genstande ..
  5. $ w ('hat coat tie'). hver (funktion (sprite_id) {
  6. hvis (! localStorage.getItem (sprite_id)) {
  7. // Optag den manglende sprite ..
  8. missing.push (sprite_id);
  9. }
  10. });
  11. // Hvis der mangler ting, skal du hente dem, ellers skal du bare male.
  12. hvis (! mangler.længde) {
  13. // Store!
  14. maling();
  15. } andet {
  16. // Hent manglende sprites ..
  17. nye Ajax ({
  18. url: ’/1/jim/about/elements.json’,
  19. parametre: {
  20. dele: mangler.tilslut (’,’),
  21. },
  22. // Tilbagekald metoden build_character (), når vi er færdige
  23. oncomplete: funktion (svar) {
  24. response.responseJSON.each (funktion (sprite, sprite_id) {
  25. // Opbevar hver sprite separat i lokal opbevaring
  26. localStorage.setItem (sprite_id, JSON.stringify (sprite));
  27. });
  28. // og prøv igen.
  29. build_character ();
  30. }
  31. });
  32. }
  33. }

Oprettelse af SVG-dokumentet

Vi har brug for et sted at male vores SVG, når vi har gjort det klar, så det næste, vi har brug for, er et tomt SVG-dokument. Dette fungerer for alle moderne browsere, og vi vil se på et IE8-alternativ senere.

Vores base SVG er et næsten tomt dokument og kan lagres kraftigt, men det indeholder nogle få nøglekomponenter; dimensioner og tilbagekald. Bemærk især onload-begivenheden. Når browseren har indlæst SVG-dokumentet med succes, vil det affyre vores build_character (); metode til at starte processen med at downloade og male vores karakter.

  1. ? xml version = "1.0" kodning = "utf-8"?>
  2. ! DOCTYPE svg OFFENTLIG "- // W3C // DTD SVG 1.1 // DA" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
  3. svg id = "svg-dom" version = "1.1"
  4. xmlns = "http://www.w3.org/2000/svg" xmlns: xlink = "http://www.w3.org/1999/xlink" xml: space = "bevar"
  5. x = "0px" y = "0px" viewBox = "0 0 680 878"
  6. onload = "top.document.build_character ();">
  7. g id = "svg_root"> / g>
  8. / svg>

For at sætte dette tomme dokument på siden og derved starte hele processen med at indlæse og male tegnet tilføjer vi et enkelt objekt-tag på siden.

  1. object id = "mySVG" data = "blank.svg" type = "image / svg + xml" width = "500" height = "500"> / objekt>

Og endelig har vi brug for et håndtag på SVG's DOM til senere.

  1. svg = $ ('mySVG'). contentDocument;

Maler karakteren

Nu hvor vi har alle de sprite-elementer, vi har brug for, og vores SVG-objekt klar til at modtage vores karakter, kan vi male ham på siden.

Husk, at vores SVG-dokument er et XML-dokument, der kan tilgås ligesom ethvert andet XML-dokument eller DOM. Så for Chrome, Safari, Opera, Firefox og IE9 kan vi konstruere hver sprite som et XML-objekt og tilføje det til vores SVG-dokument. Vi har brug for en ensartet metode til at analysere XML i forskellige browsere, som vi har kaldt xml_parser ().

  1. // Kan vi parse nativt, eller har vi brug for vores egen måde at gøre det på?
  2. xml_parser = (vindue [’parseXML’])? window.parseXML: funktion (er, doc) {
  3. doc = doc || dokument;
  4. hvis (vindue.DOMParser) {
  5. parser = ny DOMParser ();
  6. xmlDoc = parser.parseFromString (s, "text / xml");
  7. returnere doc.adoptNode (xmlDoc.documentElement);
  8. } andet {
  9. xmlDoc = ny ActiveXObject ("Microsoft.XMLDOM");
  10. xmlDoc.async = "falsk";
  11. xmlDoc.loadXML (r);
  12. returner xmlDoc.documentElement;
  13. }
  14. };

Nu har vi alt klar, vi gentager gennem vores karakters liste over sprites, denne gang analyserer vi hvert JSON-objekt hentet fra lokal opbevaring tilbage til den oprindelige JavasScript-objekttilstand og få fat i XML-strengen indefra. Vi bruger vores xml_parser () metode til at konstruere et XML-objekt af hver sprite og derefter blot tilføje det til vores SVG-dokument.

  1. // Iterer gennem vores sprites og mal karakteren
  2. $ w ('hat coat tie'). hver (funktion (sprite_id) {
  3. hvis (sprite = JSON.parse (localStorage.getItem (sprite_id))) {
  4. // Opret vores SVG-objekt
  5. var sprite_object = xml_parser (
  6. ’Svg xmlns =" ​​http://www.w3.org/2000/svg "> g id =" g-wrap ">’
  7. + sprite.svg +
  8. ’/ G> / svg>’
  9. );
  10. // Føj det til SVG DOM 'svg', vi oprettede tidligere.
  11. svg.getElementById ('svg_root'). appendChild (sprite_object.childNodes [0]);
  12. }
  13. });

Herunder Internet Explorer 8

Det sidste stykke puslespil får alt til at fungere for de Windows XP-brugere, der stadig bruger Internet Explorer. IE8 har localStorage, men det kan ikke male vores SVG, så i denne ene undtagelse skal vi lave SVG-maleriet ved hjælp af Flash og det strålende svgweb JavaScript-bibliotek.

Vi fandt ud af, at svgweb fungerer bedst ved sideindlæsning, og fordi twiDAQ er et fuldt AJAX / JSON-sted, som ikke ofte genindlæser vores løsning til IE8, er at skabe en gennemsigtig iframe /> når vi har brug for at male et tegn. Det iframe /> i sig selv indeholder en statisk, cacheable .html-fil, der gør arbejdet for os.

Listen over sprites overføres til iframe /> ved hjælp af en hash, så browseren kan cache filen en gang.

  1. iframe src = "static / ie-svg.html # hat, tie, coat"> / iframe>

Hashet læses derefter indefra iframe />, SVG trækkes fra localStorage, sammenkædes og skrives ind på siden under indlæsning via et opkald til document.write ().

  1. ! doctype html>
  2. html>
  3. hoved>
  4. meta charset = "utf-8" />
  5. meta name = "svg.config.data-path" content = "/ images / js / libs / svgweb /">
  6. meta name = "svg.render.forceflash" content = "true">
  7. script type = "text / javascript" src = "/ images / js / libs / svgweb / svg.js"> / script>
  8. script type = "text / javascript">
  9. // Træne de sprites, vi vil bruge: ie.html # hat, slips, frakke, rør
  10. var hash = document.location.hash.substr (1);
  11. var sprites = hash.split (’,’);
  12. // Definer streng, hvor vi gemmer vores XML ..
  13. var svg = ’’;
  14. // Kør gennem hash og indsaml fra localStorage
  15. for (i = 0; i sprites.length; i ++) {
  16. hvis (sprite = localStorage.getItem (sprites [i])) {
  17. // Sammenkæd vores XML-kilde
  18. svg + = JSON.parse (sprite) .svg;
  19. }
  20. }
  21. / script>
  22. / hoved>
  23. body style = "baggrund: gennemsigtig; margin: 0; polstring: 0; overflow: skjult;">
  24. script type = "text / javascript">
  25. hvis (svg) {
  26. // Skriv SVGWeb’esque-script / objekt-tag
  27. document.write (
  28. ’Sc’ + ’ript type =" image / svg + xml ">’
  29. + ’Svg xmlns =" ​​http://www.w3.org/2000/svg "width =" 200 "height =" 500 "version =" 1.1 "baseProfile =" full "id =" twiDAQ_JIM ">’
  30. + svg
  31. + ’/ Svg>’
  32. + ’/ Scri’ + ’pt>’
  33. );
  34. // Whoop!
  35. }
  36. / script>
  37. / krop>
  38. / html>

En vellykket løsning

Hvis du kun kunne se din egen karakter på twiDAQ, kunne det have været praktisk at blot downloade din karakter i ren SVG. For et enkelt tegn kiggede vi på mellem 400 og 800 KB, og SVG kunne caches. Problemet er virkelig, at hver gang der er en lille variation, skal du foretage den fulde download igen.

Denne løsning giver os mulighed for at vise dig nogens karakter med et downloadkrav, der reducerer dramatisk og hurtigt forsvinder med hvert nyt tegn, du ser. Det giver os mulighed for vilkårligt at tilføje funktioner og stemning til hver karakter med ringe eller ingen yderligere downloadpåvirkning og til sidst fordi det er SVG snarere end et statisk billede; vi kan få ham til at blinke!

Hvis du finder ud af, at du har et projekt, hvor du har at gøre med en masse kompleks grafik, der kan opdeles i mindre sprites, og som er ens, men ikke altid den samme fra side til side, vil denne løsning måske være nyttig for dig.

Jeg må indrømme, på grund af manglen på localStorage er denne løsning ikke praktisk for IE6 og 7. En mulig løsning er at generere billeder på serveren og servere dem til browsere, der mangler localStorage. Dette er noget, vi har valgt ikke at gøre på dette tidspunkt, men det er fuldt ud muligt med værktøjer som ImageMagick.

Ord: Jim Morrison

Jim er grundlægger af twiDAQ og ejer af Deep Blue Sky. Han kan følges på App.net @jimbo eller Twitter @jimbomorrison.

Friske Indlæg
Hvordan man skulpturerer en rig-klar 3D-skabning
Læs Mere

Hvordan man skulpturerer en rig-klar 3D-skabning

Oprettel e af et godt ba i net er vigtigt, hvi du har til hen igt at animere dine karakterer. Tidligere ville dette være gjort omhyggeligt, polygon for polygon, i en 3D-pakke om Maya eller 3d Max...
Batman kæmper Superman i ny filmkonceptkunst
Læs Mere

Batman kæmper Superman i ny filmkonceptkunst

Batman og uperman er to af de me t ikoni ke figurer kabt af nogle af de tør te tegne eriekun tnere nogen inde. Nyheden om efterfølgeren til Man of teel fik fan af tegne eriefilm i en fart, m...
10 tip til design af lokaliserede grænseflader
Læs Mere

10 tip til design af lokaliserede grænseflader

Catering til internationale kunder kan øge antallet af variabler, om en de igner kal overveje betydeligt, når de opretter en brugervenlig græn eflade. Ord og ætninger kan ændr...