• Главная
  • Карта сайта
Не найдено

Typographic effects in canvas

  1. Передісторія
  2. Вступ
  3. Текстові тіні в canvas
  4. Як уникнути появи декількох альфа-каналів?
  5. Обрізка текстових блоків
  6. Ефект затримки (не пов'язаний з пікселізацією)
  7. Ефекти неонової веселки і відображення "зебра" - накладення декількох ефектів
  8. Ефект тремтіння неоново-райдужного контуру
  9. Ефект віддзеркалення "зебра"
  10. Ефект внутрішньої і зовнішньої тіні на елементі canvas
  11. Ефект зображення с помощью простору
  12. Модель HSL: тон, насиченість, яскравість (1978)
  13. Створення анімації за допомогою методу requestAnimationFrame
  14. Вихідний код

Передісторія

Я вперше зіткнувся з елементом в 2006 р, коли вийшов браузер Firefox версії 2.0. Стаття під назвою Ajaxian , В якій описувалася матриця перетворення, підштовхнула мене до написання першого веб-додатки з використанням елемента - Color Sphere (2007), в якому я поринув у світ кольору і найпростіших графічних об'єктів, що, в свою чергу, призвело до створення програми Sketchpad (2007-2008). Я хотів створити браузерні додаток, яке мало б більшу функціональність у порівнянні з Paint.

Ці експерименти врешті-решт привели до створення початкової версії Mugtug у співпраці з моїм давнім другом Чарльзом Прічард (Charles Pritchard). В даний час ми розробляємо програму Darkroom на базі елемента <canvas> в HTML5. Darkroom - це Недеструктивні додаток для обміну фотографіями, в якому поєднуються можливості піксельних фільтрів і векторної графіки, а також малювання.

Вступ

Елементи <canvas> дають програмістам JavaScript багаті можливості для управління кольором, векторами і пікселями на екрані, а також візуальним макетом монітора.

У цьому прикладі ми маємо справу зі сферою застосування <canvas>, яка поки не приваблювала особливої уваги, - створенням текстових ефектів. Елемент <canvas> дозволяє формувати велику кількість різноманітних текстових ефектів: наші демонстраційні приклади розкривають лише частина з доступних можливостей. Хоча в цій статті ми маємо справу з текстом, ці методи застосовні до будь-якого векторного об'єкту і дозволяють створювати чудові візуальні ефекти в іграх та інших додатках.

Ефект текстових тіней з використанням елемента <canvas>

. Текстові ефекти, подібні CSS, для елемента <canvas>: створення шаблонів обрізки, виявлення параметрів в <canvas> і використання властивості тіні. Неоново-райдужне світіння, відбиття "зебра", ефекти накладення . Текстові ефекти Photoshop на базі елемента <canvas>: приклади використання методів globalCompositeOperation, createLinearGradient, createPattern. Ефекти внутрішньої і зовнішньої тіні в <canvas> . Використовуємо маловідому функцію: обертання за годинниковою і проти годинникової стрілки для створення інверсії падаючої тіні (ефект внутрішньої тіні). Ефект імітації простору . Ефект створення тексту на елементі <canvas> шляхом циклічного перебору квітів hsl () і за допомогою функції window.requestAnimationFrame для створення ілюзії руху.

Текстові тіні в canvas

Одна з моїх улюблених функцій в специфікації CSS3 (поряд зі скруглением кордонів, веб-градієнтами та іншими) - це створення тіней. Важливо розуміти різницю між створенням тіней за допомогою CSS і <canvas>.

В CSS використовується два методи: box-shadow для box-елементів, наприклад div, span і т. П., І text-shadow для текстових компонентів.

У <canvas> є один тип тіні. Він використовується для всіх векторних об'єктів: ctx.moveTo, ctx.lineTo, ctx.bezierCurveTo, ctx.quadradicCurveTo, ctx.arc, ctx.rect, ctx.fillText, ctx.strokeText і т. Д. Щоб створити тінь в елементі <canvas >, потрібно вказати чотири властивості, перерахованих нижче.

ctx.shadowColor

= "red" // string Колір тіні. Підтримуються стандарти RGB, RGBA, HSL, HEX і деякі інші. ctx.shadowOffsetX = 0; // integer Горизонтальна довжина тіні щодо тексту. ctx.shadowOffsetY = 0; // integer Висота тіні щодо тексту. ctx.shadowBlur = 10; // integer Ефект розмиття тіні; чим більше значення, тим сильніше ефект.

Для початку подивимося, як за допомогою елемента <canvas> можна імітувати ефекти CSS. У Картинках Google за запитом css text-shadow можна знайти кілька прекрасних прикладів імітації: Line25 і Stereoscopic , а також Shadow 3D .

Стереоскопічний об'ємний ефект (більш докладні відомості див. У статті, присвяченій Анагліфов ) Є прекрасним прикладом простого коду. За допомогою наведеної нижче рядки CSS можна створити ілюзію глибини при перегляді в червоних або синіх 3D-окулярах (на зразок тих, що видаються в кінотеатрах).

text-shadow: -0.06em 0 0 red, 0.06em 0 0 cyan;

При перетворенні цього рядка з використанням елемента <canvas> потрібно звернути увагу на два моменти.

1. Ефект розмиття тіні (третій параметр) відсутня, тому його не потрібно застосовувати, так як функція fillText видасть той же результат:

var text = "Hello world!" ctx.fillStyle = "# 000" ctx.fillText (text, -7, 0); ctx.fillStyle = "red" ctx.fillText (text, 0, 0); ctx.fillStyle = "cyan" ctx.fillText (text, 7, 0);

2. Одиниця виміру EM не підтримує елементом <canvas>, тому відповідні значення потрібно перетворити в пікселі. Коефіцієнт перетворення для PT, PC, EM, EX, PX і т. Д. Можна дізнатися, створивши елемент з тими ж властивостями шрифтів в DOM і задавши діапазон в форматі вимірювання. Наприклад, щоб отримати результати перетворення з EM в пікселі, ми виміряємо елемент DOM висотою 1em: загальна висота offsetHeight буде дорівнює кількості пікселів в одиниці EM.

var font = "20px sans-serif" var d = document.createElement ( "span"); d.style.cssText = "font:" + font + "height: 1em; display: block "// the value to multiply PX's by to convert to EM's var EM2PX = 1 / d.offsetHeight;

Як уникнути появи декількох альфа-каналів?

У більш складних прикладах, наприклад при додаванні ефекту неонового свічення в Line25, необхідно використовувати параметр shadowBlur для правильної імітації ефекту. Так як ефект неону заснований на множинної тіні, ми зупинимося на цьому питанні. В елементі <canvas> у кожного векторного об'єкта може бути тільки одна тінь. Таким чином, щоб створити множинну тінь, потрібно намалювати кілька примірників тексту один над одним. Це призводить до множення альфа-каналів і в підсумку до появи розмитих країв.

Це призводить до множення альфа-каналів і в підсумку до появи розмитих країв

Я пробував використовувати ctx.fillStyle = "rgba (0,0,0,0)" або "transparent", щоб приховати текст під час відображення тіні, проте це не дало ніякого результату, оскільки тінь є результатом множення альфа-каналів fillStyle і не може бути менш прозорою, ніж закладено в цій функції.

На щастя, рішення є: можна застосувати зміщення тіні, відокремивши її від тексту (щоб вони не накладалися), і тим самим приховати текст на краю екрану.

var text = "Hello world!" var blur = 10; var width = ctx.measureText (text) .width + blur * 2; ctx.textBaseline = "top" ctx.shadowColor = "# 000" ctx.shadowOffsetX = width; ctx.shadowOffsetY = 0; ctx.shadowBlur = blur; ctx.fillText (text, -width, 0);

Обрізка текстових блоків

Щоб зробити приклад більш зрозумілим, заборонимо початковий виклик функції fillText (при цьому зберігши малювання тіні). Для цього потрібно додати шлях обрізки. Щоб створити шлях обрізки навколо тексту, потрібно знати висоту тексту (величину в em - одиниці, історично рівній висоті літери M на друкованому пресі) і його ширину. Ширину можна дізнатися за допомогою параметра ctx.measureText (). Width, однак аналогічного значення ctx.measureText (). Height для висоти не існує.

На щастя, за допомогою CSS-прийомів (див. Інші способи виправлення недоробок в більш ранніх версіях об'єкта <canvas> за допомогою параметрів CSS в статті Друкарські метрики ), Можна знайти висоту тексту, вимірявши параметр offsetHeight тега <span> з такими ж властивостями шрифту.

var d = document.createElement ( "span"); d.font = "20px arial" d.textContent = "Hello world!" var emHeight = d.offsetHeight;

Таким чином, можна створити прямокутник в якості шляху обрізки, включивши в нього тінь і видаливши фігуру-заповнювач.

ctx.rect (0, 0, width, emHeight); ctx.clip ();

Зведемо ці прийоми воєдино, трохи оптимізуємо алгоритм і отримаємо наведений нижче приклад. Якщо тінь використовується без розмиття, за допомогою функції fillText можна досягти того ж ефекту, не ставлячи шаблон обрізки.

var width = ctx.measureText (text) .width; var style = shadowStyles [text]; // add a background to the current effect ctx.fillStyle = style.background; ctx.fillRect (0, offsetY, ctx.canvas.width, textHeight - 1) // parse text-shadows from css var shadows = parseShadow (style.shadow); // loop through the shadow collection var n = shadows.length; while (n--) {var shadow = shadows [n]; var totalWidth = width + shadow.blur * 2; ctx.save (); ctx.beginPath (); ctx.rect (offsetX - shadow.blur, offsetY, offsetX + totalWidth, textHeight); ctx.clip (); if (shadow.blur) {// just run shadow (clip text) ctx.shadowColor = shadow.color; ctx.shadowOffsetX = shadow.x + totalWidth; ctx.shadowOffsetY = shadow.y; ctx.shadowBlur = shadow.blur; ctx.fillText (text, -totalWidth + offsetX, offsetY + metrics.top); } Else {// just run pseudo-shadow ctx.fillStyle = shadow.color; ctx.fillText (text, offsetX + (shadow.x || 0), offsetY - (shadow.y || 0) + metrics.top); } Ctx.restore (); } // drawing the text in the foreground if (style.color) {ctx.fillStyle = style.color; ctx.fillText (text, offsetX, offsetY + metrics.top); } // jump to next em-line ctx.translate (0, textHeight);

Щоб не вводити всі ці команди для роботи з елементом <canvas> вручну, я додав в демонстраційний код простий синтаксичний аналізатор для текстових тіней. Він приймає команди CSS і видає команди для роботи з <canvas>. Тепер елементам <canvas> можна застосувати цілий ряд стилів. Аналогічні ефекти тіні можна використовувати з будь-якими векторними об'єктами: від WebFonts до складних фігур, імпортованих з SVG-файлів, що генеруються векторних фігур і т. П.

Перегляньте в дії ефекти тіні на базі елемента <canvas> .

Перегляньте в дії   ефекти тіні на базі елемента <canvas>

Ефект затримки (не пов'язаний з пікселізацією)

До написання цього розділу мене підштовхнув демонстраційний приклад Stereoscopic. Наскільки складно створити об'ємний ефект за допомогою елемента <canvas> і двох знімків, зроблених під різними кутами? Думаю, не дуже. У наведеному нижче ядрі червоний канал першого знімка (data) поєднується з синім каналом другого знімка (data2).

data [i] = data [i] * 255 / 0xFF; data [i + 1] = 255 * data2 [i + 1] / 0xFF; data [i + 2] = 255 * data2 [i + 2] / 0xFF;

Зайдіть на сторінку прикладу Stereoscopic , Щоб дізнатися, як створювати зображення для показу в стереоочков (синій / червоний). Тепер досить прикріпити два пристрої iPhone на голову, включити на них одночасно запис відео, і можна створювати тривимірні фільми за допомогою HTML5. Хочете спробувати?

Хочете спробувати

Ефекти неонової веселки і відображення "зебра" - накладення декількох ефектів

Накласти кілька ефектів за допомогою елемента <canvas> нескладно, але для цього потрібні базові знання globalCompositeOperation (GCO). Якщо порівняти ці операції з GIMP (або Photoshop), то в <canvas> є 12 операцій GCO. Затемнення і освітлення можна вважати режимами змішування шарів, а решта 10 операцій застосовуються до верствам подібно альфа-масці (новий шар видаляє пікселі попереднього). Функція globalCompositeOperation з'єднує разом кілька шарів (в нашому випадку - рядків програмного коду), комбінуючи їх особливим чином.

Функція globalCompositeOperation з'єднує разом кілька шарів (в нашому випадку - рядків програмного коду), комбінуючи їх особливим чином

В таблиці globalCompositeOperation показані режими роботи GCO. Тут використовується основна частина спектра і кілька рівнів прозорості альфа-каналу, що дозволяє продемонструвати результат в деталях. Текстові описи можна знайти в довідковому керівництві Mozilla по globalCompositeOperation . Про те, як працює ця операція, можна дізнатися в статті Портера Даффа (Porter Duff) Комбінування цифрових зображень .

Найбільше мені подобається використовувати режим освітлення: globalCompositeOperation = "lighter". Ця функція змішує накладені пікселі подібно змішання компонентів світла: поєднання червоного, зеленого і синього кольорів при максимальній інтенсивності дає білий. Це надзвичайно цікава функція, особливо при низьких значеннях globalAlpha в елементі <canvas>: це покращує управління і дозволяє згладити кордону. Функція освітлення широко використовується. Один з моїх улюблених прикладів - інструмент для створення фону робочого столу на HTML5, який можна знайти на сайті http://weavesilk.com/ . Режим освітлення також використовується в одній з моїх демонстраційних програм, Breathing Galaxies : Текстури з цих двох прикладів дозволяють оцінити можливості цього режиму.

Увага! Необхідно враховувати, що не всі режими GCO підтримуються різними браузерами. Тільки шість з них працюють скрізь (Chrome, Safari, Firefox і Opera): source-over, source-atop, destination-over, destination-out, lighter і xor. Сподіваюся, ця проблема буде вирішена в майбутніх версіях. Додаткову інформацію можна знайти на сторінці, присвяченій використання функції globalCompositeOperation в різних браузерах .

Ефект тремтіння неоново-райдужного контуру

У наступному прикладі ми спробуємо створити ефект неоново-райдужного світіння з мерехтливим контуром, як в Photoshop, наклавши кілька ефектів за допомогою режимів globalCompositeOperation (source-in, lighter і darker). Це демонстраційний приклад є подальшим розвитком програми, що використовує ефекти тіні на елементі <canvas> за допомогою вже відомого нам методу відділення тіні від тексту (див. Попередній розділ).

Попередній розділ)

Перегляньте в дії ефект тремтіння неоново-райдужного контуру .

function neonLightEffect () {var text = "alert ( '" + String.fromCharCode (0x2665) + "')"; var font = "120px Futura, Helvetica, sans-serif"; var jitter = 25; // the distance of the maximum jitter var offsetX = 30; var offsetY = 70; var blur = getBlurValue (100); // save state ctx.save (); ctx.font = font; // calculate width + height of text-block var metrics = getMetrics (text, font); // create clipping mask around text-effect ctx.rect (offsetX - blur / 2, offsetY - blur / 2, offsetX + metrics.width + blur, metrics.height + blur); ctx.clip (); // create shadow-blur to mask rainbow onto (since shadowColor does not accept gradients) ctx.save (); ctx.fillStyle = "#fff"; ctx.shadowColor = "rgba (0,0,0,1)"; ctx.shadowOffsetX = metrics.width + blur; ctx.shadowOffsetY = 0; ctx.shadowBlur = blur; ctx.fillText (text, -metrics.width + offsetX - blur, offsetY + metrics.top); ctx.restore (); // create the rainbow linear-gradient var gradient = ctx.createLinearGradient (0, 0, metrics.width, 0); gradient.addColorStop (0, "rgba (255, 0, 0, 1)"); gradient.addColorStop (0.15, "rgba (255, 255, 0, 1)"); gradient.addColorStop (0.3, "rgba (0, 255, 0, 1)"); gradient.addColorStop (0.5, "rgba (0, 255, 255, 1)"); gradient.addColorStop (0.65, "rgba (0, 0, 255, 1)"); gradient.addColorStop (0.8, "rgba (255, 0, 255, 1)"); gradient.addColorStop (1, "rgba (255, 0, 0, 1)"); // change composite so source is applied within the shadow-blur ctx.globalCompositeOperation = "source-atop"; // apply gradient to shadow-blur ctx.fillStyle = gradient; ctx.fillRect (offsetX - jitter / 2, offsetY, metrics.width + offsetX, metrics.height + offsetY); // change composite to mix as light ctx.globalCompositeOperation = "lighter"; // multiply the layer ctx.globalAlpha = 0.7 ctx.drawImage (ctx.canvas, 0, 0); ctx.drawImage (ctx.canvas, 0, 0); ctx.globalAlpha = 1 // draw white-text ontop of glow ctx.fillStyle = "rgba (255,255,255,0.95)"; ctx.fillText (text, offsetX, offsetY + metrics.top); // created jittered stroke ctx.lineWidth = 0.80; ctx.strokeStyle = "rgba (255,255,255,0.25)"; var i = 10; while (i--) {var left = jitter / 2 - Math.random () * jitter; var top = jitter / 2 - Math.random () * jitter; ctx.strokeText (text, left + offsetX, top + offsetY + metrics.top); } Ctx.strokeStyle = "rgba (0,0,0,0.20)"; ctx.strokeText (text, offsetX, offsetY + metrics.top); ctx.restore (); };

Ефект віддзеркалення "зебра"

Цей ефект був розроблений під враженням від статті WebDesignerWall - прекрасного ресурсу, присвяченого використанню на веб-сторінці різних ефектів CSS. Це подальший розвиток ідеї створення відображення для тексту (як, наприклад, в iTunes). Цей ефект поєднує в собі функції fillColor (білий колір), createPattern (zebra.png) і linearGradient (блиск) і демонструє можливість застосування декількох видів заливки до одного векторному об'єкту.

png) і linearGradient (блиск) і демонструє можливість застосування декількох видів заливки до одного векторному об'єкту

Перегляньте в дії відображення "зебра" .

function sleekZebraEffect () {// inspired by - http://www.webdesignerwall.com/demo/css-gradient-text/ var text = "Sleek Zebra ..."; var font = "100px Futura, Helvetica, sans-serif"; // save state ctx.save (); ctx.font = font; // getMetrics calculates: // width + height of text-block // top + middle + bottom baseline var metrics = getMetrics (text, font); var offsetRefectionY = -20; var offsetY = 70; var offsetX = 60; // throwing a linear-gradient in to shine up the text var gradient = ctx.createLinearGradient (0, offsetY, 0, metrics.height + offsetY); gradient.addColorStop (0.1, '# 000'); gradient.addColorStop (0.35, '#fff'); gradient.addColorStop (0.65, '#fff'); gradient.addColorStop (1.0, '# 000'); ctx.fillStyle = gradient ctx.fillText (text, offsetX, offsetY + metrics.top); // draw reflected text ctx.save (); ctx.globalCompositeOperation = "source-over"; ctx.translate (0, metrics.height + offsetRefectionY) ctx.scale (1, -1); ctx.font = font; ctx.fillStyle = "#fff"; ctx.fillText (text, offsetX, -metrics.height - offsetY + metrics.top); ctx.scale (1, -1); // cut the gradient out of the reflected text ctx.globalCompositeOperation = "destination-out"; var gradient = ctx.createLinearGradient (0, offsetY, 0, metrics.height + offsetY); gradient.addColorStop (0.0, 'rgba (0,0,0,0.65)'); gradient.addColorStop (1.0, '# 000'); ctx.fillStyle = gradient; ctx.fillRect (offsetX, offsetY, metrics.width, metrics.height); // restore back to original transform state ctx.restore (); // using source-atop to allow the transparent .png to show through to the gradient ctx.globalCompositeOperation = "source-atop"; // creating pattern from <image> sourced. ctx.fillStyle = ctx.createPattern (image, 'repeat'); // fill the height of two em-boxes, to encompass both normal and reflected state ctx.fillRect (offsetX, offsetY, metrics.width, metrics.height * 2); ctx.restore (); };

Ефект внутрішньої і зовнішньої тіні на елементі canvas

У специфікації елемента <canvas> не розглядається питання внутрішньої і зовнішньої тіней. На перший погляд може здатися, що внутрішня тінь не підтримується. Насправді це не так: просто її трохи складніше реалізувати. Як було запропоновано в одному з недавніх повідомлень F1LT3R , Ефект внутрішньої тіні можна створити за допомогою унікальних властивостей правил обертання за годинниковою і проти годинникової стрілки. Щоб додати внутрішню тінь, потрібно намалювати прямокутний контейнер, а потім, обертаючи його в зворотний бік, створити профіль для обрізки, інвертовану фігуру.

У наведеному нижче прикладі можна змінювати параметри кольору, градієнтних і текстури одночасно для внутрішньої тіні і функції fillStyle. Параметри обертання текстури можна задавати окремо: зверніть увагу на смуги зебри, розташовані перпендикулярно. Шаблон обрізки за розміром обмежує рамки позбавляє від потреби в надвеликих контейнерах для профілю обрізки: обробляється тільки необхідна частина тіні, що економить час.

Перегляньте в дії ефект внутрішньої тіні .

function innerShadow () {function drawShape () {// draw anti-clockwise ctx.arc (0, 0, 100, 0, Math.PI * 2, true); // Outer circle ctx.moveTo (70, 0); ctx.arc (0, 0, 70, 0, Math.PI, false); // Mouth ctx.moveTo (-20, -20); ctx.arc (30, -30, 10, 0, Math.PI * 2, false); // Left eye ctx.moveTo (140, 70); ctx.arc (-20, -30, 10, 0, Math.PI * 2, false); // Right eye}; var width = 200; var offset = width + 50; var innerColor = "rgba (0,0,0,1)"; var outerColor = "rgba (0,0,0,1)"; ctx.translate (150, 170); // apply inner-shadow ctx.save (); ctx.fillStyle = "# 000"; ctx.shadowColor = innerColor; ctx.shadowBlur = getBlurValue (120); ctx.shadowOffsetX = -15; ctx.shadowOffsetY = 15; // create clipping path (around blur + shape, preventing outer-rect blurring) ctx.beginPath (); ctx.rect (-offset / 2, -offset / 2, offset, offset); ctx.clip (); // apply inner-shadow (w / clockwise vs. anti-clockwise cutout) ctx.beginPath (); ctx.rect (-offset / 2, -offset / 2, offset, offset); drawShape (); ctx.fill (); ctx.restore (); // cutout temporary rectangle used to create inner-shadow ctx.globalCompositeOperation = "destination-out"; ctx.fill (); // prepare vector paths ctx.beginPath (); drawShape (); // apply fill-gradient to inner-shadow ctx.save (); ctx.globalCompositeOperation = "source-in"; var gradient = ctx.createLinearGradient (-offset / 2, 0, offset / 2, 0); gradient.addColorStop (0.3, '# ff0'); gradient.addColorStop (0.7, '# f00'); ctx.fillStyle = gradient; ctx.fill (); // apply fill-pattern to inner-shadow ctx.globalCompositeOperation = "source-atop"; ctx.globalAlpha = 1; ctx.rotate (0.9); ctx.fillStyle = ctx.createPattern (image, 'repeat'); ctx.fill (); ctx.restore (); // apply fill-gradient ctx.save (); ctx.globalCompositeOperation = "destination-over"; var gradient = ctx.createLinearGradient (-offset / 2, -offset / 2, offset / 2, offset / 2); gradient.addColorStop (0.1, '# f00'); gradient.addColorStop (0.5, 'rgba (255,255,0,1)'); gradient.addColorStop (1.0, '# 00f'); ctx.fillStyle = gradient ctx.fill (); // apply fill-pattern ctx.globalCompositeOperation = "source-atop"; ctx.globalAlpha = 0.2; ctx.rotate (-0.4); ctx.fillStyle = ctx.createPattern (image, 'repeat'); ctx.fill (); ctx.restore (); // apply outer-shadow (color-only without temporary layer) ctx.globalCompositeOperation = "destination-over"; ctx.shadowColor = outerColor; ctx.shadowBlur = 40; ctx.shadowOffsetX = 15; ctx.shadowOffsetY = 10; ctx.fillStyle = "#fff"; ctx.fill (); };

На цих прикладах видно, що за допомогою globalCompositeOperation можна накладати кілька простих ефектів один на одного і отримувати в результаті більш складні, використовуючи маскування і змішання. Все у ваших руках!

Ефект зображення с помощью простору

За допомогою елемента <canvas> перейти від символу Юникода 0x2708 ...

За допомогою елемента <canvas> перейти від символу Юникода 0x2708

... до наведеного нижче прикладу з тінню ...

до наведеного нижче прикладу з тінню

... можна за допомогою множинних звернень до функції ctx.strokeText () з невеликим значенням lineWidth (0,25) при паралельному зменшенні горизонтального зсуву і прозорості, що створює ілюзію руху векторного елемента.

Шляхом синусоїдального і косинусоїдального зміщення координат елементів і циклічного перебору квітів за допомогою властивості HSL можна створювати і більш цікаві ефекти, як у наведеному нижче прикладі "Біологічна небезпека".

Модель HSL: тон, насиченість, яскравість (1978)

Модель HSL - це новий формат, підтримуваний специфікацією CSS3. На відміну від схеми HEX, розробленої для комп'ютерів, модель HSL призначена для використання людьми.

Змінити колірну палітру в моделі HSL дуже просто: значення тону збільшується від 360 і відображається на циліндричній спектрі. Параметр яскравості визначає, наскільки світлим або темним буде колір: значення 0% відповідає чорному пікселу, тоді як 100% - білому. Параметр насиченості визначає, наскільки яскравим і живим буде колір: сірий відтінок відповідає насиченості 0%, а яскраві живі кольори - насиченості 100%.

Так як стандарт HSL з'явився недавно, рекомендується продовжувати підтримувати більш ранні версії браузерів (наприклад, шляхом перетворення колірного простору). У наведеному нижче коді об'єкт HSL з параметрами {H: 360, S: 100, L: 100} перетворюється в об'єкт RGB виду {R: 255, G: 255, B: 255}. Ці значення можна використовувати для створення власних рядків rgb і rgba. Вичерпну інформацію можна знайти в статті Вікіпедії про HSL .

// HSL (1978) = H: Hue / S: Saturation / L: Lightness HSL_RGB = function (o) {// {H: 0-360, S: 0-100, L: 0-100} var H = oH / 360, S = oS / 100, L = oL / 100, R, G, B, _1, _2; function Hue_2_RGB (v1, v2, vH) {if (vH <0) vH + = 1; if (vH> 1) vH - = 1; if ((6 * vH) <1) return v1 + (v2 - v1) * 6 * vH; if ((2 * vH) <1) return v2; if ((3 * vH) <2) return v1 + (v2 - v1) * ((2/3) - vH) * 6; return v1; } If (S == 0) {// HSL from 0 to 1 R = L * 255; G = L * 255; B = L * 255; } Else {if (L <0.5) {_2 = L * (1 + S); } Else {_2 = (L + S) - (S * L); } _1 = 2 * L - _2; R = 255 * Hue_2_RGB (_1, _2, H + (1/3)); G = 255 * Hue_2_RGB (_1, _2, H); B = 255 * Hue_2_RGB (_1, _2, H - (1/3)); } Return {R: R, G: G, B: B}; };

Створення анімації за допомогою методу requestAnimationFrame

Раніше для створення анімаційних ефектів у JavaScript використовувалися методи setTimeout і setInterval.

window.requestAnimationFrame - це новий стандарт, покликаний замінити обидва ці способи, а також сприяти економії електроенергії і продовження терміну служби комп'ютерів за рахунок керування анімацією в браузері в залежності від доступних ресурсів. Ось деякі з його можливостей.

  • Коли користувач залишає фрейм, анімацію можна уповільнити і навіть повністю зупинити, щоб заощадити ресурси системи.
  • Швидкість поновлення обмежена 60 кадрами в секунду. Це обумовлено особливостями сприйняття людини (для більшості людей відчуття плавного переходу виникає на швидкості 30 кадрів в секунду).

На момент написання цієї статті для використання методу requestAnimationFrame необхідні префікси для конкретних браузерів. Пол Айріш (Paul Irish) пропонує своє рішення для підтримки різних браузерів: інтелектуальна анімація за допомогою requestAnimationFrame .

// shim layer with setTimeout fallback window.requestAnimFrame = (function () {return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (/ * function * / callback , / * DOMElement * / element) {window.setTimeout (callback, 1000/60);};}) ();

Більш амбітні розробники можуть піти далі і використовувати також технологію poly-fill, приклад якої наведено в скрипті requestAnimationFrame.js (Деякі функції вимагають доопрацювання) і яка буде підтримувати як попередні версії браузерів, так і новий стандарт.

У наведеному нижче прикладі показано, як створити анімацію шляхом багаторазового виклику методу strokeText з низьким рівнем альфа-каналу без "зависання" браузера. Елементи управління можуть здатися незвичайними, проте результат дуже цікавий.

Перегляньте в дії ефект імітації простору .

(Function animate () {var i = 50; while (i--) {if (n> endpos) return; n + = definition; ctx.globalAlpha = (0.5 - (n + startpos) / endpos) * alpha; if (doColorCycle) {hue = n + color; ctx.strokeStyle = "hsl (" + (hue% 360) + ", 99%, 50%)"; // iterate hue} var x = cos (n / cosdiv) * n * cosmult; // cosine var y = sin (n / sindiv) * n * sinmult; // sin ctx.strokeText (text, x + xoffset, y + yoffset); // draw rainbow text} timeout = window.requestAnimationFrame (animate, 0);}) (); (Function animate () {var i = 50; while (i--) {if (n> endpos) return; n + = definition; ctx

Вихідний код

З підтримкою розробників браузерів технологія <canvas> має хороші перспективи: її можна перенести в виконувані файли для пристроїв iPhone, Android і звичайних комп'ютерів засобами PhoneGap або Titanium .

Вихідний код наведено в файлі CanvasTextEffects.zip .

Наскільки складно створити об'ємний ефект за допомогою елемента <canvas> і двох знімків, зроблених під різними кутами?
5. Хочете спробувати?
Провайдеры:
  • 08.09.2015

    Batyevka.NET предоставляет услуги доступа к сети Интернет на территории Соломенского района г. Киева.Наша миссия —... 
    Читать полностью

  • 08.09.2015
    IPNET

    Компания IPNET — это крупнейший оператор и технологический лидер на рынке телекоммуникаций Киева. Мы предоставляем... 
    Читать полностью

  • 08.09.2015
    Boryspil.Net

    Интернет-провайдер «Boryspil.net» начал свою работу в 2008 году и на данный момент является одним из крупнейших поставщиков... 
    Читать полностью

  • 08.09.2015
    4OKNET

    Наша компания работает в сфере телекоммуникационных услуг, а именно — предоставлении доступа в сеть интернет.Уже... 
    Читать полностью

  • 08.09.2015
    Телегруп

    ДП «Телегруп-Украина» – IT-компания с 15-летним опытом работы на рынке телекоммуникационных услуг, а также официальный... 
    Читать полностью

  • 08.09.2015
    Софтлинк

    Высокая скоростьМы являемся участником Украинского центра обмена трафиком (UA — IX) с включением 10 Гбит / сек... 
    Читать полностью