Skip to content

Instantly share code, notes, and snippets.

@DASPRiD
Created November 19, 2011 17:46
Show Gist options
  • Save DASPRiD/1379119 to your computer and use it in GitHub Desktop.
Save DASPRiD/1379119 to your computer and use it in GitHub Desktop.
<?php
class CssCompiler
{
protected $gradients;
public function compile($input, $output, $gradients)
{
$this->gradients = $gradients;
$content = file_get_contents($input);
$compiled = preg_replace('([\-.#_a-zA-Z0-9-:\[\]>, \t\r\n]+\{[^}]+\})se', "\$this->expandVendorPrefixes('\\0')", $content);
echo $compiled;
file_put_contents($output, $compiled);
}
protected function expandVendorPrefixes($rule)
{
$expanded = $rule;
$expanded = preg_replace('([ \t]*background\s*:[^;]+;[ \t]*(\r?\n))se', "\$this->expandGradients('\\0')", $expanded);
$expanded = preg_replace('([ \t]*box-shadow*:[^;]+;[ \t]*(\r?\n))se', "\$this->expandBoxShadow('\\0')", $expanded);
return $expanded;
}
protected function expandBoxShadow($shadow)
{
$result = '';
foreach (array('moz', 'webkit') as $prefix) {
$result .= str_replace('box-shadow', '-' . $prefix . '-box-shadow', $shadow);
}
$result .= $shadow;
return $result;
}
protected function expandGradients($background)
{
if (strpos($background, 'linear-gradient') === false) {
return $background;
}
$result = preg_replace('(linear-gradient\((.*?)\)([ \t\r\n]*[,;]))se', "\$this->createSvgGradient('\\1', '\\2')", $background);
foreach (array('moz', 'webkit', 'o', 'ms') as $prefix) {
$result .= str_replace('linear-gradient', '-' . $prefix . '-linear-gradient', $background);
}
$result .= $background;
return $result;
}
protected function createSvgGradient($def, $end)
{
list($direction, $values) = explode(',', $def, 2);
preg_match_all('((#([a-fA-F0-9]{6})|rgba\s*\(\s*(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*\d*(.\d+)?\s*)\))\s*(\d+%|\d+px))', $values, $matches, PREG_SET_ORDER);
$values = array();
foreach ($matches as $match) {
if (!empty($match[2])) {
$color = hexdec($match[2]);
$values[] = array(0xff & ($color >> 0x10), 0xff & ($color >> 0x8), 0xff & $color, 1.0, $match[5]);
} else {
$data = explode(',', $match[3]);
$values[] = array((int) $data[0], (int) $data[1], (int) $data[2], (float) $data['3'], $match[5]);
}
}
$hash = sha1($direction . ':' . serialize($values));
switch (strtolower(trim($direction))) {
case 'top':
$svgDirection = 'x1="0%" y1="0%" x2="0%" y2="100%"';
break;
case 'left':
$svgDirection = 'x1="0%" y1="0%" x2="100%" y2="0%"';
break;
case 'bottom':
$svgDirection = 'x1="0%" y1="100%" x2="0%" y2="0%"';
break;
case 'right':
$svgDirection = 'x1="100%" y1="0%" x2="0%" y2="0%"';
break;
}
$svgStops = '';
foreach ($values as $value) {
$color = str_pad(dechex($value[0]), 2, '0', STR_PAD_LEFT)
. str_pad(dechex($value[1]), 2, '0', STR_PAD_LEFT)
. str_pad(dechex($value[2]), 2, '0', STR_PAD_LEFT);
$svgStops .= '<stop offset="' . $value[4] . '" style="stop-color: #' . $color . '; stop-opacity: ' . $value[3] . ';"/>';
}
$svg = '
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100" height="100" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="gradient-box" ' . $svgDirection . '>
' . $svgStops . '
</linearGradient>
</defs>
<rect x="0" y="0" width="100" height="100" style="fill:url(#gradient-box)" />
</svg>
';
$svg = trim(preg_replace('(>\s+<)', '><', $svg));
file_put_contents($this->gradients . '/' . $hash . '.svg', $svg);
return 'url(gradients/' . $hash . '.svg)' . $end;
}
}
header('Content-Type: text/css');
$compiler = new CssCompiler();
$compiler->compile(
dirname(__FILE__) . '/screen.css',
dirname(__FILE__) . '/screen-all.css',
dirname(__FILE__) . '/gradients'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment