Skip to content

Instantly share code, notes, and snippets.

@navt
Last active February 1, 2018 19:10
Show Gist options
  • Save navt/c4d0c9a74fe2b910ce90be08d09d82a6 to your computer and use it in GitHub Desktop.
Save navt/c4d0c9a74fe2b910ce90be08d09d82a6 to your computer and use it in GitHub Desktop.
Класс для формирования svg изображения с текстом внутри
<?php
class RectDraw
{
public $inscription; // содержание надписи
public $width; // ширина svg изображения
public $bg_color; // цвер фона
public $font_size; // размер шрифта
public $strings = [];
public $error = '';
public function __construct($inscription,$width,$bg_color,$font_size)
{
if ($inscription == '') {
$this->error .=__METHOD__.' задана пустая строка.';
return;
}
$this->inscription = $inscription;
if ($width <= 0 || $font_size <= 0) {
$this->error .=__METHOD__.' неверно заданы размеры.';
return;
}
$this->width = (integer)$width;
$this->font_size = (integer)$font_size;
$this->bg_color = $bg_color;
}
public function recipient()
{
if ($this->error !== '') {
echo $this->error;
return;
}
$this->inscription = str_replace(["\r\n", "\n\r", "\n", "\r"], ["~~~", "~~~", "~~~", "~~~"],
$this->inscription);
$this->inscription = explode('~~~', $this->inscription);
foreach ($this->inscription as $line) {
$this->toStrings($line);
}
return $this;
}
public function toStrings($line)
{
if ($this->error !== '') {
echo $this->error;
return;
}
$words = explode(' ', trim($line));
$strLength = (integer)($this->width - 4*$this->font_size); // длина строки в рх
$wl = (integer)($this->font_size*0.5); // ширина буквы в рх ?
$actual = 0; // длина очередной строки
$i = 0; // текущий номер слова
$str = ''; // заготовка для очередной строки
$flag = false; // флаг записи в массив $this->strings
foreach ($words as $word) {
$lword = mb_strlen($word);
if (($actual+($lword*$wl)) < $strLength) {
$str = $str.$word.' ';
$actual = $actual+($lword+1)*$wl;
$i = $i + 1;
if ($i === count($words)) {
$this->strings[] = $str;
$flag = true;
}
} else {
$this->strings[] = $str;
$actual = ($lword+1)*$wl;
$str = $word.' ';
$i = $i + 1;
if ($i === count($words)) {
$this->strings[] = $str;
$flag = true;
}
}
}
if ($flag === false) { // строка была слишком короткой
$this->strings[] = $str;
}
return $this;
}
public function filler()
{
if (!is_array($this->strings) || empty($this->strings)) {
$this->error .=__METHOD__.' ранее не был сформирован массив для текста.';
}
if ($this->error !== '') {
echo $this->error;
return;
}
$h = (count($this->strings)+2.5)*1.2*$this->font_size;
$height = floor($h);
$svg = $this->getBlank();
$svg = str_replace(['~width~', '~height~', '~bg_color~', '~font_size~'],
[(string)$this->width, (string)$height, $this->bg_color, (string)$this->font_size], $svg);
$x = (integer)$this->font_size*1.5; // отступ слева
$y = $this->font_size;
foreach ($this->strings as $string) {
$cursor = strpos($svg,"<!--label-->");
if ($cursor !== false) {
$y = floor($y + ($this->font_size*1.2)); // отступ сверху для строки
$tag = '<text x="'.(string)$x.'" y="'.(string)$y.'" class="letter">'.
$string.'</text>';
$svg = substr($svg, 0, $cursor).$tag.substr($svg, $cursor);
}
}
return $svg;
}
public function getBlank()
{
return
'<div style="max-width: ~width~px">
<svg viewBox="0 0 ~width~ ~height~" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<style>
.ground {fill:~bg_color~;}
.letter {fill: #ffffff; font-size: ~font_size~px; font-family: Arial;}
</style>
</defs>
<rect class="ground" width="~width~" height="~height~" rx="30" ry="30"/>
<!--label-->
</svg>
</div>';
}
}
// пример использования
$inscription = 'Новые серии знаменитого мультфильма "Простоквашино" покажут уже этой весной. Такое объявление сделали в пресс-службе киностудии "Союзмульфильм". В компании рассказали, что первые эпизоды продолжения мультипликационной ленты уже находятся на завершающей стадии производства.';
$rd = new RectDraw($inscription, 720, '#9e004d', 24);
echo $rd->recipient()->filler();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment