From 1798c91cd9daa6f2a6b88178ed15a8c841c7a412 Mon Sep 17 00:00:00 2001 From: mzabriskie Date: Wed, 9 Sep 2015 08:57:45 -0600 Subject: [PATCH] firstish --- .gitignore | 1 + example/annotations.js | 24 ++++++++++++++++++++++++ example/helloworld.pdf | Bin 0 -> 678 bytes example/index.html | 11 +++++++++++ example/index.js | 30 ++++++++++++++++++++++++++++++ index.js | 3 +++ package.json | 31 +++++++++++++++++++++++++++++++ src/AnnotateView.js | 26 ++++++++++++++++++++++++++ src/PDFJSAnnotate.js | 18 ++++++++++++++++++ src/StoreAdapter.js | 11 +++++++++++ src/render/renderDrawing.js | 18 ++++++++++++++++++ src/render/renderSVG.js | 13 +++++++++++++ src/utils/abstractFunction.js | 5 +++++ src/utils/uuid.js | 6 ++++++ webpack.config.js | 13 +++++++++++++ webpack.example.js | 12 ++++++++++++ 16 files changed, 222 insertions(+) create mode 100644 .gitignore create mode 100644 example/annotations.js create mode 100644 example/helloworld.pdf create mode 100644 example/index.html create mode 100644 example/index.js create mode 100644 index.js create mode 100644 package.json create mode 100644 src/AnnotateView.js create mode 100644 src/PDFJSAnnotate.js create mode 100644 src/StoreAdapter.js create mode 100644 src/render/renderDrawing.js create mode 100644 src/render/renderSVG.js create mode 100644 src/utils/abstractFunction.js create mode 100644 src/utils/uuid.js create mode 100644 webpack.config.js create mode 100644 webpack.example.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..c2658d7d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/example/annotations.js b/example/annotations.js new file mode 100644 index 00000000..82a528e0 --- /dev/null +++ b/example/annotations.js @@ -0,0 +1,24 @@ +import uuid from '../src/utils/uuid'; + +export default [ + { + class: 'Annotation', + uuid: uuid(), + page: 1, + owner: 'admin', + type: 'drawing', + color: '0000ff', + lines: [[48, 55], [48, 57], [48, 58], [48, 58], [49, 60], [50, 61], [51, 64], [53, 67], [56, 72], [58, 76], [61, 82], [65, 90], [67, 95], [71, 102], [75, 110], [77, 116], [80, 122], [83, 127], [85, 132], [86, 137], [89, 142], [92, 147], [95, 152], [98, 158], [101, 164], [105, 170], [108, 175], [111, 181], [115, 185], [118, 191], [120, 194], [121, 198], [123, 201], [124, 204], [125, 207], [125, 208], [126, 210], [127, 210], [127, 212], [128, 212], [128, 213]] + }, + { + class: 'Annotation', + uuid: uuid(), + page: 1, + owner: 'admin', + type: 'drawing', + color: '000000', + x: 100, + y: 50, + lines: [[294, 161], [294, 160], [293, 159], [292, 159], [292, 157], [291, 156], [291, 156], [291, 155], [291, 154], [290, 153], [289, 152], [289, 152], [287, 152], [287, 151], [287, 150], [285, 150], [285, 148], [284, 147], [283, 147], [281, 147], [280, 146], [278, 144], [278, 144], [276, 144], [275, 143], [274, 143], [273, 142], [272, 142], [271, 141], [270, 141], [268, 141], [267, 141], [266, 141], [264, 141], [263, 141], [262, 140], [261, 140], [259, 140], [258, 140], [255, 140], [255, 140], [252, 140], [251, 140], [248, 140], [247, 140], [245, 140], [244, 140], [242, 140], [241, 140], [240, 140], [239, 140], [236, 141], [235, 141], [234, 142], [233, 142], [231, 143], [230, 143], [229, 144], [227, 144], [226, 144], [224, 146], [224, 147], [224, 148], [223, 149], [222, 149], [222, 150], [221, 151], [220, 151], [219, 152], [217, 153], [217, 154], [215, 156], [214, 157], [212, 158], [211, 160], [209, 161], [209, 163], [206, 164], [204, 166], [203, 166], [202, 168], [201, 169], [201, 170], [201, 171], [201, 172], [201, 173], [201, 174], [201, 175], [201, 176], [201, 177], [201, 179], [201, 180], [201, 181], [201, 183], [201, 184], [202, 185], [202, 187], [202, 188], [207, 200], [207, 203], [209, 206], [212, 211], [213, 214], [215, 215], [217, 219], [218, 220], [221, 222], [224, 225], [225, 225], [225, 226], [227, 226], [227, 226], [230, 226], [232, 226], [233, 226], [236, 226], [238, 228], [241, 228], [242, 228], [245, 228], [247, 228], [250, 228], [253, 228], [258, 230], [261, 231], [264, 231], [267, 231], [270, 233], [274, 234], [275, 234], [280, 236], [283, 236], [287, 237], [290, 239], [293, 239], [297, 242], [300, 243], [304, 246], [307, 248], [310, 251], [312, 253], [313, 253], [315, 256], [318, 257], [320, 259], [321, 261], [323, 263], [326, 266], [327, 268], [329, 270], [330, 272], [331, 274], [332, 276], [332, 277], [333, 279], [333, 281], [333, 283], [333, 285], [333, 287], [333, 289], [333, 291], [333, 293], [333, 294], [333, 297], [333, 298], [333, 299], [333, 301], [333, 302], [333, 304], [332, 305], [332, 306], [330, 308], [330, 308], [330, 309], [330, 310], [328, 311], [327, 312], [324, 315], [322, 317], [319, 318], [318, 319], [316, 320], [315, 322], [312, 323], [310, 325], [307, 326], [304, 327], [301, 328], [297, 329], [293, 331], [289, 331], [286, 331], [281, 332], [277, 332], [273, 332], [269, 332], [264, 332], [263, 332], [257, 332], [253, 332], [250, 332], [246, 332], [243, 332], [241, 332], [238, 332], [237, 331], [235, 331], [233, 331], [232, 331], [229, 329], [227, 329], [227, 328], [226, 327], [224, 327], [224, 326], [223, 325], [222, 325], [222, 324], [221, 322], [221, 322], [219, 322], [219, 320], [218, 320], [217, 319], [217, 317], [216, 316], [216, 314], [216, 313], [215, 311], [215, 310], [215, 308], [215, 307], [215, 306], [215, 305], [215, 304], [215, 302], [215, 302], [215, 300], [215, 299], [215, 298], [215, 297], [215, 296], [215, 295], [215, 292], [215, 291], [215, 290], [215, 289], [215, 288], [215, 287], [215, 285], [215, 285], [215, 284], [215, 282], [215, 282], [215, 280], [215, 279], [215, 278], [215, 278], [215, 276], [215, 276], [216, 275], [216, 274], [216, 273], [218, 273], [218, 272], [218, 271], [219, 270], [219, 269], [219, 268], [220, 267], [222, 267], [222, 266], [224, 264], [225, 263], [226, 261], [227, 260], [228, 260], [229, 258], [230, 257], [230, 256], [231, 255], [232, 254], [233, 253], [233, 252], [234, 250], [235, 250], [236, 249], [236, 248], [236, 247], [236, 246], [237, 244], [239, 243], [239, 242], [242, 240], [242, 239], [244, 239], [248, 237], [250, 237], [256, 234], [259, 232], [263, 231], [265, 229], [267, 228], [271, 226], [274, 226], [276, 225], [279, 223], [282, 223], [285, 221], [288, 220], [290, 220], [292, 219], [294, 217], [296, 217], [297, 216], [299, 215], [300, 215], [302, 215], [302, 214], [304, 212], [305, 212], [306, 211], [306, 210], [308, 210], [308, 209], [309, 208], [310, 207], [310, 206], [312, 206], [312, 205], [312, 204], [312, 203], [312, 203], [312, 202], [312, 201], [312, 200], [312, 199], [312, 198], [312, 197], [312, 196], [312, 195], [312, 194], [312, 193], [312, 192], [312, 192], [312, 190], [312, 189], [314, 187], [314, 187], [314, 186], [314, 185], [314, 182], [314, 181], [313, 181], [313, 179], [313, 179], [312, 179], [312, 178], [312, 176], [312, 176], [312, 175], [311, 174], [311, 173], [310, 172], [310, 171], [310, 170], [308, 170], [308, 169], [307, 168], [306, 167], [306, 166], [305, 166], [305, 166], [303, 166], [302, 165], [301, 165], [301, 164], [300, 164], [300, 163], [299, 163], [299, 162], [298, 162], [298, 161], [298, 161], [298, 160], [297, 160], [297, 159], [296, 159], [296, 157], [295, 157], [295, 157], [295, 157], [295, 156]] + } +]; diff --git a/example/helloworld.pdf b/example/helloworld.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d98b4e1dbef68af5863b06f7dac29f7d11a0ca2d GIT binary patch literal 678 zcmZuvO>e?5488kTc!x@xG)7t|9TMWemnLn~5bJH?5NKdUB|%BhV84ELDXe0P)GB%L zdw#YPOh=PO_>cgED9|i6hyg0??Gbk-*B*L3Ky0SRox$H4kO~spx+0j zGvWd;z?(X&3}w!%%5pg{2mGKYfsr_UbG{pzz4jRL_BqcSg|t{3=XG_4{!>30vShn* zL@G1o%-$}^Wa)*FiJ|-Iz{e2VWeQ>=QVrFQtY}YC4r9Kq=jZtA{H)6P-}eh&Hi=tR z)-jMyl{uSfzE!RZ?6PKsNRr6kyUi(jMx0&L+RdNf16cT~4z;py$ zKp0`Vg4-um6y_ekj4iU8J4`n)PI)91>pYx;RVxtK0dZN_iQ`s`E4*MKjfNNMUo7eV y!NP=waTV7R^oFjn$C{qEGB1>^3VhGM6`A2#8AG!_ciVYsed)E`jUWidZ<8MpEU1bA literal 0 HcmV?d00001 diff --git a/example/index.html b/example/index.html new file mode 100644 index 00000000..9e6e16b3 --- /dev/null +++ b/example/index.html @@ -0,0 +1,11 @@ + + + + + PDFJSAnnotate + + + + + + diff --git a/example/index.js b/example/index.js new file mode 100644 index 00000000..3bbce439 --- /dev/null +++ b/example/index.js @@ -0,0 +1,30 @@ +import __pdfjs from 'pdfjs-dist/build/pdf.js'; +import PDFJSAnnotate from '../'; +import annotations from './annotations'; + +PDFJS.workerSrc = '../node_modules/pdfjs-dist/build/pdf.worker.js'; + +PDFJSAnnotate.StoreAdapter.getAnnotations = (documentId, pageNumber) => { + return new Promise((resolve, reject) => { + resolve(annotations); + }); +}; + +PDFJS.getDocument('helloworld.pdf').then((pdf) => { + Promise.all([ + pdf.getPage(1), + PDFJSAnnotate.getAnnotations(1) + ]) + .then(([page, annotations]) => { + let scale = 3.5; + let viewport = page.getViewport(scale); + let canvas = document.getElementById('canvas'); + let canvasContext = canvas.getContext('2d'); + + canvas.height = viewport.height; + canvas.width = viewport.width; + + page.render({canvasContext, viewport}); + PDFJSAnnotate.render(viewport, annotations); + }); +}); diff --git a/index.js b/index.js new file mode 100644 index 00000000..c8ad845a --- /dev/null +++ b/index.js @@ -0,0 +1,3 @@ +import PDFJSAnnotate from './src/PDFJSAnnotate'; + +export default PDFJSAnnotate; diff --git a/package.json b/package.json new file mode 100644 index 00000000..ced23000 --- /dev/null +++ b/package.json @@ -0,0 +1,31 @@ +{ + "name": "pdf-annotate.js", + "version": "0.0.0", + "description": "Annotation layer for pdf.js", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "./node_modules/.bin/webpack-dev-server --inline --config ./webpack.example.js --content-base ./" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/mzabriskie/pdf-annotate.js.git" + }, + "keywords": [ + "pdf", + "annotation" + ], + "author": "Matt Zabriskie", + "license": "MIT", + "bugs": { + "url": "https://github.com/mzabriskie/pdf-annotate.js/issues" + }, + "homepage": "https://github.com/mzabriskie/pdf-annotate.js#readme", + "devDependencies": { + "babel-core": "5.8.22", + "babel-loader": "5.3.2", + "pdfjs-dist": "1.1.399", + "webpack": "1.11.0", + "webpack-dev-server": "1.10.1" + } +} diff --git a/src/AnnotateView.js b/src/AnnotateView.js new file mode 100644 index 00000000..a015d680 --- /dev/null +++ b/src/AnnotateView.js @@ -0,0 +1,26 @@ +import renderSVG from './render/renderSVG'; +import renderDrawing from './render/renderDrawing'; + +export default class AnnotateView { + constructor(viewport, annotations) { + this.viewport = viewport; + this.annotations = annotations; + } + + render() { + let svg = renderSVG(this.viewport); + + this.annotations.forEach((a) => { + let el; + switch (a.type) { + case 'drawing': + el = renderDrawing(a); + break; + } + + svg.appendChild(el); + }); + + document.body.appendChild(svg); + } +} diff --git a/src/PDFJSAnnotate.js b/src/PDFJSAnnotate.js new file mode 100644 index 00000000..e02c1f3f --- /dev/null +++ b/src/PDFJSAnnotate.js @@ -0,0 +1,18 @@ +import StoreAdapter from './StoreAdapter'; +import AnnotateView from './AnnotateView'; + +// Public API +let PDFJSAnnotate = { + StoreAdapter, + + getAnnotations(documentId, pageNumber) { + return this.StoreAdapter.getAnnotations(documentId, pageNumber); + }, + + render(viewport, annotations) { + let view = new AnnotateView(viewport, annotations); + view.render(); + } +}; + +export default PDFJSAnnotate; diff --git a/src/StoreAdapter.js b/src/StoreAdapter.js new file mode 100644 index 00000000..df259716 --- /dev/null +++ b/src/StoreAdapter.js @@ -0,0 +1,11 @@ +import abstractFunction from './utils/abstractFunction'; + +// Adapter should never be invoked publicly +let StoreAdapter = { + getAnnotations: abstractFunction('getAnnotations'), + addAnnotation: abstractFunction('addAnnotation'), + editAnnotation: abstractFunction('editAnnotation'), + deleteAnnotation: abstractFunction('deleteAnnotation') +}; + +export default StoreAdapter; diff --git a/src/render/renderDrawing.js b/src/render/renderDrawing.js new file mode 100644 index 00000000..423d19b6 --- /dev/null +++ b/src/render/renderDrawing.js @@ -0,0 +1,18 @@ +export default function renderDrawing(a) { + let d = []; + let path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); + + for (let i=0, l=a.lines.length; i