cvs
Version:
A basic canvas framework for 2d drawing.
85 lines (80 loc) • 2.61 kB
JavaScript
import { oneOrTwoValues, error, getMatrix } from './utils'
import SvgPath from '../svgPath'
export default function toSvg (d) {
if (typeof d === 'string') return new SvgPath(d)
if (typeof d === 'object') {
let pas = ''
if (d.path) pas = d.path
else if (d.type === 'rect') pas = rect2svg(d)
else if (d.type === 'circle') pas = circle2svg(d)
else error('unexpected type of path.')
let p = new SvgPath(pas)
let m = getMatrix(d)
p.transform(...m)
return p
}
}
// 矩形转成 svg 路径
function rect2svg (d) {
if (!d.borderRadius) {
return `M ${d.x || 0} ${d.y || 0} h ${d.w} v ${d.h} h -${d.w} z`
} else {
let r = [],
radius = d.borderRadius,
x = d.x || 0,
y = d.y || 0,
w = d.w,
h = d.h
if (radius instanceof Array) {
if (radius.length >= 4) r = radius.slice(0, 4)
else if (radius.length === 3) {
r[1] = r[3] = radius[1]
r[0] = radius[0]
r[2] = radius[2]
} else if (radius.length === 2) {
r[0] = r[2] = radius[0]
r[1] = r[3] = radius[1]
}
} else r = new Array(4).fill(radius)
const aCmd = r.map((item, index) => {
if (index === 0) return `a ${item} ${item} 0 0 1 ${item} -${item}`
if (index === 1) return `a ${item} ${item} 0 0 1 ${item} ${item}`
if (index === 2) return `a ${item} ${item} 0 0 1 -${item} ${item}`
if (index === 3) return `a ${item} ${item} 0 0 1 -${item} -${item}`
})
const lCmd = r.map((item, index) => {
if (index === 0) return `h ${w - r[0] - r[1]}`
if (index === 1) return `v ${h - r[1] - r[2]}`
if (index === 2) return `h ${(w - r[2] - r[3]) * -1}`
})
return `M ${x} ${y + r[0]} ${aCmd[0]} ${lCmd[0]} ${aCmd[1]} ${lCmd[1]} ${
aCmd[2]
} ${lCmd[2]} ${aCmd[3]} z`
}
}
// 圆形、椭圆转成 svg 路径
function circle2svg (d) {
const [rx, ry] = oneOrTwoValues(d.r),
{ cx = rx, cy = ry, rotate = 0 } = d
const calc = calculate({ cx, cy, rx, ry, rotate })
const start = calc(0)
const end = calc(-1)
return `M ${start.x} ${start.y} A ${rx} ${ry} ${rotate} 1 1 ${end.x} ${
end.y
} z`
}
function calculate ({ cx, cy, rx, ry, rotate }) {
return function (angle) {
const rnx = rx * Math.cos((angle * Math.PI) / 180)
const rny = ry * Math.sin((angle * Math.PI) / 180)
const x =
cx +
rnx * Math.cos((rotate * Math.PI) / 180) -
rny * Math.sin((rotate * Math.PI) / 180)
const y =
cy +
rnx * Math.sin((rotate * Math.PI) / 180) +
rny * Math.cos((rotate * Math.PI) / 180)
return { x, y }
}
}