В наше время многочисленные сайты создают страницы, которыми пользователи хотели бы делиться в разных социальных сетях или мессенджерах. Благодаря тегам Open Graph ссылки могут иметь красочное превью изображение, которое привлекает еще больше внимания, например, с помощью тега og:image.
Обычно многие веб-сайты не прикладывают особых усилий к предварительному просмотру изображений и просто добавляют одно изображение на большинство страниц. Если изображения нет, парсеры пытаются автоматически найти первое доступное подходящее изображение и использовать его.
Но представьте как бы было здорово иметь персонализированную картинку на странице, например, когда у вас есть профили ваших пользователей, или каких-то событий в которых они участвуют. Такая задача возникла и в нашем проекте, где мы хотели бы генерировать страницы с красочными изображениями которыми пользователи хотели бы делиться.
Например, посмотрите на картинку ниже которую мы генерируем для шаринга в социальных сетях. Тут есть кастомный шрифт, градиент, и даже локализация картинки на разные языки.

В нашем проекте первоначальные версии изображений создавались с помощью PHP, и какое-то время этого было достаточно, поскольку изображения были не очень сложными и содержали только картинку пользователя. Однако как только мы добавили имя пользователя, то уже сразу возникли проблемы с позиционированием текста. Возьмем для примера простой скрипт создания изображения на PHP.
Пример создания изображения на PHP
<?php
$width = 400;
$height = 200;
$image = imagecreatetruecolor($width, $height);
$backgroundColor = imagecolorallocate($image, 255, 255, 255);
imagefill($image, 0, 0, $backgroundColor);
$textColor = imagecolorallocate($image, 0, 0, 0);
$fontFile = 'path/to/your/font.ttf';
$language = isset($_GET['lang']) ? $_GET['lang'] : 'ru';
$text = getLocalizedText($language);
$fontSize = 24;
$textbox = imagettfbbox($fontSize, 0, $fontFile, $text);
$textX = ($width - ($textbox[2] - $textbox[0])) / 2;
$textY = ($height - ($textbox[5] - $textbox[3])) / 2 + ($textbox[5] - $textbox[3]);
imagettftext($image, $fontSize, 0, $textX, $textY, $textColor, $fontFile, $text);
header("Content-Type: image/png");
imagepng($image);
imagedestroy($image);
function getLocalizedText($language) {
switch ($language) {
case 'en':
return 'Hello, PHP!';
case 'fr':
return 'Bonjour, PHP!';
default:
return 'Привет, PHP!';
}
}Как видно из примера, если текст будет слишком длинный, то может уйти и за рамки изображения. А если сюда добавить градиенты, полупрозрачность, тени или что-то еще интересное, то код усложнится и поддерживать его будет не очень просто.
Все это приводит к тому, что затраты на изменение изображения требуют достаточно большого количества времени разработки.
Решение, о котором я хотел бы рассказать позволяет в разы сократить время разработки и упростить поддержку таких изображений. Более того - оно гибкое и очень легко масштабируется и для других вещей.
Для веб-разработчика HTML - это самый простой и удобный язык разметки. Вместе со стилями CSS вы можете создать гибкий интерфейс, учитывающий расположение любых элементов на странице — изображений, текста, таблиц, списков и т.д.
Давайте посмотрим и на примере ниже. Это простая HTML-страница со множеством стилей CSS, таких как градиент в тексте, тени, ограничение текстовых строк для длинного текста и другое.
Пример HTML кода для страницы профиля
html>
<head>
<style>
html, body {
margin: 0;
padding: 0;
}
body {
background-color: #0093E9;
background-image: linear-gradient(160deg, #0093E9 0%, #80D0C7 100%);
font-family: Helvetica, sans-serif;
padding: 5%;
text-align: center;
}
header {
position: relative;
}
header .emoji {
position: absolute;
top: -10px;
left: 0;
transform: rotate(20deg);
font-size: 3rem;
}
* {
box-sizing: border-box;
}
h1 {
text-transform: uppercase;
font-size: 3rem;
background: -webkit-linear-gradient(45deg, #85FFBD 0%, #FFFB7D 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.wrapper {
display: flex;
padding-top: 2rem;
}
.avatar {
display: flex;
justify-content: center;
align-items: center;
}
.avatar img {
width: 140px;
height: 140px;
border-radius: 100px;
border: 5px solid rgba(255,255,255, 0.5);
box-shadow: 0 0 10px rgba(0,0,0,0.2);
object-fit: cover;
}
.content {
padding: 1rem 2rem;
}
.content .text {
font-size: 1.5rem;
display: -webkit-box;
-webkit-line-clamp: 3; /* number of lines to show */
line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
color: rgba(255,255,255, 0.8);
}
</style>
</head>
<body>
<div>
<header>
<h1>Hello, Javascript</h1>
<div class="emoji"> 