Advertisement
  1. Web Design
  2. General

Web-Icons intelligenter machen 

Scroll to top
Read Time: 12 min

() translation by (you can also view the original English article)

Dieser Artikel ist der erste in einer dreiteiligen Serie zeigt die neuen Ansätze zur Ikonographie Legendären liefern wird. Wenn Sie mögen, was Sie sehen in diesem Artikel, bitte prüfen Legendären backing auf Kickstarter. 


Was Genau ist ein Smart-Icon? 

 Ein smart-icon ist so gestaltet, dass die Elemente, um Sie auf input, Interaktion oder die zugehörigen Daten. Kurz gesagt, es ist dynamisch. Smart icons sind SVG-basiert und kontrolliert mit einer Kombination von Javascript und CSS.


Warum Dies Relevant ist 

Web-Ikonen bis zu diesem Punkt waren statisch—in Erster Linie aufgrund von Einschränkungen in der Technologie. In anderen Staaten oder Variationen ein Symbol geschaffen würden einfach durch die einzelnen Dateien der einzelnen permutation.  Zum Beispiel, ein Akku-Symbol kommen würde, in vier verschiedenen Versionen: Aufladung, volle Ladung, halbe Ladung und ohne Ladung. Nicht gerade die optimale Vorgehensweise. 

Eine ganze Reihe neuer Möglichkeiten sind jetzt lebensfähig mit mainstream-browser die Annahme von SVG 1.1. Wegen SVG-semantischen Struktur, ein smart-icon anzeigen zu können, seine volle Reihe von Zuständen und Variationen.   Dadurch entfällt die Notwendigkeit für image-swapping und ermöglicht übergänge zwischen Zuständen auftreten, flüssig.

Smart icons auch Entwicklern die option zur Anzeige der relevanten kontextuellen Informationen in einem Symbol. Eine gut gestaltete Symbol ist schon ein relativ informationell dichtes Objekt.   Durch hinzufügen von Kontextinformationen in ein Symbol, Informations-Dichte ist noch größer, ohne erheblich erhöhte kognitive Belastung. In der Theorie sind diese Arten von icons werden in der Lage sein, die schwere Hebe-Kommunikation, wodurch die Menge an anderen Elementen auf dem Bildschirm. 


Use-cases für Smart Icons 

Es gibt viele verschiedene Richtungen smart icons gehen können—einige sind leichter umzusetzen als andere. Wir sind immer noch in der discovery-Prozess, aber so weit wir kommen mit drei primären use-cases: 

Bereitstellung von Kontext-Informationen 

 Es gibt viele Symbole, die könnte eine weitere Schicht von Informationen, aber einfach nicht bis zu diesem Punkt, die aufgrund Ihrer statischen Methode display. Beispiele sind die Symbole wie die Uhr, thermometer, Blende, WIFI-signal-und Akku-Ladung.

clockclockclock

 Handeln als einfache Daten-vis-Elemente (wenn d3.js ist zu viel)

 Eine der besten Anwendungsfälle für smart icons ist eine einfache Daten-Visualisierung. Symbole, die passen in diese Kategorie sind das audio-Spektrum, Messgerät/meter und Ladeanzeige.  Smart Symbole könnten erheblich vereinfachen den Prozess der Erstellung von dashboard—denke einfach das hinzufügen von vier oder fünf Symbole, um Ihre HTML-und Anpassung der gauge-Wert mit einem data-Attribut.

audio-spectrum-analyzeraudio-spectrum-analyzeraudio-spectrum-analyzer

Anzeige verschiedener Staaten 

 Viele Symbole kommen Häufig in einer Reihe von Variationen zu vermitteln, in all Ihren verschiedenen Zuständen. Beispiele sind der Akku, die WIFI, die Wiedergabe von Medien (z.B. play, pause, etc.) und Kraft (z.B. in, an, aus, standby).  Eine weitere mögliche Anwendung für smart icons zu Rollen alle ein Symbol-Staaten in einem einzigen SVG. Anstatt also den Austausch von Bild-assets wenn Sie ein Thema Zustand ändert, Sie ändern Sie einfach ein data-Attribut auf den entsprechenden Status.  

batterybatterybattery

Muttern und Schrauben 

Hinweis: Bevor ich in die details, es ist wichtig zu beachten, dass die Beispiele, die wir zeigen sind einfach nur proof-of-concept Prototypen.  Diese Prototypen sollen zu kommunizieren, um die Funktionalität werden wir bauen. Keine der folgenden code-Finale, geschweige denn beta.  Wir sind immer noch in der R&D phase dieser Methode, und wir wissen, es gibt viele Probleme, die noch angegangen werden müssen. Wir arbeiten auf eine konkrete Richtung für diese Methode auf, nachdem die Kickstarter-Kampagne abgeschlossen ist. 

 Smart icons bestehen von SVG, Javascript und CSS-Dateien. Unsere aktuelle denken ist zur Behandlung jedes Symbol wie eine kleine autarke app mit einem einfachen API anpassen Elemente innerhalb des symbols.  Um dies zu erreichen, zuverlässig, erfordert dieser Ansatz die SVG-markup enthalten sein, die in der DOM.

 Beachten Sie, dass die SVG-mark-up braucht, um angemessen strukturiert für diesen Ansatz zu arbeiten. Dies ist, was wir empfinden, macht Ikonischen einzigartig. Die icons sind entworfen und in Handarbeit mit neuen Konzepten in den Sinn.  Diese Konzepte setzen auf klare Semantik und ein durchdachtes markup-Struktur, um korrekt zu arbeiten. Dies ist nicht anders als entsprechend strukturierte HTML—, wenn Ihr markup ist gobbleygoop, es wird schwierig sein, etwas zu tun anspruchsvoll.

 Viele fesselnde Dinge können passieren, wenn gut strukturierte SVG-markup wird in der DOM. Das problem ist, dass das hinzufügen von SVG-markup in HTML ist ein Schmerz.  Die SVG-markup können eine beträchtliche Menge von aufblasen, um Ihren code und es wird schwieriger zu unterscheiden zwischen strukturellen HTML-und Vektor-Bilder. Um zu entfernen, diese Reibung, empfehlen wir die Injektion SVG-markup in den DOM zur Laufzeit.

 Wir haben einen einfachen Prototyp SVG-Injektor ersetzt alle angegebenen img-tags das markup aus der referenzierten SVG-Datei. Also diese...

1
2
<div class="image-container">
3
    <img src="images/circle.svg" class="svg-inject" width="300" />
4
</div>

Verwandelt sich in diese: 

1
2
<div class="image-container">
3
    <svg version="1.1" xmlns="https://www.w3.org/2000/svg" x="0px" y="0px" width="100px" height="100px">
4
        <circle cx="50" cy="50" r="50"/>
5
    </svg>
6
</div>

 Hinweis: bitte beachten Sie, dieser Injektor Ansatz sicherlich fühlt sich an wie eine Notlösung und wir hoffen, dass unsere Arbeit helfen wird, schieben Sie einen browser-basierten standard. Bis dann, unsere aktuelle denken ist, dass dies der beste Ansatz.

 Nachdem die SVG injiziert, die in den DOM, JavaScript gekapselt ausgeführt und es ist bereit, verwendet werden. Einige Symbole werden auf Ihre eigenen laufen (wie eine Uhr), während anderen müssen die Eingaben anpassen.

 Self-running Symbol

Die Uhr ist ein perfektes Beispiel für ein Symbol, das läuft auf seine eigenen. Einmal injiziert, wird es nur gehen. Sehen Sie es in Aktion  

HTML 

1
2
<img src="clock.svg" class="svg-inject" alt="clock" />

JS 

1
2
$('.svg-inject').svgInject();

SVG: Uhr.svg 

1
2
<svg version="1.1" class="iconic-clock" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="384px" height="384px" viewBox="0 0 384 384" enable-background="new 0 0 384 384" xml:space="preserve">
3
    <path class="iconic-clock-frame"        d="M192,0C85.961,0,0,85.961,0,192s85.961,192,192,192s192-85.961,192-192S298.039,0,192,0zM315.037,315.037c-9.454,9.454-19.809,17.679-30.864,24.609l-14.976-25.939l-10.396,6l14.989,25.964c-23.156,12.363-48.947,19.312-75.792,20.216V336h-12v29.887c-26.845-0.903-52.636-7.854-75.793-20.217l14.989-25.963l-10.393-6l-14.976,25.938c-11.055-6.931-21.41-15.154-30.864-24.608s-17.679-19.809-24.61-30.864l25.939-14.976l-6-10.396l-25.961,14.99C25.966,250.637,19.017,224.846,18.113,198H48v-12H18.113c0.904-26.844,7.853-52.634,20.216-75.791l25.96,14.988l6.004-10.395L44.354,99.827c6.931-11.055,15.156-21.41,24.61-30.864s19.809-17.679,30.864-24.61l14.976,25.939l10.395-6L110.208,38.33C133.365,25.966,159.155,19.017,186,18.113V48h12V18.113c26.846,0.904,52.635,7.853,75.792,20.216l-14.991,25.965l10.395,6l14.978-25.942c11.056,6.931,21.41,15.156,30.865,24.611c9.454,9.454,17.679,19.808,24.608,30.863l-25.94,14.976l6,10.396l25.965-14.99c12.363,23.157,19.312,48.948,20.218,75.792H336v12h29.887c-0.904,26.845-7.853,52.636-20.216,75.792l-25.964-14.989l-6.002,10.396l25.941,14.978C332.715,295.229,324.491,305.583,315.037,315.037z" />
4
    <line class="iconic-clock-hour-hand" id="foo" fill="none" stroke="#000000" stroke-width="18" stroke-miterlimit="10" x1="192" y1="192" x2="192" y2="87.5"/>
5
    <line class="iconic-clock-minute-hand" id="iconic-anim-clock-minute-hand" fill="none" stroke="#000000" stroke-width="12" stroke-miterlimit="10" x1="192" y1="192" x2="192" y2="54"/>
6
    <circle class="iconic-clock-axis" cx="192" cy="192" r="9"/>
7
    <g class="iconic-clock-second-hand" id="iconic-anim-clock-second-hand">
8
        <line class="iconic-clock-second-hand-arm" fill="none" stroke="#D53A1F" stroke-width="4" stroke-miterlimit="10" x1="192" y1="192" x2="192" y2="28.5"/>
9
        <circle class="iconic-clock-second-hand-axis" fill="#D53A1F" cx="192" cy="192" r="4.5"/>
10
    </g>
11
    <defs>
12
        <animateTransform
13
            type="rotate"
14
            fill="remove"
15
            restart="always"
16
            calcMode="linear"
17
            accumulate="none"
18
            additive="sum"
19
            xlink:href="#iconic-anim-clock-hour-hand"
20
            repeatCount="indefinite"
21
            dur="43200s"
22
            to="360 192 192"
23
            from="0 192 192"
24
            attributeName="transform"
25
            attributeType="xml">
26
        </animateTransform>
27
28
        <animateTransform
29
            type="rotate"
30
            fill="remove"
31
            restart="always"
32
            calcMode="linear"
33
            accumulate="none"
34
            additive="sum"
35
            xlink:href="#iconic-anim-clock-minute-hand"
36
            repeatCount="indefinite"
37
            dur="3600s"
38
            to="360 192 192"
39
            from="0 192 192"
40
            attributeName="transform"
41
            attributeType="xml">
42
        </animateTransform>
43
44
        <animateTransform
45
            type="rotate"
46
            fill="remove"
47
            restart="always"
48
            calcMode="linear"
49
            accumulate="none"
50
            additive="sum"
51
            xlink:href="#iconic-anim-clock-second-hand"
52
            repeatCount="indefinite"
53
            dur="60s"
54
            to="360 192 192"
55
            from="0 192 192"
56
            attributeName="transform"
57
            attributeType="xml">
58
        </animateTransform>
59
    </defs>
60
    <script  type="text/javascript">
61
    <![CDATA[

62
        var date = new Date;

63
        var seconds = date.getSeconds();

64
        var minutes = date.getMinutes();

65
        var hours = date.getHours();

66
        hours = (hours > 12) ? hours - 12 : hours;
67
68
        minutes = (minutes * 60) + seconds;
69
        hours = (hours * 3600) + minutes;
70
71
        document.querySelector('.iconic-clock-second-hand').setAttribute('transform', 'rotate('+360*(seconds/60)+',192,192)');
72
        document.querySelector('.iconic-clock-minute-hand').setAttribute('transform', 'rotate('+360*(minutes/3600)+',192,192)');
73
        document.querySelector('.iconic-clock-hour-hand').setAttribute('transform', 'rotate('+360*(hours/43200)+',192,192)');
74
    ]]>
75
    </script>
76
</svg>

Input-basierte Symbol 

Wenn ein icon reagiert auf Eingaben oder Daten, Bedarf es ein wenig mehr Arbeit, aber die Grundlagen sind unverändert. Sehen Sie es in Aktion 

HTML 

1
2
<img src="audio-spectrum-analyzer.svg" class="svg-inject" alt="audio spectrum analyzer" />

JS 

1
2
$('.svg-inject').svgInject();

SVG: audio-Spektrum-analyzer.svg 

1
2
<svg id="audio-spectrum-analyzer" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" height="320px" width="210px" version="1.1" y="0px" x="0px" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 210 320" onclick="toggleAudio()">  
3
  <g id="eq-bars" height="320px" width="210px" fill="#010101" transform="">
4
    <rect x="00" y="150" height="20" width="10" />
5
    <rect x="20" y="140" height="40" width="10"  />
6
    <rect x="40" y="100" height="120" width="10"  />
7
    <rect x="60" y="120" height="80" width="10"  />
8
    <rect x="80" y="60" height="200" width="10"  />
9
    <rect x="100" y="20" height="280" width="10"  />
10
    <rect x="120" y="70" height="180" width="10"  />
11
    <rect x="140" y="120" height="80" width="10"  />
12
    <rect x="160" y="140" height="40" width="10"  />
13
    <rect x="180" y="150" height="20" width="10"  />
14
    <rect x="200" y="155" height="10" width="10"  />
15
  </g>
16
17
  <defs>
18
    <style type="text/css"><![CDATA[

19
      svg#audio-spectrum-analyzer {

20
        margin: 0 auto;

21
      }

22
    ]]></style>
23
  </defs>
24
25
  <script type="application/javascript"><![CDATA[

26
    var context;

27
    if (typeof AudioContext !== "undefined") {

28
      context = new AudioContext();

29
    }

30
    else if (typeof webkitAudioContext !== "undefined") {

31
      context = new webkitAudioContext();

32
    }

33
    else {

34
      throw new Error('AudioContext not supported. :(');

35
    }

36


37
    var eqHeight = document.querySelector('svg#audio-spectrum-analyzer > g#eq-bars').getAttribute('height').replace('px', '');
38
    var bars = document.querySelectorAll('svg#audio-spectrum-analyzer rect');
39
40
    var playing = false;
41
42
    var audioFileUrl = document.querySelector('svg#audio-spectrum-analyzer').getAttribute('data-audiofile');
43
    if (audioFileUrl === undefined) {
44
      throw new Error('Audio File not defined');
45
    }
46
47
    var soundSource;
48
    var fft;
49
    var fftSmoothing = 0.6;
50
    var fftMaxValue = 256;
51
    var samples = 128;
52
    var sampleIntervalID;
53
    var ampFactor = 1.25;
54
    var numBars = bars.length;
55
    var soundBuffer;
56
57
58
    var request = new XMLHttpRequest();
59
    request.open("GET", audioFileUrl, true);
60
    request.responseType = "arraybuffer";
61
62
    // Our asynchronous callback
63
    request.onload = function () {
64
      var audioData = request.response;
65
66
      // The Audio Context handles creating source
67
      // buffers from raw binary data
68
      soundBuffer = context.createBuffer(audioData, true /*make mono*/ );
69
70
    };
71
    request.send();
72
73
    function sampleAudio() {
74
      var data = new Uint8Array(fft.frequencyBinCount);
75
      fft.getByteFrequencyData(data);
76
77
      // Calc bin size to sum freqs into.
78
      // Carve off some of the high-end, lower energy bars (+2)
79
      var bin_size = Math.floor(data.length / (numBars + 2));
80
81
      // Sum up and average the samples into their bins
82
      for (var i = 0; i < numBars; ++i) {
83
84
        // Sum this bin
85
        var sum = 0;
86
        for (var j = 0; j < bin_size; ++j) {
87
          sum += data[(i * bin_size) + j];
88
        }
89
90
        // Duck some of the low-end power
91
        if (i === 0) {
92
          sum = sum * 0.75;
93
        }
94
95
        // Calculate the average frequency of the samples in the bin
96
        var average = sum / bin_size;
97
        var scaled_average = Math.max(10, ((average / fftMaxValue) * eqHeight) * ampFactor);
98
99
        // Update eq bar height
100
        bars[i].setAttribute('height', scaled_average);
101
102
        // Center bar
103
        bars[i].setAttribute('y', (eqHeight - scaled_average) / 2);
104
      }
105
    }
106
107
    function playSound() {
108
      // create a sound source
109
      soundSource = context.createBufferSource();
110
111
      // Add the buffered data to our object
112
      soundSource.buffer = soundBuffer;
113
114
      // Create the FFT
115
      fft = context.createAnalyser();
116
      fft.smoothingTimeConstant = fftSmoothing;
117
      fft.fftSize = samples;
118
119
      soundSource.connect(fft);
120
      fft.connect(context.destination);
121
122
      soundSource.noteOn(context.currentTime);
123
124
      // Start the FFT sampler
125
      sampleIntervalID = setInterval(sampleAudio, 30);
126
127
      playing = true;
128
    }
129
130
    function stopSound() {
131
      // Stop the FFT sampler
132
      clearInterval(sampleIntervalID);
133
134
      if (soundSource) {
135
        soundSource.noteOff(context.currentTime);
136
      }
137
      playing = false;
138
    }
139
140
    var toggleAudio = function () {
141
      if (!playing) {
142
        playing = true;
143
        playSound();
144
      }
145
      else {
146
        stopSound();
147
        playing = false;
148
      }
149
    }
150
151
    window.addEventListener('load', function () {
152
      window.toggleAudio = toggleAudio;
153
    }, false);
154
155
  ]]></script>
156
157
</svg>

Hinzufügen von Bewegung (das Sahnehäubchen) 

Ein smart-icon wird noch besser mit Bewegung. Es gibt viele Möglichkeiten, dies zu tun. Wir sind derzeit mit SVG-animationselemente, wie dies ermöglicht eine erhebliche Funktionalität direkt in den browser—also weniger code im SVG.  Ist zwar noch ein wenig wackelig (wir lief in Probleme in Safari 6), aber es wird immer besser von Tag zu Tag. Sehen Sie es in Aktion 

HTML 

1
2
<img src="thermometer.svg" class="svg-inject" alt="thermometer" />
3
<ul class="menu">
4
  <li><a href="#1">Hot</a></li>
5
  <li><a href="#0.66">Warm</a></li>
6
  <li><a href="#0.33">Chilly</a></li>
7
  <li><a href="#0">Cold</a></li>
8
</ul>

JS 

1
2
$('.svg-inject').svgInject();

SVG: themometer.svg 

1
2
<svg version="1.0" class="iconic-thermometer"  xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="40px"
3
 height="128px" viewBox="0 0 40 128" enable-background="new 0 0 40 128" xml:space="preserve">
4
    <path class="iconic-thermometer-container" d="M20,6c2.757,0,5,2.243,5,5v80.305v3.234l2.701,1.777C31.646,98.912,34,103.279,34,108c0,7.72-6.28,14-14,14

5
            s-14-6.28-14-14c0-4.721,2.354-9.088,6.298-11.684L15,94.539v-3.234V11C15,8.243,17.243,6,20,6 M20,0C13.935,0,9,4.935,9,11

6
            v80.305c-5.501,3.62-9,9.829-9,16.695c0,11.028,8.972,20,20,20c11.028,0,20-8.972,20-20c0-6.865-3.499-13.075-9-16.695V11

7
            C31,4.935,26.065,0,20,0L20,0z"/>
8
    <line class="iconic-thermometer-shaft iconic-thermometer-hot" id="iconic-anim-thermometer-shaft" fill="none" stroke="#000000" stroke-width="6" stroke-linecap="round" stroke-miterlimit="10" x1="20" y1="108" x2="20" y2="11" />
9
    <circle class="iconic-thermometer-well iconic-thermometer-hot" cx="20" cy="108" r="12" />
10
11
    <animate
12
        id="shaft-animate"
13
        attributeName= "y2"
14
        begin= "indefinite"
15
        dur="1s"
16
        xlink:href="#iconic-anim-thermometer-shaft"
17
        fill="freeze"
18
        calcMode="spline"
19
        keySplines="0.42 0 0.58 1"
20
        keyTimes="0;1"
21
        restart="whenNotActive"
22
    />
23
24
    <script type="text/ecmascript">
25
    <![CDATA[

26


27
        var shaft = document.querySelector('#iconic-anim-thermometer-shaft');

28
        var well = document.querySelector('.iconic-thermometer-well');

29
        var yOrigin2 = parseFloat(shaft.getAttribute('y2'));

30
        var yOrigin1 = parseFloat(shaft.getAttribute('y1'));

31
        var yPos = yOrigin2;

32
        var tempClass;

33


34
        window.addEventListener('hashchange', function() {

35
        var hash = window.location.hash.substr(1);

36
        goto(hash);

37
        }, false);

38


39
        function goto(amount) {

40
            var shaftAnim = document.querySelector('#shaft-animate');

41


42
                shaft.setAttribute('y2', yPos)

43


44
        amount = parseFloat(amount)

45
        if( isNaN( amount ) ) return;

46


47
                if(amount>.9) {
48
                    tempClass="iconic-thermometer-hot";
49
                } else if(amount>.5) {
50
                    tempClass="iconic-thermometer-warm";
51
                } else if(amount>.2) {
52
                    tempClass="iconic-thermometer-chilly";
53
                } else {
54
                    tempClass="iconic-thermometer-cold";
55
                }
56
57
        amount = 1 - amount;
58
        amount = Math.min(Math.max(0, amount), 1);
59
60
        var ry = ( amount * ( yOrigin1-yOrigin2 ) ) + yOrigin2;
61
62
                /*
63
                 * Unfortunately, Safari doesn't make life easy on us. We need to remove and re-initialize
64
                 * the animation element for animations to start from the last end point.
65
                 */
66
        var ns =  shaftAnim.cloneNode(true);
67
        ns.setAttribute( 'from', yPos )
68
        ns.setAttribute( 'to', ry );
69
70
        shaftAnim.parentNode.replaceChild(ns, shaftAnim);
71
72
                well.setAttribute('class', 'iconic-thermometer-well ' + tempClass);
73
                shaft.setAttribute('class', 'iconic-thermometer-shaft ' + tempClass);
74
        ns.beginElement();
75
        yPos = ry;
76
77
        }
78
    ]]>
79
    </script>
80
</svg>

Fazit

Ikonographie eine wichtige Rolle zu spielen in interface-design. Die mehr relevanten Informationen, die unsere Symbole bieten kann, desto mächtiger werden Sie.   Wir glauben wirklich, dass smart-Ikonographie werden können, ein überzeugendes Werkzeug für Designer, fügen Sie eine weitere Schicht von Bedeutung, Ihre Symbole.  Nicht jedes Symbol ist geeignet für diesen Ansatz—wie alle guten Dinge, die es erfordert moderation. Allerdings, wenn richtig eingesetzt, kann es eine enorme neue tool.


Zurück Ikonischen auf Kickstarter 

 Das Ziel der Ikone ist zu helfen, neue Ansätze zur Ikonographie. Es gibt eine Menge mehr Kult als nur smart-icons, und wir freuen uns auf die Freigabe ein weiteres Interessantes feature, mit dem Sie nächste Woche.

iconic-logoiconic-logoiconic-logo

 Bitte beachten Legendären backing auf Kickstarter.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.