И вот он, SVG-календарь, который всегда показывает сегодняшнюю дату:
Фоновое изображение сделано на основе иконки Twitter TweMoji Calendar — CC-BY
Поддержка текста в SVG слегка неудобная, так что позвольте объяснить, как я это сделал.
SVG поддерживает JavaScript. Это запускается сразу после загрузки изображения.
<svg onload="init(evt)" xmlns="http://www.w3.org/2000/svg"
aria-label="Calendar" role="img" viewBox="0 0 512 512">
Следующий этап — получить различные строки с датами. Я использую британскую локаль
en-GB
, поскольку нахожусь в Великобритании.<script type="text/ecmascript"><![CDATA[
function init(evt) {
var time = new Date();
var locale = "en-gb";
Мне нужно что-то вроде “Sunday 25 FEB”. Настройки локали поддерживают короткие и длинные имена, так что вы можете выбрать “SUN 25 February”.
var DD = time.getDate();
var DDDD = time.toLocaleString(locale, {weekday: "long"});
var MMM = time.toLocaleString(locale, {month: "short"});
Наконец, добавляем текст на изображение.
var svgDocument = evt.target.ownerDocument;
var dayNode = svgDocument.createTextNode(DD);
svgDocument.getElementById("day").appendChild(dayNode);
var weekdayNode = svgDocument.createTextNode(DDDD);
svgDocument.getElementById("weekday").appendChild(weekdayNode);
var monthNode = svgDocument.createTextNode(MMM.toUpperCase());
svgDocument.getElementById("month").appendChild(monthNode);
}
]]></script>
Позиционировать текст относительно просто. Координаты X и Y привязываются к нижней границе текста — помните, что литеры с нижними выносными элементами, такие как g, выйдут за пределы координаты Y. Тут же мы устанавливаем цвет текста, размер и шрифт.
Макетирование проще всего с моноширинными шрифтами.
<text id="month"
x="32"
y="164"
fill="#fff"
font-family="monospace"
font-size="140px"
style="text-anchor: left"></text>
По поводу выравнивания. Чтобы выровнять текст по центру, укажите
style="text-anchor: middle"
.Предварительные тесты показали, что этот SVG работает во всех десктопных браузерах и в браузерах под Android. Мы не проводили тесты на iPhone или более экзотических устройствах.
Наслаждайтесь!
Комментарии (53)
perfect_genius
06.03.2018 15:20+3Откройте в новой вкладке
vbif
06.03.2018 15:44+2А в текущей вкладке показывает ерунду
perfect_genius
06.03.2018 16:16Можете заскринить?
kruslan
06.03.2018 16:32Лучше ссылкой)
perfect_genius
06.03.2018 16:37И что же не так? На текущей вкладке запускается с нуля (с 12и), на новой вкладке — системное время.
Max_JK
08.03.2018 08:53Там случайно не встроен майнер?
ivan386
08.03.2018 11:07Это анимация жрёт. Её коряво реализовали в браузере. Даже если в картинке ничего не меняется она перерисовывается полностью.
BigDflz
09.03.2018 18:03не неполностью, там три момента анимации — для каждой стрелки, можно по частям убирать и смотреть на проц. это относится и к мозиле и к хрому.
ivan386
09.03.2018 19:05Это да. Но когда они встроены через тег img а в этом случае картинка перересовывается полностью постоянно. Даже шаговая анимация в одну минуту (
<animateTransform calcMode="discrete" dur="1min" type="rotate" fill="freeze" by="6" />
) перерисовывается несколько раз в секунду хотя в этом нет необходимости.BigDflz
09.03.2018 19:09как это можно проверить/увидеть?
если это без тега img — то нагрузка на проц будет меньше?
В хроме можно залезть во внутрь svg, а в мозиле — нет.ivan386
09.03.2018 19:20В Firefox есть кнопка "Подсветить прорисованную область" в панели иструментов консоли. Её надо добавить в "Настройки инструментов" -> "Дополнительные кнопки инструментов" -> "Подсветить прорисованную область".
В хроме аналог флажок "Enable paint flashing" на вкладке Rendering в консоли.
Только осторожно с этим. Зрелище не для эпилептиков. В хроме это нежнее реализовано.BigDflz
09.03.2018 19:39проверил, перерисовывает не всю картинку, а только прямоугольник, в который вписывается стрелка(и)
hdfan2
06.03.2018 15:25+1А если заменить
var locale = "en-gb";
на
var locale = undefined;
то получим то же самое в текущей локали.
impwx
06.03.2018 16:48+4Вся статья сводится к трем тезисам:
- SVG поддерживает Javascript
new Date()
evt.target.ownerDocument.createTextNode()
DistortNeo
07.03.2018 12:20SVG поддерживает Javascript
А не дыра ли это?
ivan386
07.03.2018 12:31С чего вдруг? В img скрипты не работают. Они работают только если svg встроен напрямую в html или открыт в отдельном окне.
DistortNeo
07.03.2018 18:45открыт в отдельном окне.
Заставить пользователя открыть ссылку в новом окне — раз плюнуть. И при этом выполнится неподконтрольный скрипт в домене сервера, на который было загружено изображение.
PoliTeX
06.03.2018 19:52+4>>Этот SVG всегда показывает сегодняшнюю дату
Нет, он показывает дату открытия, завтра соврет.
geoolekom
07.03.2018 23:49Мы не проводили тесты на iPhone или более экзотических устройствах.
С каких это пор айфон — хоть сколько-нибудь экзотическое устройство?)
synedra
08.03.2018 09:14А вне браузера он и не должен исполняться, верно? По крайней мере в eog скрипт не отрабатывает и картинка показывает дефолтное 29 февраля.
kekekeks
В связи с чем возникает законный вопрос: что будет, если кто-нибудь догадается встроить в SVG криптомайнер и начнёт постить такую картинку везде в комментариях?
vesper-bot
Она по сигнатурам попадет в фильтры uBlock.
anador
В связи с чем? Статья не о том, что SVG поддерживает JavaScript. Или, вы думаете, автор сделал открытие?
semen-pro
Майнеры сделали открытие)
arandomic
Картинки в комментариях обычно выводятся «as image»
Теоретически скрипты бы должны не работать.
SVG_Security
Psychosynthesis
Ну вот в этом комменте почему-то работает: habrahabr.ru/post/350596/#comment_10699028
nidalee
В текущей вкладке стартует ровно с 00:00
codemafia
Здорово. Можно утащить куки пользователей Хабра.
dmitryredkin
Скрипт в этих часах используется только для инициализации. Вся анимация работает без скриптов.
kalininmr
кстати пришла похожая мысль на тему svg.
но не столь радикальная