【问题标题】:How to convert integer to hex in SASS如何在SASS中将整数转换为十六进制
【发布时间】:2013-04-04 08:59:22
【问题描述】:

代替 Chris Eppstein 提到的作为 SASS 正在进行的工作的 Map data structure 之类的东西,我正在尝试实现类似的东西 - 将字符串映射到相应的十六进制值,该值将用于指定 unicode CSS content 属性的字符。 (我正在尝试重构一些字体图标 SASS 代码。)

目前我有一些基本的东西,例如:

/*icon1  -->  \F000
  icon2  -->  \F001
  icon3  -->  \F002*/

@function u-char($name) {
    @if $name == icon1 {
        @return "000";
    } @else if $name == icon2 {
        @return "001";
    } @else if $name == icon3 {
        @return "001";
    }
}

@mixin icon-class($name) {
    ...
    content: "\f#{u-char($name)}";
    ...
}

但我实际上是在尝试映射大量字符,所以这种方法很费力。我希望能够做类似的事情:

@function u-char($name) {
    $i: 0;
    $itemList: item1, item2, item3;

    @each $currItem in $itemList {
        @if $name == item1 {
            @return i-to-hex-str($i);
        }
        $i: $i + 1;
    }
}

在 SASS 中有什么可以做整数到十六进制字符串的转换吗?还有另一种优雅的方法吗?

【问题讨论】:

    标签: css sass hex string-conversion


    【解决方案1】:

    我会这样做:

    $icons: "000", "001", "002";
    
    @function icon($i) {
      @return "\F#{nth($icons, 1)}";
    }
    
    h1::before {
      content: icon(1);
    }
    

    编辑:

    如果您想将单词与值相关联,请尝试使用列表列表并遍历它们。我不会假装这是非常有效的,但它确实有效。如果 Sass 有哈希就好了。

    $icons: '000' calendar, '001' inbox, '002' home
    
    @function icon($call)
      @for $i from 1 through length($icons)
        @if $call == nth(nth($icons, $i), 2)
          @return "\F#{nth(nth($icons, $i), 1)}"
    
    h1::before
      content: icon(calendar)
    

    【讨论】:

    • 我试图实现的是使 mixin 更直观,通过一个 mixin 可以简单地使用名称指定图标。例如。 font-icon(copyright); 目前,mixin 要求您指定名称和相应的 unicode 字符,例如:font-icon(calendar, "008");
    • 谢谢 - 考虑到限制(即没有地图/哈希)的出色解决方法。我喜欢!
    • 我来到这里是因为我在 SASS 中搜索将整数转换为十六进制,而这个接受的答案没有回答!
    【解决方案2】:

    要回答您帖子中的最后一个问题, “有什么东西可以在 SASS 中进行整数到十六进制字符串的转换吗?”。嗯……不是内置的,但我认为这很清楚,而且代码行数相对较少:

    /** Returns an at least one byte hex value */
    @function dec-to-hex($d) {
        $hexVals: "A" "B" "C" "D" "E" "F";
        $base: 16;
        $quotient: $d;
        $result: "";
        @if $d == 0 {
            $result: "00";
        }
        @while $quotient != 0 {
            $mod: $quotient % $base;
            $quotient: floor($quotient / $base);
            @if $mod > 9 {
                $mod: nth($hexVals, $mod - 9);
            }
            @if $d < $base {
                $result: "0" + $mod;
            } @else {
                $result: $mod + $result;
            }
        }
        @return $result;
    }
    

    这不会在字符串前面添加十六进制限定符(例如“0x”或“#”),但您可以将其硬编码到最后一行(@return "#" + $result;),或者就地应用它当你调用函数时。

    【讨论】:

    • 感谢这个功能。令人惊讶的是,SASS 还没有内置这样的东西。
    • 此答案已在 SASS 存储库的 this feauture request 中引用。
    【解决方案3】:

    您帖子中最后一个问题的另一个实现:“有什么东西可以在 SASS 中进行整数到十六进制字符串的转换吗?”这是一个最短的版本(不适用于最旧的版本,因为可能缺少 str-slice)。

    @function decToHex($dec) {
        $hex: "0123456789ABCDEF";
        $first: (($dec - $dec % 16)/16)+1;
        $second: ($dec % 16)+1;
        @return str-slice($hex, $first, $first) + str-slice($hex, $second, $second)
    }
    

    【讨论】:

    【解决方案4】:

    前面的答案对我们不起作用,所以这里有两个快速函数,用于将整数转换为多个不同的基数,包括十六进制:

    @function decimal-to-base($decimal, $to_base, $chars: '0123456789abcdefghijklmnopqrstuvwxyz')
      @if type-of($decimal) != 'number'
        @error '$decimal must be an integer.'
      @if type-of($to_base) != 'number'
        @error '$to-base must be an integer.'
      @if type-of($chars) != 'string'
        @error '$chars must be a string.'
      @if $to_base < 2
        @error '$to-base must be larger than 1.'
      @if $to_base > str-length($chars)
        @error 'Length of $chars must be equal or larger than $to-base.'
      @return _decimal-to-base($decimal, $to_base, $chars)
    
    @function _decimal-to-base($decimal, $to_base, $chars, $_accum: '')
      @if $decimal <= 0
        @return if($_accum != '', $_accum, '0')
      $remainder: $decimal % $to_base
      $char: str-slice($chars, $remainder + 1, $remainder + 1)
      $remaining_decimal: ($decimal - $remainder) / $to_base
      @return _decimal-to-base($remaining_decimal, $to_base, $chars, $char + $_accum)
    

    如果您不关心错误处理,您可以跳过冗长的第一个函数(它实际上只验证参数并设置默认字符)并复制第二个函数。

    另外,请注意这是用 SASS 编写的,而不是 SCSS。对于 SCSS 支持,您需要添加一些大括号和分号。

    示例:

    • 十进制转十六进制:
      decimal-to-base(15731618, 16) // "f00ba2".

    • 十进制转二进制:
      decimal-to-base(34, 2) // "100010".

    • 查询字符串的时间戳:
      decimal-to-base(1547598870, 2) // "pleb0y".

    • 绝对不是摩尔斯电码:
      decimal-to-base(34, 2, '-.') // "-...-.".

    • 过度设计的整数到字符串:
      decimal-to-base(123456, 10) // "123456".

    已知警告:(因为这是一个肮脏的实现)

    • 输入的小数必须是整数 >= 0。
    • 最小基数为 2。
    • 您需要小心处理大整数。

    【讨论】:

      【解决方案5】:

      我在十六进制和十进制之间来回改变数字的函数是

      $hex-chars: "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F";
      
      @function dec-to-hex($d) {
          $result: "";
          $rest: $d;
          @while $rest > 0 {
              $result: nth($hex-chars, $rest % 16 + 1) + $result;
              $rest: floor($rest / 16);
          }
          @return $result;
      }
      
      @function pow($number, $exponent) {
          $value: 1;
          @if $exponent > 0 {
              @for $i from 1 through $exponent {
                  $value: $value * $number;
              }
          }
          @return $value;
      }
      
      @function hex-to-dec($d) {
          $result: 0;
          $number: inspect($d);
          $power: 0;
          @for $index from str-length($number) through 1 {
              $digit: str-slice($number, $index, $index);
              $value: index($hex-chars, $digit) - 1;
              $result: $result + ($value * pow(16, $power) );
              $power: $power + 1;
          }
          @return $result;
      }
      

      十进制数视为Number,十六进制视为String

      【讨论】:

        猜你喜欢
        • 2010-10-16
        • 2014-04-16
        • 2016-12-04
        • 1970-01-01
        • 2015-04-04
        • 1970-01-01
        相关资源
        最近更新 更多