create.scss 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /* #ifdef VUE3 */
  2. @use "sass:math";
  3. /* #endif */
  4. $use-css-var: false !default;
  5. @function div($dividend, $divisor) {
  6. /* #ifdef VUE3 */
  7. @return math.div($dividend, $divisor);
  8. /* #endif */
  9. /* #ifndef VUE3 */
  10. @return $dividend / $divisor;
  11. /* #endif */
  12. }
  13. @function rpx-to-px($value) {
  14. // 递归处理列表
  15. @if type-of($value) == list {
  16. $new-list: ();
  17. @each $item in $value {
  18. $new-list: append($new-list, rpx-to-px($item));
  19. }
  20. @return $new-list;
  21. }
  22. // 处理数字类型 - 带 rpx 单位
  23. @if type-of($value) == number and unit($value) == 'rpx' {
  24. // 安全处理单位转换
  25. @return calc-strip-unit($value) * 0.5 * 1px;
  26. }
  27. // 处理字符串类型
  28. @if type-of($value) == string {
  29. $string: $value;
  30. $rpx-index: str-index($string, 'rpx');
  31. // 如果字符串以数字开头并以 rpx 结尾,转换为数值
  32. @if $rpx-index == (str-length($string) - 2) {
  33. $num-str: str-slice($string, 1, $rpx-index - 1);
  34. $number: to-number($num-str);
  35. @if type-of($number) == number {
  36. @return $number * 0.5 * 1px;
  37. }
  38. }
  39. // 字符串中可能包含多个 rpx 值
  40. @if $rpx-index {
  41. $result: '';
  42. @while $rpx-index {
  43. // 找到数字部分起点
  44. $num-end: $rpx-index - 1;
  45. $num-start: $num-end;
  46. @while $num-start > 0 and is-numeric-char(str-slice($string, $num-start, $num-start)) {
  47. $num-start: $num-start - 1;
  48. }
  49. // 提取数字部分
  50. $num-str: str-slice($string, $num-start + 1, $num-end);
  51. $number: to-number($num-str);
  52. // 转换为 px 数值
  53. $px-value: $number * 0.5 * 1px;
  54. // 构建结果字符串
  55. $result: $result + str-slice($string, 1, $num_start) + '#{$px_value}';
  56. // 更新剩余字符串
  57. $string: str-slice($string, $rpx-index + 3);
  58. $rpx-index: str-index($string, 'rpx');
  59. }
  60. @return #{$result + $string};
  61. }
  62. }
  63. // 其他类型直接返回
  64. @return $value;
  65. }
  66. // 辅助函数:安全去除单位并返回数值
  67. @function calc-strip-unit($number) {
  68. @if type-of($number) == number {
  69. $unit: unit($number);
  70. $units: ("px": 1px, "rpx": 1rpx, "em": 1em, "rem": 1rem, "%": 1%);
  71. @if map-has-key($units, $unit) {
  72. @return div($number , map-get($units, $unit));
  73. }
  74. @if unitless($number) {
  75. @return $number;
  76. }
  77. }
  78. @return $number;
  79. }
  80. // 辅助函数:检查字符是否为数字
  81. @function is-numeric-char($char) {
  82. $chars: "-.0123456789";
  83. @return str-index($chars, $char) != null;
  84. }
  85. // 辅助函数:将字符串安全转换为数字
  86. @function to-number($string) {
  87. // 如果输入已经是数字,直接返回
  88. @if type-of($string) == number {
  89. @return $string;
  90. }
  91. // 处理带符号的数字
  92. $is-negative: false;
  93. $numeric: "";
  94. $found-number: false;
  95. // 提取所有数字字符
  96. @for $i from 1 through str-length($string) {
  97. $char: str-slice($string, $i, $i);
  98. @if $char == "-" and $numeric == "" {
  99. $is-negative: true;
  100. }
  101. @else if $char == "." and str-index($numeric, ".") == null {
  102. $numeric: $numeric + $char;
  103. }
  104. @else if $char >= "0" and $char <= "9" {
  105. $numeric: $numeric + $char;
  106. $found-number: true;
  107. }
  108. }
  109. // 如果有实际数字内容,转换为数值
  110. @if $found-number {
  111. $result: 0;
  112. $decimal-index: str-index($numeric, ".");
  113. @if $decimal-index {
  114. // 处理带小数的数字
  115. $integer-part: str-slice($numeric, 1, $decimal-index - 1);
  116. $decimal-part: str-slice($numeric, $decimal-index + 1);
  117. @if $integer-part == "" { $integer-part: "0"; }
  118. $result: to-integer($integer-part);
  119. $divisor: 1;
  120. @for $i from 1 through str-length($decimal-part) {
  121. $divisor: $divisor * 10;
  122. $digit: to-integer(str-slice($decimal-part, $i, $i));
  123. $result: $result + ($digit / $divisor);
  124. }
  125. } @else {
  126. // 处理整数
  127. $result: to-integer($numeric);
  128. }
  129. @return if($is-negative, -$result, $result);
  130. }
  131. // 无法转换则返回原字符串
  132. @return $string;
  133. }
  134. // 辅助函数:将整数字符串转换为数字
  135. @function to-integer($string) {
  136. $result: 0;
  137. @for $i from 1 through str-length($string) {
  138. $char: str-slice($string, $i, $i);
  139. $result: $result * 10 + (str-index("0123456789", $char) - 1);
  140. }
  141. @return $result;
  142. }
  143. @function create-var($name, $values...) {
  144. // 将不定数量的参数转换为列表
  145. $value-list: $values;
  146. $css-value: null;
  147. @if length($value-list) == 0 {
  148. // @warn "The list must have at least 1 values.";
  149. @return '';
  150. } @else {
  151. // 初始化CSS变量的值为列表中的第一个值
  152. /* #ifndef VUE2 */
  153. $css-value: nth($value-list, 1);
  154. /* #endif */
  155. /* #ifdef VUE2 */
  156. $css-value: rpx-to-px(nth($value-list, 1));
  157. /* #endif */
  158. }
  159. // 检查列表长度是否大于等于2
  160. @if length($value-list) >= 2 {
  161. // 使用@for循环遍历剩余的值,并构建CSS变量的完整值
  162. @for $i from 2 through length($value-list) {
  163. /* #ifndef VUE2 */
  164. $css-value: $css-value + ", " + nth($value-list, $i);
  165. /* #endif */
  166. /* #ifdef VUE2 */
  167. $css-value: $css-value + ", " + rpx-to-px(nth($value-list, $i));
  168. /* #endif */
  169. }
  170. }
  171. /* #ifdef UNI-APP-X && APP && uniVersion >= 4.75 */
  172. @if $use-css-var {
  173. @return var(--l-#{$name}, #{$css-value});
  174. } @else {
  175. @return $css-value;
  176. }
  177. /* #endif */
  178. /* #ifdef UNI-APP-X && APP || APP-NVUE */
  179. @return $css-value;
  180. /* #endif */
  181. @return var(--l-#{$name}, #{$css-value});
  182. }