init
16
.browserslistrc
Normal file
@ -0,0 +1,16 @@
|
||||
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
|
||||
# For additional information regarding the format and rule options, please see:
|
||||
# https://github.com/browserslist/browserslist#queries
|
||||
|
||||
# For the full list of supported browsers by the Angular framework, please see:
|
||||
# https://angular.io/guide/browser-support
|
||||
|
||||
# You can see what browsers were selected by your queries by running:
|
||||
# npx browserslist
|
||||
|
||||
Chrome >=79
|
||||
ChromeAndroid >=79
|
||||
Firefox >=70
|
||||
Edge >=79
|
||||
Safari >=14
|
||||
iOS >=14
|
16
.editorconfig
Normal file
@ -0,0 +1,16 @@
|
||||
# Editor configuration, see https://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.ts]
|
||||
quote_type = single
|
||||
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
trim_trailing_whitespace = false
|
46
.eslintrc.json
Normal file
@ -0,0 +1,46 @@
|
||||
{
|
||||
"root": true,
|
||||
"ignorePatterns": ["projects/**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts"],
|
||||
"parserOptions": {
|
||||
"project": ["tsconfig.json"],
|
||||
"createDefaultProgram": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:@angular-eslint/recommended",
|
||||
"plugin:@angular-eslint/template/process-inline-templates"
|
||||
],
|
||||
"rules": {
|
||||
"@angular-eslint/component-class-suffix": [
|
||||
"error",
|
||||
{
|
||||
"suffixes": ["Page", "Component"]
|
||||
}
|
||||
],
|
||||
"@angular-eslint/component-selector": [
|
||||
"error",
|
||||
{
|
||||
"type": "element",
|
||||
"prefix": "app",
|
||||
"style": "kebab-case"
|
||||
}
|
||||
],
|
||||
"@angular-eslint/directive-selector": [
|
||||
"error",
|
||||
{
|
||||
"type": "attribute",
|
||||
"prefix": "app",
|
||||
"style": "camelCase"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["*.html"],
|
||||
"extends": ["plugin:@angular-eslint/template/recommended"],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
68
.gitignore
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
# Specifies intentionally untracked files to ignore when using Git
|
||||
# http://git-scm.com/docs/gitignore
|
||||
|
||||
*~
|
||||
*.sw[mnpcod]
|
||||
.tmp
|
||||
*.tmp
|
||||
*.tmp.*
|
||||
UserInterfaceState.xcuserstate
|
||||
$RECYCLE.BIN/
|
||||
|
||||
*.log
|
||||
log.txt
|
||||
|
||||
|
||||
/.sourcemaps
|
||||
/.versions
|
||||
/coverage
|
||||
|
||||
# Ionic
|
||||
/.ionic
|
||||
/www
|
||||
/platforms
|
||||
/plugins
|
||||
|
||||
# Compiled output
|
||||
/dist
|
||||
/tmp
|
||||
/out-tsc
|
||||
/bazel-out
|
||||
|
||||
# Node
|
||||
/node_modules
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
|
||||
# IDEs and editors
|
||||
.idea/
|
||||
.project
|
||||
.classpath
|
||||
.c9/
|
||||
*.launch
|
||||
.settings/
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
|
||||
# Visual Studio Code
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
.history/*
|
||||
|
||||
|
||||
# Miscellaneous
|
||||
/.angular
|
||||
/.angular/cache
|
||||
.sass-cache/
|
||||
/connect.lock
|
||||
/coverage
|
||||
/libpeerconnection.log
|
||||
testem.log
|
||||
/typings
|
||||
|
||||
# System files
|
||||
.DS_Store
|
||||
Thumbs.db
|
5
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"ionic.ionic"
|
||||
]
|
||||
}
|
3
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"typescript.preferences.autoImportFileExcludePatterns": ["@ionic/angular/common", "@ionic/angular/standalone"]
|
||||
}
|
3
README.md
Normal file
@ -0,0 +1,3 @@
|
||||
### pdf js annotation 的 Demo
|
||||
是一个 ionic 的项目,为了山核项目准备的。
|
||||
在满足山核功能的基础上,精简了界面,处理了保存功能。
|
179
angular.json
Normal file
@ -0,0 +1,179 @@
|
||||
{
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"version": 1,
|
||||
"newProjectRoot": "projects",
|
||||
"projects": {
|
||||
"app": {
|
||||
"projectType": "application",
|
||||
"schematics": {},
|
||||
"root": "",
|
||||
"sourceRoot": "src",
|
||||
"prefix": "app",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "www",
|
||||
"index": "src/index.html",
|
||||
"main": "src/main.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"inlineStyleLanguage": "scss",
|
||||
"assets": [
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "src/assets",
|
||||
"output": "assets"
|
||||
},
|
||||
{
|
||||
"glob": "**/*.svg",
|
||||
"input": "node_modules/ionicons/dist/ionicons/svg",
|
||||
"output": "./svg"
|
||||
}
|
||||
],
|
||||
"styles": [
|
||||
"src/global.scss",
|
||||
"src/theme/variables.scss"
|
||||
],
|
||||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "2mb",
|
||||
"maximumError": "5mb"
|
||||
},
|
||||
{
|
||||
"type": "anyComponentStyle",
|
||||
"maximumWarning": "2kb",
|
||||
"maximumError": "4kb"
|
||||
}
|
||||
],
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"outputHashing": "all"
|
||||
},
|
||||
"development": {
|
||||
"buildOptimizer": false,
|
||||
"optimization": false,
|
||||
"vendorChunk": true,
|
||||
"extractLicenses": false,
|
||||
"sourceMap": true,
|
||||
"namedChunks": true
|
||||
},
|
||||
"ci": {
|
||||
"progress": false
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"configurations": {
|
||||
"production": {
|
||||
"buildTarget": "app:build:production"
|
||||
},
|
||||
"development": {
|
||||
"buildTarget": "app:build:development"
|
||||
},
|
||||
"ci": {
|
||||
"progress": false
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"buildTarget": "app:build"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "src/test.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.spec.json",
|
||||
"karmaConfig": "karma.conf.js",
|
||||
"inlineStyleLanguage": "scss",
|
||||
"assets": [
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "src/assets",
|
||||
"output": "assets"
|
||||
},
|
||||
{
|
||||
"glob": "**/*.svg",
|
||||
"input": "node_modules/ionicons/dist/ionicons/svg",
|
||||
"output": "./svg"
|
||||
}
|
||||
],
|
||||
"styles": [
|
||||
"src/global.scss",
|
||||
"src/theme/variables.scss"
|
||||
],
|
||||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
"ci": {
|
||||
"progress": false,
|
||||
"watch": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-eslint/builder:lint",
|
||||
"options": {
|
||||
"lintFilePatterns": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.html"
|
||||
]
|
||||
}
|
||||
},
|
||||
"ionic-cordova-serve": {
|
||||
"builder": "@ionic/cordova-builders:cordova-serve",
|
||||
"options": {
|
||||
"cordovaBuildTarget": "app:ionic-cordova-build",
|
||||
"devServerTarget": "app:serve"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"cordovaBuildTarget": "app:ionic-cordova-build:production",
|
||||
"devServerTarget": "app:serve:production"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ionic-cordova-build": {
|
||||
"builder": "@ionic/cordova-builders:cordova-build",
|
||||
"options": {
|
||||
"browserTarget": "app:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "app:build:production"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"cli": {
|
||||
"schematicCollections": [
|
||||
"@ionic/angular-toolkit"
|
||||
]
|
||||
},
|
||||
"schematics": {
|
||||
"@ionic/angular-toolkit:component": {
|
||||
"styleext": "scss"
|
||||
},
|
||||
"@ionic/angular-toolkit:page": {
|
||||
"styleext": "scss"
|
||||
}
|
||||
}
|
||||
}
|
101
config.xml
Normal file
@ -0,0 +1,101 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<widget id="cn.shuto.demo.pdfannotation" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
|
||||
<name>pdfannotation-demo</name>
|
||||
<description>An awesome Ionic/Cordova app.</description>
|
||||
<author email="hi@ionicframework.com" href="http://ionicframework.com/">Ionic Framework Team</author>
|
||||
<content src="index.html" />
|
||||
<access origin="*" />
|
||||
<allow-intent href="http://*/*" />
|
||||
<allow-intent href="https://*/*" />
|
||||
<allow-intent href="tel:*" />
|
||||
<allow-intent href="sms:*" />
|
||||
<allow-intent href="mailto:*" />
|
||||
<allow-intent href="geo:*" />
|
||||
<preference name="ScrollEnabled" value="false" />
|
||||
<preference name="BackupWebStorage" value="none" />
|
||||
<preference name="SplashMaintainAspectRatio" value="true" />
|
||||
<preference name="FadeSplashScreenDuration" value="300" />
|
||||
<preference name="SplashShowOnlyFirstTime" value="false" />
|
||||
<preference name="SplashScreen" value="screen" />
|
||||
<preference name="SplashScreenDelay" value="3000" />
|
||||
<platform name="android">
|
||||
<preference name="Scheme" value="http" />
|
||||
<edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<application android:networkSecurityConfig="@xml/network_security_config" />
|
||||
</edit-config>
|
||||
<resource-file src="resources/android/xml/network_security_config.xml" target="app/src/main/res/xml/network_security_config.xml" />
|
||||
<allow-intent href="market:*" />
|
||||
<icon density="ldpi" src="resources/android/icon/drawable-ldpi-icon.png" />
|
||||
<icon density="mdpi" src="resources/android/icon/drawable-mdpi-icon.png" />
|
||||
<icon density="hdpi" src="resources/android/icon/drawable-hdpi-icon.png" />
|
||||
<icon density="xhdpi" src="resources/android/icon/drawable-xhdpi-icon.png" />
|
||||
<icon density="xxhdpi" src="resources/android/icon/drawable-xxhdpi-icon.png" />
|
||||
<icon density="xxxhdpi" src="resources/android/icon/drawable-xxxhdpi-icon.png" />
|
||||
<splash density="land-ldpi" src="resources/android/splash/drawable-land-ldpi-screen.png" />
|
||||
<splash density="land-mdpi" src="resources/android/splash/drawable-land-mdpi-screen.png" />
|
||||
<splash density="land-hdpi" src="resources/android/splash/drawable-land-hdpi-screen.png" />
|
||||
<splash density="land-xhdpi" src="resources/android/splash/drawable-land-xhdpi-screen.png" />
|
||||
<splash density="land-xxhdpi" src="resources/android/splash/drawable-land-xxhdpi-screen.png" />
|
||||
<splash density="land-xxxhdpi" src="resources/android/splash/drawable-land-xxxhdpi-screen.png" />
|
||||
<splash density="port-ldpi" src="resources/android/splash/drawable-port-ldpi-screen.png" />
|
||||
<splash density="port-mdpi" src="resources/android/splash/drawable-port-mdpi-screen.png" />
|
||||
<splash density="port-hdpi" src="resources/android/splash/drawable-port-hdpi-screen.png" />
|
||||
<splash density="port-xhdpi" src="resources/android/splash/drawable-port-xhdpi-screen.png" />
|
||||
<splash density="port-xxhdpi" src="resources/android/splash/drawable-port-xxhdpi-screen.png" />
|
||||
<splash density="port-xxxhdpi" src="resources/android/splash/drawable-port-xxxhdpi-screen.png" />
|
||||
</platform>
|
||||
<platform name="ios">
|
||||
<allow-intent href="itms:*" />
|
||||
<allow-intent href="itms-apps:*" />
|
||||
<icon height="57" src="resources/ios/icon/icon.png" width="57" />
|
||||
<icon height="114" src="resources/ios/icon/icon@2x.png" width="114" />
|
||||
<icon height="29" src="resources/ios/icon/icon-small.png" width="29" />
|
||||
<icon height="58" src="resources/ios/icon/icon-small@2x.png" width="58" />
|
||||
<icon height="87" src="resources/ios/icon/icon-small@3x.png" width="87" />
|
||||
<icon height="20" src="resources/ios/icon/icon-20.png" width="20" />
|
||||
<icon height="40" src="resources/ios/icon/icon-20@2x.png" width="40" />
|
||||
<icon height="60" src="resources/ios/icon/icon-20@3x.png" width="60" />
|
||||
<icon height="48" src="resources/ios/icon/icon-24@2x.png" width="48" />
|
||||
<icon height="55" src="resources/ios/icon/icon-27.5@2x.png" width="55" />
|
||||
<icon height="29" src="resources/ios/icon/icon-29.png" width="29" />
|
||||
<icon height="58" src="resources/ios/icon/icon-29@2x.png" width="58" />
|
||||
<icon height="87" src="resources/ios/icon/icon-29@3x.png" width="87" />
|
||||
<icon height="40" src="resources/ios/icon/icon-40.png" width="40" />
|
||||
<icon height="80" src="resources/ios/icon/icon-40@2x.png" width="80" />
|
||||
<icon height="120" src="resources/ios/icon/icon-40@3x.png" width="120" />
|
||||
<icon height="88" src="resources/ios/icon/icon-44@2x.png" width="88" />
|
||||
<icon height="50" src="resources/ios/icon/icon-50.png" width="50" />
|
||||
<icon height="100" src="resources/ios/icon/icon-50@2x.png" width="100" />
|
||||
<icon height="60" src="resources/ios/icon/icon-60.png" width="60" />
|
||||
<icon height="120" src="resources/ios/icon/icon-60@2x.png" width="120" />
|
||||
<icon height="180" src="resources/ios/icon/icon-60@3x.png" width="180" />
|
||||
<icon height="72" src="resources/ios/icon/icon-72.png" width="72" />
|
||||
<icon height="144" src="resources/ios/icon/icon-72@2x.png" width="144" />
|
||||
<icon height="76" src="resources/ios/icon/icon-76.png" width="76" />
|
||||
<icon height="152" src="resources/ios/icon/icon-76@2x.png" width="152" />
|
||||
<icon height="167" src="resources/ios/icon/icon-83.5@2x.png" width="167" />
|
||||
<icon height="172" src="resources/ios/icon/icon-86@2x.png" width="172" />
|
||||
<icon height="196" src="resources/ios/icon/icon-98@2x.png" width="196" />
|
||||
<icon height="1024" src="resources/ios/icon/icon-1024.png" width="1024" />
|
||||
<splash height="480" src="resources/ios/splash/Default~iphone.png" width="320" />
|
||||
<splash height="960" src="resources/ios/splash/Default@2x~iphone.png" width="640" />
|
||||
<splash height="1024" src="resources/ios/splash/Default-Portrait~ipad.png" width="768" />
|
||||
<splash height="768" src="resources/ios/splash/Default-Landscape~ipad.png" width="1024" />
|
||||
<splash height="1125" src="resources/ios/splash/Default-Landscape-2436h.png" width="2436" />
|
||||
<splash height="1242" src="resources/ios/splash/Default-Landscape-736h.png" width="2208" />
|
||||
<splash height="2048" src="resources/ios/splash/Default-Portrait@2x~ipad.png" width="1536" />
|
||||
<splash height="1536" src="resources/ios/splash/Default-Landscape@2x~ipad.png" width="2048" />
|
||||
<splash height="2732" src="resources/ios/splash/Default-Portrait@~ipadpro.png" width="2048" />
|
||||
<splash height="2048" src="resources/ios/splash/Default-Landscape@~ipadpro.png" width="2732" />
|
||||
<splash height="1136" src="resources/ios/splash/Default-568h@2x~iphone.png" width="640" />
|
||||
<splash height="1334" src="resources/ios/splash/Default-667h.png" width="750" />
|
||||
<splash height="2208" src="resources/ios/splash/Default-736h.png" width="1242" />
|
||||
<splash height="2436" src="resources/ios/splash/Default-2436h.png" width="1125" />
|
||||
<splash height="2732" src="resources/ios/splash/Default@2x~universal~anyany.png" width="2732" />
|
||||
</platform>
|
||||
<plugin name="cordova-plugin-statusbar" spec="2.4.2" />
|
||||
<plugin name="cordova-plugin-device" spec="2.0.2" />
|
||||
<plugin name="cordova-plugin-splashscreen" spec="5.0.2" />
|
||||
<plugin name="cordova-plugin-ionic-webview" spec="^5.0.0" />
|
||||
<plugin name="cordova-plugin-ionic-keyboard" spec="^2.0.5" />
|
||||
</widget>
|
7
ionic.config.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "pdfannotation-demo",
|
||||
"integrations": {
|
||||
"cordova": {}
|
||||
},
|
||||
"type": "angular"
|
||||
}
|
44
karma.conf.js
Normal file
@ -0,0 +1,44 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage'),
|
||||
require('@angular-devkit/build-angular/plugins/karma')
|
||||
],
|
||||
client: {
|
||||
jasmine: {
|
||||
// you can add configuration options for Jasmine here
|
||||
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
|
||||
// for example, you can disable the random execution with `random: false`
|
||||
// or set a specific seed with `seed: 4321`
|
||||
},
|
||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
jasmineHtmlReporter: {
|
||||
suppressAll: true // removes the duplicated traces
|
||||
},
|
||||
coverageReporter: {
|
||||
dir: require('path').join(__dirname, './coverage/app'),
|
||||
subdir: '.',
|
||||
reporters: [
|
||||
{ type: 'html' },
|
||||
{ type: 'text-summary' }
|
||||
]
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true
|
||||
});
|
||||
};
|
15829
package-lock.json
generated
Normal file
77
package.json
Normal file
@ -0,0 +1,77 @@
|
||||
{
|
||||
"name": "pdfannotation-demo",
|
||||
"version": "0.0.1",
|
||||
"author": "Ionic Framework",
|
||||
"homepage": "https://ionicframework.com/",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"watch": "ng build --watch --configuration development",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^17.0.2",
|
||||
"@angular/common": "^17.0.2",
|
||||
"@angular/compiler": "^17.0.2",
|
||||
"@angular/core": "^17.0.2",
|
||||
"@angular/forms": "^17.0.2",
|
||||
"@angular/platform-browser": "^17.0.2",
|
||||
"@angular/platform-browser-dynamic": "^17.0.2",
|
||||
"@angular/router": "^17.0.2",
|
||||
"@ionic/angular": "^7.0.0",
|
||||
"@ionic/cordova-builders": "^11.0.0",
|
||||
"ionicons": "^7.0.0",
|
||||
"rxjs": "~7.8.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.14.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "^17.0.0",
|
||||
"@angular-eslint/builder": "^17.0.0",
|
||||
"@angular-eslint/eslint-plugin": "^17.0.0",
|
||||
"@angular-eslint/eslint-plugin-template": "^17.0.0",
|
||||
"@angular-eslint/schematics": "^17.0.0",
|
||||
"@angular-eslint/template-parser": "^17.0.0",
|
||||
"@angular/cli": "^17.0.0",
|
||||
"@angular/compiler-cli": "^17.0.2",
|
||||
"@angular/language-service": "^17.0.2",
|
||||
"@ionic/angular-toolkit": "^11.0.1",
|
||||
"@types/jasmine": "~5.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
||||
"@typescript-eslint/parser": "^6.0.0",
|
||||
"cordova-android": "^12.0.1",
|
||||
"cordova-plugin-device": "2.0.2",
|
||||
"cordova-plugin-ionic-keyboard": "^2.0.5",
|
||||
"cordova-plugin-ionic-webview": "^5.0.0",
|
||||
"cordova-plugin-splashscreen": "5.0.2",
|
||||
"cordova-plugin-statusbar": "^2.4.2",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"eslint-plugin-jsdoc": "^48.2.1",
|
||||
"eslint-plugin-prefer-arrow": "1.2.2",
|
||||
"jasmine-core": "~5.1.0",
|
||||
"jasmine-spec-reporter": "~5.0.0",
|
||||
"karma": "~6.4.0",
|
||||
"karma-chrome-launcher": "~3.2.0",
|
||||
"karma-coverage": "~2.2.0",
|
||||
"karma-jasmine": "~5.1.0",
|
||||
"karma-jasmine-html-reporter": "~2.1.0",
|
||||
"typescript": "~5.2.2"
|
||||
},
|
||||
"description": "An Ionic project",
|
||||
"cordova": {
|
||||
"plugins": {
|
||||
"cordova-plugin-statusbar": {},
|
||||
"cordova-plugin-device": {},
|
||||
"cordova-plugin-splashscreen": {},
|
||||
"cordova-plugin-ionic-webview": {},
|
||||
"cordova-plugin-ionic-keyboard": {}
|
||||
},
|
||||
"platforms": [
|
||||
"android"
|
||||
]
|
||||
}
|
||||
}
|
8
resources/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
These are Cordova resources. You can replace icon.png and splash.png and run
|
||||
`ionic cordova resources` to generate custom icons and splash screens for your
|
||||
app. See `ionic cordova resources --help` for details.
|
||||
|
||||
Cordova reference documentation:
|
||||
|
||||
- Icons: https://cordova.apache.org/docs/en/latest/config_ref/images.html
|
||||
- Splash Screens: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-splashscreen/
|
BIN
resources/android/icon/drawable-hdpi-icon.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
resources/android/icon/drawable-ldpi-icon.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
resources/android/icon/drawable-mdpi-icon.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
resources/android/icon/drawable-xhdpi-icon.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
resources/android/icon/drawable-xxhdpi-icon.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
resources/android/icon/drawable-xxxhdpi-icon.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
resources/android/splash/drawable-land-hdpi-screen.png
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
resources/android/splash/drawable-land-ldpi-screen.png
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
resources/android/splash/drawable-land-mdpi-screen.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
resources/android/splash/drawable-land-xhdpi-screen.png
Normal file
After Width: | Height: | Size: 47 KiB |
BIN
resources/android/splash/drawable-land-xxhdpi-screen.png
Normal file
After Width: | Height: | Size: 79 KiB |
BIN
resources/android/splash/drawable-land-xxxhdpi-screen.png
Normal file
After Width: | Height: | Size: 111 KiB |
BIN
resources/android/splash/drawable-port-hdpi-screen.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
resources/android/splash/drawable-port-ldpi-screen.png
Normal file
After Width: | Height: | Size: 8.0 KiB |
BIN
resources/android/splash/drawable-port-mdpi-screen.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
resources/android/splash/drawable-port-xhdpi-screen.png
Normal file
After Width: | Height: | Size: 47 KiB |
BIN
resources/android/splash/drawable-port-xxhdpi-screen.png
Normal file
After Width: | Height: | Size: 69 KiB |
BIN
resources/android/splash/drawable-port-xxxhdpi-screen.png
Normal file
After Width: | Height: | Size: 99 KiB |
6
resources/android/xml/network_security_config.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<domain-config cleartextTrafficPermitted="true">
|
||||
<domain includeSubdomains="true">localhost</domain>
|
||||
</domain-config>
|
||||
</network-security-config>
|
BIN
resources/icon.png
Normal file
After Width: | Height: | Size: 59 KiB |
BIN
resources/ios/icon/icon-1024.png
Normal file
After Width: | Height: | Size: 60 KiB |
BIN
resources/ios/icon/icon-20.png
Normal file
After Width: | Height: | Size: 686 B |
BIN
resources/ios/icon/icon-20@2x.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
resources/ios/icon/icon-20@3x.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
resources/ios/icon/icon-24@2x.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
resources/ios/icon/icon-27.5@2x.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
resources/ios/icon/icon-29.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/ios/icon/icon-29@2x.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
resources/ios/icon/icon-29@3x.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
resources/ios/icon/icon-40.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
resources/ios/icon/icon-40@2x.png
Normal file
After Width: | Height: | Size: 5.1 KiB |
BIN
resources/ios/icon/icon-40@3x.png
Normal file
After Width: | Height: | Size: 8.1 KiB |
BIN
resources/ios/icon/icon-44@2x.png
Normal file
After Width: | Height: | Size: 5.7 KiB |
BIN
resources/ios/icon/icon-50.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
resources/ios/icon/icon-50@2x.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
resources/ios/icon/icon-60.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
resources/ios/icon/icon-60@2x.png
Normal file
After Width: | Height: | Size: 8.1 KiB |
BIN
resources/ios/icon/icon-60@3x.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
resources/ios/icon/icon-72.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
resources/ios/icon/icon-72@2x.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
resources/ios/icon/icon-76.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
resources/ios/icon/icon-76@2x.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
resources/ios/icon/icon-83.5@2x.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
resources/ios/icon/icon-86@2x.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
resources/ios/icon/icon-98@2x.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
resources/ios/icon/icon-small.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/ios/icon/icon-small@2x.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
resources/ios/icon/icon-small@3x.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
resources/ios/icon/icon.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
resources/ios/icon/icon@2x.png
Normal file
After Width: | Height: | Size: 8.0 KiB |
BIN
resources/ios/splash/Default-2436h.png
Normal file
After Width: | Height: | Size: 104 KiB |
BIN
resources/ios/splash/Default-568h@2x~iphone.png
Normal file
After Width: | Height: | Size: 39 KiB |
BIN
resources/ios/splash/Default-667h.png
Normal file
After Width: | Height: | Size: 50 KiB |
BIN
resources/ios/splash/Default-736h.png
Normal file
After Width: | Height: | Size: 106 KiB |
BIN
resources/ios/splash/Default-Landscape-2436h.png
Normal file
After Width: | Height: | Size: 113 KiB |
BIN
resources/ios/splash/Default-Landscape-736h.png
Normal file
After Width: | Height: | Size: 117 KiB |
BIN
resources/ios/splash/Default-Landscape@2x~ipad.png
Normal file
After Width: | Height: | Size: 133 KiB |
BIN
resources/ios/splash/Default-Landscape@~ipadpro.png
Normal file
After Width: | Height: | Size: 93 KiB |
BIN
resources/ios/splash/Default-Landscape~ipad.png
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
resources/ios/splash/Default-Portrait@2x~ipad.png
Normal file
After Width: | Height: | Size: 147 KiB |
BIN
resources/ios/splash/Default-Portrait@~ipadpro.png
Normal file
After Width: | Height: | Size: 99 KiB |
BIN
resources/ios/splash/Default-Portrait~ipad.png
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
resources/ios/splash/Default@2x~iphone.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
resources/ios/splash/Default@2x~universal~anyany.png
Normal file
After Width: | Height: | Size: 120 KiB |
BIN
resources/ios/splash/Default~iphone.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
resources/splash.png
Normal file
After Width: | Height: | Size: 77 KiB |
22
src/app/app-routing.module.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: 'home',
|
||||
loadChildren: () => import('./home/home.module').then( m => m.HomePageModule)
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
redirectTo: 'home',
|
||||
pathMatch: 'full'
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules, useHash: false })
|
||||
],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class AppRoutingModule { }
|
3
src/app/app.component.html
Normal file
@ -0,0 +1,3 @@
|
||||
<ion-app>
|
||||
<ion-router-outlet></ion-router-outlet>
|
||||
</ion-app>
|
0
src/app/app.component.scss
Normal file
21
src/app/app.component.spec.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [AppComponent],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
it('should create the app', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
});
|
||||
|
||||
});
|
10
src/app/app.component.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: 'app.component.html',
|
||||
styleUrls: ['app.component.scss'],
|
||||
})
|
||||
export class AppComponent {
|
||||
constructor() {}
|
||||
}
|
16
src/app/app.module.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { RouteReuseStrategy } from '@angular/router';
|
||||
|
||||
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent],
|
||||
imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule],
|
||||
providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
export class AppModule {}
|
16
src/app/home/home-routing.module.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { HomePage } from './home.page';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: HomePage,
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class HomePageRoutingModule {}
|
19
src/app/home/home.module.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { HomePage } from './home.page';
|
||||
|
||||
import { HomePageRoutingModule } from './home-routing.module';
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
IonicModule,
|
||||
HomePageRoutingModule
|
||||
],
|
||||
declarations: [HomePage]
|
||||
})
|
||||
export class HomePageModule {}
|
17
src/app/home/home.page.html
Normal file
@ -0,0 +1,17 @@
|
||||
<ion-header [translucent]="true">
|
||||
<ion-toolbar>
|
||||
<ion-title>
|
||||
PDF标注 Demo
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content [fullscreen]="true" scroll-y="false">
|
||||
<ion-header collapse="condense">
|
||||
<ion-toolbar>
|
||||
<ion-title size="large">PDF标注 Demo</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<iframe id='my-pdfjs-iframe' class='sticky-container' src="/assets/pdf-annotation/web/viewer.html?file=tutorial.pdf&user=shuto" frameborder="0" width="100%" height="100%"></iframe>
|
||||
</ion-content>
|
27
src/app/home/home.page.scss
Normal file
@ -0,0 +1,27 @@
|
||||
#container {
|
||||
text-align: center;
|
||||
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
#container strong {
|
||||
font-size: 20px;
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
#container p {
|
||||
font-size: 16px;
|
||||
line-height: 22px;
|
||||
|
||||
color: #8c8c8c;
|
||||
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#container a {
|
||||
text-decoration: none;
|
||||
}
|
24
src/app/home/home.page.spec.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
|
||||
import { HomePage } from './home.page';
|
||||
|
||||
describe('HomePage', () => {
|
||||
let component: HomePage;
|
||||
let fixture: ComponentFixture<HomePage>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [HomePage],
|
||||
imports: [IonicModule.forRoot()]
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(HomePage);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
16
src/app/home/home.page.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-home',
|
||||
templateUrl: 'home.page.html',
|
||||
styleUrls: ['home.page.scss'],
|
||||
})
|
||||
export class HomePage {
|
||||
|
||||
constructor() {}
|
||||
|
||||
}
|
||||
|
||||
window.addEventListener("message", function(event: any){
|
||||
console.log(event);
|
||||
}, false);
|
BIN
src/assets/icon/favicon.png
Normal file
After Width: | Height: | Size: 930 B |
5364
src/assets/pdf-annotation/annotation/annotation.js
Executable file
829
src/assets/pdf-annotation/annotation/config.js
Executable file
@ -0,0 +1,829 @@
|
||||
var post_to_parent = false;
|
||||
var shiftKeyPressed = false;
|
||||
// tips_language决定了操作提示语
|
||||
var tips_language = 'zh-cn';
|
||||
// var tips_language = 'en';
|
||||
var first_load = true;
|
||||
var default_show_annotation_list = false; //控制右侧列表是否默认显示
|
||||
if (window.screen.availWidth <= 650) {
|
||||
default_show_annotation_list = false;
|
||||
}
|
||||
|
||||
var last_connect_id = '-1';
|
||||
var run_in_angular=true;
|
||||
|
||||
var select_link_type='url'; //超链接类型
|
||||
var current_link_annotation_item=null; //当前批注对象
|
||||
var is_hyper_link_highlight=false; //是否高亮
|
||||
var is_hyper_edit=false; //是否高亮
|
||||
var hyper_open_page=1;
|
||||
var hyper_open_file=false;
|
||||
|
||||
var show_state = {}; //是否默认显示页面的批注列表
|
||||
|
||||
var add_water_mark = false; //是否添加水印
|
||||
|
||||
var show_my_menu = false; //显示颜色控制面板
|
||||
var fold_my_munu=false;
|
||||
var show_setting_menu = false; //显示配置面板
|
||||
var changed_number_value = false; //修改颜色面板的内容
|
||||
var onload_record_history = true; //加载时保存一次历史记录
|
||||
var object_modified = false; //对象是否被编辑
|
||||
|
||||
// var add_annotation_list_title=true; //保留批注的表头按钮
|
||||
var add_annotation_list_title=false; //保留批注的表头按钮
|
||||
|
||||
//是否默认显示批注
|
||||
var hidden_open = '';
|
||||
var hidden_close = '';
|
||||
if (default_show_annotation_list == false) {
|
||||
hidden_open = "hidden='true'";
|
||||
} else {
|
||||
hidden_close = "hidden='true'";
|
||||
}
|
||||
|
||||
var default_show_onepage_annotation_list = false; //控制右侧列表每页批注是否默认展开
|
||||
|
||||
var hidden_container = '';
|
||||
if (default_show_onepage_annotation_list == false) {
|
||||
hidden_container = "hidden='true'";
|
||||
hidden_open = "hidden='true'";
|
||||
hidden_close = "";
|
||||
} else {
|
||||
hidden_close = "hidden='true'";
|
||||
hidden_open = "";
|
||||
}
|
||||
|
||||
var defult_left = 0;
|
||||
var defult_top = 0;
|
||||
var left_top_offset = 30;
|
||||
|
||||
//默认在视图上的显示比例
|
||||
var show_scale_value = 1;
|
||||
|
||||
//下划线宽度和画笔宽度
|
||||
var default_underline_width = 1;
|
||||
var default_brush_width = 15;
|
||||
var default_arrow_width = 3; //箭头粗细
|
||||
|
||||
//橡皮擦的默认大小
|
||||
var default_eraser_brush_width = 30;
|
||||
var default_text_size = 30;
|
||||
|
||||
//待提取的pdf页面列表
|
||||
var extract_page_numbers = [];
|
||||
|
||||
var default_brush_opacity=100;
|
||||
var default_fill_color_opacity = 30; //填充色不透明度
|
||||
var default_border_color_opacity = 100; //边框色不透明度
|
||||
//各类批注的的颜色
|
||||
var default_border_color = "rgba(17, 153,158,1)";
|
||||
var default_text_color = "rgba(17, 153,158,1)";
|
||||
var default_fill_color = 'rgba(255, 237, 0,0.30)';
|
||||
var default_hyperlink_fill_color = 'rgba(0,129,255,0.3)';
|
||||
var default_stamp_color = "#0081FF";
|
||||
var default_brush_color = '#E60000';
|
||||
// var default_brush_decimate = 10; //画笔拐角流畅度
|
||||
var default_brush_decimate = 0; //画笔拐角流畅度
|
||||
var default_screenshot_rect_fill_color = 'rgba(236, 240, 241,0.5)';
|
||||
var default_screenshot_rect_background_color = "rgba(17, 153,158,1)";
|
||||
var default_screenshot_rect_text_color = 'rgba(255, 255, 255,1)';
|
||||
var default_transparency_color = 'rgba(255, 255, 255,0)';
|
||||
var default_highlight_color = 'rgba(255, 237, 0,1)';
|
||||
var default_hyper_highlight_color='rgba(0,129,255,1)';
|
||||
var default_underline_color = 'rgba(57, 181, 74,1)';
|
||||
var defult_top = 0;
|
||||
var defult_screen_shot_top = 30;
|
||||
var default_eraser_color = "#0081FF";
|
||||
|
||||
var default_text;
|
||||
var default_idcard_stamp;
|
||||
var default_triangle;
|
||||
var default_line;
|
||||
var default_check_left_line;
|
||||
var default_check_right_line;
|
||||
var default_rectangle;
|
||||
var default_straight_line;
|
||||
var default_screenshot_text;
|
||||
var default_screenshot_rectangle;
|
||||
var default_circle;
|
||||
var default_fill_opacity;
|
||||
|
||||
//设置默认批注对象
|
||||
function setDefaultAnnotations() {
|
||||
//default annotation object 默认批注对象
|
||||
default_text = {
|
||||
left: defult_left,
|
||||
top: defult_top,
|
||||
fill: default_text_color,
|
||||
fontSize: default_text_size,
|
||||
selectable: true,
|
||||
id: 'id',
|
||||
};
|
||||
|
||||
//身份印章配置,包括颜色,文字大小等
|
||||
default_idcard_stamp = {
|
||||
left: defult_left,
|
||||
top: defult_top,
|
||||
fill: default_stamp_color,
|
||||
textAlign: 'center',
|
||||
fontSize: 25,
|
||||
selectable: true,
|
||||
padding: 2,
|
||||
my_type:'idcard_stamp_text',
|
||||
};
|
||||
|
||||
default_triangle = {
|
||||
width: 30,
|
||||
height: 40,
|
||||
fill: default_border_color,
|
||||
left: 200 + left_top_offset,
|
||||
top: 0 + left_top_offset,
|
||||
angle: 90,
|
||||
};
|
||||
|
||||
default_line = {
|
||||
left: 0 + left_top_offset,
|
||||
top: 13 + left_top_offset,
|
||||
strokeWidth: 4,
|
||||
stroke: default_border_color,
|
||||
};
|
||||
|
||||
//对勾预制函数,由左右两条线构成
|
||||
var default_check_width = 12;
|
||||
default_check_left_line = {
|
||||
left: 66 + default_check_width / 2 + left_top_offset,
|
||||
top: 54 + default_check_width + left_top_offset,
|
||||
angle: 67,
|
||||
strokeWidth: default_check_width,
|
||||
stroke: default_stamp_color,
|
||||
};
|
||||
|
||||
default_check_right_line = {
|
||||
left: 210 + default_check_width / 4 + left_top_offset,
|
||||
top: 10 + default_check_width + left_top_offset,
|
||||
angle: 135,
|
||||
strokeWidth: default_check_width,
|
||||
stroke: default_stamp_color,
|
||||
};
|
||||
|
||||
default_rectangle = {
|
||||
left: defult_left,
|
||||
top: defult_top,
|
||||
width: 300,
|
||||
height: 300,
|
||||
fill: default_fill_color,
|
||||
stroke: default_border_color,
|
||||
strokeSize: 1,
|
||||
id: 'id',
|
||||
};
|
||||
|
||||
// let line1 = new fabric.Line([lineleft, lineheight, lineleft,
|
||||
// 0], { //终止位置,线长,起始位置,top,这里是从项目中截下来的我用了变量代替,你要用的话lineheight和lineleft用自己的变量或者数字代替。如果两个终止位置和起始位置的数值一样那么这个线条会垂直,这个应该很好理解。
|
||||
// fill: '#5E2300', //填充颜色
|
||||
// stroke: '#5E2300', //笔触颜色
|
||||
// strokeWidth: 2, //笔触宽度
|
||||
// hasControls: false, //选中时是否可以放大缩小
|
||||
// hasRotatingPoint: false, //选中时是否可以旋转
|
||||
// hasBorders: false, //选中时是否有边框
|
||||
// transparentCorners: true,
|
||||
// perPixelTargetFind: true, //默认false。当设置为true,对象的检测会以像互点为基础,而不是以边界的盒模型为基础。
|
||||
// selectable: true, //是否可被选中
|
||||
// lockMovementX: true, //X轴是否可被移动(true为不可,因为前缀是lock)
|
||||
// lockMovementY: true, //Y轴是否可被移动(true为不可,因为前缀是lock)
|
||||
// });
|
||||
|
||||
default_straight_line
|
||||
= { //终止位置,线长,起始位置,top,这里是从项目中截下来的我用了变量代替,你要用的话lineheight和lineleft用自己的变量或者数字代替。如果两个终止位置和起始位置的数值一样那么这个线条会垂直,这个应该很好理解。
|
||||
fill: default_border_color, //填充颜色
|
||||
stroke: default_border_color, //笔触颜色
|
||||
strokeWidth: 3, //笔触宽度
|
||||
hasControls: true, //选中时是否可以放大缩小
|
||||
hasRotatingPoint: true, //选中时是否可以旋转
|
||||
hasBorders: true, //选中时是否有边框
|
||||
selectable: true, //是否可被选中
|
||||
};
|
||||
|
||||
//截屏批注
|
||||
default_screenshot_text = {
|
||||
left: defult_left,
|
||||
top: defult_top,
|
||||
fill: default_screenshot_rect_text_color,
|
||||
backgroundColor: default_screenshot_rect_background_color,
|
||||
fontSize: 25,
|
||||
strokeWidth: 5,
|
||||
underline: true,
|
||||
selectable: true,
|
||||
id: 'id',
|
||||
lockRotation: true,
|
||||
};
|
||||
|
||||
default_screenshot_rectangle = {
|
||||
left: defult_left,
|
||||
top: defult_screen_shot_top,
|
||||
width: 300,
|
||||
height: 300,
|
||||
fill: default_screenshot_rect_fill_color,
|
||||
stroke: default_fill_color,
|
||||
lockRotation: true,
|
||||
strokeSize: 1,
|
||||
id: 'id',
|
||||
lockRotation: true,
|
||||
};
|
||||
|
||||
default_circle = {
|
||||
left: defult_left,
|
||||
top: defult_top,
|
||||
radius: 200,
|
||||
fill: default_fill_color,
|
||||
stroke: default_border_color,
|
||||
strokeSize: 1,
|
||||
id: 'id',
|
||||
};
|
||||
}
|
||||
|
||||
//create color control panel 创建颜色控制面板
|
||||
function setColorControl() {
|
||||
if (isIE11()){
|
||||
setColorControlForIE();
|
||||
return;
|
||||
}
|
||||
|
||||
var my_menu_node = document.getElementById('my-menu');
|
||||
my_menu_node.innerHTML = ''; //clear 清空所有子元素
|
||||
var buttons_text = {
|
||||
'zh-cn': [
|
||||
'<div title="关闭" onclick="hiddenMenu()"><label>关闭/close</label><i class="fa fa-times-circle" style="font-size: 15px;" aria-hidden="true"></i></div>',
|
||||
'<div id="fold_or_open_div" title="折叠或展开面板" onclick="foldOrOpenMenu()"><label>折叠/展开面板</label><i class="fa fa-window-restore" style="font-size: 15px;margin-left:10px;" aria-hidden="true"></i></div>',
|
||||
'<div onclick="clickColorInput(this)" title="点击色块修改颜色"><label>填充色</label><input type="color" value="#000000" id="fill"></div>',
|
||||
'<div onclick="clickColorInput(this)" title="点击色块修改颜色"><label>边框色</label><input type="color" value="#000000" id="stroke"></div>',
|
||||
'<div onclick="clickColorInput(this)" title="点击色块修改颜色"><label>背景色</label><input type="color" value="#000000" id="backgroundColor"></div>',
|
||||
'<div title="拖动进度条调整"><label style="margin-right: 20px;">边框粗细</label><input type="range" style="width: 80px;" id="strokeWidth" value="1" min="0" max="20" step="0.5"></div>',
|
||||
'<div title="拖动进度条调整"><label style="margin-right: 20px;">不透明度</label><input type="range" style="width: 80px;" id="opacity" value="100" min="1" max="100" step="1"></div>',
|
||||
'<div hidden=true id="ff-panel-screenshot" onclick="screenShotEl()" title="截取当前区域"><label>截图当前区域</label><i class="fa fa-camera" style="font-size: 15px;" aria-hidden="true"></i></div>',
|
||||
'<div onclick="delEl()" title="删除对象"><label>删除</label><i class="fa fa-trash" style="font-size: 15px;" aria-hidden="true"></i></div>',
|
||||
],
|
||||
'en': [
|
||||
'<div title="Close" onclick="hiddenMenu()"><label>Close</label><i class="fa fa-times-circle" style="font-size: 15px;" aria-hidden="true"></i></div>',
|
||||
'<div id="fold_or_open_div" title="fold or open panel" onclick="foldOrOpenMenu()"><label>Fold/Open Panel</label><i class="fa fa-window-restore" style="font-size: 15px;" aria-hidden="true"></i></div>',
|
||||
'<div onclick="clickColorInput(this)" title="click to select color"><label>FillColor</label><input type="color" value="#000000" id="fill"></div>',
|
||||
'<div onclick="clickColorInput(this)" title="click to select color"><label>BorderColor</label><input type="color" value="#000000" id="stroke"></div>',
|
||||
'<div onclick="clickColorInput(this)" title="click to select color"><label>BackgroundColor</label><input type="color" value="#000000" id="backgroundColor"></div>',
|
||||
'<div title="select range"><label style="margin-right: 20px;">BorderSize</label><input type="range" style="width: 80px;" id="strokeWidth" value="1" min="0" max="20" step="0.5"></div>',
|
||||
'<div title="select range"><label style="margin-right: 20px;">Opacity</label><input type="range" style="width: 80px;" id="opacity" value="100" min="1" max="100" step="1"></div>',
|
||||
'<div hidden=true id="ff-panel-screenshot" onclick="screenShotEl()" title="shot current rect"><label>Shot Current Rect</label><i class="fa fa-camera" style="font-size: 15px;" aria-hidden="true"></i></div>',
|
||||
'<div onclick="delEl()" title="delete this object"><label>Delete</label><i class="fa fa-trash" style="font-size: 15px;" aria-hidden="true"></i></div>',
|
||||
]
|
||||
} [tips_language];
|
||||
|
||||
for (var i = 0; i < buttons_text.length; i++) {
|
||||
var parent_button = document.createElement('div'); //add button 增加按钮
|
||||
var outer_html = buttons_text[i];
|
||||
parent_button.innerHTML = outer_html;
|
||||
my_menu_node.appendChild(parent_button.childNodes[0]);
|
||||
}
|
||||
|
||||
|
||||
//listen color and opacity change 监听颜色变化和透明度变化
|
||||
pdfAnnotation.observeValue('fill');
|
||||
pdfAnnotation.observeValue('stroke');
|
||||
pdfAnnotation.observeValue('backgroundColor');
|
||||
pdfAnnotation.observeNumeric('opacity');
|
||||
pdfAnnotation.observeNumeric('strokeWidth');
|
||||
// setMenuInputBackgroundColor();
|
||||
}
|
||||
|
||||
//create color control panel 创建颜色控制面板
|
||||
function setColorControlForIE() {
|
||||
var my_menu_node = document.getElementById('my-menu');
|
||||
my_menu_node.innerHTML = ''; //clear 清空所有子元素
|
||||
var buttons_text = {
|
||||
'zh-cn': [
|
||||
'<div title="关闭" onclick="hiddenMenu()"><label>关闭/close</label><i class="fa fa-times-circle" style="font-size: 15px;" aria-hidden="true"></i></div>',
|
||||
'<div id="fold_or_open_div" title="折叠或展开面板" onclick="foldOrOpenMenu()"><label>折叠/展开面板</label><i class="fa fa-window-restore" style="font-size: 15px;margin-left:10px;" aria-hidden="true"></i></div>',
|
||||
'<div title="点击色块修改颜色"><label>填充色</label><select type="color" id="fill"></select></div>',
|
||||
'<div onclick="clickColorInput(this)" title="点击色块修改颜色"><label>边框色</label><select type="color" id="stroke"></select></div>',
|
||||
'<div onclick="clickColorInput(this)" title="点击色块修改颜色"><label>背景色</label><select type="color" id="backgroundColor"></select></div>',
|
||||
'<div title="拖动进度条调整"><label style="margin-right: 20px;">边框粗细</label><input type="range" style="width: 80px;" id="strokeWidth" value="1" min="0" max="20" step="0.5"></div>',
|
||||
'<div title="拖动进度条调整"><label style="margin-right: 20px;">不透明度</label><input type="range" style="width: 80px;" id="opacity" value="100" min="1" max="100" step="1"></div>',
|
||||
'<div hidden=true id="ff-panel-screenshot" onclick="screenShotEl()" title="截取当前区域"><label>截图当前区域</label><i class="fa fa-camera" style="font-size: 15px;" aria-hidden="true"></i></div>',
|
||||
'<div onclick="delEl()" title="删除对象"><label>删除</label><i class="fa fa-trash" style="font-size: 15px;" aria-hidden="true"></i></div>',
|
||||
],
|
||||
'en': [
|
||||
'<div title="Close" onclick="hiddenMenu()"><label>Close</label><i class="fa fa-times-circle" style="font-size: 15px;" aria-hidden="true"></i></div>',
|
||||
'<div id="fold_or_open_div" title="fold or open panel" onclick="foldOrOpenMenu()"><label>Fold/Open Panel</label><i class="fa fa-window-restore" style="font-size: 15px;" aria-hidden="true"></i></div>',
|
||||
'<div onclick="clickColorInput(this)" title="click to select color"><label>FillColor</label><select type="color" id="fill"></select></div>',
|
||||
'<div onclick="clickColorInput(this)" title="click to select color"><label>BorderColor</label><select type="color" id="stroke"></select></div>',
|
||||
'<div onclick="clickColorInput(this)" title="click to select color"><label>BackgroundColor</label><select type="color" id="backgroundColor"></select></div>',
|
||||
'<div title="select range"><label style="margin-right: 20px;">BorderSize</label><input type="range" style="width: 80px;" id="strokeWidth" value="1" min="0" max="20" step="0.5"></div>',
|
||||
'<div title="select range"><label style="margin-right: 20px;">Opacity</label><input type="range" style="width: 80px;" id="opacity" value="100" min="1" max="100" step="1"></div>',
|
||||
'<div hidden=true id="ff-panel-screenshot" onclick="screenShotEl()" title="shot current rect"><label>Shot Current Rect</label><i class="fa fa-camera" style="font-size: 15px;" aria-hidden="true"></i></div>',
|
||||
'<div onclick="delEl()" title="delete this object"><label>Delete</label><i class="fa fa-trash" style="font-size: 15px;" aria-hidden="true"></i></div>',
|
||||
]
|
||||
} [tips_language];
|
||||
|
||||
for (var i = 0; i < buttons_text.length; i++) {
|
||||
var parent_button = document.createElement('div'); //add button 增加按钮
|
||||
var outer_html = buttons_text[i];
|
||||
parent_button.innerHTML = outer_html;
|
||||
my_menu_node.appendChild(parent_button.childNodes[0]);
|
||||
}
|
||||
|
||||
//设置颜色选择器
|
||||
setSelections("fill");
|
||||
setSelections("stroke");
|
||||
setSelections("backgroundColor");
|
||||
|
||||
|
||||
//listen color and opacity change 监听颜色变化和透明度变化
|
||||
pdfAnnotation.observeIEValue('fill');
|
||||
pdfAnnotation.observeIEValue('stroke');
|
||||
pdfAnnotation.observeIEValue('backgroundColor');
|
||||
pdfAnnotation.observeNumeric('opacity');
|
||||
pdfAnnotation.observeNumeric('strokeWidth');
|
||||
// setMenuInputBackgroundColor();
|
||||
}
|
||||
|
||||
//选中文字后浮动菜单生成
|
||||
function setHorAnnotationOperater() {
|
||||
var buttons_text = {
|
||||
'zh-cn': [
|
||||
'<button title="撤销最后一个批注" id="ff-hor-undo-btn" onclick="undoAnnotation()" type="button"><span style="margin-right: 5px;">撤销</span><i class="fa fa-undo" aria-hidden="true"></i></button>',
|
||||
'<button title="清空本人所有批注" id="ff-hor-clear-btn" onclick="clearFileAnnotations()" type="button"><span style="margin-right: 5px;">清空</span><i class="fa fa-trash" aria-hidden="true"></i></button>',
|
||||
'<button title="选中对象" id="ff-pointer-obj-btn" onclick="setFabricTop(this)" type="button"><span style="margin-right: 5px;">选中</span><i class="fa fa-mouse-pointer" aria-hidden="true"></i></button>',
|
||||
'<button title="提交后台保存批注" id="ff-save-upload-btn" onclick="outputAnnotations()" type="button"><span style="margin-right: 5px;">保存</span><i class="fa fa-upload" aria-hidden="true"></i></button>',
|
||||
'<button title="关闭批注栏" id="ff-close-hor-btn" onclick="closeHorAnnotationButtons(0)" type="button"><span style="margin-right: 5px;">关闭</span><i class="fa fa-window-close" aria-hidden="true"></i></button>',
|
||||
],
|
||||
'en': [
|
||||
'<button title="highlight selection text" id="ff-touch-highlight-btn" onclick="singleHighlightAndUnderline(0)" type="button"><span style="margin-right: 5px;">Highlight</span><i class="fa fa-paint-brush" aria-hidden="true"></i></button>',
|
||||
'<button title="underline selection text" id="ff-touch-underline-btn" onclick="singleHighlightAndUnderline(1)" type="button"><span style="margin-right: 5px;">Underline</span><i class="fa fa-underline" aria-hidden="true"></i></button>',
|
||||
'<button title="copy selection text" id="ff-touch-highlight-btn" onclick="singleCopy()" type="button"><span style="margin-right: 5px;">Copy</span><i class="fa fa-clipboard" aria-hidden="true"></i></button>',
|
||||
'<button title="cancel selection" onclick="closeCopyConfirm()" type="button"><span style="margin-right: 5px;">Cancel</span><i class="fa fa-window-close" aria-hidden="true"></i></button>',
|
||||
]
|
||||
} [tips_language];
|
||||
|
||||
var single_buttons = document.getElementById('ff-hor-annotation-btn');
|
||||
single_buttons.innerHTML = ''; //clear 清空所有子元素
|
||||
|
||||
for (var i = 0; i < buttons_text.length; i++) {
|
||||
var parent_button = document.createElement('button'); //add button 增加按钮
|
||||
var outer_html = buttons_text[i];
|
||||
parent_button.innerHTML = outer_html;
|
||||
single_buttons.appendChild(parent_button.childNodes[0]);
|
||||
|
||||
if (i != buttons_text.length - 1) {
|
||||
var split_div = document.createElement('div');
|
||||
split_div.classList.add('vertical-split');
|
||||
single_buttons.appendChild(split_div);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function setLinkControl(){
|
||||
var extract_pdf_html = {
|
||||
'zh-cn': [
|
||||
'<div class="linkform"><form class="selectform">'+
|
||||
'<label><input type="radio" id="hy_url" checked="true" name="choice" value="url" onchange="handleSelection(this)"> URL</label>'+
|
||||
'<label><input type="radio" id="hy_page" name="choice" value="page" onchange="handleSelection(this)"> 文档页面</label>'+
|
||||
'<label><input type="radio" id="hy_file" name="choice" value="file" onchange="handleSelection(this)"> 在线文档#页面</label>'+
|
||||
'</form>'+
|
||||
'<p class="linktip" id="link_tips">请输入要跳转的URL</p>'+
|
||||
'<input id="link_input" style="width: inherit;font-size: 15px;padding: 5px 3px 5px 3px;margin-bottom: 10px;" value="">'+
|
||||
'<button type="button" onclick="linkToURL()" style="width: 80px;font-size: 15px;float: left;"><i style="padding: 5px;" class="fa fa-link" aria-hidden="true"></i>链接</button>'+
|
||||
'<button type="button" onclick="unLink()" style="width: 100px;font-size: 15px;float: middle;"><i style="padding: 5px;" class="fa fa-unlink" aria-hidden="true"></i>取消链接</button>'+
|
||||
'<button type="button" onclick="cancelLink()" style="width: 80px;font-size: 15px;float: right;"><i style="padding: 5px;" class="fa fa-times" aria-hidden="true"></i>关闭</button>'+
|
||||
'</div>'
|
||||
],
|
||||
'en': [
|
||||
'<div class="linkform"><form class="selectform">'+
|
||||
'<label><input type="radio" id="hy_url" checked="true" name="choice" value="url" onchange="handleSelection(this)"> URL</label>'+
|
||||
'<label><input type="radio" id="hy_page" name="choice" value="page" onchange="handleSelection(this)">Page</label>'+
|
||||
'<label><input type="radio" id="hy_file" name="choice" value="file" onchange="handleSelection(this)">file#page</label>'+
|
||||
'</form>'+
|
||||
'<p class="linktip" id="link_tips">Enter URL you would like to link to</p>'+
|
||||
'<input id="link_input" style="width: inherit;font-size: 15px;padding: 5px 3px 5px 3px;margin-bottom: 10px;" value="">'+
|
||||
'<button type="button" onclick="linkToURL()" style="width: 90px;font-size: 15px;float: left;"><i style="padding: 5px;" class="fa fa-link" aria-hidden="true"></i>Link</button>'+
|
||||
'<button type="button" onclick="unLink()" style="width: 90px;font-size: 15px;float: middle;"><i style="padding: 5px;" class="fa fa-unlink" aria-hidden="true"></i>Unlink</button>'+
|
||||
'<button type="button" onclick="cancelLink()" style="width: 90px;font-size: 15px;float: right;"><i style="padding: 5px;" class="fa fa-times" aria-hidden="true"></i>Close</button>'+
|
||||
'</div>'
|
||||
]
|
||||
} [tips_language];
|
||||
document.getElementById('my-link-set-div').innerHTML = extract_pdf_html[0];
|
||||
}
|
||||
|
||||
//选中文字后浮动菜单生成
|
||||
function setSingleOperater() {
|
||||
var buttons_text = {
|
||||
'zh-cn': [
|
||||
'<button title="高亮选中的文本" id="ff-touch-highlight-btn" onclick="singleHighlightAndUnderline(0)" type="button"><i class="fa fa-paint-brush" aria-hidden="true"></i></button>',
|
||||
'<button title="为选中的文本添加下划线" id="ff-touch-underline-btn" onclick="singleHighlightAndUnderline(1)" type="button"><i class="fa fa-underline" aria-hidden="true"></i></button>',
|
||||
'<button title="为选中的文本添加超链接" id="ff-touch-hyperlink-btn" onclick="showHyperLinkSet()" type="button"><i class="fa fa-link" aria-hidden="true"></i></button>',
|
||||
'<button title="复制选中的文本" id="ff-touch-highlight-btn" onclick="singleCopy()" type="button"><i class="fa fa-clipboard" aria-hidden="true"></i></button>',
|
||||
'<button title="取消选择" onclick="closeCopyConfirm()" type="button"><i class="fa fa-window-close" aria-hidden="true"></i></button>',
|
||||
],
|
||||
'en': [
|
||||
'<button title="highlight selection text" id="ff-touch-highlight-btn" onclick="singleHighlightAndUnderline(0)" type="button"><i class="fa fa-paint-brush" aria-hidden="true"></i></button>',
|
||||
'<button title="underline selection text" id="ff-touch-underline-btn" onclick="singleHighlightAndUnderline(1)" type="button"><i class="fa fa-underline" aria-hidden="true"></i></button>',
|
||||
'<button title="hyperlink selection text" id="ff-touch-hyperlink-btn" onclick="showHyperLinkSet()" type="button"><i class="fa fa-link" aria-hidden="true"></i></button>',
|
||||
'<button title="copy selection text" id="ff-touch-highlight-btn" onclick="singleCopy()" type="button"><i class="fa fa-clipboard" aria-hidden="true"></i></button>',
|
||||
'<button title="cancel selection" onclick="closeCopyConfirm()" type="button"><i class="fa fa-window-close" aria-hidden="true"></i></button>',
|
||||
]
|
||||
} [tips_language];
|
||||
|
||||
var single_buttons = document.getElementById('ff-copyconfirm-btn');
|
||||
single_buttons.innerHTML = ''; //clear 清空所有子元素
|
||||
|
||||
for (var i = 0; i < buttons_text.length; i++) {
|
||||
var parent_button = document.createElement('button'); //add button 增加按钮
|
||||
var outer_html = buttons_text[i];
|
||||
parent_button.innerHTML = outer_html;
|
||||
single_buttons.appendChild(parent_button.childNodes[0]);
|
||||
|
||||
// if (i != buttons_text.length - 1) {
|
||||
// var split_div = document.createElement('div');
|
||||
// split_div.classList.add('vertical-split');
|
||||
// single_buttons.appendChild(split_div);
|
||||
// }
|
||||
}
|
||||
var down_triangle = document.createElement('div');
|
||||
down_triangle.innerHTML='<span class="triangle-down"><em></em></span>';
|
||||
down_triangle.classList.add('popup');
|
||||
single_buttons.appendChild(down_triangle);
|
||||
}
|
||||
|
||||
// 顶部注释工具栏生成
|
||||
function setAnnotationButtons() {
|
||||
var buttons_text = [
|
||||
'<button title="画笔工具" id="ff-free-draw" onclick="fabricDraw(this)" type="button" class="toolbarButton fontButton"><i class="fa fa-pencil" aria-hidden="true"><span></span></i></button>',
|
||||
'<div class="show-connect-div" id="show_connect_div"></div>',
|
||||
'<button title="撤销批注" id="ff-undo-btn" onclick="undoAnnotation()" type="button" class="toolbarButton fontButton"><i class="fa fa-undo" aria-hidden="true"><span></span></i></button>',
|
||||
'<button title="重做批注" id="ff-redo-btn" onclick="redoAnnotation()" type="button" class="toolbarButton fontButton"><i style="transform: rotateY(180deg);" class="fa fa-undo" aria-hidden="true"><span></span></i></button>',
|
||||
'<button title="清除本人所有批注" id="ff-clear-file-annotation-btn" onclick="clearFileAnnotations()" type="button" class="toolbarButton fontButton"><i class="fa fa-trash" aria-hidden="true"><span></span></i></button>',
|
||||
'<div class="verticalToolbarSeparator"></div>',
|
||||
'<button title="保存" id="ff-download-btn" onclick="mySave()" type="button" class="toolbarButton fontButton"><i class="fa fa-save" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button id="download" class="toolbarButton hiddenMediumView" title="Save" tabindex="33" data-l10n-id="save"> <span data-l10n-id="save_label">Save</span> </button>',
|
||||
];
|
||||
var annotation_buttons_node = document.getElementById('toolbarViewerRight');
|
||||
var new_html = '';
|
||||
for (var i = 0; i < buttons_text.length; i++) {
|
||||
new_html += buttons_text[i];
|
||||
}
|
||||
annotation_buttons_node.innerHTML += new_html;
|
||||
}
|
||||
// function setAnnotationButtons() {
|
||||
// // return;
|
||||
// var annotation_buttons_node = document.getElementById('firefly-annotation-buttons');
|
||||
//
|
||||
// annotation_buttons_node.innerHTML = ''; //clear 清空所有子元素
|
||||
// // '<div class="splitToolbarButtonSeparator"></div>'
|
||||
// var buttons_text = {
|
||||
// 'zh-cn': [
|
||||
// '<div>',
|
||||
// '<button title="下载批注后的文件(批注将标记在下载的文件中)" id="ff-download-btn" onclick="myDownLoad()" type="button"><i class="fa fa-folder" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="截取PDF部分页" id="ff-extract-pdf" onclick="extractPDF()" type="button"><i class="fa fa-map" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="导出标注(json格式)" id="ff-output-btn" onclick="outputAnnotations()" type="button"><i class="fa fa-upload" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="导入标注(json格式)" id="ff-import-btn" onclick="openAnnotationFile()" type="button"><i class="fa fa-download" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="下载注释(txt格式)" id="ff-download-btn" onclick="downloadAnnotations()" type="button"><i class="fa fa-arrow-circle-down" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="切换至英文" id="ff-language-btn" onclick="setLanguage(1)" type="button"><i class="fa fa-etsy" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="画笔、高亮及各类配置" id="ff-setting-btn" onclick="showOrHideSettingMenu()" type="button"><i class="fa fa-gear" aria-hidden="true"><span style="font-weight:600;margin-left:5px;">配置</span></i></button>',
|
||||
// '</div>',
|
||||
// '<div>',
|
||||
// '<button title="选中对象" id="ff-pointer-obj" onclick="setFabricTop(this)" type="button"><i class="fa fa-mouse-pointer" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="编辑标注" id="ff-edit-btn" onclick="editAnnotation()" type="button"><i class="fa fa-list-ul" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="文本高亮(再次点击取消滑选标注)" id="ff-highlight-btn" onclick="clickTab(this)" type="button"><i class="fa fa-paint-brush" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="文本下划线(再次点击取消滑选标注)" id="ff-underline-btn" onclick="clickTab(this)" type="button"><i class="fa fa-underline" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="插入图片" id="ff-import-img" onclick="chooseImage()" type="button"><i class="fa fa-picture-o" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="页面截图" id="ff-screen-shot" onclick="addFabricObj(this,6)" type="button"><i class="fa fa-camera"><span></span></i></button>',
|
||||
// '<button title="画笔工具" id="ff-free-draw" onclick="fabricDraw(this)" type="button"><i class="fa fa-pencil" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="文字工具" id="ff-add-text" onclick="addFabricObj(this,2)" type="button"><i class="fa fa-font" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="箭头工具" id="ff-add-arrow" onclick="addFabricObj(this,3)" type="button"><i class="fa fa-external-link-square" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="矩形工具" id="ff-add-rect" onclick="addFabricObj(this,4)" type="button"><i class="fa fa-window-maximize" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="圆形工具" id="ff-add-circle" onclick="addFabricObj(this,5)" type="button"><i class="fa fa-circle" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="直线工具" id="ff-add-line" onclick="addFabricObj(this,7)" type="button"><i class="fa fa-minus" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="超链接工具" id="ff-add-hyperlink" onclick="addFabricObj(this,10)" type="button"><i class="fa fa-link" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="身份印章工具" id="ff-add-stamp" onclick="addFabricObj(this,8)" type="button"><i class="fa fa-id-card" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="插入对勾" id="ff-extract-pdf" onclick="addFabricObj(this,9)" type="button"><i class="fa fa-check" aria-hidden="true"><span></span></i></button>',
|
||||
// '</div>',
|
||||
// '<div>',
|
||||
// '<div class="show-connect-div" id="show_connect_div"></div>',
|
||||
// '<button title="橡皮檫" id="ff-eraser-btn" onclick="clickTab(this)" type="button"><i class="fa fa-eraser" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="撤销批注" id="ff-undo-btn" onclick="undoAnnotation()" type="button"><i class="fa fa-undo" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="重做批注" id="ff-redo-btn" onclick="redoAnnotation()" type="button"><i style="transform: rotateY(180deg);" class="fa fa-undo" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="清除本人所有批注" id="ff-clear-file-annotation-btn" onclick="clearFileAnnotations()" type="button"><i class="fa fa-trash" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="帮助文档" id="ff-undo-btn" onclick="openHelpDoc()" type="button"><i class="fa fa-question-circle" aria-hidden="true"><span></span></i></button>',
|
||||
// '</div>',
|
||||
// ],
|
||||
// 'en': [
|
||||
// '<div>',
|
||||
// '<button title="download pdf with annotations mark" id="ff-download-btn" onclick="myDownLoad()" type="button"><i class="fa fa-folder" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="PDF extracter" id="ff-extract-pdf" onclick="extractPDF()" type="button"><i class="fa fa-map" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="output annotations(json)" id="ff-output-btn" onclick="outputAnnotations()" type="button"><i class="fa fa-upload" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="import annotations(json)" id="ff-import-btn" onclick="openAnnotationFile()" type="button"><i class="fa fa-download" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="download annotations(txt)" id="ff-download-btn" onclick="downloadAnnotations()" type="button"><i class="fa fa-arrow-circle-down" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="change tips to Chinese" id="ff-language-btn" onclick="setLanguage(0)" type="button"><i class="fa fa-etsy" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="highlght brush width and colors setting" id="ff-setting-btn" onclick="showOrHideSettingMenu()" type="button"><i class="fa fa-gear" aria-hidden="true"><span style="font-weight:600;margin-left:5px;">Settings</span></i></button>',
|
||||
// '</div>',
|
||||
// '<div>',
|
||||
// '<button title="select annotation object" id="ff-pointer-obj" onclick="setFabricTop(this)" type="button"><i class="fa fa-mouse-pointer" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="edit annotations" id="ff-edit-btn" onclick="editAnnotation()" type="button"><i class="fa fa-list-ul" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="highlight" id="ff-highlight-btn" onclick="clickTab(this)" type="button"><i class="fa fa-paint-brush" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="underline" id="ff-underline-btn" onclick="clickTab(this)" type="button"><i class="fa fa-underline" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="insert image" id="ff-import-img" onclick="chooseImage()" type="button"><i class="fa fa-picture-o" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="screen shot" id="ff-screen-shot" onclick="addFabricObj(this,6)" type="button"><i class="fa fa-camera"><span></span></i></button>',
|
||||
// '<button title="free draw" id="ff-free-draw" onclick="fabricDraw(this)" type="button"><i class="fa fa-pencil" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="add text" id="ff-add-text" onclick="addFabricObj(this,2)" type="button"><i class="fa fa-font" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="add arrow" id="ff-add-arrow" onclick="addFabricObj(this,3)" type="button"><i class="fa fa-external-link-square" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="add rectangle" id="ff-add-rect" onclick="addFabricObj(this,4)" type="button"><i class="fa fa-window-maximize" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="add circle" id="ff-add-circle" onclick="addFabricObj(this,5)" type="button"><i class="fa fa-circle" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="add line" id="ff-add-line" onclick="addFabricObj(this,7)" type="button"><i class="fa fa-minus" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="add hyperlink" id="ff-add-hyperlink" onclick="addFabricObj(this,10)" type="button"><i class="fa fa-link" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="add id card stamp" id="ff-add-stamp" onclick="addFabricObj(this,8)" type="button"><i class="fa fa-id-card" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="add check" id="ff-extract-pdf" onclick="addFabricObj(this,9)" type="button"><i class="fa fa-check" aria-hidden="true"><span></span></i></button>',
|
||||
// '</div>',
|
||||
// '<div>',
|
||||
// '<div class="show-connect-div" id="show_connect_div"></div>',
|
||||
// '<button title="eraser" id="ff-eraser-btn" onclick="clickTab(this)" type="button"><i class="fa fa-eraser" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="undo annotation" id="ff-undo-btn" onclick="undoAnnotation()" type="button"><i class="fa fa-undo" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="redo annotation" id="ff-redo-btn" onclick="redoAnnotation()" type="button"><i style="transform: rotateY(180deg);" class="fa fa-undo" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="clear your all annotations" id="ff-clear-file-annotation-btn" onclick="clearFileAnnotations()" type="button"><i class="fa fa-trash" aria-hidden="true"><span></span></i></button>',
|
||||
// '<button title="help" id="ff-undo-btn" onclick="openHelpDoc()" type="button"><i class="fa fa-question-circle" aria-hidden="true"><span></span></i></button>',
|
||||
// '</div>',
|
||||
// ]
|
||||
// } [tips_language];
|
||||
//
|
||||
// var new_html = '';
|
||||
// for (var i = 0; i < buttons_text.length; i++) {
|
||||
// new_html += buttons_text[i];
|
||||
// }
|
||||
// annotation_buttons_node.innerHTML = new_html;
|
||||
// }
|
||||
|
||||
//create help text and show 创建帮助文本并显示
|
||||
function openHelpDoc() {
|
||||
var helps = {
|
||||
'zh-cn': [{
|
||||
'title': '下载文件',
|
||||
'detail': '下载批注后的文件,批注将标记在下载的文件中且不可撤销,如果需要编辑批注请打开未经本应用导入的文件',
|
||||
},
|
||||
{
|
||||
'title': '文本高亮',
|
||||
'detail': '高亮滑选的文本,对非黑色字体无效。',
|
||||
},
|
||||
{
|
||||
'title': '文本下划线',
|
||||
'detail': '给滑选的文本增加下划线,对非黑色字体无效。',
|
||||
},
|
||||
{
|
||||
'title': '注释列表',
|
||||
'detail': '打开注释列表并编辑(复制/删除/前往)',
|
||||
},
|
||||
{
|
||||
'title': '选中对象',
|
||||
'detail': '选中批注对象并修改',
|
||||
},
|
||||
{
|
||||
'title': '插入图片',
|
||||
'detail': '插入本地图片,会自动压缩图片',
|
||||
},
|
||||
{
|
||||
'title': '画笔工具',
|
||||
'detail': '在当前页面使用画笔工具自由绘制',
|
||||
},
|
||||
{
|
||||
'title': '文本框工具',
|
||||
'detail': '给当前页面添加可输入文本框',
|
||||
},
|
||||
{
|
||||
'title': '箭头工具',
|
||||
'detail': '给当前页面添加箭头',
|
||||
},
|
||||
{
|
||||
'title': '矩形工具',
|
||||
'detail': '给当前页面添加矩形框',
|
||||
},
|
||||
{
|
||||
'title': '圆形工具',
|
||||
'detail': '给当前页面添加圆',
|
||||
},
|
||||
{
|
||||
'title': '导出注释',
|
||||
'detail': '导出完整结构标注,用于给同名文件增加标注。',
|
||||
},
|
||||
{
|
||||
'title': '导入标注',
|
||||
'detail': '导入完整结构标注,用于给当前文件增加标注。',
|
||||
},
|
||||
{
|
||||
'title': '下载标注',
|
||||
'detail': '导出当前文件标注和评论为txt格式文档。',
|
||||
},
|
||||
{
|
||||
'title': '切换语言',
|
||||
'detail': '切换提示语言至英文',
|
||||
},
|
||||
{
|
||||
'title': '帮助文档',
|
||||
'detail': '打开帮助文档。',
|
||||
},
|
||||
],
|
||||
'en': [{
|
||||
'title': 'download',
|
||||
'detail': 'download pdf with annotations mark, it can not be undo, if you want to modify annotations, please open source file',
|
||||
}, {
|
||||
'title': 'highlight',
|
||||
'detail': 'highlight selected text, valid for only black text',
|
||||
},
|
||||
{
|
||||
'title': 'underline',
|
||||
'detail': 'underline selected text, valid for only black text',
|
||||
},
|
||||
{
|
||||
'title': 'annotation list',
|
||||
'detail': 'show annotation list and edit (copy/delete/gotp)',
|
||||
},
|
||||
{
|
||||
'title': 'select object',
|
||||
'detail': 'select annotation to modify',
|
||||
},
|
||||
{
|
||||
'title': 'insert image',
|
||||
'detail': 'insert image to current page and compress it',
|
||||
},
|
||||
{
|
||||
'title': 'free draw',
|
||||
'detail': 'free draw by brush in current page',
|
||||
},
|
||||
{
|
||||
'title': 'text input box',
|
||||
'detail': 'add text input box to current page',
|
||||
},
|
||||
{
|
||||
'title': 'arrow tool',
|
||||
'detail': 'add arrow to current page',
|
||||
},
|
||||
{
|
||||
'title': 'rectangle tool',
|
||||
'detail': 'add rectangle to current page',
|
||||
},
|
||||
{
|
||||
'title': 'circle tool',
|
||||
'detail': 'add circle to current page',
|
||||
},
|
||||
{
|
||||
'title': 'output annotations',
|
||||
'detail': 'output annotations for importing',
|
||||
},
|
||||
{
|
||||
'title': 'import annotations',
|
||||
'detail': 'import annotations for current file',
|
||||
},
|
||||
{
|
||||
'title': 'download annotations',
|
||||
'detail': 'download only annotations text and comments to txt',
|
||||
},
|
||||
{
|
||||
'title': 'set language',
|
||||
'detail': 'change tips language to Chinese',
|
||||
},
|
||||
{
|
||||
'title': 'help',
|
||||
'detail': 'open help file',
|
||||
},
|
||||
]
|
||||
} [tips_language];
|
||||
|
||||
if (post_to_parent == true) {
|
||||
helps = [{
|
||||
'title': '下载文件',
|
||||
'detail': '下载批注后的文件,批注将标记在下载的文件中且不可撤销,如果需要编辑批注请打开未经本应用导入的文件',
|
||||
}, {
|
||||
'title': '文本高亮',
|
||||
'detail': '高亮滑选的文本,对非黑色字体无效。',
|
||||
},
|
||||
{
|
||||
'title': '文本下划线',
|
||||
'detail': '给滑选的文本增加下划线,对非黑色字体无效。',
|
||||
},
|
||||
{
|
||||
'title': '注释列表',
|
||||
'detail': '打开注释列表并编辑(复制/删除/前往)',
|
||||
},
|
||||
{
|
||||
'title': '选中对象',
|
||||
'detail': '选中批注对象并修改',
|
||||
},
|
||||
{
|
||||
'title': '插入图片',
|
||||
'detail': '插入本地图片,会自动压缩图片',
|
||||
},
|
||||
{
|
||||
'title': '画笔工具',
|
||||
'detail': '在当前页面使用画笔工具自由绘制',
|
||||
},
|
||||
{
|
||||
'title': '文本框工具',
|
||||
'detail': '给当前页面添加可输入文本框',
|
||||
},
|
||||
{
|
||||
'title': '箭头工具',
|
||||
'detail': '给当前页面添加箭头',
|
||||
},
|
||||
{
|
||||
'title': '矩形工具',
|
||||
'detail': '给当前页面添加矩形框',
|
||||
},
|
||||
{
|
||||
'title': '圆形工具',
|
||||
'detail': '给当前页面添加圆',
|
||||
},
|
||||
{
|
||||
'title': '导出注释',
|
||||
'detail': '导出完整结构标注,用于给同名文件增加标注。',
|
||||
},
|
||||
{
|
||||
'title': '导入标注',
|
||||
'detail': '导入完整结构标注,用于给当前文件增加标注。',
|
||||
},
|
||||
{
|
||||
'title': '云端保存',
|
||||
'detail': '将标注保存到云端,仅可用于云端文件。',
|
||||
},
|
||||
{
|
||||
'title': '加载云端标注',
|
||||
'detail': '用于云端标注未正确加载的情况。',
|
||||
},
|
||||
{
|
||||
'title': '下载标注',
|
||||
'detail': '导出当前文件标注和评论为txt格式文档。',
|
||||
},
|
||||
{
|
||||
'title': '帮助文档',
|
||||
'detail': '打开帮助文档。',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
var help_str = {
|
||||
'zh-cn': '帮助文档:\n祝使用愉快\n\n按钮功能说明:\n',
|
||||
'en': 'help file for buttons introduction:\n',
|
||||
} [tips_language];
|
||||
|
||||
var nums = ['①', '②', '③', '④', '⑤', '⑥', '⑦', '⑧', '⑨', '⑩', '⑪', '⑫', '⑬', '⑭', '⑮', '⑯', '⑰', '⑱', '⑲', '⑳'];
|
||||
for (var i = 0; i < helps.length; i++) {
|
||||
var this_help = helps[i];
|
||||
help_str += nums[i] + ' ' + this_help['title'] + ' : ' + this_help['detail'] + '\n';
|
||||
}
|
||||
|
||||
alert(help_str);
|
||||
};
|
||||
|
||||
//listen tips_language change 监听tips language 的变化
|
||||
function setLanguage(op) {
|
||||
var tips = {
|
||||
'zh-cn': [
|
||||
"提示语言已切换至中文",
|
||||
"提示语言已切换至英文",
|
||||
],
|
||||
'en': [
|
||||
'tips language changed to Chinese',
|
||||
'tips language changed to English',
|
||||
]
|
||||
} [tips_language];
|
||||
if (op == 0) {
|
||||
tips_language = "zh-cn";
|
||||
addOperationTips(tips[0]);
|
||||
} else {
|
||||
tips_language = "en";
|
||||
addOperationTips(tips[1]);
|
||||
}
|
||||
//设置提示语言
|
||||
pdfAnnotation.tips_language=tips_language;
|
||||
pdfAnnotationUI.tips_language=tips_language;
|
||||
pdfHighlight.tips_language=tips_language;
|
||||
JSplump.tips_language=tips_language;
|
||||
|
||||
setAnnotationButtons();
|
||||
setColorControl();
|
||||
setSettingsControl(); //添加设置面板
|
||||
setSingleOperater();
|
||||
setExtractPDFDiv(); //提取 pdf 的组件
|
||||
setLinkControl();
|
||||
// setHorAnnotationOperater(); //设置水平按钮
|
||||
//Listen again after switching languages 切换语言之后重新监听
|
||||
pdfAnnotation.observeValue('fill');
|
||||
pdfAnnotation.observeValue('stroke');
|
||||
pdfAnnotation.observeValue('backgroundColor');
|
||||
pdfAnnotation.observeNumeric('opacity');
|
||||
pdfAnnotation.observeNumeric('strokeWidth');
|
||||
setMenuInputBackgroundColor();
|
||||
if (pdfAnnotationUI.show_annotation_list) {
|
||||
pdfAnnotationUI.showAnnotationList();
|
||||
}
|
||||
};
|
||||
|
||||
//防止手机端双击缩放和清空添加状态
|
||||
function preventDoubleClick(event) {
|
||||
event.preventDefault();
|
||||
};
|
||||
|
212
src/assets/pdf-annotation/annotation/drag.js
Executable file
@ -0,0 +1,212 @@
|
||||
var run_in_angular = true;
|
||||
var is_droping_text = false;
|
||||
var current_drop_text = '';
|
||||
|
||||
function listenFileDrag() {
|
||||
var oDragWrap = document.getElementById('viewer');
|
||||
//拖进
|
||||
oDragWrap.addEventListener(
|
||||
"dragenter",
|
||||
function(e) {
|
||||
e.preventDefault();
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
//拖离
|
||||
oDragWrap.addEventListener(
|
||||
"dragleave",
|
||||
function(e) {
|
||||
// dragleaveHandler(e);
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
//拖来拖去 , 一定要注意dragover事件一定要清除默认事件
|
||||
//不然会无法触发后面的drop事件
|
||||
oDragWrap.addEventListener(
|
||||
"dragover",
|
||||
function(e) {
|
||||
e.preventDefault();
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
//扔
|
||||
oDragWrap.addEventListener(
|
||||
"drop",
|
||||
function(e) {
|
||||
dropHandler(e);
|
||||
},
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
// listening paste
|
||||
document.addEventListener('paste', function(event) {
|
||||
if (is_hyper_link_highlight==true || is_hyper_edit==true){
|
||||
return;
|
||||
}
|
||||
|
||||
var isChrome = false;
|
||||
if (event.clipboardData || event.originalEvent) {
|
||||
var data = (event.clipboardData && event.clipboardData.items) || [];
|
||||
// get paste text
|
||||
var copied_text=event.clipboardData.getData('text');
|
||||
if (copied_text.length!=0){
|
||||
dropTextToPDF(copied_text);
|
||||
return;
|
||||
}else{
|
||||
var bolb = null;
|
||||
if ((data[0].kind == 'file') &&
|
||||
(data[0].type.match('^image/'))) {
|
||||
blob = data[0].getAsFile();
|
||||
if (blob !== null) {
|
||||
dropImageToPDF(blob);
|
||||
}
|
||||
}
|
||||
|
||||
// let div = document.querySelector("div")
|
||||
// for (var i = 0; i < data.length; i += 1) {
|
||||
// if ((data[i].kind == 'file') &&
|
||||
// (data[i].type.match('^image/'))) {
|
||||
// blob = data[i].getAsFile();
|
||||
// if (blob !== null) {
|
||||
// dropImageToPDF(blob);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function dropHandler(e) {
|
||||
console.log('拖放结果',e);
|
||||
e.preventDefault(); //获取文件列表
|
||||
//将本地图片拖拽到页面中后要进行的处理都在这
|
||||
console.log('拖放结束', e.dataTransfer.getData("text"));
|
||||
var fileList = e.dataTransfer.files;
|
||||
console.log('文件列表', fileList);
|
||||
if (fileList.length === 0) {
|
||||
var this_drop_text = e.dataTransfer.getData("text");
|
||||
if (this_drop_text.length != 0) {
|
||||
// console.log('拖入了文字',drop_text);
|
||||
// alert(drop_text);
|
||||
dropTextToPDF(this_drop_text);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 检测文件是不是图片
|
||||
if (fileList[0].type.indexOf("image") === -1) {
|
||||
return;
|
||||
}
|
||||
//插入图片
|
||||
dropImageToPDF(fileList[0]);
|
||||
};
|
||||
|
||||
function dropTextToPDF(text) {
|
||||
is_droping_text = true;
|
||||
current_drop_text = text;
|
||||
document.getElementById("ff-add-text").click();
|
||||
}
|
||||
|
||||
function initialDropText() {
|
||||
is_droping_text = false;
|
||||
current_drop_text = '';
|
||||
document.getElementById("ff-pointer-obj").click();
|
||||
}
|
||||
|
||||
|
||||
function dropImageToPDF(file) {
|
||||
var blobURL;
|
||||
try {
|
||||
blobURL = URL.createObjectURL(file);
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
const img = new Image();
|
||||
img.setAttribute('crossOrigin', 'Anonymous');
|
||||
img.src = blobURL;
|
||||
img.onerror = function() {
|
||||
URL.revokeObjectURL(this.src);
|
||||
alert(tips[0]);
|
||||
};
|
||||
img.onload = function() {
|
||||
const MAX_WIDTH = 500;
|
||||
const MAX_HEIGHT = 500;
|
||||
const MIME_TYPE = 'image/png';
|
||||
const QUALITY = 1;
|
||||
|
||||
URL.revokeObjectURL(this.src);
|
||||
const this_size = pdfAnnotation.calculateSize(
|
||||
img,
|
||||
MAX_WIDTH,
|
||||
MAX_HEIGHT
|
||||
);
|
||||
var newWidth = this_size[0];
|
||||
var newHeight = this_size[1];
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = newWidth;
|
||||
canvas.height = newHeight;
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(img, 0, 0, newWidth, newHeight);
|
||||
//销毁图片
|
||||
image = null;
|
||||
|
||||
var new_image = new Image();
|
||||
// The value is set to anonymous, indicating that CORS requests for this element will not set credential flags. You cannot export a canvas or an object on a canvas as a picture without setting it.
|
||||
//值设置为 anonymous,表示对此元素的 CORS 请求将不设置凭据标志。若不设置,无法将画布或画布上的对象导出为图片。
|
||||
new_image.setAttribute('crossOrigin', 'Anonymous');
|
||||
// console.log('加载文件');
|
||||
new_image.onload = function() {
|
||||
//插入图片对象
|
||||
pdfAnnotation.insertImage(new_image);
|
||||
new_image = null; //销毁图片
|
||||
}
|
||||
var img_data = canvas.toDataURL('image/png');
|
||||
new_image.src = img_data;
|
||||
}
|
||||
}
|
||||
|
||||
function prepareImages(){
|
||||
var tips = {
|
||||
'zh-cn': [
|
||||
'无法加载图片',
|
||||
'添加评论',
|
||||
'点击画布以插入图片',
|
||||
],
|
||||
'en': [
|
||||
'can not load image',
|
||||
'add comments',
|
||||
'click canvas to insert image',
|
||||
]
|
||||
} [this.tips_language];
|
||||
|
||||
//activate selectable mode 激活选择模式
|
||||
if (this.fabric_top == false) {
|
||||
var top_node = document.getElementById('ff-pointer-obj');
|
||||
pdfAnnotationUI.setFabricTop(top_node);
|
||||
}
|
||||
var that = this;
|
||||
var fabricObj = this.getCurrentPageFabricCanvas();
|
||||
var fabric_item_id = this.buildId(fabricObj.getObjects().length + 1);
|
||||
if (fabricObj) {
|
||||
var set_img = new fabric.Image(new_image, {
|
||||
id: fabric_item_id,
|
||||
member_id: that.getRandomMemberID(),
|
||||
my_type: 'image',
|
||||
comment: tips[1],
|
||||
backup_opacity: 1,
|
||||
});
|
||||
set_img.crossOrigin = "Anonymous"; //这里是主要添加的属性
|
||||
// fabricObj.add(set_img);
|
||||
that.adding_item = set_img; //将图片作为待插入对象
|
||||
that.current_click_type = 'add_image';
|
||||
// console.log('图片加载成功');
|
||||
// addOperationTips(tips[2]);
|
||||
pdfAnnotationUI.changeMouseText(1); //修改鼠标文字
|
||||
that.changeAllCanvasSelectState();
|
||||
// that.saveAllFabricData();
|
||||
}
|
||||
}
|
239
src/assets/pdf-annotation/annotation/main.js
Executable file
@ -0,0 +1,239 @@
|
||||
|
||||
// main function, load html and listen 主函数
|
||||
window.onload = function() {
|
||||
if (isIE11()) {
|
||||
// 在IE11中执行特定操作
|
||||
addCssForIE11();
|
||||
}
|
||||
|
||||
pdfAnnotationUI.initControls();
|
||||
|
||||
var all_href = location.href;
|
||||
var params = all_href.split('?')[1].split('&');
|
||||
var file_id = params[0];
|
||||
var oriUrl = file_id.split('=')[1];
|
||||
var user = params.length > 1 ? params[1].split('=')[1] : null;
|
||||
if (user) {
|
||||
setCurrentMemberId({id: user, name: user});
|
||||
}
|
||||
// console.log('加载pdf');
|
||||
// var oriUrl = 'example_new_link.pdf';
|
||||
// var pdfUrl;
|
||||
// pdfUrl=oriUrl;
|
||||
// // openFile(oriUrl);
|
||||
// window.PDFViewerApplication.open(pdfUrl); //open pdf 打开pdf文档
|
||||
|
||||
pdfAnnotation.openFile(oriUrl);
|
||||
|
||||
//监听加载是否完成
|
||||
loadDetect();
|
||||
// pdfAnnotationUI.addPinchListener(); // Listen gesture zoom 监听手势缩放
|
||||
// listenFileDrag();
|
||||
|
||||
setAnnotationButtons(); //add annotation buttons 添加批注功能按钮
|
||||
// setColorControl(); //Add color control panel 添加颜色控制面板
|
||||
// setSettingsControl(); //添加设置面板
|
||||
setExtractPDFDiv(); //提取 pdf 的组件
|
||||
setLinkControl(); //超链接组件
|
||||
setSingleOperater(); //add operation buttons after selection 增加选中后的操作按钮
|
||||
// testSetAllMemberList(); //set member 设置用户
|
||||
|
||||
pdf_viewer = document.getElementById('viewer');
|
||||
pdf_viewer.addEventListener("mouseup", function(event) {
|
||||
var span_id_list=event.target.id.split('-');
|
||||
if (span_id_list.length<3 || span_id_list[2]!='textspan'){
|
||||
pdfHighlight.closeCopyConfirm();
|
||||
return;
|
||||
}
|
||||
|
||||
listenHighlight();
|
||||
try{
|
||||
postToParent(); //API
|
||||
}catch(e){
|
||||
console.error(e);
|
||||
}
|
||||
// event.preventDefault();
|
||||
}, true);
|
||||
|
||||
//listen selectionchange 监听选区变化
|
||||
// document.addEventListener("selectionchange", function(event) {
|
||||
// console.log('选区变化');
|
||||
// }, true);
|
||||
|
||||
//remove listen 监听删除
|
||||
document.addEventListener("keydown", function(event) {
|
||||
if (event.shiftKey) {
|
||||
shiftKeyPressed = true;
|
||||
// console.log('Shift键被按下');
|
||||
}
|
||||
|
||||
if (event.key === "Delete") {
|
||||
pdfAnnotation.delEl();
|
||||
};
|
||||
// console.log('event',event);
|
||||
|
||||
if (event.ctrlKey && event.keyCode === 90) {
|
||||
// Your code here to handle the "ctrl+z" key combination
|
||||
// console.log("ctrl+z pressed");
|
||||
pdfAnnotation.undoAnnotation();
|
||||
};
|
||||
if (event.ctrlKey && event.keyCode === 89) {
|
||||
// Your code here to handle the "ctrl+z" key combination
|
||||
// console.log("ctrl+z pressed");
|
||||
pdfAnnotation.redoAnnotation();
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('keyup', function(event) {
|
||||
if (!event.shiftKey) {
|
||||
shiftKeyPressed = false;
|
||||
// console.log('Shift键被释放');
|
||||
}
|
||||
});
|
||||
|
||||
// pdf_viewer.addEventListener("dblclick", function(event) {
|
||||
// // console.log('双击了页面');
|
||||
// if (current_click_type!='select'){
|
||||
// // console.log(event);
|
||||
// var this_canvas = getCurrentClickCanvas(event);
|
||||
// initialFabricState(this_canvas);//清空添加状态
|
||||
// }
|
||||
// event.preventDefault();
|
||||
// }, true);
|
||||
|
||||
|
||||
// console.log('域名',document.domain);
|
||||
var that = this;
|
||||
//listen file choosing and open 监听文件选择
|
||||
var this_e = document.getElementById('choose_file');
|
||||
this_e.addEventListener('change', function(e) {
|
||||
setFileAnnotation(this_e, e);
|
||||
this_e.value = null;
|
||||
});
|
||||
|
||||
var inputElement = document.getElementById("image_insert");
|
||||
// console.log('加载图片');
|
||||
inputElement.addEventListener('change', function(ev) {
|
||||
// console.log('插入图片');
|
||||
onlaodImgToInsert(ev);
|
||||
inputElement.value = null;
|
||||
});
|
||||
|
||||
//ban mouse right click 禁止在菜单上的默认右键事件
|
||||
var my_menu = document.getElementById('my-menu');
|
||||
my_menu.oncontextmenu = function(e) {
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
// //默认打开列表
|
||||
// if (default_show_annotation_list==true){
|
||||
// editAnnotation();
|
||||
// // console.log('打开列表');
|
||||
// pdfAnnotationUI.show_all_annotation_list=true;
|
||||
// pdfAnnotationUI.showAnnotationList();
|
||||
// // // //刷新批注显示列表
|
||||
// // if (pdfAnnotationUI.show_annotation_list) {
|
||||
// // }
|
||||
// }
|
||||
//历史框可标注
|
||||
listenDrag("my_annotation_history");
|
||||
}
|
||||
|
||||
window.onresize = function() { //监听屏幕的改变
|
||||
setTimeout(function() {
|
||||
JSplump.refreshConnections();
|
||||
}, 100)
|
||||
};
|
||||
|
||||
|
||||
|
||||
var interval = null;
|
||||
|
||||
function loadDetect() {
|
||||
var tips = {
|
||||
'zh-cn': [
|
||||
'文档加载中...',
|
||||
],
|
||||
'en': [
|
||||
'Loading PDF...',
|
||||
]
|
||||
} [tips_language];
|
||||
pdfAnnotationUI.showDownloadLog(tips[0]);
|
||||
interval = setInterval('loadPdf()', 1000);
|
||||
}
|
||||
|
||||
function loadPdf() {
|
||||
if (PDFViewerApplication.pdfDocument == null) {
|
||||
console.info('Loading...');
|
||||
} else {
|
||||
//文档加载完成
|
||||
clearInterval(interval);
|
||||
setSettingsControl(); //添加设置面板
|
||||
pdfAnnotationUI.closeDownloadLog();
|
||||
if (hyper_open_file==true){
|
||||
PDFViewerApplication.page=hyper_open_page;
|
||||
hyper_open_file=false;
|
||||
hyper_open_page=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//实现文件下载
|
||||
function downFromATag(blobUrl,filename,option,tip){
|
||||
//blobUrl为PDF数据,可转换为base 64后上传至服务器
|
||||
if (option==0){
|
||||
//IE11的下载方式
|
||||
//在IE环境下,blobUrl是 blob,转换到 base64时请注意区分
|
||||
window.navigator.msSaveBlob(blobUrl,filename);
|
||||
// window.navigator.msSaveOrOpenBlob(blobUrl, filename);
|
||||
}else{
|
||||
//非IE 11的下载方式
|
||||
var a = document.createElement('a');
|
||||
if (!a.click) {
|
||||
throw new Error('DownloadManager: "a.click()" is not supported.');
|
||||
}
|
||||
|
||||
a.href = blobUrl;
|
||||
a.target = '_parent';
|
||||
|
||||
if ('download' in a) {
|
||||
a.download = filename;
|
||||
}
|
||||
|
||||
try{
|
||||
postPDFData({
|
||||
"filename":filename,
|
||||
"file_blob_url_data":blobUrl,
|
||||
});
|
||||
}catch(e){
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
(document.body || document.documentElement).appendChild(a);
|
||||
a.click();
|
||||
a.remove();
|
||||
|
||||
// alert(tip);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function postPDFData(function_name,new_content){
|
||||
window.parent.postMessage({"type":0,"source":"pdfmaster",'function_name':function_name,"content":new_content},'*');
|
||||
}
|
||||
|
||||
var down_load_file=true;
|
||||
var return_data=false;
|
||||
function getPDFBlobData(){
|
||||
//get pdf blob data but not download file
|
||||
down_load_file=false;
|
||||
return_data=true;
|
||||
PDFViewerApplication.download();
|
||||
}
|
||||
|
||||
function getPDFBlobDataAndDownLoad(){
|
||||
//get pdf blob data and download file
|
||||
down_load_file=true;
|
||||
return_data=true;
|
||||
PDFViewerApplication.download();
|
||||
}
|
422
src/assets/pdf-annotation/annotation/promise_js.js
Executable file
@ -0,0 +1,422 @@
|
||||
|
||||
// import "@babel/polyfill";
|
||||
|
||||
pdfwheel.Annotation.prototype.modifyPdf = async function(blobUrl, filename) {
|
||||
var tips = {
|
||||
'zh-cn': [
|
||||
'初始化文档...',
|
||||
'1/2 处理文档...',
|
||||
'2/2 下载准备中...',
|
||||
'1. 文档已自动下载,请留意浏览器下载窗口\n2. 若文档较大时则耗时较久,请耐心等待',
|
||||
],
|
||||
'en': [
|
||||
'Initialing PDF...',
|
||||
'1/2 Processing File...',
|
||||
'2/2 Prepare for downloading...',
|
||||
'1. File is downloading, please pay attention to the browser download window\n\n2. When the file is large, it will take a long time, please wait patiently.',
|
||||
]
|
||||
} [tips_language];
|
||||
pdfAnnotationUI.showDownloadLog(tips[0]);
|
||||
// increase();
|
||||
var file_annotation = this.readFileAnnotations();
|
||||
var havenot_annotation=true;
|
||||
for (var key in file_annotation){
|
||||
var this_annotation=file_annotation[key];
|
||||
var string_obj=JSON.stringify(this_annotation.page_canvas.fabric_canvas_json.objects);
|
||||
if (string_obj!=='{}'){
|
||||
havenot_annotation=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (havenot_annotation==true){
|
||||
pdfAnnotationUI.closeDownloadLog();
|
||||
downFromATag(blobUrl, filename,1,tips[3]);
|
||||
return;
|
||||
}
|
||||
|
||||
pdfAnnotationUI.showDownloadLog(tips[1]);
|
||||
|
||||
// URL for request URL是要请求的地址
|
||||
var existingPdfBytes = await window.fetch(blobUrl).then(res => res
|
||||
.arrayBuffer());
|
||||
// console.log('文件加载完成');
|
||||
// var existingPdfBytes = blobUrl.arrayBuffer();
|
||||
var pdfDoc = await window.PDFLib.PDFDocument.load(existingPdfBytes);
|
||||
var pages = pdfDoc.getPages();
|
||||
// console.log('批注pdf加载完成2', pages.length);
|
||||
var pages_imgs = [];
|
||||
var canvas_scale = 1;
|
||||
|
||||
for (var j = 0; j < pages.length; j++) {
|
||||
var img = await this.drawCanvasForDownload(pages[j], j + 1, canvas_scale);
|
||||
// console.log('图片链接',img);
|
||||
if (img) {
|
||||
// console.log('图片转换',img);
|
||||
var eleImgCover = await pdfDoc.embedPng(img);
|
||||
// console.log('图片转换完成',eleImgCover);
|
||||
pages_imgs.push(eleImgCover);
|
||||
} else {
|
||||
pages_imgs.push(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pdfAnnotationUI.showDownloadLog(tips[2]);
|
||||
|
||||
var i = 0;
|
||||
pages.forEach(item => {
|
||||
// console.log('当前页面',i);
|
||||
var this_img = pages_imgs[i];
|
||||
// const pageRotation = getPageRotation(item);
|
||||
if (this_img != null) {
|
||||
var page_width = item.getSize().width;
|
||||
var page_height = item.getSize().height;
|
||||
const rotationAngle = item.getRotation().angle;
|
||||
|
||||
var draw_x;
|
||||
var draw_y;
|
||||
var this_scale;
|
||||
var final_angle=0;
|
||||
var draw_width;
|
||||
var draw_height;
|
||||
if (rotationAngle==90){
|
||||
draw_x=page_width;
|
||||
draw_y=0;
|
||||
final_angle=90;
|
||||
draw_width=page_height;
|
||||
draw_height=page_width;
|
||||
}else if(rotationAngle==180){
|
||||
draw_x=page_width;
|
||||
draw_y=page_height;
|
||||
final_angle=180;
|
||||
draw_width=page_width;
|
||||
draw_height=page_height;
|
||||
}else if(rotationAngle==270){
|
||||
this_scale = this_img.width / page_width;
|
||||
draw_x=0;
|
||||
draw_y=page_height;
|
||||
final_angle=270;
|
||||
draw_width=page_height;
|
||||
draw_height=page_width;
|
||||
}else{
|
||||
this_scale = this_img.width / page_width;
|
||||
draw_x=0;
|
||||
draw_y=0;
|
||||
final_angle=0;
|
||||
draw_width=page_width;
|
||||
draw_height=page_height;
|
||||
}
|
||||
// console.log('页面旋转角度',rotationAngle);
|
||||
|
||||
item.drawImage(this_img, {
|
||||
x: draw_x,
|
||||
y: draw_y,
|
||||
rotate: PDFLib.degrees(final_angle),
|
||||
width: draw_width,
|
||||
height: draw_height,
|
||||
});
|
||||
|
||||
// if (this.add_water_mark == true) {
|
||||
// item.drawText('https://demos.libertynlp.com', {
|
||||
// x: 0,
|
||||
// y: page_height / 2,
|
||||
// size: 40,
|
||||
// color: PDFLib.rgb(0, 0, 0),
|
||||
// })
|
||||
// }
|
||||
}
|
||||
|
||||
i = i + 1;
|
||||
})
|
||||
|
||||
|
||||
//如果存在需要提取的页面
|
||||
if (extract_page_numbers.length > 0) {
|
||||
var new_pdfDoc = await PDFLib.PDFDocument.create();
|
||||
for (var j = 0; j < pages.length - 1; j++) {
|
||||
if (extract_page_numbers.indexOf(j) != -1) {
|
||||
var [added_Page] = await new_pdfDoc.copyPages(pdfDoc, [j])
|
||||
// Add the first copied page
|
||||
new_pdfDoc.addPage(added_Page)
|
||||
}
|
||||
}
|
||||
pdfDoc = new_pdfDoc;
|
||||
//处理完之后置空
|
||||
extract_page_numbers = [];
|
||||
}
|
||||
|
||||
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
|
||||
const blob = new Blob([await pdfDoc.save()], {
|
||||
type: 'application/pdf'
|
||||
});
|
||||
// console.log('IE-批注转Blob完成');
|
||||
downFromATag(blob, filename,0,tips[3]);
|
||||
} else {
|
||||
const pdfUrl = URL.createObjectURL(
|
||||
new Blob([await pdfDoc.save()], {
|
||||
type: 'application/pdf'
|
||||
}),
|
||||
);
|
||||
// window.open(pdfUrl, '_blank');
|
||||
// console.log('批注转Blob完成');
|
||||
downFromATag(pdfUrl, filename,1,tips[3]);
|
||||
}
|
||||
pdfAnnotationUI.closeDownloadLog();
|
||||
}
|
||||
|
||||
// wux 添加了 merge 方法,将 annotation 合并到 pdf 中。内容基本上是抄的上面 download 方法。
|
||||
pdfwheel.Annotation.prototype.merge = async function(blob) {
|
||||
var tips = {
|
||||
'zh-cn': [
|
||||
'初始化文档...',
|
||||
'1/2 处理文档...',
|
||||
'2/2 准备中...',
|
||||
'1. 文档正在保存\n2. 若文档较大时则耗时较久,请耐心等待',
|
||||
],
|
||||
'en': [
|
||||
'Initialing PDF...',
|
||||
'1/2 Processing File...',
|
||||
'2/2 Preparing...',
|
||||
'1. File is saving,\n\n2. When the file is large, it will take a long time, please wait patiently.',
|
||||
]
|
||||
} [tips_language];
|
||||
pdfAnnotationUI.showDownloadLog(tips[0]);
|
||||
// increase();
|
||||
var file_annotation = this.readFileAnnotations();
|
||||
var havenot_annotation=true;
|
||||
for (var key in file_annotation){
|
||||
var this_annotation=file_annotation[key];
|
||||
var string_obj=JSON.stringify(this_annotation.page_canvas.fabric_canvas_json.objects);
|
||||
if (string_obj!=='{}'){
|
||||
havenot_annotation=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (havenot_annotation==true){
|
||||
pdfAnnotationUI.closeDownloadLog();
|
||||
return pdfDoc;
|
||||
}
|
||||
|
||||
pdfAnnotationUI.showDownloadLog(tips[1]);
|
||||
|
||||
//////////
|
||||
// console.log('文件加载完成');
|
||||
var existingPdfBytes = await blob.arrayBuffer();
|
||||
var pdfDoc = await window.PDFLib.PDFDocument.load(existingPdfBytes);
|
||||
var pages = pdfDoc.getPages();
|
||||
|
||||
//////////
|
||||
// URL for request URL是要请求的地址
|
||||
// console.log('文件加载完成');
|
||||
// var existingPdfBytes = blobUrl.arrayBuffer();
|
||||
// var pdfDoc = await window.PDFLib.PDFDocument.load(existingPdfBytes);
|
||||
var pages = pdfDoc.getPages();
|
||||
// console.log('批注pdf加载完成2', pages.length);
|
||||
var pages_imgs = [];
|
||||
var canvas_scale = 1;
|
||||
|
||||
for (var j = 0; j < pages.length; j++) {
|
||||
var img = await this.drawCanvasForDownload(pages[j], j + 1, canvas_scale);
|
||||
// console.log('图片链接',img);
|
||||
if (img) {
|
||||
// console.log('图片转换',img);
|
||||
var eleImgCover = await pdfDoc.embedPng(img);
|
||||
// console.log('图片转换完成',eleImgCover);
|
||||
pages_imgs.push(eleImgCover);
|
||||
} else {
|
||||
pages_imgs.push(null);
|
||||
}
|
||||
}
|
||||
|
||||
pdfAnnotationUI.showDownloadLog(tips[2]);
|
||||
|
||||
var i = 0;
|
||||
pages.forEach(item => {
|
||||
// console.log('当前页面',i);
|
||||
var this_img = pages_imgs[i];
|
||||
// const pageRotation = getPageRotation(item);
|
||||
if (this_img != null) {
|
||||
var page_width = item.getSize().width;
|
||||
var page_height = item.getSize().height;
|
||||
const rotationAngle = item.getRotation().angle;
|
||||
|
||||
var draw_x;
|
||||
var draw_y;
|
||||
var this_scale;
|
||||
var final_angle=0;
|
||||
var draw_width;
|
||||
var draw_height;
|
||||
if (rotationAngle==90){
|
||||
draw_x=page_width;
|
||||
draw_y=0;
|
||||
final_angle=90;
|
||||
draw_width=page_height;
|
||||
draw_height=page_width;
|
||||
}else if(rotationAngle==180){
|
||||
draw_x=page_width;
|
||||
draw_y=page_height;
|
||||
final_angle=180;
|
||||
draw_width=page_width;
|
||||
draw_height=page_height;
|
||||
}else if(rotationAngle==270){
|
||||
this_scale = this_img.width / page_width;
|
||||
draw_x=0;
|
||||
draw_y=page_height;
|
||||
final_angle=270;
|
||||
draw_width=page_height;
|
||||
draw_height=page_width;
|
||||
}else{
|
||||
this_scale = this_img.width / page_width;
|
||||
draw_x=0;
|
||||
draw_y=0;
|
||||
final_angle=0;
|
||||
draw_width=page_width;
|
||||
draw_height=page_height;
|
||||
}
|
||||
// console.log('页面旋转角度',rotationAngle);
|
||||
|
||||
item.drawImage(this_img, {
|
||||
x: draw_x,
|
||||
y: draw_y,
|
||||
rotate: PDFLib.degrees(final_angle),
|
||||
width: draw_width,
|
||||
height: draw_height,
|
||||
});
|
||||
|
||||
// if (this.add_water_mark == true) {
|
||||
// item.drawText('https://demos.libertynlp.com', {
|
||||
// x: 0,
|
||||
// y: page_height / 2,
|
||||
// size: 40,
|
||||
// color: PDFLib.rgb(0, 0, 0),
|
||||
// })
|
||||
// }
|
||||
}
|
||||
|
||||
i = i + 1;
|
||||
})
|
||||
|
||||
//如果存在需要提取的页面
|
||||
if (extract_page_numbers.length > 0) {
|
||||
var new_pdfDoc = await PDFLib.PDFDocument.create();
|
||||
for (var j = 0; j < pages.length - 1; j++) {
|
||||
if (extract_page_numbers.indexOf(j) != -1) {
|
||||
var [added_Page] = await new_pdfDoc.copyPages(pdfDoc, [j])
|
||||
// Add the first copied page
|
||||
new_pdfDoc.addPage(added_Page)
|
||||
}
|
||||
}
|
||||
pdfDoc = new_pdfDoc;
|
||||
//处理完之后置空
|
||||
extract_page_numbers = [];
|
||||
}
|
||||
|
||||
pdfAnnotationUI.closeDownloadLog();
|
||||
const pdfBlob = new Blob([await pdfDoc.save()], {
|
||||
type: 'application/pdf'
|
||||
});
|
||||
return pdfBlob;
|
||||
}
|
||||
|
||||
|
||||
// draw canvas and convert to pdf 绘制批注到 canvas 并转换为 png
|
||||
pdfwheel.Annotation.prototype.drawCanvasForDownload = async function(item, page_number, scale) {
|
||||
var old_fabric_obj = this.readFabricAnnotationsForPage(page_number);
|
||||
if (old_fabric_obj) {
|
||||
var width = parseFloat(old_fabric_obj.page_canvas.width);
|
||||
var height = parseFloat(old_fabric_obj.page_canvas.height);
|
||||
|
||||
var anno_canvas = document.createElement("canvas");
|
||||
anno_canvas.width = width;
|
||||
anno_canvas.height = height;
|
||||
var page_id = this.fabric_annos_id_tag + 'for-download-' + page_number.toString();
|
||||
anno_canvas.setAttribute('id', page_id);
|
||||
|
||||
var canvas_container = document.getElementById('div-for-download-canvas');
|
||||
canvas_container.appendChild(anno_canvas);
|
||||
|
||||
var this_fabric_canvas = new fabric.Canvas(page_id, {
|
||||
includeDefaultValues: true,
|
||||
isDrawingMode: false,
|
||||
fireRightClick: true,
|
||||
stopContextMenu: false,
|
||||
backgroundColor: 'rgba(255, 255, 255, 0)',
|
||||
});
|
||||
|
||||
async function loadImageFabricCanvas() {
|
||||
return new Promise(resolve => {
|
||||
this_fabric_canvas.loadFromJSON(old_fabric_obj.page_canvas.fabric_canvas_json,
|
||||
function() {
|
||||
var this_canvas = document.getElementById(page_id);
|
||||
var pic_url = this_canvas.toDataURL('image/png');
|
||||
canvas_container.innerHTML = '';
|
||||
resolve(pic_url);
|
||||
});
|
||||
})
|
||||
}
|
||||
let this_pic_url = await loadImageFabricCanvas();
|
||||
return this_pic_url;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
拓展功能:
|
||||
|
||||
增加文字水印
|
||||
*/
|
||||
pdfwheel.Annotation.prototype.addWaterMark = async function(url) {
|
||||
const existingPdfBytes = await fetch(url).then(res => res.arrayBuffer())
|
||||
const pdfDoc = await window.PDFLib.PDFDocument.load(existingPdfBytes)
|
||||
|
||||
//遍历页面增加水印
|
||||
const pages = pdfDoc.getPages();
|
||||
var pages_imgs = [];
|
||||
var canvas_scale = 2;
|
||||
for (var j = 0; j < pages.length; j++) {
|
||||
var page = pages[j];
|
||||
var page_width = page.getSize().width;
|
||||
var page_height = page.getSize().height;
|
||||
|
||||
// 生成水印对象
|
||||
var img = await this.drawWaterMark(page_width * canvas_scale, page_height * canvas_scale);
|
||||
var pdf_img = await pdfDoc.embedPng(img);
|
||||
pages_imgs.push(pdf_img);
|
||||
}
|
||||
|
||||
var i = 0;
|
||||
pages.forEach(item => {
|
||||
var this_img = pages_imgs[i];
|
||||
var this_scale = this_img.width / page_width;
|
||||
item.drawImage(this_img, {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: this_img.width / this_scale,
|
||||
height: this_img.height / this_scale,
|
||||
});
|
||||
i = i + 1;
|
||||
})
|
||||
// 已经处理好的数据
|
||||
const pdfBuffer = await pdfDoc.save()
|
||||
const pdfUrl = URL.createObjectURL(
|
||||
new Blob([pdfBuffer], {
|
||||
type: 'application/pdf'
|
||||
}),
|
||||
);
|
||||
// 返回出去
|
||||
return pdfUrl
|
||||
}
|
||||
|
||||
pdfwheel.Annotation.prototype.openFile =async function(oriUrl) {
|
||||
var pdfUrl;
|
||||
if (add_water_mark == true) {
|
||||
pdfAnnotationUI.showDownloadLog("文档水印处理中...");
|
||||
pdfUrl = await this.addWaterMark(oriUrl);
|
||||
pdfAnnotationUI.closeDownloadLog();
|
||||
} else {
|
||||
pdfUrl = oriUrl;
|
||||
}
|
||||
window.PDFViewerApplication.open(pdfUrl); //open pdf 打开pdf文档
|
||||
}
|