Skip to content

Commit 73afbd0

Browse files
committed
feat: add drawing
1 parent 4050de7 commit 73afbd0

File tree

13 files changed

+373
-131
lines changed

13 files changed

+373
-131
lines changed

public/CK.ttf

-10.3 MB
Binary file not shown.

public/index.html

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,64 +3,15 @@
33
<head>
44
<meta charset="utf-8" />
55
<meta name="viewport" content="width=device-width,initial-scale=1" />
6-
76
<title>PDF Editor</title>
8-
97
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
108
<link rel="stylesheet" href="/build/bundle.css" />
11-
<!-- <link
12-
rel="preload"
13-
href="/NotoSansTC-Regular.woff2"
14-
as="font"
15-
type="font/woff2"
16-
crossorigin
17-
/> -->
18-
<link
19-
rel="preload"
20-
href="/CKs.ttf"
21-
as="font"
22-
type="font/ttf"
23-
crossorigin
24-
/>
259
<style type="text/css">
26-
/* @font-face {
27-
font-family: 'Noto Sans TC';
28-
font-style: normal;
29-
font-weight: 400;
30-
src: url('/NotoSansTC-Regular.woff2') format('woff2');
31-
} */
3210
html {
3311
touch-action: none;
3412
}
35-
@font-face {
36-
font-family: 'CK';
37-
font-style: normal;
38-
font-weight: 400;
39-
src: url('/CKs.ttf') format('truetype');
40-
}
4113
</style>
42-
4314
<script defer src="/build/bundle.js"></script>
4415
</head>
45-
4616
<body></body>
47-
<script
48-
async
49-
data-async
50-
src="https://unpkg.com/[email protected]/build/pdf.min.js"
51-
id="pdfjsLib"
52-
></script>
53-
<script
54-
async
55-
data-async
56-
src="https://unpkg.com/[email protected]/dist/pdf-lib.min.js"
57-
id="PDFLib"
58-
></script>
59-
<script
60-
async
61-
data-async
62-
src="https://unpkg.com/[email protected]"
63-
id="download"
64-
></script>
65-
</script><script async data-async src="/make-font.js" id="makeFont"></script>
6617
</html>

public/make-font.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,16 @@
4343
const blobStream = require('blob-stream');
4444
const fontkit = require('fontkit');
4545
const PDFDocument = require('pdfkit');
46-
47-
const fontName = 'CKs';
48-
const fontPath = fontName + '.ttf';
46+
const fontName = 'CK';
4947

5048
window.makeFont = async function makeFont(
5149
lines,
5250
size,
5351
lineHeight,
5452
width,
55-
height
53+
height,
54+
fontBlob
5655
) {
57-
const fontBlob = await fetch(fontPath).then((r) => r.arrayBuffer());
5856
const customFont = fontkit.create(new Buffer(fontBlob)).stream
5957
.buffer;
6058
const doc = new PDFDocument({

public/test.pdf

8.5 KB
Binary file not shown.

src/App.svelte

Lines changed: 79 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
<script>
22
import { onMount } from "svelte";
3+
import { fly } from "svelte/transition";
34
import Tailwind from "./Tailwind.svelte";
45
import PDFPage from "./PDFPage.svelte";
56
import Image from "./Image.svelte";
67
import Text from "./Text.svelte";
8+
import Drawing from "./Drawing.svelte";
9+
import DrawingCanvas from "./DrawingCanvas.svelte";
710
import {
811
readAsArrayBuffer,
912
readAsImage,
@@ -20,20 +23,22 @@
2023
let allObjects = [];
2124
let selectedPageIndex = -1;
2225
let saving = false;
26+
let addingDrawing = false;
2327
// for test purpose
24-
// onMount(async () => {
25-
// try {
26-
// const res = await fetch("/test.pdf");
27-
// const pdfBlob = await res.blob();
28-
// await addPDF(pdfBlob);
29-
// selectedPageIndex = 0;
30-
// const imgBlob = await (await fetch("/test.svg")).blob();
31-
// addImage(imgBlob);
32-
// addTextField("New Text Field!");
33-
// } catch (e) {
34-
// console.log(e);
35-
// }
36-
// });
28+
onMount(async () => {
29+
try {
30+
const res = await fetch("/test.pdf");
31+
const pdfBlob = await res.blob();
32+
await addPDF(pdfBlob);
33+
selectedPageIndex = 0;
34+
// const imgBlob = await (await fetch("/test.jpg")).blob();
35+
// addImage(imgBlob);
36+
// addTextField("測試 New Text Field!");
37+
// addDrawing(200, 100, "M30,30 L100,50 L50,70", 0.5);
38+
} catch (e) {
39+
console.log(e);
40+
}
41+
});
3742
async function onUploadPDF(e) {
3843
const file = e.target.files[0];
3944
if (!file || file.type !== "application/pdf") return;
@@ -91,7 +96,7 @@
9196
console.log(`Fail to add image.`, e);
9297
}
9398
}
94-
async function onAddTextField() {
99+
function onAddTextField() {
95100
if (selectedPageIndex >= 0) {
96101
addTextField();
97102
}
@@ -105,13 +110,35 @@
105110
size: 16,
106111
lineHeight: 1.4,
107112
fontFamily: "CK",
108-
x: 0,
113+
x: 100,
109114
y: 0
110115
};
111116
allObjects = allObjects.map((objects, pIndex) =>
112117
pIndex === selectedPageIndex ? [...objects, object] : objects
113118
);
114119
}
120+
function onAddDrawing() {
121+
if (selectedPageIndex >= 0) {
122+
addingDrawing = true;
123+
}
124+
}
125+
function addDrawing(originWidth, originHeight, path, scale = 1) {
126+
const id = genID();
127+
const object = {
128+
id,
129+
path,
130+
type: "drawing",
131+
x: 0,
132+
y: 0,
133+
originWidth,
134+
originHeight,
135+
width: originWidth * scale,
136+
scale
137+
};
138+
allObjects = allObjects.map((objects, pIndex) =>
139+
pIndex === selectedPageIndex ? [...objects, object] : objects
140+
);
141+
}
115142
function selectPage(index) {
116143
selectedPageIndex = index;
117144
}
@@ -185,27 +212,25 @@
185212
on:click={onAddTextField}>
186213
<img src="notes.svg" alt="An icon for adding text" />
187214
</label>
188-
189-
<!-- coming soon -->
190-
<!-- <label
215+
<label
191216
class="flex items-center justify-center h-full w-8 hover:bg-gray-500
192217
cursor-pointer"
193-
for="pen"
218+
on:click={onAddDrawing}
194219
class:cursor-not-allowed={selectedPageIndex < 0}>
195220
<img src="gesture.svg" alt="An icon for adding drawing" />
196221
</label>
197-
<label
222+
<!-- coming soon -->
223+
<!-- <label
198224
class="flex items-center justify-center h-full w-8 hover:bg-gray-500
199225
cursor-pointer"
200-
for="pen"
201226
class:cursor-not-allowed={selectedPageIndex < 0}>
202227
<img src="add.svg" alt="An icon for create material" />
203228
</label> -->
204229
</div>
205230
<div class="justify-center mr-4 w-full max-w-xs hidden md:flex">
206231
<img src="/edit.svg" class="mr-2" alt="a pen, edit pdf name" />
207232
<input
208-
placeholder="PDF file name"
233+
placeholder="Rename your PDF here"
209234
type="text"
210235
class="flex-grow bg-transparent"
211236
bind:value={pdfName} />
@@ -220,10 +245,26 @@
220245
</button>
221246

222247
</div>
248+
{#if addingDrawing}
249+
<div
250+
transition:fly={{ y: -200, duration: 500 }}
251+
class="fixed z-10 top-0 left-0 right-0 border-b border-gray-300 bg-white
252+
shadow-lg"
253+
style="height: 50%;">
254+
<DrawingCanvas
255+
on:finish={e => {
256+
const { originWidth, originHeight, path } = e.detail;
257+
const scale = 400 / originWidth;
258+
addDrawing(originWidth, originHeight, path, scale);
259+
addingDrawing = false;
260+
}} />
261+
</div>
262+
{/if}
223263
{#if pages.length}
224264
<div class="flex justify-center px-5 w-full md:hidden">
225265
<img src="/edit.svg" class="mr-2" alt="a pen, edit pdf name" />
226266
<input
267+
placeholder="Rename your PDF here"
227268
type="text"
228269
class="flex-grow bg-transparent"
229270
bind:value={pdfName} />
@@ -232,7 +273,8 @@
232273
{#each pages as page, pIndex (page)}
233274
<div
234275
class="p-5 w-full flex flex-col items-center overflow-y-hidden"
235-
on:mousedown={() => selectPage(pIndex)}>
276+
on:mousedown={() => selectPage(pIndex)}
277+
on:touchstart={() => selectPage(pIndex)}>
236278
<div
237279
class="relative shadow-lg"
238280
bind:clientWidth={pagesWidth[pIndex]}
@@ -252,7 +294,8 @@
252294
x={object.x}
253295
y={object.y}
254296
width={object.width}
255-
height={object.height} />
297+
height={object.height}
298+
pageScale={pagesWidth[pIndex] / measures[pIndex]} />
256299
{:else if object.type === 'text'}
257300
<Text
258301
on:update={e => updateObject(object.id, e.detail)}
@@ -261,7 +304,18 @@
261304
y={object.y}
262305
size={object.size}
263306
lineHeight={object.lineHeight}
264-
fontFamily={object.fontFamily} />
307+
fontFamily={object.fontFamily}
308+
pageScale={pagesWidth[pIndex] / measures[pIndex]} />
309+
{:else if object.type === 'drawing'}
310+
<Drawing
311+
on:update={e => updateObject(object.id, e.detail)}
312+
path={object.path}
313+
x={object.x}
314+
y={object.y}
315+
width={object.width}
316+
originWidth={object.originWidth}
317+
originHeight={object.originHeight}
318+
pageScale={pagesWidth[pIndex] / measures[pIndex]} />
265319
{/if}
266320
{/each}
267321

0 commit comments

Comments
 (0)