This commit is contained in:
2024-11-19 16:59:54 +08:00
commit d2928bd43f
522 changed files with 243091 additions and 0 deletions
+16
View 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
View 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
View 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
View 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
View File
@@ -0,0 +1,5 @@
{
"recommendations": [
"ionic.ionic"
]
}
+3
View File
@@ -0,0 +1,3 @@
{
"typescript.preferences.autoImportFileExcludePatterns": ["@ionic/angular/common", "@ionic/angular/standalone"]
}
+3
View File
@@ -0,0 +1,3 @@
### pdf js annotation 的 Demo
是一个 ionic 的项目,为了山核项目准备的。
在满足山核功能的基础上,精简了界面,处理了保存功能。
+179
View 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
View 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
View File
@@ -0,0 +1,7 @@
{
"name": "pdfannotation-demo",
"integrations": {
"cordova": {}
},
"type": "angular"
}
+44
View 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
View File
File diff suppressed because it is too large Load Diff
+77
View 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
View 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/
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

@@ -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>
Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 686 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

+22
View 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
View File
@@ -0,0 +1,3 @@
<ion-app>
<ion-router-outlet></ion-router-outlet>
</ion-app>
View File
+21
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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);
Binary file not shown.

After

Width:  |  Height:  |  Size: 930 B

File diff suppressed because it is too large Load Diff
+829
View 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
View 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
View 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
View 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文档
}
File diff suppressed because it is too large Load Diff
+20056
View File
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More