-
Notifications
You must be signed in to change notification settings - Fork 1
/
copyclipboard.js
116 lines (94 loc) · 2.92 KB
/
copyclipboard.js
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
const RENDER_TEXT_SIZE = 40;
const getCopyableCanvas = async (parentEl) => {
const boundingRect = parentEl.getBoundingClientRect();
const bx = boundingRect.x;
const by = boundingRect.y;
const bw = boundingRect.width;
const bh = boundingRect.height;
const c = document.createElement("canvas");
c.width = bw;
c.height = bh;
const ctx = c.getContext("2d");
ctx.fillStyle = "#ffffff";
ctx.fillRect(0, 0, bw, bh);
ctx.strokeStyle = "#000000";
ctx.lineWidth = 2;
ctx.fillStyle = "#000000";
ctx.font = RENDER_TEXT_SIZE * 0.85 + "px Arial";
for (const svg of parentEl.querySelectorAll("svg")) {
const { x: rx, y: ry, width: w, height: h } = svg.getBoundingClientRect();
const [x, y] = [rx - bx, ry - by];
for (const line of svg.querySelectorAll("line")) {
ctx.beginPath();
ctx.moveTo(
x + (w * line.x1.baseVal.value) / 4.2,
y + (h * line.y1.baseVal.value) / 7
);
ctx.lineTo(
x + (w * line.x2.baseVal.value) / 4.2,
y + (h * line.y2.baseVal.value) / 7
);
ctx.stroke();
}
for (const circle of svg.querySelectorAll("circle")) {
ctx.beginPath();
ctx.arc(
x + (w * circle.cx.baseVal.value) / 4.2,
y + (h * circle.cy.baseVal.value) / 7,
(circle.r.baseVal.value * w) / 4.2,
0,
2 * Math.PI
);
ctx.stroke();
}
}
for (const span of parentEl.querySelectorAll("span")) {
if (span.innerText.trim() != "") {
const {
x: rx,
y: ry,
width: w,
height: h,
} = span.getBoundingClientRect();
const [x, y] = [rx - bx, ry - by];
ctx.fillText(span.innerText, x, y + (h * 2) / 3);
}
}
return c;
};
const canvasToClipboard = async (c) => {
return new Promise((res) => {
c.toBlob((blob) => {
navigator.clipboard.write([
new ClipboardItem({
"image/png": blob,
}),
]);
res();
});
});
};
const copyToClipboard = async (text) => {
// Create an invisible div to render our flex elements
const displayArea = document.createElement("div");
displayArea.style.position = "fixed";
displayArea.style.left = 0;
displayArea.style.top = 0;
displayArea.style.display = "inline-block";
displayArea.style.opacity = 0;
displayArea.style.maxWidth = `${RENDER_TEXT_SIZE * 20}px`;
const parent = displayArea.appendChild(document.createElement("div"));
parent.style.padding = `${RENDER_TEXT_SIZE / 5}px`;
parent.style.gap = `${RENDER_TEXT_SIZE * 0.2}px`;
parent.style.display = "flex";
parent.style.flexWrap = "wrap";
generateText(text, parent, RENDER_TEXT_SIZE, "px");
document.body.appendChild(displayArea);
// Wait for flexbox to calculate (wait for next animation frame)
await new Promise(requestAnimationFrame);
// Render and copy
const c = await getCopyableCanvas(parent);
await canvasToClipboard(c);
// Clean up
document.body.removeChild(displayArea);
};