Published
Edited
Aug 16, 2021
2 forks
1 star
Insert cell
Insert cell
Insert cell
{
let theSvg = svg`<svg width=${width} height=${height}>`;

// Small square size
let s = width / 17;

// Pattern with squares and stripes
let pattern = svg`
<defs>
<g id=sqstripes clip-path=url(#clipPattern)>
<!-- big black square -->
<rect x=${-s * 2.5} y=${-s * 2.5}
width=${s * 5} height=${s * 5} fill=black />
<!-- big white square -->
<rect x=${-s * 1.5} y=${-s * 1.5}
width=${s * 3} height=${s * 3} fill=white />
<!-- small black square -->
<rect x=${-s * 0.5}
y=${-s * 0.5}
width=${s} height=${s} fill=black />
<!-- top stripe -->
<rect width=${s * 10} height=${s}
x=${s * 2.5 - 0.5} y=${-s * 2.5} fill=black />
<!-- middle stripe -->
<rect width=${s * 10} height=${s}
x=${s * 2.5 - 0.5} y=${-s * 0.5} fill=black />
<!-- bottom stripe -->
<rect width=${s * 10} height=${s}
x=${s * 2.5 - 0.5} y=${s * 1.5} fill=black />
</g>
</defs>`;

// Pattern clip path
let clipRect = svg`<rect x=${-s * 2.5} y=${-s * 2.5}
width=${s * 15} height=${s * 5} />`;

let clipPattern = svg`
<defs>
<clipPath id=clipPattern>
${clipRect};
</clipPath>
</defs>`;

// The left group
let left = svg`<use
href=#sqstripes
transform="translate(${width / 2 - s * 5},${height / 2 - s * 3})" />`;

// The right group
let right = svg`<use
href=#sqstripes
transform="translate(${width / 2 + s * 5},${
height / 2 + s * 3
})rotate(180)" />`;

theSvg.append(clipPattern, pattern, left, right);
//return theSvg;

let spec = {
clip_dx: [
[0, 0],
[100, s * 5]
],
pat_dy: [
[0, 0],
[100, 0],
[200, (s * 6) / 2]
],
pat_dx: [
[0, 0],
[200, 0],
[300, s * 4]
],
t: [[400, 0]]
};
while (true) {
await visibility();
for (let { clip_dx, pat_dy, pat_dx } of animation(spec, 0.2)) {
clipRect.setAttribute("width", s * 15 - clip_dx - pat_dx);
left.setAttribute(
"transform",
`translate(${width / 2 - s * 5 + pat_dx / 2},${
height / 2 + s * 3 - pat_dy
})`
);
right.setAttribute(
"transform",
`translate(${width / 2 + s * 5 - pat_dx / 2},${
height / 2 - s * 3 + pat_dy
})rotate(180)`
);

yield theSvg;
}
}
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
spec2 = ({
bigCircleRadius: [
[0, height * 0.2],
[30, height * 0.4],
[40, height * 0.3],
[60, height * 0.6],
[80, height * 0.5],
[120, height * 0.9]
],
yarc: [
[0, height],
[120, height],
[240, 0],
[360, margin]
],
xarc: [
[0, 0],
[360, 0],
[600, width]
],
rot: [
[0, 0],
[360, 0],
[361, 90],
[600, 90]
]
})
Insert cell
plotAnim(spec2)
Insert cell
{
while (true)
for (let { frame, bigCircleRadius, xarc, yarc, rot } of animation(
spec2,
0.7
)) {
await visibility();
yield svg`
<svg width=${width} height=${height}>
<defs>
<!-- Center rectangle used as a clip path-->
<clipPath id=clip>
<rect x=${margin} y=${margin} width=${width - margin * 2} height=${
height - margin * 2
} />
</clipPath>
<!-- A half-circle of radius 1 at the origin -->
<path d="M 0,-1 a 1 1 0 0 0 0,2" id=halfCircle />
</defs>
<!-- A circle clipped by a rectangle -->
<circle cx=${width / 2} cy=${
height / 2
} r=${bigCircleRadius} clip-path="url(#clip)" />

<!-- Left white half circle -->
<use href=#halfCircle
transform="translate(${width / 2 + xarc},${
height / 2 + margin - yarc
})scale(${radius})rotate(${rot})"
fill=white />
<!-- right white half circle -->
<use href=#halfCircle
transform="translate(${width / 2 - xarc},${
height / 2 - margin + yarc
})scale(${radius})rotate(180)rotate(${rot})"
fill=white />
<!-- center black circle -->
<circle cx=${width / 2} cy=${height / 2} r=${height / 8} fill=black />
</svg>
`;
}
}
Insert cell
Insert cell
{
// thickness
let s = height / 10;

// central square size half size
let q = s * 2;

// The central black square
let sq1 = svg`<polygon points="${-q},${-q} ${-q},${q} ${q},${q} ${q},${-q}"
fill=none stroke=black stroke-width=${s} >`;

// The central circle
let c1 = svg`<circle r=${s * 0.8} />`;

// The central group
let g1 = svg`<g
transform="translate(${width / 2},${height / 2})rotate(45)">${sq1}${c1}`;

// A clipping square for creating isosceles triangles
let isoclip = svg`<defs>
<clipPath id=isoclip>
<rect x=${-s * 2.5} y=${-s * 2.5} width=${s * 5} height=${
s * 5
} transform="rotate(45)" />
</clipPath>
</defs>`;

// Isosceles triangles
let iso1 = svg`<rect x=${s * 0.25} y=${s * 0.25}
width=${s * 3} height=${s * 3} clip-path=url(#isoclip)
transform="translate(${width / 2 - s * 4.2},${height / 2 - s * 4.2})" />`;
let iso2 = svg`<rect x=${s * 0.25} y=${s * 0.25}
width=${s * 3} height=${s * 3} clip-path=url(#isoclip)
transform="translate(${width / 2 + s * 4.2},${
height / 2 + s * 4.2
})rotate(180)" />`;
let iso3 = svg`<rect x=${s * 0.25} y=${s * 0.25}
width=${s * 3} height=${s * 3} clip-path=url(#isoclip)
transform="translate(${width / 2 + s * 4.2},${
height / 2 - s * 4.2
})rotate(90)" />`;
let iso4 = svg`<rect x=${s * 0.25} y=${s * 0.25}
width=${s * 3} height=${s * 3} clip-path=url(#isoclip)
transform="translate(${width / 2 - s * 4.2},${
height / 2 + s * 4.2
})rotate(-90)" />`;

// The two side rectangles
let left = svg`<rect x=${s} y=${s}
width=${s} height=${height - s * 2} />`;
let right = svg`<rect x=${width - s * 2} y=${s}
width=${s} height=${height - s * 2} />`;

while (true)
for (let { angle, circle_radius, d1, d2, h } of animation(
{
angle: [
[0, 0],
[120, 45]
],
circle_radius: [
[0, 0],
[150, 0],
[151, s * 0.8]
],
d1: [
[0, s * 3],
[180, s * 3],
[300, s * 0.25]
],
d2: [
[0, s * 3],
[300, s * 3],
[420, s * 0.25]
],
h: [
[0, height - s * 2],
[460, height - s * 2],
[560, 0],
[800, 0]
]
},
0.5
)) {
g1.setAttribute(
"transform",
`translate(${width / 2},${height / 2})rotate(${angle})`
);
c1.setAttribute("r", circle_radius);
iso1.setAttribute("x", d1);
iso1.setAttribute("y", d1);
iso2.setAttribute("x", d1);
iso2.setAttribute("y", d1);
iso3.setAttribute("x", d2);
iso3.setAttribute("y", d2);
iso4.setAttribute("x", d2);
iso4.setAttribute("y", d2);
left.setAttribute("y", s + h);
left.setAttribute("height", height - s * 2 - h);
right.setAttribute("height", height - s * 2 - h);
yield svg`<svg width=${width} height=${height}>
${isoclip}${g1}${iso1}${iso2}${iso3}${iso4}${left}${right} </svg>`;
}
}
Insert cell
// Original static code
{
// thickness
let s = height / 10;

// central square size half size
let q = s * 2;

// The central black square
let sq1 = svg`<polygon points="${-q},${-q} ${-q},${q} ${q},${q} ${q},${-q}"
fill=none stroke=black stroke-width=${s} >`;

// The central circle
let c1 = svg`<circle r=${s * 0.8} />`;

// The central group
let g1 = svg`<g
transform="translate(${width / 2},${height / 2})rotate(45)">${sq1}${c1}`;

// A clipping square for creating isosceles triangles
let isoclip = svg`<defs>
<clipPath id=isoclip>
<rect x=${-s * 2.5} y=${-s * 2.5} width=${s * 5} height=${
s * 5
} transform="rotate(45)" />
</clipPath>
</defs>`;

// Isosceles triangles
let iso1 = svg`<rect x=${s * 0.25} y=${s * 0.25}
width=${s * 3} height=${s * 3} clip-path=url(#isoclip)
transform="translate(${width / 2 - s * 4.2},${height / 2 - s * 4.2})" />`;
let iso2 = svg`<rect x=${s * 0.25} y=${s * 0.25}
width=${s * 3} height=${s * 3} clip-path=url(#isoclip)
transform="translate(${width / 2 + s * 4.2},${
height / 2 + s * 4.2
})rotate(180)" />`;
let iso3 = svg`<rect x=${s * 0.25} y=${s * 0.25}
width=${s * 3} height=${s * 3} clip-path=url(#isoclip)
transform="translate(${width / 2 + s * 4.2},${
height / 2 - s * 4.2
})rotate(90)" />`;
let iso4 = svg`<rect x=${s * 0.25} y=${s * 0.25}
width=${s * 3} height=${s * 3} clip-path=url(#isoclip)
transform="translate(${width / 2 - s * 4.2},${
height / 2 + s * 4.2
})rotate(-90)" />`;

// The two side rectangles
let left = svg`<rect x=${s} y=${s}
width=${s} height=${height - s * 2} />`;
let right = svg`<rect x=${width - s * 2} y=${s}
width=${s} height=${height - s * 2} />`;

return svg`<svg width=${width} height=${height}>
${isoclip}${g1}${iso1}${iso2}${iso3}${iso4}${left}${right} </svg>`;
}
Insert cell
Insert cell
import { plotAnim, animation } from "@esperanc/keyframe-animation"
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more