1
|
|
|
<?php declare(strict_types=1); |
2
|
|
|
|
3
|
|
|
if(!extension_loaded('gd')) { die('GD ext is required to run this!'); } |
4
|
|
|
|
5
|
|
|
const ASSET_FOLDER = 'public/assets'; |
6
|
|
|
|
7
|
|
|
/** @noinspection AutoloadingIssuesInspection */ |
8
|
|
|
class Spritesheet { |
9
|
|
|
private $type; |
10
|
|
|
private $iconFolder; |
11
|
|
|
|
12
|
|
|
private $updateLESS; |
13
|
|
|
|
14
|
|
|
private $fileList; |
15
|
|
|
private $less; |
16
|
|
|
|
17
|
|
|
public function __construct(string $type, bool $updateLESS = TRUE) { |
18
|
|
|
$this->type = $type; |
19
|
|
|
$this->updateLESS = $updateLESS; |
20
|
|
|
|
21
|
|
|
$this->iconFolder = ASSET_FOLDER."/img/{$type}_icons"; |
22
|
|
|
|
23
|
|
|
$this->fileList = array_filter($this->getFileList(), function($str) { |
24
|
|
|
return substr($str, -3) === 'png'; |
25
|
|
|
}); |
26
|
|
|
$this->less = ''; |
27
|
|
|
} |
28
|
|
|
|
29
|
|
|
public function generate() : void { |
30
|
|
|
$this->generateSpritesheet(); |
31
|
|
|
if($this->updateLESS) { $this->modifyIconLESS(); } |
32
|
|
|
} |
33
|
|
|
|
34
|
|
|
private function generateSpritesheet() : void { |
35
|
|
|
$width = (count($this->fileList) * (16 + /* padding */ 2)) - 2; |
36
|
|
|
|
37
|
|
|
$sheetImage = imagecreatetruecolor($width, 16); |
38
|
|
|
imagealphablending($sheetImage, FALSE); |
39
|
|
|
imagesavealpha($sheetImage, TRUE); |
40
|
|
|
|
41
|
|
|
imagefill($sheetImage,0,0,0x7fff0000); |
42
|
|
|
|
43
|
|
|
$x = 0; |
44
|
|
|
foreach ($this->fileList as $filename) { |
45
|
|
|
$iconImage = imagecreatefrompng("{$this->iconFolder}/{$filename}"); |
46
|
|
|
imagealphablending($iconImage, TRUE); |
47
|
|
|
|
48
|
|
|
$dst_x = ((16 + 2) * $x); |
49
|
|
|
imagecopyresampled($sheetImage, $iconImage, $dst_x, 0, 0, 0, 16, 16, 16, 16); |
50
|
|
|
|
51
|
|
|
$this->generateLESS($filename, $dst_x); |
52
|
|
|
$x++; |
53
|
|
|
} |
54
|
|
|
|
55
|
|
|
imagepng($sheetImage, ASSET_FOLDER . "/img/{$this->type}s.png"); |
56
|
|
|
say('Updated spritesheet!'); |
57
|
|
|
} |
58
|
|
|
private function generateLESS(string $filename, int $dst_x) : void { |
59
|
|
|
$parts = pathinfo($filename); |
60
|
|
|
|
61
|
|
|
$this->less .= "\n". |
62
|
|
|
" &.sprite-{$parts['filename']} {\n". |
63
|
|
|
" .stitches-sprite(-{$dst_x}px);\n". |
64
|
|
|
" }\n"; |
65
|
|
|
} |
66
|
|
|
private function modifyIconLESS() : void { |
67
|
|
|
$newIconLESS = trim($this->less); |
68
|
|
|
|
69
|
|
|
$icons_file = ASSET_FOLDER.'/less/modules/icons.less'; |
70
|
|
|
$oldLESS = file_get_contents($icons_file); |
71
|
|
|
if(preg_match('/\.sprite-'.$this->type.' {\n\t\@cache-version: (\d+);/s', $oldLESS, $cvMatches)) { |
72
|
|
|
$cacheVersion = ((int) $cvMatches[1]) + 1; |
73
|
|
|
|
74
|
|
|
$newLESS = preg_replace('/\.sprite-'.$this->type.'.*end sprite-'.$this->type.'/s', |
75
|
|
|
''. |
76
|
|
|
".sprite-{$this->type} {\n". |
77
|
|
|
" @cache-version: {$cacheVersion};\n". |
78
|
|
|
" .sprite();\n". |
79
|
|
|
" background: url('../../img/{$this->type}s.@{cache-version}.png') no-repeat;\n\n". |
80
|
|
|
" {$newIconLESS}\n". |
81
|
|
|
"} //end sprite-{$this->type}",$oldLESS); |
82
|
|
|
|
83
|
|
|
file_put_contents($icons_file, $newLESS); |
84
|
|
|
say('Updated LESS!'); |
85
|
|
|
} else { |
86
|
|
|
die("Can't find cache-version?"); |
87
|
|
|
} |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
private function getFileList() : array { |
91
|
|
|
return array_diff(scandir($this->iconFolder, SCANDIR_SORT_ASCENDING), array('..', '.')); |
92
|
|
|
} |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
/** @noinspection PhpFunctionNamingConventionInspection */ |
96
|
|
|
function say(string $text = '') { print "{$text}\n"; } |
|
|
|
|
97
|
|
|
|
This check looks for functions that have already been defined in other files.
Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the
@ignore
annotation.See also the PhpDoc documentation for @ignore.