1import { useRef, useEffect } from 'react';
2import WebViewer from '@pdftron/webviewer';
3import './App.css';
4import canvasToPDF from '@pdftron/canvas-to-pdf';
5import { drawTiger } from './drawTiger';
6
7const App = () => {
8 const viewer = useRef(null);
9
10 useEffect(() => {
11 WebViewer(
12 {
13 path: "/webviewer/lib",
14 initialDoc: "/files/PDFTron_about.pdf",
15 },
16 viewer.current
17 ).then(async (instance) => {
18 const { documentViewer, annotationManager, Annotations } = instance.Core;
19
20 const annotWidth = 600;
21 const annotHeight = 600;
22
23 documentViewer.addEventListener("documentLoaded", async () => {
24 const rectangleAnnot = new Annotations.RectangleAnnotation({
25 PageNumber: 1,
26 // values are in page coordinates with (0, 0) in the top left
27 X: 0,
28 Y: 0,
29 Width: annotWidth,
30 Height: annotHeight,
31 Author: annotationManager.getCurrentUser(),
32 });
33
34 const drawRect = (ctx) => {
35 const lineWidth = 20;
36 ctx.fillStyle = "red";
37 ctx.lineWidth = lineWidth;
38 ctx.strokeStyle = "black";
39 ctx.rect(
40 lineWidth / 2,
41 lineWidth / 2,
42 annotWidth - lineWidth,
43 annotHeight - lineWidth
44 );
45 ctx.fill();
46 ctx.stroke();
47 };
48
49 const drawGradientCircles = (ctx) => {
50 for (let i = 0; i < 15; i++) {
51 for (let j = 0; j < 15; j++) {
52 ctx.strokeStyle = `rgb(
53 0,
54 ${Math.floor(255 - 42.5 * i)},
55 ${Math.floor(255 - 42.5 * j)})`;
56 ctx.beginPath();
57 ctx.arc(25 + j * 40, 25 + i * 40, 15, 0, Math.PI * 2, true);
58 ctx.stroke();
59 }
60 }
61 };
62
63 const drawHatch = (ctx) => {
64 let X = 0;
65 let Y = 0;
66
67 ctx.save();
68
69 ctx.beginPath();
70 ctx.arc(
71 annotWidth * 0.5,
72 annotHeight * 0.5,
73 Math.max(annotHeight * 0.5, 0),
74 0,
75 Math.PI * 2,
76 false
77 );
78 ctx.closePath();
79 ctx.restore();
80 ctx.clip();
81
82 ctx.stroke();
83
84 const hatchSize = 10;
85 const hatchLineWidth = 1;
86 ctx.lineWidth = hatchLineWidth;
87
88 // horizontal lines
89 for (let i = Y; i < Y + annotHeight; i += hatchSize) {
90 ctx.beginPath();
91 ctx.moveTo(X, i);
92 ctx.lineTo(X + annotWidth, i);
93 ctx.stroke();
94 }
95
96 for (let i = X; i < X + annotWidth; i += hatchSize) {
97 ctx.beginPath();
98 ctx.moveTo(i, Y);
99 ctx.lineTo(i, Y + annotHeight);
100 ctx.stroke();
101 }
102 };
103
104 function rnd(min, max) {
105 return Math.floor(Math.random() * (max - min + 1) + min);
106 }
107
108 const drawTriangles = (ctx) => {
109 const canvasWidth = annotWidth;
110 const canvasHeight = annotHeight;
111 var heightScale = 0.866;
112
113 ctx.fillStyle = "rgb(0,0,0)";
114 ctx.fillRect(0, 0, annotWidth, annotHeight);
115 ctx.lineWidth = 1;
116
117 var hueStart = rnd(0, 360);
118 var triSide = 40;
119 var halfSide = triSide / 2;
120 var rowHeight = Math.floor(triSide * heightScale);
121 var columns = Math.ceil(canvasWidth / triSide) + 1;
122 var rows = Math.ceil(canvasHeight / rowHeight);
123
124 var col, row;
125 for (row = 0; row < rows; row++) {
126 var hue = hueStart + row * 3;
127
128 for (col = 0; col < columns; col++) {
129 var x = col * triSide;
130 var y = row * rowHeight;
131 var clr;
132
133 if (row % 2 !== 0) {
134 x -= halfSide;
135 }
136
137 // upward pointing triangle
138 clr = "hsl(" + hue + ", 50%, " + rnd(0, 60) + "%)";
139 ctx.fillStyle = clr;
140 ctx.strokeStyle = clr;
141 ctx.beginPath();
142 ctx.moveTo(x, y);
143 ctx.lineTo(x + halfSide, y + rowHeight);
144 ctx.lineTo(x - halfSide, y + rowHeight);
145 ctx.closePath();
146 ctx.fill();
147 ctx.stroke(); // needed to fill antialiased gaps on edges
148
149 // downward pointing triangle
150 clr = "hsl(" + hue + ", 50%, " + rnd(0, 60) + "%)";
151 ctx.fillStyle = clr;
152 ctx.strokeStyle = clr;
153 ctx.beginPath();
154 ctx.moveTo(x, y);
155 ctx.lineTo(x + triSide, y);
156 ctx.lineTo(x + halfSide, y + rowHeight);
157 ctx.closePath();
158 ctx.fill();
159 ctx.stroke();
160 }
161 }
162 };
163
164 const blob = await canvasToPDF(drawGradientCircles, {
165 width: rectangleAnnot.Width,
166 height: rectangleAnnot.Height,
167 });
168 const doc = await instance.Core.createDocument(blob, {
169 extension: "pdf",
170 });
171
172 rectangleAnnot.addCustomAppearance(doc, { pageNumber: 1 });
173
174 annotationManager.addAnnotation(rectangleAnnot);
175 // need to draw the annotation otherwise it won't show up until the page is refreshed
176 annotationManager.redrawAnnotation(rectangleAnnot);
177 });
178 });
179 }, []);
180
181 return (
182 <div className="App">
183 <div className="header">React sample</div>
184 <div className="webviewer" ref={viewer}></div>
185 </div>
186 );
187};
188
189export default App;
190