【问题标题】:Invert all colors with LESS用LESS反转所有颜色
【发布时间】:2014-04-21 17:06:18
【问题描述】:

我有一个我很满意的样式表,我使用以下代码对其进行编译。效果很好。

function css($inputFile, $outputFile)
{
    $cacheFile = $inputFile.".cache";

    $cache = file_exists($cacheFile)
        ? unserialize(file_get_contents($cacheFile))
        : $inputFile;

    $less = new lessc;
    $less->setFormatter("compressed");
    $newCache = $less->cachedCompile($cache);

    if ( ! file_exists($outputFile) || ! is_array($cache) || $newCache["updated"] > $cache["updated"])
    {
        file_put_contents($cacheFile, serialize($newCache));
        file_put_contents($outputFile, $newCache['compiled']);
    }
}

我有一种简单的方法来生成一个样式表版本,其中所有定义的颜色都被反转了?你能用 LESS 编译器做一些花哨的事情吗?

我对此感到好奇的原因是,当我反转它的屏幕截图时,该网站看起来不错,而且如果有一种廉价的方法来生成当前黑暗的网站的黑暗版本,那就太酷了开灯。

有什么聪明的想法吗?

【问题讨论】:

  • 你必须知道你的颜色变量,然后重新定义它们,将色调旋转 180 度。
  • @helderdarocha 是的,这似乎很可行。挑战在于以某种方式自动完成。最好不要编辑现有的less 文件。
  • 如果你所有的颜色都在变量中,你可以使用less.modifyVars()来替换它们。您也可以使用 PHP 生成反转颜色,只需将变量替换为字符串即可。
  • 变量中只有少数颜色,其他的都是根据这些计算出来的。使用深色时效果很好,但如果我使用浅色,基本上一切都是白色的:)

标签: php css colors less


【解决方案1】:

您可以简单地扩展 lessc 类并修改编译器以使所有颜色都反转。

我们添加一个扩展类lessc的新类(例如lessc_invert),现在我们只需要:

  • 定义一个简单的反转颜色函数:invert_color($c){ return abs($c - 255); }
  • 并从lessc 覆盖protected function compileValue($value),其中我们:
    • 'raw_color' 类型的值强制转换为'color'
    • 'keyword' 类型的值强制转换为'color'(如果在$cssColors 数组中找到)
    • 然后使用invert_color() 函数反转颜色的$r, $g, $b 分量。

类似这样的:

class lessc_invert extends lessc {
  protected function invert_color($c){
    return abs($c - 255);
  }
  protected function compileValue($value) {
    switch ($value[0]) {
    case 'list':
      return implode($value[1], array_map(array($this, 'compileValue'), $value[2]));
    case 'raw_color':
      return $this->compileValue($this->coerceColor($value));
    case 'keyword':
      if (isset(self::$cssColors[$value[1]])) {
        return $this->compileValue($this->coerceColor($value));
      }
      return $value[1];
    case 'number':
      list(, $num, $unit) = $value;
      if ($this->numberPrecision !== null) {
        $num = round($num, $this->numberPrecision);
      }
      return $num . $unit;
        case 'string':
      list(, $delim, $content) = $value;
      foreach ($content as &$part) {
        if (is_array($part)) {
          $part = $this->compileValue($part);
        }
      }
      return $delim . implode($content) . $delim;
    case 'color':
      list(, $r, $g, $b) = $value;
      $r = $this->invert_color(round($r));
      $g = $this->invert_color(round($g));
      $b = $this->invert_color(round($b));
      if (count($value) == 5 && $value[4] != 1) {
        return 'rgba('.$r.','.$g.','.$b.','.$value[4].')';
      }
      $h = sprintf("#%02x%02x%02x", $r, $g, $b);
      if (!empty($this->formatter->compressColors)) {
        if ($h[1] === $h[2] && $h[3] === $h[4] && $h[5] === $h[6]) {
          $h = '#' . $h[1] . $h[3] . $h[5];
        }
      }      
      return $h;
    case 'function':
      list(, $name, $args) = $value;
      return $name.'('.$this->compileValue($args).')';
    default:
      $this->throwError("unknown value type: $value[0]");
    }
  }
}

现在我们可以使用我们的新类lessc_invert,而不是实例化lessc,如下所示:

$less = new lessc_invert;
$less->setFormatter("compressed");
$newCache = $less->cachedCompile($cache);

这应该可以解决问题 =)


例如:

echo $less->compile("a { color: blue; }");

现在返回:

a{color:#ff0;}

【讨论】:

  • 看起来确实很有希望!今天晚些时候会试一试:)
  • 这完全有效!惊人的。知道如何不反转阴影吗?
  • 要执行特定于属性的操作,您还需要包含compileProp() 方法,这里我创建了a gist (https://gist.github.com/mturjak/9684082),我在invert_color() 方法中添加了一个开关$f 并更改了此开关基于 compileProp()$this->f = preg_match('/shadow/',$name) ? 0 : 1; 中的属性 $name,因此如果属性是阴影(框阴影或文本阴影),颜色不会反转,但当然您可以根据需要进行修改.
猜你喜欢
  • 1970-01-01
  • 2011-06-13
  • 2012-12-13
  • 1970-01-01
  • 1970-01-01
  • 2011-06-08
  • 2021-09-23
  • 2013-07-24
  • 2011-06-05
相关资源
最近更新 更多