Advertisement
  1. Web Design
  2. General

Создание веб-иконки умнее

Scroll to top
Read Time: 11 min

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

Эта статья является первой в серии из трех частей, показаны новые подходы к иконографии знаковых будут доставлять. Если вам нравится, что вы видите в этой статье, пожалуйста, рассмотреть вопрос о поддержке знаменитого на Kickstarter.


Что такое умный значок?

Умный значок разработан таким образом, что элементы внутри него подстраиваться ввода, взаимодействия и связанные с ними данные. Короче говоря, он динамичный. Умные иконки в SVG-основано и управляется с комбинацией JavaScript и CSS.


Почему это актуально

Веб-иконки до этого момента были статические—в первую очередь из-за ограничений в технологии. Различных государств или вариации значок может быть создан просто путем предоставления отдельных файлов каждой перестановки. Например, значок батареи будет в четырех различных версиях: зарядки, полной зарядки, половину заряда и не заряжать. Не совсем оптимальный подход.

Целый ряд новых возможностей теперь возможен с массового применения браузера для SVG 1.1. Из-за семантической структуры СВГ, а умный значок может отображать полный диапазон состояний и вариаций. Это устраняет необходимость замены изображения и позволяет переходы между состояниями происходят плавно.

Умные иконки также дают дизайнерам возможность отображать соответствующую контекстную информацию в икону. Хорошо разработанный значок уже относительно пиков плотный объект. Добавление контекстной информации к иконе, его информационную плотность еще больше, если бы не значительное увеличение когнитивной нагрузки. В теории, эти типы икон будет способен взять на себя тяжелую коммуникации, таким образом, уменьшая количество другие элементы на экране.


Примеры использования для смарт-иконы

Существует множество различных направлений умные иконки могут пойти—некоторые из них проще в реализации, чем другие. Мы все еще в процессе поиска, но пока мы придумали три основных варианта использования:

Предоставление контекстной информации

Есть много икон, которые могли бы обеспечить другой слой информации, но просто не до этого момента, из-за их статического метода отображения. Примеры включают значки, такие как часы, термометр, диафрагма, WiFi сигнала и заряда батареи.

clockclockclock

Действуя как простые данные-ВИС элементов (при d3.js это слишком много)

Один из лучших использования-чехлы для смарт-значки прост визуализации данных. Иконки, которые вписываются в эту категорию, звукового спектра, датчик/метр и индикатор загрузки. Умные иконки могут значительно упростить процесс создания панели отображает—думаю, просто добавив четыре или пять иконок в HTML и регулировки значения датчика с атрибутом данных.

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

Отображение различных государств

Много икон, часто попадают в серию вариаций, чтобы передать все их разных государств. Примеры включают батареи, беспроводной доступ в интернет, воспроизведения медиа-файлов (например, воспроизведение, пауза и т. д.) и мощности (например, включение, выключение, режим ожидания). Еще одна возможность применения смарт-иконки свернуть все государства-икона в единую СВГ. Поэтому вместо замены активов изображение, когда предмет государственного меняется, вы просто изменить атрибут данных в соответствующее состояние.

batterybatterybattery

Гайки и болты

Примечание: перед вдаваясь в подробности, важно отметить, что в примерах мы просто доказательство концепции прототипов. Эти прототипы предназначены для передачи функциональности, которую мы будем создавать. Ни один из следующий код является окончательной, не говоря уже бета. Мы все еще в стадии разработки этого метода и мы знаем, что есть много вопросов, которые еще предстоит решить. Мы будем работать над более конкретное направление на этот метод после того, как кампания на Kickstarter завершится.

Умные иконки состоят из формата SVG, JavaScript и CSS. Наше нынешнее мышление к каждому значок как небольшие автономные приложения с помощью простого API для настройки элементов внутри значка. Для достижения такой надежной, такой подход требует разметки SVG, которые должны быть включены в дом.

Имейте в виду, что СВГ размечаем должен быть соответствующим образом структурирован для такого подхода к работе. Это то, что мы чувствуем, делает знаковые уникальные. Значки были спроектированы и изготовлены новые концепции в уме. Эти концепции опираются на четкую семантику и хорошо продуманная структура разметки для правильной работы. Это ничем не отличается от правильно структурированный HTML—если ваша разметка gobbleygoop, это будет сложно сделать, ничего сложного.

Много убедительных вещи могут случиться один раз хорошо структурированной разметки SVG в дом. Проблема в том, что при добавлении разметки SVG в HTML-это боль. Разметки SVG может добавить значительное количество наворотов в ваш код, и это становится труднее различать между структурными HTML и векторных изображений. Для того, чтобы убрать это трение, мы предлагаем инъекционных разметки SVG в DOM во время выполнения.

Мы сделали простой прототип инжектора СВГ, который заменяет все указанные теги img с разметки из ссылочного файла SVG. Так это...

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

Превращается в это:

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

Примечание: имейте в виду, это форсунки подход, безусловно, чувствует, как временная мера и мы надеемся, что наша работа поможет подтолкнуть браузер-родной стандарт. До тех пор, наше нынешнее мышление заключается в том, что это лучший подход.

После того, как СВГ вводят в DOM, JavaScript-код инкапсулирован в ее выполнении и готов к использованию. Некоторые иконки будут работать самостоятельно (как часы), тогда как другие требуют ввода для регулировки.

Значок работающей в автоматическом режиме

Часы-это прекрасный пример значок, который работает на своей собственной. После инъекции, он будет просто идти. Увидеть его в действии

HTML-код

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

Яш

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

СВГ: часы.СВГ

1
<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">
2
    <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" />
3
    <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"/>
4
    <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"/>
5
    <circle class="iconic-clock-axis" cx="192" cy="192" r="9"/>
6
    <g class="iconic-clock-second-hand" id="iconic-anim-clock-second-hand">
7
        <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"/>
8
        <circle class="iconic-clock-second-hand-axis" fill="#D53A1F" cx="192" cy="192" r="4.5"/>
9
    </g>
10
    <defs>
11
        <animateTransform
12
            type="rotate"
13
            fill="remove"
14
            restart="always"
15
            calcMode="linear"
16
            accumulate="none"
17
            additive="sum"
18
            xlink:href="#iconic-anim-clock-hour-hand"
19
            repeatCount="indefinite"
20
            dur="43200s"
21
            to="360 192 192"
22
            from="0 192 192"
23
            attributeName="transform"
24
            attributeType="xml">
25
        </animateTransform>
26
27
        <animateTransform
28
            type="rotate"
29
            fill="remove"
30
            restart="always"
31
            calcMode="linear"
32
            accumulate="none"
33
            additive="sum"
34
            xlink:href="#iconic-anim-clock-minute-hand"
35
            repeatCount="indefinite"
36
            dur="3600s"
37
            to="360 192 192"
38
            from="0 192 192"
39
            attributeName="transform"
40
            attributeType="xml">
41
        </animateTransform>
42
43
        <animateTransform
44
            type="rotate"
45
            fill="remove"
46
            restart="always"
47
            calcMode="linear"
48
            accumulate="none"
49
            additive="sum"
50
            xlink:href="#iconic-anim-clock-second-hand"
51
            repeatCount="indefinite"
52
            dur="60s"
53
            to="360 192 192"
54
            from="0 192 192"
55
            attributeName="transform"
56
            attributeType="xml">
57
        </animateTransform>
58
    </defs>
59
    <script  type="text/javascript">
60
    <![CDATA[

61
        var date = new Date;

62
        var seconds = date.getSeconds();

63
        var minutes = date.getMinutes();

64
        var hours = date.getHours();

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

Значок ввода на основе

Когда значок откликается на ввод данных, она требует немного больше работы, но основы остаются неизменными. Увидеть его в действии

HTML-код

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

Яш

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

СВГ: аудио спектр-анализатор.СВГ

1
<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()">  
2
  <g id="eq-bars" height="320px" width="210px" fill="#010101" transform="">
3
    <rect x="00" y="150" height="20" width="10" />
4
    <rect x="20" y="140" height="40" width="10"  />
5
    <rect x="40" y="100" height="120" width="10"  />
6
    <rect x="60" y="120" height="80" width="10"  />
7
    <rect x="80" y="60" height="200" width="10"  />
8
    <rect x="100" y="20" height="280" width="10"  />
9
    <rect x="120" y="70" height="180" width="10"  />
10
    <rect x="140" y="120" height="80" width="10"  />
11
    <rect x="160" y="140" height="40" width="10"  />
12
    <rect x="180" y="150" height="20" width="10"  />
13
    <rect x="200" y="155" height="10" width="10"  />
14
  </g>
15
16
  <defs>
17
    <style type="text/css"><![CDATA[

18
      svg#audio-spectrum-analyzer {

19
        margin: 0 auto;

20
      }

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

25
    var context;

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

27
      context = new AudioContext();

28
    }

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

30
      context = new webkitAudioContext();

31
    }

32
    else {

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

34
    }

35


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

Добавление движения (вишенка на торте)

Умный значок становится еще лучше с движением. Есть много способов сделать это. В настоящее время мы используем элементы анимации SVG, так как это позволяет значительно функциональность встроена прямо в браузере—меньше кода в SVG. Поддержка еще не восстановилось (мы столкнулись с вопросами в Safari 6), но он становится лучше день ото дня. Увидеть его в действии

HTML-код

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

Яш

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

СВГ: термометр.СВГ

1
<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"
2
 height="128px" viewBox="0 0 40 128" enable-background="new 0 0 40 128" xml:space="preserve">
3
    <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

4
            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

5
            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

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

25


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

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

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

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

30
        var yPos = yOrigin2;

31
        var tempClass;

32


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

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

35
        goto(hash);

36
        }, false);

37


38
        function goto(amount) {

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

40


41
                shaft.setAttribute('y2', yPos)

42


43
        amount = parseFloat(amount)

44
        if( isNaN( amount ) ) return;

45


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

Заключение

Иконография имеет важную роль в дизайн интерфейса. Более актуальную информацию на наших иконах, тем более могущественными они становятся. Мы искренне верим, что умная иконография может быть незаменимым инструментом для дизайнеров, чтобы добавить еще один слой смысла в их иконах. Не каждая икона подходит для такого подхода—как и все хорошие вещи, он требует умеренности. Однако, когда используется должным образом, это может быть огромный новый инструмент.


Обратно знаковых на Kickstarter

Цель знаковых для обеспечения новых подходов к иконографии. Есть много более известных, чем просто умные иконки и мы рады поделиться еще одной интересной особенностью с вами на следующей неделе.

iconic-logoiconic-logoiconic-logo

Пожалуйста, рассмотреть вопрос о поддержке знаменитого на 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.