
Должен ли дизайнер уметь программировать? На этот вопрос вываливается куча статей в поисковиках, где у авторов приводятся похожие аргументы «за» и «против». Иногда в комментариях появляются разработчики, которые критикуют дизайнеров, лезущих не в своё дело.
В этой статье хочу поделиться одним примером рабочего инструмента, который появился благодаря коду. Это поможет вам определиться, нужно изучать азы программирования дизайнеру, или нет.
Содержание статьи
Немного обо мне и коде
Я графический дизайнер и иллюстратор, который знаком с программированием. Я немного разбираюсь в HTML, CSS, JavaScript, знаком с PHP и работой с Xcode.
Знания не раз помогали в коммерческих проектах, связанных с веб-дизайном. В свободное время создаю скрипты для Иллюстратора и Фотошопа, написал расширения для Хрома Open in Figma, Open in Notion. Я не обладаю какими-то сверх глубокими познаниями в коде, но могу написать что-то простое самостоятельно, не тратя время знакомых разработчиков.
Предыстория
В конце 2019 мы с продуктовой и маркетинговой командами Модульбанка применили систему аналитики Микспанель в новом для себя ключе.
Микспанель рассылает информационные и рекламные уведомления в личном кабинете пользователя, сегментирует аудиторию и анализирует поведение пользователей. При наличии такого готового инструмента вкладывать ресурсы в собственную разработку не было смысла:
CSS и кастомизация
В ходе первых тестов обнаружился первый минус. Превью в редакторе Микспанели далёк от реальности. Во время отправки тестового варианта мы обнаружили сильные отличия:
С этим связан второй минус. Оказалось, что в Микспанели нельзя настраивать свои CSS стили. Это довольно грустно для современного сервиса, а нам необходимо было стилизовать попап под интерфейс нашего продукта.
Как решили
Я подготовил редизайн уведомлений на базе имеющихся продуктовых компонентов в Фигме, а верстальщик сделал единственно возможное в этой ситуации — проанализировал все CSS стили окна Микспанели и переписал каждый.
Когда попап из Микспанели попадает в личный кабинет пользователя, стили на лету меняются. Костыль, но куда деваться:
Теперь начинается самое интересное. После запуска теста появилась потребность проверять попап перед отправкой реальным пользователям. Запускать на тестовом мире каждое новое всплывающее окно оказалось затратным, а проверять надо было. Ведь мне, как иллюстратору, нужно примерить скетч, оценить готовую иллюстрацию с текстом, а копирайтерам нужно понимать, сколько символов заголовка и описания помещается в окно. Я могу собрать мокап в Фотошопе или Фигме, но как быть остальным у кого нет под рукой софта?
Так пришла идея реализовать на базе кода от верстальщиков обычную html-страничку с формой ввода текста для попапа и изображения. В данном случае обращаться к коллегам по такой мелочи нелогично: у всех задачи расписаны наперёд. Просить помочь в нерабочее время — можно, но неприлично. А так как знания программирования у меня имеются, то эта идея крепко засела в моей голове.
Генератор v1. Начало
На первом этапе в html с попапом я решил добавить простенькую форму из пары полей , чтобы можно было вводить заголовок и описание в несколько строк и обычным
для текста кнопки. Здесь и далее я буду приводить только куски кода непосредственно генератора.
Кнопка «Просмотреть» для подставки текста в попап. Зачем для предпросмотра было делать отдельную кнопку, добавляя на пути пользователя лишний клик? На тот момент мне эта кнопка казалась логичной, но позже я её выпилил.
После клика на «Просмотреть» функция submitTxt()
брала значение из полей ввода по ID и подставляла также по ID в соответствующие блоки попапа на странице:
function submitTxt() {
var title = $("#myTitle").val();
var descr = $("#myDesc").val();
var btn = $("#myBtn").val();
$("#mixpanel-notification-title").html(nl2br(title));
$("#mixpanel-notification-body").html(nl2br(descr));
$("#mixpanel-notification-button-link").text(btn);
}
Проблема в том, что хоть и поддерживает перенос строк, но при подставке в попап эти переносы исчезали и текст шёл в одну строку.
Покопавшись, я узнал о существовании функции nl2br()
, которая преобразует перенос строки в html-код. Поэтому наш текст вставляется в попап после промежуточной обработки этой функцией:
function nl2br (str, replaceMode) {
var breakTag = "
";
var replaceStr = (replaceMode) ? "$1"+ breakTag : "$1"+ breakTag +"$2";
return (str + "").replace(/([^>rn]?)(rn|nr|r|n)/g, replaceStr);
}
Кнопка «Сбросить» вызывает перезагрузку страницы.
function resetPage() {
window.location.reload(false);
}
Первое творение показалось мне вполне жизнеспособным, хотя уже тогда маячила мысль об автоматизации подстановки картинок. Генератор был выложен на внутреннем ресурсе в оффлайн-папке с файлами вёрстки.
Генератор v2. Эволюция
Прошло пару месяцев и в феврале 2020 я набрался сил для улучшений функционала и рефакторинга кода. В планах было:
- сразу видеть результат ввода текста;
- подгружать иллюстрации через форму;
- скачивать попап в png, чтобы пересылать внутренним заказчикам на согласование.
Ввод
Отказаться от кнопки «Просмотреть» мне помог здравый смысл и события input
, которое реагирует на каждое изменение текста в поле ввода, и change
, которое сработает при потере фокуса с поля:
$(document).ready(function() {
$("#myTitle, #myDesc, #myBtn").on("input", delayChange);
$("#myTitle, #myDesc, #myBtn").on("change", doChange);
});
Чтобы после каждой набранной буквы весь текст не отправлялся в попап, я добавил функцию delayChange()
. Она ждёт одну секунду, если больше не было нажатий, и отправляет обработанный текст в попап. Если же вставлять в поле скопированный текст и переходить сразу на следующее, то сработает событие change
. Здесь задержка без надобности и достаточно функции doChange()
.
function doChange(e) {
obj = e.target;
var inpID = $(obj).attr("id");
$("."+inpID).html(nl2br(obj.value));
}var timeout = null;
function delayChange(e) {
clearTimeout(timeout);
timeout = setTimeout(function() {
doChange(e);
}, 1000);
}
Добавление иллюстраций
Чтобы добавить иллюстрации, я вставил стандартный инпут , но чтобы стилизовать внешний вид под себя — подключил библиотеку FileInput.
Изменение внешнего вида прикрепления файлов можно реализовать по-разному, но для странички, которая используется периодически, я не вижу смысла тестировать и выбирать какое-то сверх оптимизированное решение.
После выбора файла, также как и с вводом текста, надо подставить его в попап. По знакомому нам событию change
вызывается функция previewFile()
.
$(document).ready(function() {
$("#picture").on("change", previewFile);
});
Она считывает файл методом readAsDataURL как кодированный url, чтобы в итоге изображение оказалось в попапе в обычном теге
.
function previewFile() {
var preview = document.querySelector("#mixpanel-notification-img");
var file = document.querySelector("input[type=file]").files[0];
var reader = new FileReader();
reader.onloadend = function () {
preview.src = reader.result;
}
if (file) { reader.readAsDataURL(file); }
}
Скачивание
Что представляет собой скачивание превью? Нужно текущее состояние блока попапа на html-странице превратить в растровое изображение и после скачать. Для этого решил использовать открытую библиотеку html2canvas. Она в общих чертах берёт содержимое указанного нами блока и отрисовывает, как графику, в элементе .
$(document).ready(function() {
$("#download").on("click", screenshot);
});function screenshot() {
var canvasPromise = html2canvas(document.getElementById("mixpanel-notification-mainbox"), {
useCORS: true
});
canvasPromise.then(function(canvas) {
saveAs(canvas.toDataURL("image/png"), "mixpanel-web.png");
});
}
Это только часть дела. Полученное в канвасе изображение нам ещё нужно скачать. Сразу после отрисовки вызывается функция saveAs()
, которая создаёт временную ссылку для скачивания канваса и эмулирует клик по ней, подчищая всё за собой:
function saveAs(uri, filename) {
var link = document.createElement("a");
if (typeof link.download === 'string') {
link.href = uri;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
} else {
window.open(uri);
}
}
Ниже видно текущую версию генератора превью, через которую можно тестировать внешний вид иллюстраций и текста для новых рассылок. Для удобства я разместил его на отдельном домене, чтобы коллеги имели к нему доступ с любого устройства и можно было быстро вносить будущие улучшения в код.
Оглядываясь на проделанную работу всё кажется простым, но когда сталкиваешься с некоторыми вещами в первый раз, не всегда с ходу получается заставить их работать.
Например, я делал страничку локально и c html2canvas не работало скачивание, пока в консоли Хрома не обнаружил ошибку. При запуске из папки не выполнялся метод toDataURL
: Хром считал, что в канвас попадают данные с другого домена и нарушается Same Origin Policy. Стоило загрузить генератор на хостинг и всё сразу заработало.
Заключение
Знать хотя бы немного код — отличный мастхев для дизайнеров. Вы сможете лучше понимать разработчиков и верстальщиков. Вы сможете самостоятельно делать простые прототипы и автоматизировать собственную работу. Да и лишний навык — это +1 балл в резюме и лишний 0 к возможной зарплате.
Я рекомендую хотя бы немного изучить языки программирования. Насколько глубоко? Каждый определяет сам, насколько это интересно и от наличия свободного времени.
Если не понравится — ок, у дизайнеров столько направлений для развития, что можно найти любое по душе. Не стоит заставлять себя изучать то, что не нравится, потому что это написали в вакансии или «все вокруг говорят, что надо». Вы так или иначе найдёте применение своим сильным сторонам.
Когда несколько строк кода немного улучшают жизнь , находишь в этом особое очарование. Если нравится это направление, то находишь время для практики, идёшь к поставленным целям и запускаешь свои проекты. Я по-прежнему не обладаю сильными знаниями в языках программирования, но мне нравится работать с кодом. И это главное.