Створення піктограм веб-смартфонів
Ukrainian (українська мова) translation by Tanya Ira (you can also view the original English article)
Ця стаття є першою в серії з трьох частин, показано нові підходи до іконографії знакових будуть доставляти. Якщо вам подобається, що ви бачите в цій статті, будь ласка, розглянути питання про підтримку знаменитого на Kickstarter.
Цей контент був замовлений знакових і написав і/або відредагував команда туц+. Наша мета з авторами контенту, щоб публікувати актуальні та об'єктивні підручники, кейс-стаді, і надихаючі інтерв'ю, що пропозиція справжнє виховне значення для наших читачів і дозволить фінансувати створення більш корисного контенту.
Що таке розумний значок?
Розумний значок розроблений таким чином, що елементи всередині нього підлаштовуватися введення, взаємодії та пов'язані з ними дані. Коротше кажучи, він динамічний. Розумні іконки в SVG-засновано і управляється з комбінацією JavaScript і CSS.
Чому це актуально
Веб-іконки до цього моменту були статичні—в першу чергу з-за обмежень у технології. Різних держав або варіації значок може бути створений просто шляхом надання окремих файлів кожної перестановки. Наприклад, значок батареї буде в чотирьох різних версіях: зарядки, повної зарядки, половину заряду і не заряджати. Не зовсім оптимальний підхід.
Цілий ряд нових можливостей тепер можливий з масового застосування браузера для SVG 1.1. З-за семантичної структури СВГ, а розумний значок може відображати повний діапазон станів і варіацій. Це усуває необхідність заміни зображення і дозволяє переходи між станами відбуваються плавно.
Розумні іконки також дають дизайнерам можливість відображати відповідну контекстну інформацію в ікону. Добре розроблений значок вже відносно піків щільний об'єкт. Додавання контекстної інформації до ікони, його інформаційну щільність ще більше, якби не значне збільшення когнітивної навантаження. В теорії ці типи ікон буде здатний взяти на себе важку комунікації, таким чином, зменшуючи кількість інших елементів на екрані.
Приклади використання смарт-ікони
Існує безліч різних напрямків розумні іконки можуть піти—деякі з них простіший в реалізації, ніж інші. Ми все ще в процесі пошуку, але поки ми придумали три основних варіанти використання:
Надання контекстної інформації
Є багато ікон, які могли б забезпечити інший шар інформації, але просто не до цього моменту, з-за їх статичного методу відображення. Приклади включають значки, такі як годинник, термометр, діафрагма, WiFi сигналу і заряду батареї.



Діючи як прості дані-ВІС елементів (при d3.js це занадто багато)
Один з кращих використання-чохли для смарт-значки простий візуалізації даних. Іконки, які вписуються в цю категорію, звукового спектру, датчик/метр і індикатор завантаження. Розумні іконки можуть значно спростити процес створення панелі відображає думаю, просто додавши чотири або п'ять іконок в HTML і регулювання значення датчика з атрибутом даних.



Відображення різних держав
Багато ікон, часто потрапляють в серію варіацій, щоб передати всі їх різних держав. Приклади включають батареї, бездротовий доступ в інтернет, відтворення медіа-файлів (наприклад, відтворення, пауза і т. д.) і потужності (наприклад, включення, вимикання, режим очікування). Ще одна можливість застосування смарт-іконки згорнути всі держави-ікона в єдину СВГ. Тому замість заміни активів зображення, коли предмет державного змінюється, ви просто змінити атрибут даних у відповідний стан.



Гайки і болти
Примітка: перед вдаючись в подробиці, важливо відзначити, що в прикладах ми просто доказ концепції прототипів. Ці прототипи призначені для передачі функціональності, яку ми будемо створювати. Жоден з наступний код є остаточною, не кажучи вже бета. Ми все ще в стадії розробки цього методу і ми знаємо, що є багато питань, які ще належить вирішити. Ми будемо працювати над більш конкретне спрямування на цей метод після того, як кампанія на Kickstarter завершиться.
Розумні іконки складаються з формату SVG, JavaScript і CSS. Наше нинішнє мислення до кожного значок як невеликі автономні програми з допомогою простого API для налаштування елементів всередині піктограми. Для досягнення такої надійної, такий підхід вимагає розмітки SVG, які повинні бути включені в будинок.
Майте на увазі, що СВГ розмічаємо повинен бути відповідним чином структурований для такого підходу до роботи. Це те, що ми відчуваємо, робить знакові унікальні. Значки були спроектовані і виготовлені нові концепції в розумі. Ці концепції спираються на чітку семантику і добре продумана структура розмітки для правильної роботи. Це нічим не відрізняється від правильно структурований HTML—якщо ваша розмітка gobbleygoop, це буде складно зробити, нічого складного.
Багато переконливих речі можуть статися один раз добре структурованої розмітки SVG у будинок. Проблема в тому, що при додаванні розмітки SVG на HTML-це біль. Розмітки SVG може додати значну кількість наворотів в ваш код, і це стає важче розрізняти між структурними HTML і векторних зображень. Для того, щоб прибрати це тертя, ми пропонуємо ін'єкційних розмітки SVG DOM під час виконання.
Ми зробили простий прототип інжектора СВГ, який замінює всі зазначені теги img з розмітки з посилального файлу SVG. Так це...
<div class="image-container"> <img src="images/circle.svg" class="svg-inject" width="300" /> </div>
Перетворюється на це:
<div class="image-container"> <svg version="1.1" xmlns="https://www.w3.org/2000/svg" x="0px" y="0px" width="100px" height="100px"> <circle cx="50" cy="50" r="50"/> </svg> </div>
Примітка: майте на увазі, це форсунки підхід, безумовно, відчуває, як тимчасова міра і ми сподіваємося, що наша робота допоможе підштовхнути браузер-рідний стандарт. До тих пір, наше нинішнє мислення полягає в тому, що це найкращий підхід.
Після того, як СВГ вводять в DOM, JavaScript-код инкапсулирован в її виконанні і готовий до використання. Деякі іконки будуть працювати самостійно (як годинник), тоді як інші вимагають введення для регулювання.
Значок працює в автоматичному режимі
Годинник-це прекрасний приклад значок, який працює на своїй власній. Після ін'єкції, він буде просто йти. Побачити його у дії
HTML-код
<img src="clock.svg" class="svg-inject" alt="clock" />
Яш
$('.svg-inject').svgInject();
СВГ: годинник.СВГ
<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"> <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" /> <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"/> <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"/> <circle class="iconic-clock-axis" cx="192" cy="192" r="9"/> <g class="iconic-clock-second-hand" id="iconic-anim-clock-second-hand"> <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"/> <circle class="iconic-clock-second-hand-axis" fill="#D53A1F" cx="192" cy="192" r="4.5"/> </g> <defs> <animateTransform type="rotate" fill="remove" restart="always" calcMode="linear" accumulate="none" additive="sum" xlink:href="#iconic-anim-clock-hour-hand" repeatCount="indefinite" dur="43200s" to="360 192 192" from="0 192 192" attributeName="transform" attributeType="xml"> </animateTransform> <animateTransform type="rotate" fill="remove" restart="always" calcMode="linear" accumulate="none" additive="sum" xlink:href="#iconic-anim-clock-minute-hand" repeatCount="indefinite" dur="3600s" to="360 192 192" from="0 192 192" attributeName="transform" attributeType="xml"> </animateTransform> <animateTransform type="rotate" fill="remove" restart="always" calcMode="linear" accumulate="none" additive="sum" xlink:href="#iconic-anim-clock-second-hand" repeatCount="indefinite" dur="60s" to="360 192 192" from="0 192 192" attributeName="transform" attributeType="xml"> </animateTransform> </defs> <script type="text/javascript"> <![CDATA[ var date = new Date; var seconds = date.getSeconds(); var minutes = date.getMinutes(); var hours = date.getHours(); hours = (hours > 12) ? hours - 12 : hours; minutes = (minutes * 60) + seconds; hours = (hours * 3600) + minutes; document.querySelector('.iconic-clock-second-hand').setAttribute('transform', 'rotate('+360*(seconds/60)+',192,192)'); document.querySelector('.iconic-clock-minute-hand').setAttribute('transform', 'rotate('+360*(minutes/3600)+',192,192)'); document.querySelector('.iconic-clock-hour-hand').setAttribute('transform', 'rotate('+360*(hours/43200)+',192,192)'); ]]> </script> </svg>
Значок введення на основі
Коли значок відгукується на введення даних, вона вимагає трохи більше роботи, але основи залишаються незмінними. Побачити його у дії
HTML-код
<img src="audio-spectrum-analyzer.svg" class="svg-inject" alt="audio spectrum analyzer" />
Яш
$('.svg-inject').svgInject();
СВГ: аудіо спектр-аналізатор.СВГ
<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()"> <g id="eq-bars" height="320px" width="210px" fill="#010101" transform=""> <rect x="00" y="150" height="20" width="10" /> <rect x="20" y="140" height="40" width="10" /> <rect x="40" y="100" height="120" width="10" /> <rect x="60" y="120" height="80" width="10" /> <rect x="80" y="60" height="200" width="10" /> <rect x="100" y="20" height="280" width="10" /> <rect x="120" y="70" height="180" width="10" /> <rect x="140" y="120" height="80" width="10" /> <rect x="160" y="140" height="40" width="10" /> <rect x="180" y="150" height="20" width="10" /> <rect x="200" y="155" height="10" width="10" /> </g> <defs> <style type="text/css"><![CDATA[ svg#audio-spectrum-analyzer { margin: 0 auto; } ]]></style> </defs> <script type="application/javascript"><![CDATA[ var context; if (typeof AudioContext !== "undefined") { context = new AudioContext(); } else if (typeof webkitAudioContext !== "undefined") { context = new webkitAudioContext(); } else { throw new Error('AudioContext not supported. :('); } var eqHeight = document.querySelector('svg#audio-spectrum-analyzer > g#eq-bars').getAttribute('height').replace('px', ''); var bars = document.querySelectorAll('svg#audio-spectrum-analyzer rect'); var playing = false; var audioFileUrl = document.querySelector('svg#audio-spectrum-analyzer').getAttribute('data-audiofile'); if (audioFileUrl === undefined) { throw new Error('Audio File not defined'); } var soundSource; var fft; var fftSmoothing = 0.6; var fftMaxValue = 256; var samples = 128; var sampleIntervalID; var ampFactor = 1.25; var numBars = bars.length; var soundBuffer; var request = new XMLHttpRequest(); request.open("GET", audioFileUrl, true); request.responseType = "arraybuffer"; // Our asynchronous callback request.onload = function () { var audioData = request.response; // The Audio Context handles creating source // buffers from raw binary data soundBuffer = context.createBuffer(audioData, true /*make mono*/ ); }; request.send(); function sampleAudio() { var data = new Uint8Array(fft.frequencyBinCount); fft.getByteFrequencyData(data); // Calc bin size to sum freqs into. // Carve off some of the high-end, lower energy bars (+2) var bin_size = Math.floor(data.length / (numBars + 2)); // Sum up and average the samples into their bins for (var i = 0; i < numBars; ++i) { // Sum this bin var sum = 0; for (var j = 0; j < bin_size; ++j) { sum += data[(i * bin_size) + j]; } // Duck some of the low-end power if (i === 0) { sum = sum * 0.75; } // Calculate the average frequency of the samples in the bin var average = sum / bin_size; var scaled_average = Math.max(10, ((average / fftMaxValue) * eqHeight) * ampFactor); // Update eq bar height bars[i].setAttribute('height', scaled_average); // Center bar bars[i].setAttribute('y', (eqHeight - scaled_average) / 2); } } function playSound() { // create a sound source soundSource = context.createBufferSource(); // Add the buffered data to our object soundSource.buffer = soundBuffer; // Create the FFT fft = context.createAnalyser(); fft.smoothingTimeConstant = fftSmoothing; fft.fftSize = samples; soundSource.connect(fft); fft.connect(context.destination); soundSource.noteOn(context.currentTime); // Start the FFT sampler sampleIntervalID = setInterval(sampleAudio, 30); playing = true; } function stopSound() { // Stop the FFT sampler clearInterval(sampleIntervalID); if (soundSource) { soundSource.noteOff(context.currentTime); } playing = false; } var toggleAudio = function () { if (!playing) { playing = true; playSound(); } else { stopSound(); playing = false; } } window.addEventListener('load', function () { window.toggleAudio = toggleAudio; }, false); ]]></script> </svg>
Додавання руху (вишенька на торті)
Розумний значок стає ще краще з рухом. Є багато способів зробити це. В даний час ми використовуємо елементи анімації SVG, так як це дозволяє значно функціональність вбудована прямо в браузері—менше коду в SVG. Підтримка ще не відновилося (ми зіткнулися з питаннями в Safari 6), але він стає краще з кожним днем. Побачити його у дії
HTML-код
<img src="thermometer.svg" class="svg-inject" alt="thermometer" /> <ul class="menu"> <li><a href="#1">Hot</a></li> <li><a href="#0.66">Warm</a></li> <li><a href="#0.33">Chilly</a></li> <li><a href="#0">Cold</a></li> </ul>
Яш
$('.svg-inject').svgInject();
СВГ: термометр.СВГ
<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" height="128px" viewBox="0 0 40 128" enable-background="new 0 0 40 128" xml:space="preserve"> <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 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 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 C31,4.935,26.065,0,20,0L20,0z"/> <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" /> <circle class="iconic-thermometer-well iconic-thermometer-hot" cx="20" cy="108" r="12" /> <animate id="shaft-animate" attributeName= "y2" begin= "indefinite" dur="1s" xlink:href="#iconic-anim-thermometer-shaft" fill="freeze" calcMode="spline" keySplines="0.42 0 0.58 1" keyTimes="0;1" restart="whenNotActive" /> <script type="text/ecmascript"> <![CDATA[ var shaft = document.querySelector('#iconic-anim-thermometer-shaft'); var well = document.querySelector('.iconic-thermometer-well'); var yOrigin2 = parseFloat(shaft.getAttribute('y2')); var yOrigin1 = parseFloat(shaft.getAttribute('y1')); var yPos = yOrigin2; var tempClass; window.addEventListener('hashchange', function() { var hash = window.location.hash.substr(1); goto(hash); }, false); function goto(amount) { var shaftAnim = document.querySelector('#shaft-animate'); shaft.setAttribute('y2', yPos) amount = parseFloat(amount) if( isNaN( amount ) ) return; if(amount>.9) { tempClass="iconic-thermometer-hot"; } else if(amount>.5) { tempClass="iconic-thermometer-warm"; } else if(amount>.2) { tempClass="iconic-thermometer-chilly"; } else { tempClass="iconic-thermometer-cold"; } amount = 1 - amount; amount = Math.min(Math.max(0, amount), 1); var ry = ( amount * ( yOrigin1-yOrigin2 ) ) + yOrigin2; /* * Unfortunately, Safari doesn't make life easy on us. We need to remove and re-initialize * the animation element for animations to start from the last end point. */ var ns = shaftAnim.cloneNode(true); ns.setAttribute( 'from', yPos ) ns.setAttribute( 'to', ry ); shaftAnim.parentNode.replaceChild(ns, shaftAnim); well.setAttribute('class', 'iconic-thermometer-well ' + tempClass); shaft.setAttribute('class', 'iconic-thermometer-shaft ' + tempClass); ns.beginElement(); yPos = ry; } ]]> </script> </svg>
Висновок
Іконографія має важливу роль в дизайн інтерфейсу. Більш актуальну інформацію на наших іконах, тим більш могутніми вони стають. Ми щиро віримо, що розумна іконографія може бути незамінним інструментом для дизайнерів, щоб додати ще один шар сенсу в їхніх іконах. Не кожна ікона підходить для такого підходу—як і всі хороші речі, він вимагає помірності. Однак, коли використовується належним чином, це може бути величезний новий інструмент.
Назад знакових на Kickstarter
Мета знакових для забезпечення нових підходів до іконографії. Є багато більш відомих, ніж просто розумні іконки і ми раді поділитися ще однією цікавою особливістю з вами на наступному тижні.



Будь ласка, розглянути питання про підтримку знаменитого на Kickstarter.