-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtemplates.js
More file actions
98 lines (93 loc) · 2.38 KB
/
templates.js
File metadata and controls
98 lines (93 loc) · 2.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
export const trim = string => props => string(props)
.replace(/(\r\n|\n|\r)/gm, "")
.replace(/ +(?= )/g,'')
export const animation = (fill) => `
<linearGradient id="${fill}">
<stop
offset="0.599964"
stop-color="#f3f3f3"
stop-opacity="1"
>
<animate
attributeName="offset"
values="-2; -2; 1"
keyTimes="0; 0.25; 1"
dur="2s"
repeatCount="indefinite"
></animate>
</stop>
<stop
offset="1.59996"
stop-color="#ecebeb"
stop-opacity="1"
>
<animate
attributeName="offset"
values="-1; -1; 2"
keyTimes="0; 0.25; 1"
dur="2s"
repeatCount="indefinite"
></animate>
</stop>
<stop
offset="2.59996"
stop-color="#f3f3f3"
stop-opacity="1"
>
<animate
attributeName="offset"
values="0; 0; 3"
keyTimes="0; 0.25; 1"
dur="2s"
repeatCount="indefinite"
></animate>
</stop>
</linearGradient>
`
const render = {
rect({ x, y, width, height }) {
return ` <rect rx="3" ry="3" x="${x}" y="${y}" width="${width}" height="${height}" />`
},
use({ id, x, y }) {
return `<use href="#${id}" x="${x}" y="${y}" />`
},
path({ path, id }) {
return `<path id="${id}" d="${path}" />`
},
circle({ r, cx, cy }) {
return `<circle r="${r}" cx="${cx}" cy="${cy}" />`
}
}
const renderRefs = (groups) =>
groups.reduce(
(acc, group) => acc + group.positions.map(
(position) => render.use({ ...group, ...position })
).join('')
, '')
const renderSingleElement = ({ type, ...props }) => render[type](props);
const randomKey = () => Math.random().toString(36).substring(7);
const generateIds = () => [
`clip-${randomKey()}`,
`fill-${randomKey()}`
];
export const template = trim(({
width,
height,
singles,
groups
}) => {
const [clip, fill] = generateIds();
return `
<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}" preserveAspectRatio="none">
<rect x="0" y="0" width="100%" height="100%" clip-path="url(#${clip})" style='fill: url("#${fill}");' />
<defs>
${groups.map(render.path).join('')}
<clipPath id="${clip}">
${renderRefs(groups)}
${singles.map(renderSingleElement).join('')}
</clipPath>
${animation(fill)}
</defs>
</svg>
`
})