예제 #1
0
 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);
     }
 }
예제 #2
0
 public function createStorage($id)
 {
     $id = str_replace('\\', '/', $id);
     $path = $this->directory . $id . '/';
     FileTools::createDirectory($path);
     return $path;
 }
예제 #3
0
 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));
     }
 }
예제 #4
0
 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;
 }
예제 #5
0
    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);
        }
    }