其实所有的图形都是由点,线,面组成的。点线面可以组成一个设备。下面就简单讲讲点线面是怎么画的吧
对于线,可以用path
<g>
<path
:d="`M ${beginX},${beginY} L ${endX},${endY}`"
:stroke-width="lineWidth"
:stroke="stroke"
:style="{ transform: `rotate(${rotateAngle}deg)`, transformOrigin: transformOrigin }"
>
<animate attributeName="stroke" :values="animateStyle" dur="1s" begin="0s" repeatCount="indefinite" v-if="animation" />
</path>
</g>
两点一线,只要知道两个点的坐标就可以,但是基础图元可以旋转,也可以闪烁,所以这些属性都需要动态计算。
两点可以组成线,多点可以组成折线,这就需要一个polyline类去解析每个折线。
ployline也是用path就可以了,但是中间的点需要连起来,样式的计算需要循环拼接字符串
const d = computed(() => {
if (polyline.value && centerPoint.value) {
let tmp = "";
for (let i = 0; i < pointList.value.length; i++) {
const point = pointList.value[i];
if (i === 0) {
beginX.value = (point.X() + centerPoint.value.X()) * scaleX.value;
beginY.value = (point.Y() + centerPoint.value.Y()) * scaleY.value;
tmp += `M ${beginX.value},${beginY.value}`;
} else {
if (i === pointList.value.length - 1) {
endX.value = (point.X() + centerPoint.value.X()) * scaleX.value;
endY.value = (point.Y() + centerPoint.value.Y()) * scaleY.value;
}
tmp += `L ${(point.X() + centerPoint.value.X()) * scaleX.value},${(point.Y() + centerPoint.value.Y()) * scaleY.value}`;
}
}
transformOrigin.value = `${(beginX.value + endX.value) / 2}px ${(beginY.value + endY.value) / 2}px`;
return tmp;
}
return "";
});
有了线,当然需要面,这时候一个polygon类就可以解决,唯一和polyline不同的是,path最后一个点需要Z闭合
tmp += "Z";
svg里面的渲染最有难度的大圆弧和小圆弧,需要用到三角函数
<path
v-else
:d="`M ${beginX},${beginY}
A ${r} ${r} 0 ${largeArcFlag} ${sweepFlag} ${endX} ${endY}
L ${cx} ${cy}
Z`"
:style="style"
>
<animate attributeName="stroke" :values="animateStyle" dur="1s" begin="0s" repeatCount="indefinite" v-if="animation" />
</path>
整圆就用<circle>标签
剩下的都是用foreignObject写的
<foreignObject :x="beginX" :y="beginY" :width="countWidth" :height="countHeight" requiredExtensions="http://www.w3.org/1999/xhtml">
<body xmlns="http://www.w3.org/1999/xhtml" class="textBg" :style="{ transform: `rotate(${rotateAngle}deg)` }">
<div :class="[isVertical ? 'isVertical' : '', 'textStyle']" v-if="!htmlText" :id="`${str._id}`">
{{ strText }}
</div>
<div :class="[isVertical ? 'isVertical' : '', 'textStyle']" v-else v-html="strText" :id="`${str._id}`"></div>
</body>
</foreignObject>