Пример #1
0
 /**
  * Creates a SVG gradient
  *
  * @param Node $direction
  * @param Node ...$stop1
  * @return UrlNode
  * @throws CompilerException If the arguments are invalid
  */
 public function svggradient(Node $direction)
 {
     $numArgs = func_num_args();
     $arguments = func_get_args();
     if ($numArgs === 2) {
         // a list of colors
         if (is_array($arguments[1]->value) && count($arguments[1]->value) < 2) {
             throw new CompilerException('svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position]');
         }
         $stops = $arguments[1]->value;
     } elseif ($numArgs < 3) {
         throw new CompilerException('svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position]');
     } else {
         $stops = array_slice($arguments, 1);
     }
     $gradientType = 'linear';
     $rectangleDimension = 'x="0" y="0" width="1" height="1"';
     $renderEnv = new Context(['compress' => false]);
     $directionValue = $direction->toCSS($renderEnv);
     switch ($directionValue) {
         case 'to bottom':
             $gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"';
             break;
         case 'to right':
             $gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="0%"';
             break;
         case 'to bottom right':
             $gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="100%"';
             break;
         case 'to top right':
             $gradientDirectionSvg = 'x1="0%" y1="100%" x2="100%" y2="0%"';
             break;
         case 'ellipse':
         case 'ellipse at center':
             $gradientType = 'radial';
             $gradientDirectionSvg = 'cx="50%" cy="50%" r="75%"';
             $rectangleDimension = 'x="-50" y="-50" width="101" height="101"';
             break;
         default:
             throw new CompilerException("svg-gradient direction must be 'to bottom', 'to right', 'to bottom right', 'to top right' or 'ellipse at center'");
     }
     $returner = '<?xml version="1.0" ?>' . '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%" viewBox="0 0 1 1" preserveAspectRatio="none">' . '<' . $gradientType . 'Gradient id="gradient" gradientUnits="userSpaceOnUse" ' . $gradientDirectionSvg . '>';
     for ($i = 0; $i < count($stops); $i++) {
         if ($stops[$i] instanceof ExpressionNode) {
             $color = $stops[$i]->value[0];
             $position = $stops[$i]->value[1];
         } else {
             $color = $stops[$i];
             $position = null;
         }
         if (!$color instanceof ColorNode || !(($i === 0 || $i + 1 === count($stops)) && $position === null) && !$position instanceof DimensionNode) {
             throw new CompilerException('svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position] or direction, color list');
         }
         if ($position) {
             $positionValue = $position->toCSS($renderEnv);
         } elseif ($i === 0) {
             $positionValue = '0%';
         } else {
             $positionValue = '100%';
         }
         $colorValue = $color->getColor()->toRGB();
         $alpha = $color->getAlpha(true);
         $returner .= '<stop offset="' . $positionValue . '" stop-color="' . $colorValue . '"' . ($alpha < 1 ? ' stop-opacity="' . $alpha . '"' : '') . '/>';
     }
     $returner .= '</' . $gradientType . 'Gradient><rect ' . $rectangleDimension . ' fill="url(#gradient)" /></svg>';
     $returner = Util::encodeURIComponent($returner);
     $returner = 'data:image/svg+xml,' . $returner;
     return new UrlNode(new QuotedNode("'" . $returner . "'", $returner, false));
 }
Пример #2
0
 /**
  * Generates the CSS.
  *
  * @param Context $context
  *
  * @return string
  */
 public function generateCSS(Context $context)
 {
     $output = new MappedOutput($this->contentsMap, $this);
     // catch the output
     $this->root->generateCSS($context, $output);
     // prepare sources
     foreach ($this->contentsMap as $filename => $contents) {
         // match md5 hash in square brackets _[#HASH#]_
         // see ILess\Parser\Core::parseString()
         if (preg_match('/(\\[__[0-9a-f]{32}__\\])+$/', $filename)) {
             $filename = substr($filename, 0, -38);
         }
         $this->sources[$this->normalizeFilename($filename)] = $contents;
     }
     $sourceMapUrl = null;
     if ($url = $this->getOption('url')) {
         $sourceMapUrl = $url;
     } elseif ($path = $this->getOption('filename')) {
         $sourceMapUrl = $this->normalizeFilename($path);
         // naming conventions, make it foobar.css.map
         if (!preg_match('/\\.map$/', $sourceMapUrl)) {
             $sourceMapUrl = sprintf('%s.map', $sourceMapUrl);
         }
     }
     $sourceMapContent = $this->generateJson();
     // write map to a file
     if ($file = $this->getOption('write_to')) {
         $this->saveMap($file, $sourceMapContent);
     } else {
         $sourceMap = 'data:application/json;';
         if ($this->getOption('inline_encode_base64')) {
             $sourceMap .= 'base64,';
             $sourceMapContent = base64_encode($sourceMapContent);
         } else {
             $sourceMapContent = Util::encodeURIComponent($sourceMapContent);
         }
         $sourceMapUrl = $sourceMap . $sourceMapContent;
     }
     if ($sourceMapUrl) {
         $output->add(sprintf('/*# sourceMappingURL=%s */', $sourceMapUrl));
     }
     return $output->toString();
 }