由纯CSS饼图、stroke-dasharray引出的Firefox对CSS变量运算兼容的问题

我是一名刚开始接触前端(甚至刚开始接触编程)的菜鸟,以前是做平面设计的,说得有问题的话请多包涵。

这篇文章记录一下我发现的一个小问题。

这几天在做一个饼图的内容,想要实现的效果大概就是一个这样的环形:

选择的方案是用SVG绘制圆形(circle),然后通过stroke-dasharray来控制显示部分。之前考虑过计算锚点位置直接用path来绘制,但是有点复杂,就选择了这种方式。

先简单介绍下stroke-dasharray画饼图的方法。

简单来说,stroke-dasharray是用来将svg图形的描边以虚线呈现的属性,其实线和空格的长度值是会头尾相接自动循环的,而第一个值是第一段实线的长度,第二个值是第一段空格的长度。那么,只要先计算出周长,然后将周长按比例分为两个长度,分别设置为stroke-dasharray的第一个值和第二个值,这样整个周长上虚线会被恰好循环1次,即可呈现出饼图的效果。不光环状的,扇形的其实也可以做到,可以通过stroke-width来控制。

如果是多段饼,用stroke-dashoffset或者transform:rotate()控制有点太复杂了。我的思路是直接在同一位置叠多个circle,最底层是一个整环,往上逐级递减,效果是一样的:

调整各层半径和stroke-width,还可以做出叠层的效果(类似行星环),这里不细说了。

理论存在,接下来就是实践了。

于是我尝试了比较简单的写法,也就是在CSS的:root里定义了一系列的相关变量和运算法则(下面大概示意一下我的做法,不是原代码)。

:root{
--inputnum:1;
--inputtotal:1;
--array1:calc(3.1415926 * 2 * var(--inputnum) / var(--inputtotal));
--array2:calc(3.1415926 * 2 - var(array2));
--array:var(--array1),var(--array2);
}

其中“2”是圆的直径。

接下来就是用js控制其中的元变量。我是自己定义了一个函数来方便地变更CSS的变量。

function dd(key,string){document.documentElement.style.setProperty(key,string);}

然后直接dd("--inputnum",xx)就行了。

最后<circle stroke-dasharray="var(--array)"/>即可。

哦对,默认情况下绘制应该是从3点方向开始的,如果想要实线部分从12点钟方向开始绘制,需要transform:rotate(-90deg)来逆时针旋转90度。也可以用stroke-dashoffset,但我觉得这个逻辑上简单太多了。

这套方法在Chrome和Safari上完美运行,所以我一开始没有急着做兼容测试就写别的内容去了。结果当晚测试的时候发现Firefox无论是PC端还是移动端都无法正常显示,整段都是实线。

然后抓狂的一晚上开始了。

一开始我以为是stroke-width的问题,因为看到有说法说Firefox在绘制的时候会除掉stroke-width,但我将SVG的viewbox缩小,减小半径,将stroke-width改为1之后,仍然是其他浏览器都没问题,唯独Firefox不行。

然后我尝试将stroke-dasharray写到style里而不是作为circle的一个属性,依然无效。

在搜遍整个互联网都没有找到满意的答案后,我突然想到,会不会是CSS变量的问题?

于是我检查了Firefox调试界面的CSS变量,发现确实读不出来值。当时我考虑是不是Firefox不支持calc()对CSS变量的运算?但这显然不对,因为我前面用到颜色的计算,也是采用的类似方式。

--r:0;
--g:100;
--b:170;
--c0:rgb(var(--r),var(--g),var(--b));
--c1:rgb(calc(var(--r) * 0.6),calc(var(--g) * 0.6),calc(var(--b) * 0.6));

类似这样的运算在任何主流浏览器上都没有兼容性问题。

同样,这也不太可能是多个变量合并为一个变量的问题,比如上面这段代码中的--c0,跟--array的格式几乎一模一样!

--array:var(--array1),var(--array2);

等下,真的是这样吗?

最后我发现,Firefox还真就是对--array这样的格式不支持。而且并不是不支持公式的嵌套(二次运算)而是不支持这个特定格式,因为我将svg部分改为:

<circle stroke-dasharray="var(--array1),var(--array2)"/>

在Firefox下同样是无效的(而其他浏览器都没有问题)。

总结起来就是,Firefox可能无法处理没有外括号并且用逗号分隔的两个CSS变量的组合。当然我并没有在其他属性上测试,所以也可能只是对stroke-dasharray属性存在这种情况。有时间我会测试一下其他类似属性的结果。

最后我只好改为用DOM方式来控制stroke-dasharry属性,这个我就不细说了~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值