public function render(Job $job) { $format = $this->configuration->getString('format', 'png'); $defaultColor = $format == 'png' ? 0x0 : 0xffffffff; $backgroundColor = $this->configuration->getColor('background', $defaultColor); foreach ($job->spritesheets as $spritesheet) { /** @var Spritesheet $spritesheet */ $image = ImageTools::createImage($spritesheet->width, $spritesheet->height, $backgroundColor); foreach ($spritesheet->sprites as $sprite) { $repeatY = $sprite->repeatY; while ($repeatY--) { $repeatX = $sprite->repeatX; while ($repeatX--) { imagecopy($image, $sprite->image, $sprite->spriteX + $sprite->paddingLeft + $repeatX * $sprite->width, $sprite->spriteY + $sprite->paddingTop + $repeatY * $sprite->height, 0, 0, $sprite->width, $sprite->height); } } } $output = $this->mosaic->getPath($this->configuration->getString('outputFolder', Configuration::VALUE_REQUIRED)); $encodedSpritesheetPath = Tools::encodeFilePath($output . '/' . $spritesheet->name . '.' . $format); FileTools::createDirectory(dirname($encodedSpritesheetPath)); if ($format == 'png') { imagepng($image, $encodedSpritesheetPath, 9, E_ALL); } elseif ($format == 'jpg') { imagejpeg($image, $encodedSpritesheetPath, $this->configuration->getInt('quality', 90)); } imagedestroy($image); $encodedSpritesheetPath = realpath($encodedSpritesheetPath); if (!$encodedSpritesheetPath) { throw new \Exception('Could not verify rendered spritesheet path.'); } // Normalize output path $spritesheet->path = Tools::decodeFilePath($encodedSpritesheetPath); } }
public function createStorage($id) { $id = str_replace('\\', '/', $id); $path = $this->directory . $id . '/'; FileTools::createDirectory($path); return $path; }
public function onRendered(Event $e) { $json = ['images' => [], 'frames' => [], 'animations' => []]; if ($framerate = $this->configuration->getFloat('framerate')) { $json['framerate'] = $framerate; } $spritesheetIndex = -1; $spriteIndex = -1; foreach ($this->job->spritesheets as $spritesheet) { $spritesheetIndex++; $animations = []; // $animationPrefix = $this->_configuration->getString('animationPrefix', $this->_job->configuration->getString('name')); $json['images'][] = $this->configuration->getString('spritesheetFolder', Configuration::VALUE_REQUIRED) . basename($spritesheet->path); foreach ($spritesheet->sprites as $sprite) { $spriteIndex++; $configuration = $this->getSpriteConfiguration($sprite); if (preg_match('!(.+)\\{animation(@([0-9.]+))?(@([^@\\}]+))?}!', $sprite->originalName, $animationData)) { if (!isset($animations[$animationData[1]])) { $animations[$animationData[1]] = ['speed' => isset($animationData[3]) ? floatval($animationData[3]) : null, 'sprites' => [$spriteIndex], 'next' => isset($animationData[5]) ? $animationData[5] : null]; if (!$animations[$animationData[1]]['speed']) { $animations[$animationData[1]]['speed'] = $configuration->getFloat('speed', 0); } } else { $animations[$animationData[1]]['sprites'][] = $spriteIndex; } } $frameConfiguration = [$sprite->spriteX, $sprite->spriteY, $sprite->spriteWidth, $sprite->spriteHeight, $spritesheetIndex]; if ($configuration->getBool('center')) { $frameConfiguration[] = round($sprite->spriteWidth / 2); $frameConfiguration[] = round($sprite->spriteHeight / 2); } $json['frames'][] = $frameConfiguration; $json['animations'][$sprite->name] = [$spriteIndex]; } foreach ($animations as $name => $animation) { $ani = ['frames' => $animation['sprites']]; if ($animation['speed']) { $ani['speed'] = $animation['speed']; } if ($next = $animation['next']) { if ($next == 'loop') { $next = $name; } $ani['next'] = $next; } $json['animations'][$name] = $ani; } } $outputFolder = $this->mosaic->getPath($this->configuration->getString('outputFolder', Configuration::VALUE_REQUIRED)); $outputFileBasename = $this->configuration->getString('outputFile', $this->job->configuration->getString('name', Configuration::VALUE_REQUIRED)); $outputPath = $outputFolder . $outputFileBasename . '.json'; $jsonFiles = [$outputPath => $json]; foreach ($jsonFiles as $path => $content) { $path = Tools::encodeFilePath($path); FileTools::createDirectory(dirname($path)); file_put_contents($path, json_encode($content, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); } }
public function createFromContent($content, $expirationDate = 86400, $id = null, $metadata = null, $originalFilename = null) { if ($this->filesExpire) { $t = time(); if ($expirationDate < 1000000000) { $expirationDate += $t; } } else { $t = $expirationDate = 0; } $f = new TemporaryFile(); $f->storeMetadata = $this->storeMetadata; if ($id !== null) { $f->id = $id; $f->path = $this->getPathById($id, false); } else { do { $f->id = $this->idPrefix . StringTools::random($this->idLength, $this->idChars) . $this->idSuffix; $f->path = $this->getPathById($f->id, false); $exists = is_file($f->path) && (!$this->filesExpire || filemtime($f->path) > $t); } while ($exists); } $f->originalFilename = $originalFilename; $f->expires = $expirationDate; $f->url = $this->baseUrl . $f->id . $this->extension; $f->metadata = $metadata; if ($this->pathChunkSize) { $dir = dirname($f->path); if (!is_dir($dir)) { FileTools::createDirectory($dir); } } file_put_contents($f->path, $content); $f->save(); return $f; }
public function onRendered(Event $e) { $scssContent = ''; $scssVariablesContent = ''; foreach ($this->job->spritesheets as $spritesheet) { $spritesheetName = $spritesheet->name; $spritePrefix = $this->configuration->getString('classPrefix', $this->job->configuration->getString('name') . '-'); $scssPrefix = $this->configuration->getString('scssPrefix', $spritePrefix); $image = $this->configuration->getString('spritesheetFolder') . basename($spritesheet->path); if ($this->configuration->getBool('refreshCache')) { $image .= '?_' . sha1_file($spritesheet->path); } $retinaFactor = $this->configuration->getInt('retinaFactor', 1); $retinaThreshold = $retinaFactor - 0.75; $retinaThresholdPx = round($retinaThreshold * 96); $retinaEnabled = $retinaFactor > 1; $indent = str_repeat(' ', 4); $scssContent .= <<<SCSS @mixin spritesheet-{$spritesheetName}() { display: inline-block; overflow: hidden; background-repeat: no-repeat; background-image: url({$image}); SCSS; $mixinsContent = ''; if ($retinaEnabled) { $scssContent .= $indent . 'background-size: ' . self::cssFormatPx($spritesheet->width / $retinaFactor) . ' auto;' . chr(10); } else { $scssContent .= $indent . 'background-size: auto;' . chr(10); } $scssContent .= '}' . chr(10) . chr(10); if ($retinaEnabled) { $scssContent .= <<<SCSS @media (min-device-pixel-ratio: {$retinaThreshold}), (min-resolution: {$retinaThresholdPx}dpi) { SCSS; } foreach ($spritesheet->sprites as $sprite) { $configuration = $this->getSpriteConfiguration($sprite); $spriteName = $spritePrefix . $sprite->name; $scssName = $scssPrefix . $sprite->name; $realSpriteWidth = $sprite->spriteWidth; $realSpriteHeight = $sprite->spriteHeight; $realSpriteX = $sprite->spriteX; $realSpriteY = $sprite->spriteY; if ($retinaEnabled) { $realSpriteWidth = $realSpriteWidth / $retinaFactor; $realSpriteHeight = $realSpriteHeight / $retinaFactor; $realSpriteX = $realSpriteX / $retinaFactor; $realSpriteY = $realSpriteY / $retinaFactor; } $spriteContent = $indent . $indent . '@include spritesheet-' . $spritesheetName . '();' . chr(10); if ($configuration->getBool('center')) { $spriteContent .= $indent . $indent . 'margin-left: ' . self::cssFormatPx(-$realSpriteWidth / $retinaFactor) . ';' . chr(10); $spriteContent .= $indent . $indent . 'margin-top: ' . self::cssFormatPx(-$realSpriteHeight / $retinaFactor) . ';' . chr(10); } $spriteContent .= $indent . $indent . 'width: ' . self::cssFormatPx($realSpriteWidth) . ';' . chr(10); $spriteContent .= $indent . $indent . 'height: ' . self::cssFormatPx($realSpriteHeight) . ';' . chr(10); $spriteContent .= $indent . $indent . 'background-position: ' . self::cssFormatPx(-$realSpriteX) . ' ' . self::cssFormatPx(-$realSpriteY) . ';' . chr(10); foreach ($configuration->getNode('styles') as $styleName => $styleValue) { $spriteContent .= $indent . $indent . $styleName . ': ' . $styleValue . ';' . chr(10); } if ($configuration->getBool('createClass', true)) { // Write class $scssContent .= $indent . '.' . $spriteName . ' {' . chr(10) . $spriteContent . $indent . '}' . chr(10) . chr(10); } if ($configuration->getBool('createMixin', true)) { // Write mixin $mixinsContent .= chr(10) . $indent . '@mixin ' . $scssName . ' {' . chr(10) . $spriteContent . $indent . '}' . chr(10); } if ($configuration->getBool('createVariables', true)) { $scssVariablesContent .= '$' . $scssName . '-width: ' . self::cssFormatPx($sprite->spriteWidth) . ';' . chr(10); $scssVariablesContent .= '$' . $scssName . '-height: ' . self::cssFormatPx($sprite->spriteHeight) . ';' . chr(10); $scssVariablesContent .= '$' . $scssName . '-x: ' . self::cssFormatPx(-$sprite->spriteX) . ';' . chr(10); $scssVariablesContent .= '$' . $scssName . '-y: ' . self::cssFormatPx(-$sprite->spriteY) . ';' . chr(10); $scssVariablesContent .= "\${$scssName}-image: '{$image}';" . chr(10); $scssVariablesContent .= "\${$scssName}-retina-factor: {$retinaFactor};" . chr(10); $scssVariablesContent .= chr(10); } } if ($retinaEnabled) { $scssContent .= ' }' . chr(10); } if ($mixinsContent) { $scssContent .= chr(10) . $mixinsContent; } } $outputFolder = $this->mosaic->getPath($this->configuration->getString('outputFolder')); $outputFileBasename = $this->configuration->getString('outputFile', '_' . $this->job->configuration->getString('name')); $outputPath = $outputFolder . $outputFileBasename . '.scss'; $outputPathVariables = $outputFolder . $outputFileBasename . '_variables.scss'; $scssFiles = [$outputPath => $scssContent, $outputPathVariables => $scssVariablesContent]; foreach ($scssFiles as $path => $content) { $path = Tools::encodeFilePath($path); FileTools::createDirectory(dirname($path)); file_put_contents($path, $content); } }