vue.js - SVG 在 Safari 上的绘制方式不同
问题描述
我在 Vue 中创建了一个使用 SVG 的圆形进度条组件。其中一项要求是在进度条的尖端放置一个图标。这在 Firefox/Chrome 中正确呈现:
但在 Safari 中渲染时会稍微偏离:
下面是我用来渲染这个进度圈的代码:
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
:width="size"
:height="size"
viewBox="0 0 40 40"
class="progress"
>
<defs>
<filter id="progress-dropshadow">
<feGaussianBlur in="SourceAlpha" stdDeviation="0.1" />
<feOffset dx="0" dy="0.2" result="offsetblur" />
<feComponentTransfer>
<feFuncA type="linear" slope="0.5" />
</feComponentTransfer>
<feMerge>
<feMergeNode />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
<circle cx="20" cy="20" r="18" class="progress__center" />
<circle
class="progress__ring"
cx="20"
cy="20"
r="18"
stroke-width="3"
style="filter: url(#progress-dropshadow);"
/>
<circle
class="progress__segment"
cx="20"
cy="20"
r="18"
stroke-width="3"
:stroke-dasharray="strokeDashArray"
stroke-linecap="round"
/>
<svg
v-bind="iconCoordinates"
class="progress-icon"
width="4"
height="4"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<path d="M0 0h24v24H0V0z" fill="none" />
<circle cx="15.5" cy="9.5" r="1.5" />
<circle cx="8.5" cy="9.5" r="1.5" />
<circle cx="15.5" cy="9.5" r="1.5" />
<circle cx="8.5" cy="9.5" r="1.5" />
<path
d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm0-2.5c2.33 0 4.32-1.45 5.12-3.5h-1.67c-.69 1.19-1.97 2-3.45 2s-2.75-.81-3.45-2H6.88c.8 2.05 2.79 3.5 5.12 3.5z"
/>
</svg>
</svg>
</template>
<script lang="ts">
import { Vue, Component, Prop } from 'vue-property-decorator';
const degreeToRadian = (radian: number) => (radian * Math.PI) / 180;
@Component({})
export default class PieChart extends Vue {
@Prop({ default: 4 }) readonly value!: number;
@Prop({ default: 236 }) readonly size!: number;
@Prop({ default: 5 }) readonly total!: number;
RADIUS = 18;
circumference = 2 * Math.PI * this.RADIUS;
get progress() {
if (this.total === 0) return 0;
return (this.value / this.total) * 100;
}
get strokeDashArray() {
return `${(this.progress * this.circumference) / 100} ${
this.circumference
}`;
}
get iconCoordinates() {
const scaleToDegrees = (this.progress / 100) * 360 - 90;
const radians = degreeToRadian(scaleToDegrees);
const xStart = Math.cos(radians) * this.RADIUS + this.RADIUS;
const yStart = Math.sin(radians) * this.RADIUS + this.RADIUS;
return {
x: xStart,
y: yStart,
};
}
}
</script>
<style lang="scss" scoped>
.progress__center {
fill: transparent;
}
.progress__ring {
stroke: $chart-ring;
fill: transparent;
}
.progress__segment {
fill: transparent;
transform-origin: center;
transform: rotate(-90deg);
stroke: red;
}
</style>
似乎进度越远,从边缘绘制的图标就越大。
解决方案
推荐阅读
- php - Mysql 查询 - 计算联接表上的已建立行数
- javascript - 检索整个文档作为条目数组
- visual-studio-2010 - Microsoft Visual Studio 从英语到法语
- system-verilog - 如何更改这些模块以使通信是双向的(输入输出)?
- ajax - 通过 AJAX 在 laravel 中传递值
- javascript - 当在 a.html 中单击按钮并仍然使用相同的 javascript 文件时,如何在 b.html 中播放 css 动画?
- amazon-web-services - 如果达到生命周期挂钩超时,请勿终止 EC2 实例
- ios - 创建自定义 SCNGeometry 多边形
- c# - 无法使用单例 yyy 中的作用域服务 xxx
- r - 如何使用 bookdown word_document_2 包含参考文献和参考书目列表?