Spaces:
Running
Running
Deploy full app to HF Space
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .editorconfig +5 -0
- .eslintrc.js +41 -0
- .gitattributes +2 -0
- .github/ISSUE_TEMPLATE/bug_report.md +40 -0
- .github/ISSUE_TEMPLATE/feature_request.md +38 -0
- .github/ISSUE_TEMPLATE/question.md +29 -0
- .github/auto-comment.yml +10 -0
- .github/composite-actions/build-package/action.yml +43 -0
- .github/composite-actions/install-dependencies/action.yml +33 -0
- .github/composite-actions/publish-cdn/action.yml +54 -0
- .github/composite-actions/publish-docs/action.yml +77 -0
- .github/composite-actions/publish-package/action.yml +45 -0
- .github/stale.yml +30 -0
- .gitignore +69 -0
- .prettierrc +18 -0
- CODE_OF_CONDUCT.md +73 -0
- CONTRIBUTING.md +107 -0
- ISSUE_TEMPLATE.md +30 -0
- LICENSE +22 -0
- README.md +206 -14
- app.py +24 -0
- apps/image-editor/README.md +193 -0
- apps/image-editor/__mocks__/fileMock.js +7 -0
- apps/image-editor/__mocks__/svgMock.js +5 -0
- apps/image-editor/createConfigVariable.js +37 -0
- apps/image-editor/examples/css/service-basic.css +128 -0
- apps/image-editor/examples/css/service-mobile.css +203 -0
- apps/image-editor/examples/css/tui-example-style.css +21 -0
- apps/image-editor/examples/example01-includeUi.html +63 -0
- apps/image-editor/examples/example02-useApiDirect.html +380 -0
- apps/image-editor/examples/example03-mobile.html +249 -0
- apps/image-editor/examples/examples.json +11 -0
- apps/image-editor/examples/img/TOAST UI Component.png +3 -0
- apps/image-editor/examples/img/bg.jpg +3 -0
- apps/image-editor/examples/img/bg.png +3 -0
- apps/image-editor/examples/img/download.png +3 -0
- apps/image-editor/examples/img/mask.png +3 -0
- apps/image-editor/examples/img/openImage.png +3 -0
- apps/image-editor/examples/img/redo.png +3 -0
- apps/image-editor/examples/img/remove.png +3 -0
- apps/image-editor/examples/img/sampleImage.jpg +3 -0
- apps/image-editor/examples/img/sampleImage2.png +3 -0
- apps/image-editor/examples/img/undo.png +3 -0
- apps/image-editor/examples/js/service-basic.js +922 -0
- apps/image-editor/examples/js/service-mobile.js +595 -0
- apps/image-editor/examples/js/theme/black-theme.js +76 -0
- apps/image-editor/examples/js/theme/white-theme.js +76 -0
- apps/image-editor/index.d.ts +334 -0
- apps/image-editor/jest-setup.js +1 -0
- apps/image-editor/jest.config.js +21 -0
.editorconfig
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[*]
|
| 2 |
+
charset = utf-8
|
| 3 |
+
indent_style = space
|
| 4 |
+
indent_size = 2
|
| 5 |
+
end_of_line = lf
|
.eslintrc.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
module.exports = {
|
| 2 |
+
root: true,
|
| 3 |
+
extends: ['tui/es6', 'plugin:jest/recommended', 'plugin:prettier/recommended'],
|
| 4 |
+
plugins: ['jest', 'prettier'],
|
| 5 |
+
env: {
|
| 6 |
+
browser: true,
|
| 7 |
+
amd: true,
|
| 8 |
+
node: true,
|
| 9 |
+
es6: true,
|
| 10 |
+
jest: true,
|
| 11 |
+
'jest/globals': true,
|
| 12 |
+
},
|
| 13 |
+
parser: '@babel/eslint-parser',
|
| 14 |
+
parserOptions: {
|
| 15 |
+
sourceType: 'module',
|
| 16 |
+
babelOptions: {
|
| 17 |
+
rootMode: 'upward',
|
| 18 |
+
},
|
| 19 |
+
},
|
| 20 |
+
ignorePatterns: ['node_modules/*', 'dist', 'examples'],
|
| 21 |
+
rules: {
|
| 22 |
+
'prefer-destructuring': [
|
| 23 |
+
'error',
|
| 24 |
+
{
|
| 25 |
+
VariableDeclarator: { array: true, object: true },
|
| 26 |
+
AssignmentExpression: { array: false, object: false },
|
| 27 |
+
},
|
| 28 |
+
],
|
| 29 |
+
},
|
| 30 |
+
overrides: [
|
| 31 |
+
{
|
| 32 |
+
files: ['*.spec.js'],
|
| 33 |
+
rules: {
|
| 34 |
+
'max-nested-callbacks': ['error', { max: 5 }],
|
| 35 |
+
'dot-notation': ['error', { allowKeywords: true }],
|
| 36 |
+
'no-undefined': 'off',
|
| 37 |
+
'jest/expect-expect': ['error', { assertFunctionNames: ['expect', 'assert*'] }],
|
| 38 |
+
},
|
| 39 |
+
},
|
| 40 |
+
],
|
| 41 |
+
};
|
.gitattributes
CHANGED
|
@@ -33,5 +33,7 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
| 36 |
*.png filter=lfs diff=lfs merge=lfs -text
|
| 37 |
*.jpg filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
apps/vue-image-editor/.storybook/img/sampleImage2.png filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
apps/image-editor/tests/fixtures/sampleImage.jpg filter=lfs diff=lfs merge=lfs -text
|
| 38 |
*.png filter=lfs diff=lfs merge=lfs -text
|
| 39 |
*.jpg filter=lfs diff=lfs merge=lfs -text
|
.github/ISSUE_TEMPLATE/bug_report.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
name: Bug report
|
| 3 |
+
about: Create a report to help us improve
|
| 4 |
+
title: ''
|
| 5 |
+
labels: Bug
|
| 6 |
+
assignees: ''
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
**Describe the bug**
|
| 10 |
+
A clear and concise description of what the bug is.
|
| 11 |
+
|
| 12 |
+
**To Reproduce**
|
| 13 |
+
Steps to reproduce the behavior:
|
| 14 |
+
|
| 15 |
+
1. Go to '...'
|
| 16 |
+
2. Click on '....'
|
| 17 |
+
3. Scroll down to '....'
|
| 18 |
+
4. See error
|
| 19 |
+
|
| 20 |
+
**Expected behavior**
|
| 21 |
+
A clear and concise description of what you expected to happen.
|
| 22 |
+
|
| 23 |
+
**Screenshots**
|
| 24 |
+
If applicable, add screenshots to help explain your problem.
|
| 25 |
+
|
| 26 |
+
**Desktop (please complete the following information):**
|
| 27 |
+
|
| 28 |
+
- OS: [e.g. iOS]
|
| 29 |
+
- Browser [e.g. chrome, safari]
|
| 30 |
+
- Version [e.g. 22]
|
| 31 |
+
|
| 32 |
+
**Smartphone (please complete the following information):**
|
| 33 |
+
|
| 34 |
+
- Device: [e.g. iPhone6]
|
| 35 |
+
- OS: [e.g. iOS8.1]
|
| 36 |
+
- Browser [e.g. stock browser, safari]
|
| 37 |
+
- Version [e.g. 22]
|
| 38 |
+
|
| 39 |
+
**Additional context**
|
| 40 |
+
Add any other context about the problem here.
|
.github/ISSUE_TEMPLATE/feature_request.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
name: Feature request
|
| 3 |
+
about: Suggest an idea for this project
|
| 4 |
+
title: ''
|
| 5 |
+
labels: Enhancement, Need Discussion
|
| 6 |
+
assignees: ''
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
<!--
|
| 10 |
+
Thank you for your contribution.
|
| 11 |
+
|
| 12 |
+
When it comes to write an issue, please, use the template below.
|
| 13 |
+
To use the template is mandatory for submit new issue and we won't reply the issue that without the template.
|
| 14 |
+
|
| 15 |
+
And you can write template's contents in Korean also.
|
| 16 |
+
-->
|
| 17 |
+
|
| 18 |
+
<!-- TEMPLATE -->
|
| 19 |
+
|
| 20 |
+
## Version
|
| 21 |
+
|
| 22 |
+
<!-- Write the version of the imageEditor you are currently using. -->
|
| 23 |
+
|
| 24 |
+
## Development Environment
|
| 25 |
+
|
| 26 |
+
<!-- Write the browser type, OS and so on -->
|
| 27 |
+
|
| 28 |
+
## Current Behavior
|
| 29 |
+
|
| 30 |
+
<!-- Write a description of the current operation. You can add sample code, 'CodePen' or 'jsfiddle' links. -->
|
| 31 |
+
|
| 32 |
+
```js
|
| 33 |
+
// Write example code
|
| 34 |
+
```
|
| 35 |
+
|
| 36 |
+
## Expected Behavior
|
| 37 |
+
|
| 38 |
+
<!-- Write a description of the future action. -->
|
.github/ISSUE_TEMPLATE/question.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
name: Question
|
| 3 |
+
about: Create a question about imageEditor
|
| 4 |
+
title: ''
|
| 5 |
+
labels: Question
|
| 6 |
+
assignees: ''
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
<!--
|
| 10 |
+
To make it easier for us to help you, please include as much useful information as possible.
|
| 11 |
+
|
| 12 |
+
Useful Links:
|
| 13 |
+
- tutorial: https://github.com/nhn/tui.image-editor/tree/master/docs
|
| 14 |
+
- API/Example: https://nhn.github.io/tui.image-editor/latest
|
| 15 |
+
|
| 16 |
+
Before opening a new issue, please search existing issues https://github.com/nhn/tui.image-editor/issues
|
| 17 |
+
-->
|
| 18 |
+
|
| 19 |
+
**Summary**
|
| 20 |
+
A clear and concise description of what the question is.
|
| 21 |
+
|
| 22 |
+
**Screenshots**
|
| 23 |
+
If applicable, add screenshots to help explain your question.
|
| 24 |
+
|
| 25 |
+
**Version**
|
| 26 |
+
Write the version of the imageEditor you are currently using.
|
| 27 |
+
|
| 28 |
+
**Additional context**
|
| 29 |
+
Add any other context about the problem here.
|
.github/auto-comment.yml
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Comment to a new issue.
|
| 2 |
+
issuesOpened: >
|
| 3 |
+
Thank you for raising an issue.
|
| 4 |
+
|
| 5 |
+
We will try and get back to you as soon as possible.
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
Please make sure you have filled out issue respecting our form **in English** and given us as much context as possible.
|
| 9 |
+
**If not, the issue will be closed or not replied.**
|
| 10 |
+
|
.github/composite-actions/build-package/action.yml
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
name: 'Build'
|
| 2 |
+
description: 'Build package'
|
| 3 |
+
inputs:
|
| 4 |
+
ROOT_CACHE_KEY:
|
| 5 |
+
description: 'Key of root dependencies cache'
|
| 6 |
+
required: true
|
| 7 |
+
BUILD_CACHE_KEY:
|
| 8 |
+
description: 'Key of build cache'
|
| 9 |
+
required: true
|
| 10 |
+
runs:
|
| 11 |
+
using: 'composite'
|
| 12 |
+
steps:
|
| 13 |
+
- name: Use Node.js 15.x
|
| 14 |
+
uses: actions/setup-node@v1
|
| 15 |
+
with:
|
| 16 |
+
node-version: '15.x'
|
| 17 |
+
registry-url: https://registry.npmjs.org/
|
| 18 |
+
- name: Check root dependencies cache
|
| 19 |
+
uses: actions/cache@v2
|
| 20 |
+
with:
|
| 21 |
+
path: ./node_modules
|
| 22 |
+
key: ${{ inputs.ROOT_CACHE_KEY }}
|
| 23 |
+
- name: Install package dependencies and remove package-lock file
|
| 24 |
+
working-directory: ./apps/image-editor
|
| 25 |
+
run: |
|
| 26 |
+
npm install && rm -rf ./package-lock.json
|
| 27 |
+
shell: bash
|
| 28 |
+
- name: Check build cache
|
| 29 |
+
uses: actions/cache@v2
|
| 30 |
+
id: cache_built_packages
|
| 31 |
+
with:
|
| 32 |
+
path: ./apps/image-editor/dist
|
| 33 |
+
key: ${{ inputs.BUILD_CACHE_KEY }}
|
| 34 |
+
- name: Build package
|
| 35 |
+
working-directory: ./apps/image-editor
|
| 36 |
+
run: |
|
| 37 |
+
if echo ${{ steps.cache_built_packages.outputs.cache-hit }} | grep -c "true"
|
| 38 |
+
then
|
| 39 |
+
echo "Cache hit - skipping building"
|
| 40 |
+
else
|
| 41 |
+
npm run build
|
| 42 |
+
fi
|
| 43 |
+
shell: bash
|
.github/composite-actions/install-dependencies/action.yml
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
name: 'Install root dependencies using cache'
|
| 2 |
+
description: 'Set Node.js version and install node_modules'
|
| 3 |
+
outputs:
|
| 4 |
+
root_cache_key:
|
| 5 |
+
description: 'Key of root dependencies cache'
|
| 6 |
+
value: ${{ steps.root_lockfile_hash.outputs.hash }}
|
| 7 |
+
runs:
|
| 8 |
+
using: 'composite'
|
| 9 |
+
steps:
|
| 10 |
+
- name: Use Node.js 15.x
|
| 11 |
+
uses: actions/setup-node@v1
|
| 12 |
+
with:
|
| 13 |
+
node-version: '15.x'
|
| 14 |
+
registry-url: https://registry.npmjs.org/
|
| 15 |
+
- name: Compute root dependencies cache key
|
| 16 |
+
id: root_lockfile_hash
|
| 17 |
+
run: echo "::set-output name=hash::${{ hashFiles('package-lock.json') }}"
|
| 18 |
+
shell: bash
|
| 19 |
+
- name: Check root dependencies cache
|
| 20 |
+
uses: actions/cache@v2
|
| 21 |
+
id: root_cache_dependencies
|
| 22 |
+
with:
|
| 23 |
+
path: ./node_modules
|
| 24 |
+
key: ${{ steps.root_lockfile_hash.outputs.hash }}
|
| 25 |
+
- name: Install root dependencies
|
| 26 |
+
run: |
|
| 27 |
+
if echo ${{ steps.root_cache_dependencies.outputs.cache-hit }} | grep -c "true"
|
| 28 |
+
then
|
| 29 |
+
echo "Cache hit - skipping root dependency installation"
|
| 30 |
+
else
|
| 31 |
+
npm install
|
| 32 |
+
fi
|
| 33 |
+
shell: bash
|
.github/composite-actions/publish-cdn/action.yml
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
name: 'Publish CDN'
|
| 2 |
+
description: 'Publish CDN'
|
| 3 |
+
inputs:
|
| 4 |
+
ROOT_CACHE_KEY:
|
| 5 |
+
description: 'Key of root dependencies cache'
|
| 6 |
+
required: true
|
| 7 |
+
BUILD_CACHE_KEY:
|
| 8 |
+
description: 'Key of build cache'
|
| 9 |
+
required: true
|
| 10 |
+
TOAST_CLOUD_TENANTID:
|
| 11 |
+
description: 'Tenant id for CDN'
|
| 12 |
+
required: true
|
| 13 |
+
TOAST_CLOUD_STORAGEID:
|
| 14 |
+
description: 'Storage id for CDN'
|
| 15 |
+
required: true
|
| 16 |
+
TOAST_CLOUD_USERNAME:
|
| 17 |
+
description: 'User name for CDN'
|
| 18 |
+
required: true
|
| 19 |
+
TOAST_CLOUD_PASSWORD:
|
| 20 |
+
description: 'password for CDN'
|
| 21 |
+
required: true
|
| 22 |
+
runs:
|
| 23 |
+
using: 'composite'
|
| 24 |
+
steps:
|
| 25 |
+
- name: Use Node.js 15.x
|
| 26 |
+
uses: actions/setup-node@v1
|
| 27 |
+
with:
|
| 28 |
+
node-version: '15.x'
|
| 29 |
+
registry-url: https://registry.npmjs.org/
|
| 30 |
+
- name: Check root dependencies cache
|
| 31 |
+
uses: actions/cache@v2
|
| 32 |
+
with:
|
| 33 |
+
path: ./node_modules
|
| 34 |
+
key: ${{ inputs.ROOT_CACHE_KEY }}
|
| 35 |
+
- name: Install package dependencies and remove package-lock file
|
| 36 |
+
working-directory: ./apps/image-editor
|
| 37 |
+
run: |
|
| 38 |
+
npm install && rm -rf ./package-lock.json
|
| 39 |
+
shell: bash
|
| 40 |
+
- name: Check build cache
|
| 41 |
+
uses: actions/cache@v2
|
| 42 |
+
with:
|
| 43 |
+
path: ./apps/image-editor/dist
|
| 44 |
+
key: ${{ inputs.BUILD_CACHE_KEY }}
|
| 45 |
+
- name: Upload files to CDN
|
| 46 |
+
working-directory: ./apps/image-editor
|
| 47 |
+
run: |
|
| 48 |
+
npm run publish:cdn
|
| 49 |
+
env:
|
| 50 |
+
TOAST_CLOUD_TENANTID: ${{ inputs.TOAST_CLOUD_TENANTID }}
|
| 51 |
+
TOAST_CLOUD_STORAGEID: ${{ inputs.TOAST_CLOUD_STORAGEID }}
|
| 52 |
+
TOAST_CLOUD_USERNAME: ${{ inputs.TOAST_CLOUD_USERNAME }}
|
| 53 |
+
TOAST_CLOUD_PASSWORD: ${{ inputs.TOAST_CLOUD_PASSWORD }}
|
| 54 |
+
shell: bash
|
.github/composite-actions/publish-docs/action.yml
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
name: 'Publish docs'
|
| 2 |
+
description: 'Publish docs'
|
| 3 |
+
inputs:
|
| 4 |
+
ROOT_CACHE_KEY:
|
| 5 |
+
description: 'Key of root dependencies cache'
|
| 6 |
+
required: true
|
| 7 |
+
BUILD_CACHE_KEY:
|
| 8 |
+
description: 'Key of build'
|
| 9 |
+
required: true
|
| 10 |
+
GITHUB_TOKEN:
|
| 11 |
+
description: 'Github token'
|
| 12 |
+
required: true
|
| 13 |
+
runs:
|
| 14 |
+
using: 'composite'
|
| 15 |
+
steps:
|
| 16 |
+
- name: Use Node.js 15.x
|
| 17 |
+
uses: actions/setup-node@v1
|
| 18 |
+
with:
|
| 19 |
+
node-version: '15.x'
|
| 20 |
+
registry-url: https://registry.npmjs.org/
|
| 21 |
+
- name: Get package version
|
| 22 |
+
id: version
|
| 23 |
+
uses: PostHog/check-package-version@v2
|
| 24 |
+
with:
|
| 25 |
+
path: ./apps/image-editor/
|
| 26 |
+
- name: Check root dependencies cache
|
| 27 |
+
uses: actions/cache@v2
|
| 28 |
+
with:
|
| 29 |
+
path: ./node_modules
|
| 30 |
+
key: ${{ inputs.ROOT_CACHE_KEY }}
|
| 31 |
+
- name: Install package dependencies and remove package-lock file
|
| 32 |
+
working-directory: ./apps/image-editor
|
| 33 |
+
run: |
|
| 34 |
+
npm install && rm -rf ./package-lock.json
|
| 35 |
+
shell: bash
|
| 36 |
+
- name: Check build cache
|
| 37 |
+
uses: actions/cache@v2
|
| 38 |
+
with:
|
| 39 |
+
path: ./apps/image-editor/dist
|
| 40 |
+
key: ${{ inputs.BUILD_CACHE_KEY }}
|
| 41 |
+
- name: Install toast-ui doc
|
| 42 |
+
run: npm i -g @toast-ui/doc
|
| 43 |
+
shell: bash
|
| 44 |
+
- name: Run doc
|
| 45 |
+
working-directory: ./apps/image-editor
|
| 46 |
+
run: |
|
| 47 |
+
npm run doc
|
| 48 |
+
mv _${{ steps.version.outputs.committed-version }} ../../_${{ steps.version.outputs.committed-version }}
|
| 49 |
+
mv -i _latest ../../_latest
|
| 50 |
+
rm -rf tmpdoc
|
| 51 |
+
git stash --include-untracked
|
| 52 |
+
shell: bash
|
| 53 |
+
- name: Checkout gh-pages branch
|
| 54 |
+
uses: actions/checkout@v2
|
| 55 |
+
with:
|
| 56 |
+
ref: gh-pages
|
| 57 |
+
- name: Commit files
|
| 58 |
+
run: |
|
| 59 |
+
git config --local user.name "lja1018"
|
| 60 |
+
git config --local user.email "jaeeon.lim@nhn.com"
|
| 61 |
+
rm -rf latest
|
| 62 |
+
rm -rf ${{ steps.version.outputs.committed-version }}
|
| 63 |
+
git stash pop
|
| 64 |
+
mv _${{ steps.version.outputs.committed-version }} ${{ steps.version.outputs.committed-version }}
|
| 65 |
+
mv -i _latest latest
|
| 66 |
+
git add .
|
| 67 |
+
git commit -m "v${{ steps.version.outputs.committed-version }}"
|
| 68 |
+
shell: bash
|
| 69 |
+
- name: Push changes
|
| 70 |
+
uses: ad-m/github-push-action@master
|
| 71 |
+
with:
|
| 72 |
+
github_token: ${{ inputs.GITHUB_TOKEN }}
|
| 73 |
+
branch: gh-pages
|
| 74 |
+
- name: Checkout branch
|
| 75 |
+
uses: actions/checkout@v2
|
| 76 |
+
with:
|
| 77 |
+
ref: master
|
.github/composite-actions/publish-package/action.yml
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
name: 'Publish package'
|
| 2 |
+
description: 'Publish package'
|
| 3 |
+
inputs:
|
| 4 |
+
ROOT_CACHE_KEY:
|
| 5 |
+
description: 'Key of root dependencies cache'
|
| 6 |
+
required: true
|
| 7 |
+
BUILD_CACHE_KEY:
|
| 8 |
+
description: 'Key of build cache'
|
| 9 |
+
required: true
|
| 10 |
+
NODE_AUTH_TOKEN:
|
| 11 |
+
description: 'NPM authorization token'
|
| 12 |
+
required: true
|
| 13 |
+
runs:
|
| 14 |
+
using: 'composite'
|
| 15 |
+
steps:
|
| 16 |
+
- name: Use Node.js 15.x
|
| 17 |
+
uses: actions/setup-node@v1
|
| 18 |
+
with:
|
| 19 |
+
node-version: '15.x'
|
| 20 |
+
registry-url: https://registry.npmjs.org/
|
| 21 |
+
- name: Checkout production branch
|
| 22 |
+
uses: actions/checkout@v2
|
| 23 |
+
with:
|
| 24 |
+
ref: production
|
| 25 |
+
- name: Check root dependencies cache
|
| 26 |
+
uses: actions/cache@v2
|
| 27 |
+
with:
|
| 28 |
+
path: ./node_modules
|
| 29 |
+
key: ${{ inputs.ROOT_CACHE_KEY }}
|
| 30 |
+
- name: Install package dependencies and remove package-lock file
|
| 31 |
+
working-directory: ./apps/image-editor
|
| 32 |
+
run: |
|
| 33 |
+
npm install && rm -rf ./package-lock.json
|
| 34 |
+
shell: bash
|
| 35 |
+
- name: Check build cache
|
| 36 |
+
uses: actions/cache@v2
|
| 37 |
+
with:
|
| 38 |
+
path: ./apps/image-editor/dist
|
| 39 |
+
key: ${{ inputs.BUILD_CACHE_KEY }}
|
| 40 |
+
- name: Publish package
|
| 41 |
+
working-directory: ./apps/image-editor
|
| 42 |
+
run: npm publish
|
| 43 |
+
env:
|
| 44 |
+
NODE_AUTH_TOKEN: ${{ inputs.NODE_AUTH_TOKEN }}
|
| 45 |
+
shell: bash
|
.github/stale.yml
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Configuration for probot-stale - https://github.com/probot/stale
|
| 2 |
+
|
| 3 |
+
# Number of days of inactivity before an Issue or Pull Request becomes stale
|
| 4 |
+
daysUntilStale: 30
|
| 5 |
+
|
| 6 |
+
# Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
|
| 7 |
+
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
|
| 8 |
+
daysUntilClose: 7
|
| 9 |
+
|
| 10 |
+
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
|
| 11 |
+
exemptLabels:
|
| 12 |
+
- Feature
|
| 13 |
+
- Enhancement
|
| 14 |
+
- Bug
|
| 15 |
+
- NHN Cloud
|
| 16 |
+
|
| 17 |
+
# Label to use when marking as stale
|
| 18 |
+
staleLabel: inactive
|
| 19 |
+
|
| 20 |
+
# Comment to post when marking as stale. Set to `false` to disable
|
| 21 |
+
markComment: >
|
| 22 |
+
This issue has been automatically marked as inactive because there hasn’t been much going on it lately.
|
| 23 |
+
It is going to be closed after 7 days. Thanks!
|
| 24 |
+
# Comment to post when removing the stale label.
|
| 25 |
+
# unmarkComment: >
|
| 26 |
+
# Your comment here.
|
| 27 |
+
|
| 28 |
+
# Comment to post when closing a stale Issue or Pull Request.
|
| 29 |
+
closeComment: >
|
| 30 |
+
This issue will be closed due to inactivity. Thanks for your contribution!
|
.gitignore
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Logs
|
| 2 |
+
logs
|
| 3 |
+
*.log
|
| 4 |
+
|
| 5 |
+
# Runtime data
|
| 6 |
+
pids
|
| 7 |
+
*.pid
|
| 8 |
+
*.seed
|
| 9 |
+
|
| 10 |
+
# Directory for instrumented libs generated by jscoverage/JSCover
|
| 11 |
+
lib-cov
|
| 12 |
+
|
| 13 |
+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
| 14 |
+
.grunt
|
| 15 |
+
|
| 16 |
+
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
| 17 |
+
build/Release
|
| 18 |
+
|
| 19 |
+
# Dependency directory
|
| 20 |
+
# Deployed apps should consider commenting this line out:
|
| 21 |
+
# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
|
| 22 |
+
node_modules
|
| 23 |
+
|
| 24 |
+
# Bower Components
|
| 25 |
+
bower_components
|
| 26 |
+
lib
|
| 27 |
+
|
| 28 |
+
#JSDOC
|
| 29 |
+
doc
|
| 30 |
+
|
| 31 |
+
# IDEA
|
| 32 |
+
.idea
|
| 33 |
+
*.iml
|
| 34 |
+
|
| 35 |
+
# Window
|
| 36 |
+
Thumbs.db
|
| 37 |
+
Desktop.ini
|
| 38 |
+
|
| 39 |
+
# MAC
|
| 40 |
+
.DS_Store
|
| 41 |
+
|
| 42 |
+
# SVN
|
| 43 |
+
.svn
|
| 44 |
+
|
| 45 |
+
# eclipse
|
| 46 |
+
.project
|
| 47 |
+
.metadata
|
| 48 |
+
|
| 49 |
+
# build
|
| 50 |
+
build
|
| 51 |
+
|
| 52 |
+
# Atom
|
| 53 |
+
tags
|
| 54 |
+
.ctags
|
| 55 |
+
.tern-project
|
| 56 |
+
|
| 57 |
+
# etc
|
| 58 |
+
.agignore
|
| 59 |
+
*.swp
|
| 60 |
+
etc
|
| 61 |
+
temp
|
| 62 |
+
api
|
| 63 |
+
.tern-port
|
| 64 |
+
*.vim
|
| 65 |
+
.\#*
|
| 66 |
+
.vscode
|
| 67 |
+
|
| 68 |
+
dist
|
| 69 |
+
!_*/dist/
|
.prettierrc
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"singleQuote": true,
|
| 3 |
+
"printWidth": 100,
|
| 4 |
+
"tabWidth": 2,
|
| 5 |
+
"useTabs": false,
|
| 6 |
+
"semi": true,
|
| 7 |
+
"quoteProps": "as-needed",
|
| 8 |
+
"jsxSingleQuote": false,
|
| 9 |
+
"trailingComma": "es5",
|
| 10 |
+
"arrowParens": "always",
|
| 11 |
+
"endOfLine": "lf",
|
| 12 |
+
"bracketSpacing": true,
|
| 13 |
+
"jsxBracketSameLine": false,
|
| 14 |
+
"requirePragma": false,
|
| 15 |
+
"insertPragma": false,
|
| 16 |
+
"proseWrap": "preserve",
|
| 17 |
+
"vueIndentScriptAndStyle": false
|
| 18 |
+
}
|
CODE_OF_CONDUCT.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Contributor Covenant Code of Conduct
|
| 2 |
+
|
| 3 |
+
## Our Pledge
|
| 4 |
+
|
| 5 |
+
In the interest of fostering an open and welcoming environment, we as
|
| 6 |
+
contributors and maintainers pledge to making participation in our project and
|
| 7 |
+
our community a harassment-free experience for everyone, regardless of age, body
|
| 8 |
+
size, disability, ethnicity, gender identity and expression, level of experience,
|
| 9 |
+
education, socio-economic status, nationality, personal appearance, race,
|
| 10 |
+
religion, or sexual identity and orientation.
|
| 11 |
+
|
| 12 |
+
## Our Standards
|
| 13 |
+
|
| 14 |
+
Examples of behavior that contributes to creating a positive environment
|
| 15 |
+
include:
|
| 16 |
+
|
| 17 |
+
- Using welcoming and inclusive language
|
| 18 |
+
- Being respectful of differing viewpoints and experiences
|
| 19 |
+
- Gracefully accepting constructive criticism
|
| 20 |
+
- Focusing on what is best for the community
|
| 21 |
+
- Showing empathy towards other community members
|
| 22 |
+
|
| 23 |
+
Examples of unacceptable behavior by participants include:
|
| 24 |
+
|
| 25 |
+
- The use of sexualized language or imagery and unwelcome sexual attention or
|
| 26 |
+
advances
|
| 27 |
+
- Trolling, insulting/derogatory comments, and personal or political attacks
|
| 28 |
+
- Public or private harassment
|
| 29 |
+
- Publishing others' private information, such as a physical or electronic
|
| 30 |
+
address, without explicit permission
|
| 31 |
+
- Other conduct which could reasonably be considered inappropriate in a
|
| 32 |
+
professional setting
|
| 33 |
+
|
| 34 |
+
## Our Responsibilities
|
| 35 |
+
|
| 36 |
+
Project maintainers are responsible for clarifying the standards of acceptable
|
| 37 |
+
behavior and are expected to take appropriate and fair corrective action in
|
| 38 |
+
response to any instances of unacceptable behavior.
|
| 39 |
+
|
| 40 |
+
Project maintainers have the right and responsibility to remove, edit, or
|
| 41 |
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
| 42 |
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
| 43 |
+
permanently any contributor for other behaviors that they deem inappropriate,
|
| 44 |
+
threatening, offensive, or harmful.
|
| 45 |
+
|
| 46 |
+
## Scope
|
| 47 |
+
|
| 48 |
+
This Code of Conduct applies both within project spaces and in public spaces
|
| 49 |
+
when an individual is representing the project or its community. Examples of
|
| 50 |
+
representing a project or community include using an official project e-mail
|
| 51 |
+
address, posting via an official social media account, or acting as an appointed
|
| 52 |
+
representative at an online or offline event. Representation of a project may be
|
| 53 |
+
further defined and clarified by project maintainers.
|
| 54 |
+
|
| 55 |
+
## Enforcement
|
| 56 |
+
|
| 57 |
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
| 58 |
+
reported by contacting the project team at dl_javascript@nhn.com. All
|
| 59 |
+
complaints will be reviewed and investigated and will result in a response that
|
| 60 |
+
is deemed necessary and appropriate to the circumstances. The project team is
|
| 61 |
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
| 62 |
+
Further details of specific enforcement policies may be posted separately.
|
| 63 |
+
|
| 64 |
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
| 65 |
+
faith may face temporary or permanent repercussions as determined by other
|
| 66 |
+
members of the project's leadership.
|
| 67 |
+
|
| 68 |
+
## Attribution
|
| 69 |
+
|
| 70 |
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
| 71 |
+
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
| 72 |
+
|
| 73 |
+
[homepage]: https://www.contributor-covenant.org
|
CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Contributing to TOAST UI
|
| 2 |
+
|
| 3 |
+
First off, thanks for taking the time to contribute! 🎉 😘 ✨
|
| 4 |
+
|
| 5 |
+
The following is a set of guidelines for contributing to TOAST UI. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request.
|
| 6 |
+
|
| 7 |
+
## Reporting Bugs
|
| 8 |
+
|
| 9 |
+
Bugs are tracked as GitHub issues. Search the list and try reproduce on [demo][demo] before you create an issue. When you create an issue, please provide the following information by filling in the template.
|
| 10 |
+
|
| 11 |
+
Explain the problem and include additional details to help maintainers reproduce the problem:
|
| 12 |
+
|
| 13 |
+
- **Use a clear and descriptive title** for the issue to identify the problem.
|
| 14 |
+
- **Describe the exact steps which reproduce the problem** in as many details as possible. Don't just say what you did, but explain how you did it. For example, if you moved the cursor to the end of a line, explain if you used a mouse or a keyboard.
|
| 15 |
+
- **Provide specific examples to demonstrate the steps.** Include links to files or GitHub projects, or copy/pasteable snippets, which you use in those examples. If you're providing snippets on the issue, use Markdown code blocks.
|
| 16 |
+
- **Describe the behavior you observed after following the steps** and point out what exactly is the problem with that behavior.
|
| 17 |
+
- **Explain which behavior you expected to see instead and why.**
|
| 18 |
+
- **Include screenshots and animated GIFs** which show you following the described steps and clearly demonstrate the problem.
|
| 19 |
+
|
| 20 |
+
## Suggesting Enhancements
|
| 21 |
+
|
| 22 |
+
In case you want to suggest for TOAST UI ImageEditor, please follow this guideline to help maintainers and the community understand your suggestion.
|
| 23 |
+
Before creating suggestions, please check [issue list](../../labels/enhancement) if there's already a request.
|
| 24 |
+
|
| 25 |
+
Create an issue and provide the following information:
|
| 26 |
+
|
| 27 |
+
- **Use a clear and descriptive title** for the issue to identify the suggestion.
|
| 28 |
+
- **Provide a step-by-step description of the suggested enhancement** in as many details as possible.
|
| 29 |
+
- **Provide specific examples to demonstrate the steps.** Include copy/pasteable snippets which you use in those examples, as Markdown code blocks.
|
| 30 |
+
- **Include screenshots and animated GIFs** which helps demonstrate the steps or point out the part of TOAST UI ImageEditor which the suggestion is related to.
|
| 31 |
+
- **Explain why this enhancement would be useful** to most TOAST UI users.
|
| 32 |
+
- **List some other image editors or applications where this enhancement exists.**
|
| 33 |
+
|
| 34 |
+
## First Code Contribution
|
| 35 |
+
|
| 36 |
+
Unsure where to begin contributing to TOAST UI? You can start by looking through these `document`, `good first issue` and `help wanted` issues:
|
| 37 |
+
|
| 38 |
+
- **document issues**: issues which should be reviewed or improved.
|
| 39 |
+
- **good first issues**: issues which should only require a few lines of code, and a test or two.
|
| 40 |
+
- **help wanted issues**: issues which should be a bit more involved than beginner issues.
|
| 41 |
+
|
| 42 |
+
## Pull Requests
|
| 43 |
+
|
| 44 |
+
### Development WorkFlow
|
| 45 |
+
|
| 46 |
+
- Set up your development environment
|
| 47 |
+
- Make change from a right branch
|
| 48 |
+
- Be sure the code passes `npm run lint`, `npm run test`
|
| 49 |
+
- Make a pull request
|
| 50 |
+
|
| 51 |
+
### Development environment
|
| 52 |
+
|
| 53 |
+
- Prepare your machine node and it's packages installed.
|
| 54 |
+
- Checkout our repository
|
| 55 |
+
- Install dependencies by `npm install && bower install`
|
| 56 |
+
- Start webpack-dev-server by `npm run serve`
|
| 57 |
+
|
| 58 |
+
### Make changes
|
| 59 |
+
|
| 60 |
+
#### Checkout a branch
|
| 61 |
+
|
| 62 |
+
- **develop**: PR base branch. merge features, updates for next minor or major release
|
| 63 |
+
- **master**: bug fix or document update for next patch release. develop branch will rebase every time master branch update. so keep code change to a minimum.
|
| 64 |
+
- **production**: lastest release branch with distribution files. never make a PR on this
|
| 65 |
+
- **gh-pages**: API docs, examples and demo
|
| 66 |
+
|
| 67 |
+
#### Check Code Style
|
| 68 |
+
|
| 69 |
+
Run `npm run eslint` and make sure all the tests pass.
|
| 70 |
+
|
| 71 |
+
#### Test
|
| 72 |
+
|
| 73 |
+
Run `npm run test` and verify all the tests pass.
|
| 74 |
+
If you are adding new commands or features, they must include tests.
|
| 75 |
+
If you are changing functionality, update the tests if you need to.
|
| 76 |
+
|
| 77 |
+
#### Commit
|
| 78 |
+
|
| 79 |
+
Follow our [commit message conventions](./docs/COMMIT_MESSAGE_CONVENTION.md).
|
| 80 |
+
|
| 81 |
+
### Yes! Pull request
|
| 82 |
+
|
| 83 |
+
Make your pull request, then describe your changes.
|
| 84 |
+
|
| 85 |
+
#### Title
|
| 86 |
+
|
| 87 |
+
Follow other PR title format on below.
|
| 88 |
+
|
| 89 |
+
```
|
| 90 |
+
<Type>: Short Description (fix #111)
|
| 91 |
+
<Type>: Short Description (fix #123, #111, #122)
|
| 92 |
+
<Type>: Short Description (ref #111)
|
| 93 |
+
```
|
| 94 |
+
|
| 95 |
+
- capitalize first letter of Type
|
| 96 |
+
- use present tense: 'change' not 'changed' or 'changes'
|
| 97 |
+
|
| 98 |
+
#### Description
|
| 99 |
+
|
| 100 |
+
If it has related to issues, add links to the issues(like `#123`) in the description.
|
| 101 |
+
Fill in the [Pull Request Template](./docs/PULL_REQUEST_TEMPLATE.md) by check your case.
|
| 102 |
+
|
| 103 |
+
## Code of Conduct
|
| 104 |
+
|
| 105 |
+
This project and everyone participating in it is governed by the [Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to dl_javascript@nhn.com.
|
| 106 |
+
|
| 107 |
+
> This Guide is base on [atom contributing guide](https://github.com/atom/atom/blob/master/CONTRIBUTING.md), [CocoaPods](http://guides.cocoapods.org/contributing/contribute-to-cocoapods.html) and [ESLint](http://eslint.org/docs/developer-guide/contributing/pull-requests)
|
ISSUE_TEMPLATE.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!--
|
| 2 |
+
Thank you for your contribution.
|
| 3 |
+
|
| 4 |
+
When it comes to write an issue, please, use the template below.
|
| 5 |
+
To use the template is mandatory for submit new issue and we won't reply the issue that without the template.
|
| 6 |
+
|
| 7 |
+
And you can write template's contents in Korean also.
|
| 8 |
+
-->
|
| 9 |
+
|
| 10 |
+
<!-- TEMPLATE -->
|
| 11 |
+
|
| 12 |
+
## Version
|
| 13 |
+
|
| 14 |
+
<!-- Write the version of the grid you are currently using. -->
|
| 15 |
+
|
| 16 |
+
## Development Environment
|
| 17 |
+
|
| 18 |
+
<!-- Write the browser type, OS and so on -->
|
| 19 |
+
|
| 20 |
+
## Current Behavior
|
| 21 |
+
|
| 22 |
+
<!-- Write a description of the current operation. You can add example code, 'CodePen' or 'jsfiddle' links. -->
|
| 23 |
+
|
| 24 |
+
```js
|
| 25 |
+
// Write example code
|
| 26 |
+
```
|
| 27 |
+
|
| 28 |
+
## Expected Behavior
|
| 29 |
+
|
| 30 |
+
<!-- Write a description of the future action. -->
|
LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
The MIT License
|
| 3 |
+
|
| 4 |
+
Copyright (c) 2019 NHN Cloud Corp.
|
| 5 |
+
|
| 6 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 7 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 8 |
+
in the Software without restriction, including without limitation the rights
|
| 9 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 10 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 11 |
+
furnished to do so, subject to the following conditions:
|
| 12 |
+
|
| 13 |
+
The above copyright notice and this permission notice shall be included in
|
| 14 |
+
all copies or substantial portions of the Software.
|
| 15 |
+
|
| 16 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 17 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 18 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 19 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 20 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 21 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
| 22 |
+
THE SOFTWARE.
|
README.md
CHANGED
|
@@ -1,14 +1,206 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 
|
| 2 |
+
|
| 3 |
+
> Full featured image editor using HTML5 Canvas. It's easy to use and provides powerful filters.
|
| 4 |
+
|
| 5 |
+
[](https://github.com/nhn/tui.image-editor/releases/latest)
|
| 6 |
+
[](https://www.npmjs.com/package/tui-image-editor)
|
| 7 |
+
[](https://github.com/nhn/tui.image-editor/blob/master/LICENSE)
|
| 8 |
+
[](https://github.com/nhn/tui.image-editor/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22)
|
| 9 |
+
[](https://github.com/nhn)
|
| 10 |
+
[](https://lerna.js.org/)
|
| 11 |
+
|
| 12 |
+
## 📦 Packages
|
| 13 |
+
|
| 14 |
+
- [toast-ui.image-editor](https://github.com/nhn/tui.image-editor/tree/master/apps/image-editor
|
| 15 |
+
) - Plain JavaScript component implemented by [NHN Cloud](https://github.com/nhn).
|
| 16 |
+
- [toast-ui.vue-image-editor](https://github.com/nhn/tui.image-editor/tree/master/apps/vue-image-editor
|
| 17 |
+
) - **Vue** wrapper component is powered by [NHN Cloud](https://github.com/nhn).
|
| 18 |
+
- [toast-ui.react-image-editor](https://github.com/nhn/tui.image-editor/tree/master/apps/react-image-editor
|
| 19 |
+
) - **React** wrapper component is powered by [NHN Cloud](https://github.com/nhn).
|
| 20 |
+
|
| 21 |
+

|
| 22 |
+
|
| 23 |
+
## 🚩 Table of Contents
|
| 24 |
+
|
| 25 |
+
- [!Toast UI ImageEditor](#)
|
| 26 |
+
- [📦 Packages](#packages)
|
| 27 |
+
- [🚩 Table of Contents](#-table-of-contents)
|
| 28 |
+
- [🌏 Browser Support](#-browser-support)
|
| 29 |
+
- [💪 Has full features that stick to the basic.](#-has-full-features-that-stick-to-the-basic)
|
| 30 |
+
- [Photo manipulation](#photo-manipulation)
|
| 31 |
+
- [Integration function](#integration-function)
|
| 32 |
+
- [Powerful filter function](#powerful-filter-function)
|
| 33 |
+
- [🙆 Easy to apply the size and design you want](#-easy-to-apply-the-size-and-design-you-want)
|
| 34 |
+
- [Can be used everywhere.](#can-be-used-everywhere)
|
| 35 |
+
- [Nice default & Fully customizable Themes](#nice-default--fully-customizable-themes)
|
| 36 |
+
- [🎨 Features](#-features)
|
| 37 |
+
- [🔧 Pull Request Steps](#-pull-request-steps)
|
| 38 |
+
- [Setup](#setup)
|
| 39 |
+
- [Pull Request](#pull-request)
|
| 40 |
+
- [📙 Documents](#-documents)
|
| 41 |
+
- [💬 Contributing](#-contributing)
|
| 42 |
+
- [🔩 Dependency](#-dependency)
|
| 43 |
+
- [🍞 TOAST UI Family](#-toast-ui-family)
|
| 44 |
+
- [🚀 Used By](#-used-by)
|
| 45 |
+
- [📜 License](#-license)
|
| 46 |
+
|
| 47 |
+
## 🌏 Browser Support
|
| 48 |
+
|
| 49 |
+
| <img src="https://user-images.githubusercontent.com/1215767/34348387-a2e64588-ea4d-11e7-8267-a43365103afe.png" alt="Chrome" width="16px" height="16px" /> Chrome | <img src="https://user-images.githubusercontent.com/1215767/34348590-250b3ca2-ea4f-11e7-9efb-da953359321f.png" alt="IE" width="16px" height="16px" /> Internet Explorer | <img src="https://user-images.githubusercontent.com/1215767/34348380-93e77ae8-ea4d-11e7-8696-9a989ddbbbf5.png" alt="Edge" width="16px" height="16px" /> Edge | <img src="https://user-images.githubusercontent.com/1215767/34348394-a981f892-ea4d-11e7-9156-d128d58386b9.png" alt="Safari" width="16px" height="16px" /> Safari | <img src="https://user-images.githubusercontent.com/1215767/34348383-9e7ed492-ea4d-11e7-910c-03b39d52f496.png" alt="Firefox" width="16px" height="16px" /> Firefox |
|
| 50 |
+
| :--------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------: |
|
| 51 |
+
| Yes | 10+ | Yes | Yes | Yes |
|
| 52 |
+
|
| 53 |
+
## 💪 Has full features that stick to the basic.
|
| 54 |
+
|
| 55 |
+
### Photo manipulation
|
| 56 |
+
|
| 57 |
+
- Crop, Flip, Rotation, Drawing, Shape, Icon, Text, Mask Filter, Image Filter
|
| 58 |
+
|
| 59 |
+
### Integration function
|
| 60 |
+
|
| 61 |
+
- Download, Image Load, Undo, Redo, Reset, Delete Object(Shape, Line, Mask Image...)
|
| 62 |
+
|
| 63 |
+
<table>
|
| 64 |
+
<tbody>
|
| 65 |
+
<tr>
|
| 66 |
+
<th width="20%">Crop</th>
|
| 67 |
+
<th width="20%">Flip</th>
|
| 68 |
+
<th width="20%">Rotation</th>
|
| 69 |
+
<th width="20%">Drawing</th>
|
| 70 |
+
<th width="20%">Shape</th>
|
| 71 |
+
</tr>
|
| 72 |
+
<tr>
|
| 73 |
+
<td><img src="https://user-images.githubusercontent.com/35218826/40904241-0c28ec68-6815-11e8-8296-89a1716b22d8.png" alt="2018-06-04 4 33 16" style="max-width:100%;"></td>
|
| 74 |
+
<td><img src="https://user-images.githubusercontent.com/35218826/40904521-f7c6e184-6815-11e8-8ba3-c94664da69a2.png" alt="2018-06-04 4 40 06" style="max-width:100%;"></td>
|
| 75 |
+
<td><img src="https://user-images.githubusercontent.com/35218826/40904664-656aa748-6816-11e8-9943-6607c209deac.png" alt="2018-06-04 4 43 02" style="max-width:100%;"></td>
|
| 76 |
+
<td><img src="https://user-images.githubusercontent.com/35218826/40904850-0f26ebde-6817-11e8-97d0-d3a7e4bc02da.png" alt="2018-06-04 4 47 40" style="max-width:100%;"></td>
|
| 77 |
+
<td><img src="https://user-images.githubusercontent.com/35218826/40905037-a026296a-6817-11e8-9d28-9e1ca7bc58c4.png" alt="2018-06-04 4 51 45" style="max-width:100%;"></td>
|
| 78 |
+
</tr>
|
| 79 |
+
<tr>
|
| 80 |
+
<th>Icon</th>
|
| 81 |
+
<th>Text</th>
|
| 82 |
+
<th>Mask</th>
|
| 83 |
+
<th>Filter</th>
|
| 84 |
+
<th></th>
|
| 85 |
+
</tr>
|
| 86 |
+
<tr>
|
| 87 |
+
<td><img src="https://user-images.githubusercontent.com/35218826/40931205-2d255db6-6865-11e8-98af-ad34c5a01da1.png" alt="2018-06-05 2 06 29" style="max-width:100%;"></td>
|
| 88 |
+
<td><img src="https://user-images.githubusercontent.com/35218826/40931484-46253948-6866-11e8-8a04-fa042920e457.png" alt="2018-06-05 2 14 36" style="max-width:100%;"></td>
|
| 89 |
+
<td><img src="https://user-images.githubusercontent.com/35218826/40931743-21eeb346-6867-11e8-8e31-a59f7a43482b.png" alt="2018-06-05 2 20 46" style="max-width:100%;"></td>
|
| 90 |
+
<td><img src="https://user-images.githubusercontent.com/35218826/40932016-093ed1f4-6868-11e8-8224-a048c3ee8a09.png" alt="2018-06-05 2 27 10" style="max-width:100%;"></td>
|
| 91 |
+
<td></td>
|
| 92 |
+
</tr>
|
| 93 |
+
</tbody>
|
| 94 |
+
</table>
|
| 95 |
+
|
| 96 |
+
### Powerful filter function
|
| 97 |
+
|
| 98 |
+
- Grayscale, Invert, Sepia, Blur Sharpen, Emboss, RemoveWhite, Brightness, Noise, Pixelate, ColorFilter, Tint, Multiply, Blend
|
| 99 |
+
|
| 100 |
+
| Grayscale | Noise | Emboss | Pixelate |
|
| 101 |
+
| ------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
|
| 102 |
+
|  |  |  |  |
|
| 103 |
+
|
| 104 |
+
| Sepia | Sepia2 | Blend-righten | Blend-diff | Invert |
|
| 105 |
+
| -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
|
| 106 |
+
|  |  |  |  |  |
|
| 107 |
+
|
| 108 |
+
| Multifly | Tint | Brightness | Remove-white | Sharpen |
|
| 109 |
+
| ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
|
| 110 |
+
|  |  |  |  |  |
|
| 111 |
+
|
| 112 |
+
## 🙆 Easy to apply the size and design you want
|
| 113 |
+
|
| 114 |
+
### Can be used everywhere.
|
| 115 |
+
|
| 116 |
+
- Widely supported in browsers including IE10.
|
| 117 |
+
- Option to support various display sizes.
|
| 118 |
+
(allows you to use the editor features on your web pages at least over **550 \* 450 sizes**)
|
| 119 |
+
|
| 120 |
+

|
| 121 |
+
|
| 122 |
+
### Nice default & Fully customizable Themes
|
| 123 |
+
|
| 124 |
+
- Has a white and black theme, and you can modify the theme file to customize it.
|
| 125 |
+
- Has an API so that you can create your own instead of the built-in.
|
| 126 |
+
|
| 127 |
+
| black - top | black - bottom | white - left | white - right |
|
| 128 |
+
| --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
| 129 |
+
|  |  |  |  |
|
| 130 |
+
|
| 131 |
+
## 🎨 Features
|
| 132 |
+
|
| 133 |
+
- Load image to canvas
|
| 134 |
+
- Undo/Redo (With shortcut)
|
| 135 |
+
- Crop
|
| 136 |
+
- Flip
|
| 137 |
+
- Rotation
|
| 138 |
+
- Resize
|
| 139 |
+
- Free drawing
|
| 140 |
+
- Line drawing
|
| 141 |
+
- Shape
|
| 142 |
+
- Icon
|
| 143 |
+
- Text
|
| 144 |
+
- Mask Filter
|
| 145 |
+
- Image Filter
|
| 146 |
+
|
| 147 |
+
## 🔧 Pull Request Steps
|
| 148 |
+
|
| 149 |
+
TOAST UI products are open source, so you can create a pull request(PR) after you fix issues.
|
| 150 |
+
Run npm scripts and develop yourself with the following process.
|
| 151 |
+
|
| 152 |
+
### Setup
|
| 153 |
+
|
| 154 |
+
Fork `develop` branch into your personal repository.
|
| 155 |
+
Clone it to local computer. Install node modules.
|
| 156 |
+
Before starting development, you should check if there are any errors.
|
| 157 |
+
|
| 158 |
+
```sh
|
| 159 |
+
$ git clone https://github.com/{your-personal-repo}/[[repo name]].git
|
| 160 |
+
$ cd [[repo name]]
|
| 161 |
+
$ npm install
|
| 162 |
+
```
|
| 163 |
+
|
| 164 |
+
### Pull Request
|
| 165 |
+
|
| 166 |
+
Before uploading your PR, run test one last time to check if there are any errors.
|
| 167 |
+
If it has no errors, commit and then push it!
|
| 168 |
+
|
| 169 |
+
For more information on PR's steps, please see links in the Contributing section.
|
| 170 |
+
|
| 171 |
+
## 📙 Documents
|
| 172 |
+
|
| 173 |
+
- [Getting Started](https://github.com/nhn/tui.image-editor/tree/master/docs/Basic-Tutorial.md)
|
| 174 |
+
- [Tutorial](https://github.com/nhn/tui.image-editor/tree/master/docs)
|
| 175 |
+
- [Example](http://nhn.github.io/tui.image-editor/latest/tutorial-example01-includeUi)
|
| 176 |
+
- [API](http://nhn.github.io/tui.image-editor/latest)
|
| 177 |
+
|
| 178 |
+
## 💬 Contributing
|
| 179 |
+
|
| 180 |
+
- [Code of Conduct](https://github.com/nhn/tui.image-editor/blob/master/CODE_OF_CONDUCT.md)
|
| 181 |
+
- [Contributing guideline](https://github.com/nhn/tui.image-editor/blob/master/CONTRIBUTING.md)
|
| 182 |
+
- [Issue guideline](https://github.com/nhn/tui.image-editor/blob/master/ISSUE_TEMPLATE.md)
|
| 183 |
+
- [Commit convention](https://github.com/nhn/tui.image-editor/blob/production/docs/COMMIT_MESSAGE_CONVENTION.md)
|
| 184 |
+
|
| 185 |
+
## 🔩 Dependency
|
| 186 |
+
|
| 187 |
+
- [fabric.js](https://github.com/fabricjs/fabric.js/releases) = 4.2.0
|
| 188 |
+
- [tui.code-snippet](https://github.com/nhn/tui.code-snippet/releases/tag/v1.5.0) >= 1.5.0
|
| 189 |
+
- [tui.color-picker](https://github.com/nhn/tui.color-picker/releases/tag/v2.2.6) >= 2.2.6
|
| 190 |
+
|
| 191 |
+
## 🍞 TOAST UI Family
|
| 192 |
+
|
| 193 |
+
- [TOAST UI Editor](https://github.com/nhn/tui.editor)
|
| 194 |
+
- [TOAST UI Grid](https://github.com/nhn/tui.grid)
|
| 195 |
+
- [TOAST UI Chart](https://github.com/nhn/tui.chart)
|
| 196 |
+
- [TOAST UI Calendar](https://github.com/nhn/tui.calendar)
|
| 197 |
+
- [TOAST UI Components](https://github.com/nhn)
|
| 198 |
+
|
| 199 |
+
## 🚀 Used By
|
| 200 |
+
|
| 201 |
+
- [NHN Dooray! - Collaboration Service (Project, Messenger, Mail, Calendar, Drive, Wiki, Contacts)](https://dooray.com/home/)
|
| 202 |
+
- [Catalyst](https://catalystapp.co/)
|
| 203 |
+
|
| 204 |
+
## 📜 License
|
| 205 |
+
|
| 206 |
+
[MIT LICENSE](https://github.com/nhn/tui.image-editor/blob/master/LICENSE)
|
app.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
from PIL import Image
|
| 3 |
+
from toast_image_editor import main as editor_main
|
| 4 |
+
|
| 5 |
+
def edit_image(input_img):
|
| 6 |
+
# Convert Gradio input to PIL Image if needed
|
| 7 |
+
if isinstance(input_img, str):
|
| 8 |
+
input_img = Image.open(input_img)
|
| 9 |
+
|
| 10 |
+
# Call the core editing function (customize if needed)
|
| 11 |
+
output_img = editor_main(input_img)
|
| 12 |
+
return output_img
|
| 13 |
+
|
| 14 |
+
demo = gr.Interface(
|
| 15 |
+
fn=edit_image,
|
| 16 |
+
inputs=gr.Image(type="pil"),
|
| 17 |
+
outputs=gr.Image(type="pil"),
|
| 18 |
+
title="Toast Image Editor",
|
| 19 |
+
description="Simple image editing powered by Toast Image Editor (Fanu2)"
|
| 20 |
+
)
|
| 21 |
+
|
| 22 |
+
if __name__ == "__main__":
|
| 23 |
+
demo.launch()
|
| 24 |
+
|
apps/image-editor/README.md
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 
|
| 2 |
+
|
| 3 |
+
> Full featured image editor using HTML5 Canvas. It's easy to use and provides powerful filters.
|
| 4 |
+
|
| 5 |
+
[](https://www.npmjs.com/package/tui-image-editor)
|
| 6 |
+
|
| 7 |
+
## 🚩 Table of Contents
|
| 8 |
+
|
| 9 |
+
- [Collect statistics on the use of open source](#Collect-statistics-on-the-use-of-open-source)
|
| 10 |
+
- [Install](#-install)
|
| 11 |
+
- [Via Package Manager](#via-package-manager)
|
| 12 |
+
- [Via Contents Delivery Network (CDN)](#via-contents-delivery-network-cdn)
|
| 13 |
+
- [Download Source Files](#download-source-files)
|
| 14 |
+
- [Usage](#-usage)
|
| 15 |
+
- [HTML](#html)
|
| 16 |
+
- [JavaScript](#javascript)
|
| 17 |
+
- [Menu svg icon setting](#menu-svg-icon-setting)
|
| 18 |
+
- [TypeScript](#typescript)
|
| 19 |
+
|
| 20 |
+
## Collect statistics on the use of open source
|
| 21 |
+
|
| 22 |
+
TOAST UI ImageEditor applies Google Analytics (GA) to collect statistics on the use of open source, in order to identify how widely TOAST UI ImageEditor is used throughout the world. It also serves as important index to determine the future course of projects. location.hostname (e.g. > “ui.toast.com") is to be collected and the sole purpose is nothing but to measure statistics on the usage. To disable GA, use the following `usageStatistics` option when creating the instance.
|
| 23 |
+
|
| 24 |
+
```js
|
| 25 |
+
const options = {
|
| 26 |
+
//...
|
| 27 |
+
usageStatistics: false,
|
| 28 |
+
};
|
| 29 |
+
|
| 30 |
+
const imageEditor = new tui.ImageEditor('#tui-image-editor-container', options);
|
| 31 |
+
```
|
| 32 |
+
|
| 33 |
+
Or, include [`tui-code-snippet`](https://github.com/nhn/tui.code-snippet)(**v1.4.0** or **later**) and then immediately write the options as follows:
|
| 34 |
+
|
| 35 |
+
```js
|
| 36 |
+
tui.usageStatistics = false;
|
| 37 |
+
```
|
| 38 |
+
|
| 39 |
+
## 💾 Install
|
| 40 |
+
|
| 41 |
+
The TOAST UI products can be installed by using the package manager or downloading the source directly.
|
| 42 |
+
However, we highly recommend using the package manager.
|
| 43 |
+
|
| 44 |
+
### Via Package Manager
|
| 45 |
+
|
| 46 |
+
You can find TOAST UI products via [npm](https://www.npmjs.com/) and [bower](https://bower.io/) package managers.
|
| 47 |
+
Install by using the commands provided by each package manager.
|
| 48 |
+
When using npm, be sure [Node.js](https://nodejs.org) is installed in the environment.
|
| 49 |
+
|
| 50 |
+
#### npm
|
| 51 |
+
|
| 52 |
+
##### 1. ImageEditor installation
|
| 53 |
+
|
| 54 |
+
```sh
|
| 55 |
+
$ npm install --save tui-image-editor # Latest version
|
| 56 |
+
$ npm install --save tui-image-editor@<version> # Specific version
|
| 57 |
+
```
|
| 58 |
+
|
| 59 |
+
##### 2. If the installation of the `fabric.js` dependency module does not go smoothly
|
| 60 |
+
|
| 61 |
+
To solve the problem, you need to refer to [Some Steps](https://github.com/fabricjs/fabric.js#install-with-npm) to solve the problem.
|
| 62 |
+
|
| 63 |
+
#### bower
|
| 64 |
+
|
| 65 |
+
```sh
|
| 66 |
+
$ bower install tui-image-editor # Latest version
|
| 67 |
+
$ bower install tui-image-editor#<tag> # Specific version
|
| 68 |
+
```
|
| 69 |
+
|
| 70 |
+
### Via Contents Delivery Network (CDN)
|
| 71 |
+
|
| 72 |
+
TOAST UI products are available over the CDN powered by [NHN Cloud](https://www.toast.com).
|
| 73 |
+
|
| 74 |
+
You can use the CDN as below.
|
| 75 |
+
|
| 76 |
+
```html
|
| 77 |
+
<link
|
| 78 |
+
rel="stylesheet"
|
| 79 |
+
href="https://uicdn.toast.com/tui-image-editor/latest/tui-image-editor.css"
|
| 80 |
+
/>
|
| 81 |
+
<script src="https://uicdn.toast.com/tui-image-editor/latest/tui-image-editor.js"></script>
|
| 82 |
+
```
|
| 83 |
+
|
| 84 |
+
If you want to use a specific version, use the tag name instead of `latest` in the URL.
|
| 85 |
+
|
| 86 |
+
The CDN directory has the following structure.
|
| 87 |
+
|
| 88 |
+
```
|
| 89 |
+
tui-image-editor/
|
| 90 |
+
├─ latest/
|
| 91 |
+
│ ├─ tui-image-editor.js
|
| 92 |
+
│ ├─ tui-image-editor.min.js
|
| 93 |
+
│ └─ tui-image-editor.css
|
| 94 |
+
├─ v3.1.0/
|
| 95 |
+
│ ├─ ...
|
| 96 |
+
```
|
| 97 |
+
|
| 98 |
+
### Download Source Files
|
| 99 |
+
|
| 100 |
+
- [Download bundle files from `dist` folder](https://github.com/nhn/tui.image-editor/tree/production/dist)
|
| 101 |
+
- [Download all sources for each version](https://github.com/nhn/tui.image-editor/releases)
|
| 102 |
+
|
| 103 |
+
## 🔨 Usage
|
| 104 |
+
|
| 105 |
+
### HTML
|
| 106 |
+
|
| 107 |
+
Add the container element where TOAST UI ImageEditor will be created.
|
| 108 |
+
|
| 109 |
+
```html
|
| 110 |
+
<body>
|
| 111 |
+
...
|
| 112 |
+
<div id="tui-image-editor"></div>
|
| 113 |
+
...
|
| 114 |
+
</body>
|
| 115 |
+
```
|
| 116 |
+
|
| 117 |
+
### javascript
|
| 118 |
+
|
| 119 |
+
Add dependencies & initialize ImageEditor class with given element to make an image editor.
|
| 120 |
+
|
| 121 |
+
```javascript
|
| 122 |
+
const ImageEditor = require('tui-image-editor');
|
| 123 |
+
const FileSaver = require('file-saver'); //to download edited image to local. Use after npm install file-saver
|
| 124 |
+
const blackTheme = require('./js/theme/black-theme.js');
|
| 125 |
+
const locale_ru_RU = {
|
| 126 |
+
// override default English locale to your custom
|
| 127 |
+
Crop: 'Обзрезать',
|
| 128 |
+
'Delete-all': 'Удалить всё',
|
| 129 |
+
// etc...
|
| 130 |
+
};
|
| 131 |
+
const instance = new ImageEditor(document.querySelector('#tui-image-editor'), {
|
| 132 |
+
includeUI: {
|
| 133 |
+
loadImage: {
|
| 134 |
+
path: 'img/sampleImage.jpg',
|
| 135 |
+
name: 'SampleImage',
|
| 136 |
+
},
|
| 137 |
+
locale: locale_ru_RU,
|
| 138 |
+
theme: blackTheme, // or whiteTheme
|
| 139 |
+
initMenu: 'filter',
|
| 140 |
+
menuBarPosition: 'bottom',
|
| 141 |
+
},
|
| 142 |
+
cssMaxWidth: 700,
|
| 143 |
+
cssMaxHeight: 500,
|
| 144 |
+
selectionStyle: {
|
| 145 |
+
cornerSize: 20,
|
| 146 |
+
rotatingPointOffset: 70,
|
| 147 |
+
},
|
| 148 |
+
});
|
| 149 |
+
```
|
| 150 |
+
|
| 151 |
+
Or
|
| 152 |
+
|
| 153 |
+
```javascript
|
| 154 |
+
const ImageEditor = require('tui-image-editor');
|
| 155 |
+
const instance = new ImageEditor(document.querySelector('#tui-image-editor'), {
|
| 156 |
+
cssMaxWidth: 700,
|
| 157 |
+
cssMaxHeight: 500,
|
| 158 |
+
selectionStyle: {
|
| 159 |
+
cornerSize: 20,
|
| 160 |
+
rotatingPointOffset: 70,
|
| 161 |
+
},
|
| 162 |
+
});
|
| 163 |
+
```
|
| 164 |
+
|
| 165 |
+
### Menu svg icon setting
|
| 166 |
+
|
| 167 |
+
#### There are two ways to set icons.
|
| 168 |
+
|
| 169 |
+
1. **Use default svg built** into imageEditor without setting svg file path (Features added since version v3.9.0).
|
| 170 |
+
2. There is a way to use the **actual physical svg file** and **set the file location manually**.
|
| 171 |
+
|
| 172 |
+
Can find more details in [this document](https://github.com/nhn/tui.image-editor/blob/master/docs/Basic-Tutorial.md#4-menu-submenu-svg-icon-setting).
|
| 173 |
+
|
| 174 |
+
### TypeScript
|
| 175 |
+
|
| 176 |
+
If you use TypeScript, You must `import module = require('module')` on importing.
|
| 177 |
+
[`export =` and `import = require()`](https://www.typescriptlang.org/docs/handbook/modules.html#export--and-import--require)
|
| 178 |
+
|
| 179 |
+
```typescript
|
| 180 |
+
import ImageEditor = require('tui-image-editor');
|
| 181 |
+
const FileSaver = require('file-saver'); //to download edited image to local. Use after npm install file-saver
|
| 182 |
+
|
| 183 |
+
const instance = new ImageEditor(document.querySelector('#tui-image-editor'), {
|
| 184 |
+
cssMaxWidth: 700,
|
| 185 |
+
cssMaxHeight: 500,
|
| 186 |
+
selectionStyle: {
|
| 187 |
+
cornerSize: 20,
|
| 188 |
+
rotatingPointOffset: 70,
|
| 189 |
+
},
|
| 190 |
+
});
|
| 191 |
+
```
|
| 192 |
+
|
| 193 |
+
See [details](https://nhn.github.io/tui.image-editor/latest) for additional information.
|
apps/image-editor/__mocks__/fileMock.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const path = require('path');
|
| 2 |
+
|
| 3 |
+
module.exports = {
|
| 4 |
+
process(src, filename) {
|
| 5 |
+
return `module.exports = ${JSON.stringify(path.basename(filename))};`;
|
| 6 |
+
},
|
| 7 |
+
};
|
apps/image-editor/__mocks__/svgMock.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
module.exports = {
|
| 2 |
+
process() {
|
| 3 |
+
return `module.exports = 'PGRlZnMgaWQ9InR1aS1pbWFnZS1lZGl0b3Itc3ZnLWRlZmF1bHQtaWNvbnMiPg=='`;
|
| 4 |
+
},
|
| 5 |
+
};
|
apps/image-editor/createConfigVariable.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const fs = require('fs');
|
| 2 |
+
const path = require('path');
|
| 3 |
+
const config = require(path.resolve(__dirname, 'tuidoc.config.json'));
|
| 4 |
+
const examples = config.examples || {};
|
| 5 |
+
const { filePath, globalErrorLogVariable } = examples;
|
| 6 |
+
|
| 7 |
+
/**
|
| 8 |
+
* Get Examples Url
|
| 9 |
+
*/
|
| 10 |
+
function getTestUrls() {
|
| 11 |
+
if (!filePath) {
|
| 12 |
+
throw Error('not exist examples path at tuidoc.config.json');
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
const urlPrefix = 'http://nhn.github.io/tui.image-editor/latest';
|
| 16 |
+
|
| 17 |
+
const testUrls = fs.readdirSync(filePath).reduce((urls, fileName) => {
|
| 18 |
+
if (/html$/.test(fileName)) {
|
| 19 |
+
urls.push(`${urlPrefix}/${filePath}/${fileName}`);
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
return urls;
|
| 23 |
+
}, []);
|
| 24 |
+
|
| 25 |
+
fs.writeFileSync('url.txt', testUrls.join(', '));
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
function getGlobalVariable() {
|
| 29 |
+
if (!globalErrorLogVariable) {
|
| 30 |
+
throw Error('not exist examples path at tuidoc.config.json');
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
fs.writeFileSync('errorVariable.txt', globalErrorLogVariable);
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
getTestUrls();
|
| 37 |
+
getGlobalVariable();
|
apps/image-editor/examples/css/service-basic.css
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.border {
|
| 2 |
+
border: 1px solid black;
|
| 3 |
+
}
|
| 4 |
+
.body-container {
|
| 5 |
+
width: 1000px;
|
| 6 |
+
}
|
| 7 |
+
.tui-image-editor-controls {
|
| 8 |
+
min-height: 250px;
|
| 9 |
+
}
|
| 10 |
+
.menu {
|
| 11 |
+
padding: 0;
|
| 12 |
+
margin-bottom: 5px;
|
| 13 |
+
text-align: center;
|
| 14 |
+
color: #544b61;
|
| 15 |
+
font-weight: 400;
|
| 16 |
+
list-style-type: none;
|
| 17 |
+
user-select: none;
|
| 18 |
+
-moz-user-select: none;
|
| 19 |
+
-ms-user-select: none;
|
| 20 |
+
-webkit-user-select: none;
|
| 21 |
+
}
|
| 22 |
+
.logo {
|
| 23 |
+
margin: 0 auto;
|
| 24 |
+
width: 300px;
|
| 25 |
+
vertical-align: middle;
|
| 26 |
+
}
|
| 27 |
+
.header .name {
|
| 28 |
+
padding: 10px;
|
| 29 |
+
line-height: 50px;
|
| 30 |
+
font-size: 30px;
|
| 31 |
+
font-weight: 100;
|
| 32 |
+
vertical-align: middle;
|
| 33 |
+
}
|
| 34 |
+
.header .menu {
|
| 35 |
+
display: inline-block;
|
| 36 |
+
}
|
| 37 |
+
.menu-item {
|
| 38 |
+
padding: 10px;
|
| 39 |
+
display: inline-block;
|
| 40 |
+
cursor: pointer;
|
| 41 |
+
vertical-align: middle;
|
| 42 |
+
}
|
| 43 |
+
.menu-item a {
|
| 44 |
+
text-decoration: none;
|
| 45 |
+
}
|
| 46 |
+
.menu-item.no-pointer {
|
| 47 |
+
cursor: default;
|
| 48 |
+
}
|
| 49 |
+
.menu-item.active,
|
| 50 |
+
.menu-item:hover {
|
| 51 |
+
background-color: #f3f3f3;
|
| 52 |
+
}
|
| 53 |
+
.menu-item.disabled {
|
| 54 |
+
cursor: default;
|
| 55 |
+
color: #bfbebe;
|
| 56 |
+
}
|
| 57 |
+
.align-left-top {
|
| 58 |
+
text-align: left;
|
| 59 |
+
vertical-align: top;
|
| 60 |
+
}
|
| 61 |
+
.range-narrow {
|
| 62 |
+
width: 80px;
|
| 63 |
+
}
|
| 64 |
+
.sub-menu-container {
|
| 65 |
+
font-size: 14px;
|
| 66 |
+
margin-bottom: 1em;
|
| 67 |
+
display: none;
|
| 68 |
+
}
|
| 69 |
+
.tui-image-editor {
|
| 70 |
+
height: 500px;
|
| 71 |
+
}
|
| 72 |
+
.tui-image-editor-canvas-container {
|
| 73 |
+
margin: 0 auto;
|
| 74 |
+
top: 50%;
|
| 75 |
+
transform: translateY(-50%);
|
| 76 |
+
-ms-transform: translateY(-50%);
|
| 77 |
+
-moz-transform: translateY(-50%);
|
| 78 |
+
-webkit-transform: translateY(-50%);
|
| 79 |
+
border: 1px dashed black;
|
| 80 |
+
overflow: hidden;
|
| 81 |
+
}
|
| 82 |
+
.tui-colorpicker-container {
|
| 83 |
+
margin: 5px auto 0;
|
| 84 |
+
}
|
| 85 |
+
.tui-colorpicker-palette-toggle-slider {
|
| 86 |
+
display: none;
|
| 87 |
+
}
|
| 88 |
+
.input-wrapper {
|
| 89 |
+
position: relative;
|
| 90 |
+
}
|
| 91 |
+
.input-wrapper input {
|
| 92 |
+
cursor: pointer;
|
| 93 |
+
position: absolute;
|
| 94 |
+
font-size: 999px;
|
| 95 |
+
left: 0;
|
| 96 |
+
top: 0;
|
| 97 |
+
opacity: 0;
|
| 98 |
+
width: 100%;
|
| 99 |
+
height: 100%;
|
| 100 |
+
overflow: hidden;
|
| 101 |
+
}
|
| 102 |
+
.btn-text-style {
|
| 103 |
+
padding: 5px;
|
| 104 |
+
margin: 3px 1px;
|
| 105 |
+
border: 1px dashed #bfbebe;
|
| 106 |
+
outline: 0;
|
| 107 |
+
background-color: #eee;
|
| 108 |
+
cursor: pointer;
|
| 109 |
+
}
|
| 110 |
+
.icon-text {
|
| 111 |
+
font-size: 20px;
|
| 112 |
+
}
|
| 113 |
+
.select-line-type {
|
| 114 |
+
outline: 0;
|
| 115 |
+
vertical-align: middle;
|
| 116 |
+
}
|
| 117 |
+
#tui-color-picker {
|
| 118 |
+
display: inline-block;
|
| 119 |
+
vertical-align: middle;
|
| 120 |
+
}
|
| 121 |
+
#tui-text-palette {
|
| 122 |
+
display: none;
|
| 123 |
+
position: absolute;
|
| 124 |
+
padding: 10px;
|
| 125 |
+
border: 1px solid #bfbebe;
|
| 126 |
+
background-color: #fff;
|
| 127 |
+
z-index: 9999;
|
| 128 |
+
}
|
apps/image-editor/examples/css/service-mobile.css
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
html,
|
| 2 |
+
body {
|
| 3 |
+
margin: 0;
|
| 4 |
+
padding: 0;
|
| 5 |
+
height: 100%;
|
| 6 |
+
overflow: hidden;
|
| 7 |
+
background-color: #383838;
|
| 8 |
+
font-family: Sans-Serif;
|
| 9 |
+
}
|
| 10 |
+
ul,
|
| 11 |
+
li {
|
| 12 |
+
list-style: none;
|
| 13 |
+
margin: 0;
|
| 14 |
+
padding: 0;
|
| 15 |
+
}
|
| 16 |
+
input[type='button'],
|
| 17 |
+
button {
|
| 18 |
+
-webkit-appearance: none;
|
| 19 |
+
-moz-appearance: none;
|
| 20 |
+
background-color: #fff;
|
| 21 |
+
}
|
| 22 |
+
input[type='file'] {
|
| 23 |
+
position: absolute;
|
| 24 |
+
margin: 0;
|
| 25 |
+
padding: 0;
|
| 26 |
+
top: 0;
|
| 27 |
+
left: 0;
|
| 28 |
+
width: 100%;
|
| 29 |
+
height: 100%;
|
| 30 |
+
cursor: pointer;
|
| 31 |
+
opacity: 0;
|
| 32 |
+
filter: alpha(opacity=0);
|
| 33 |
+
}
|
| 34 |
+
.header {
|
| 35 |
+
position: fixed;
|
| 36 |
+
left: 0;
|
| 37 |
+
top: 0;
|
| 38 |
+
width: 100%;
|
| 39 |
+
background-color: #fff;
|
| 40 |
+
text-align: center;
|
| 41 |
+
z-index: 9999;
|
| 42 |
+
}
|
| 43 |
+
.header .logo {
|
| 44 |
+
margin: 10px 5px;
|
| 45 |
+
width: 180px;
|
| 46 |
+
vertical-align: middle;
|
| 47 |
+
}
|
| 48 |
+
.header .name {
|
| 49 |
+
font-size: 16px;
|
| 50 |
+
font-weight: bold;
|
| 51 |
+
}
|
| 52 |
+
.header .menu {
|
| 53 |
+
padding: 10px;
|
| 54 |
+
background-color: #000;
|
| 55 |
+
}
|
| 56 |
+
.header .menu input {
|
| 57 |
+
opacity: 0;
|
| 58 |
+
}
|
| 59 |
+
.header .menu img {
|
| 60 |
+
width: 20px;
|
| 61 |
+
height: 20px;
|
| 62 |
+
vertical-align: middle;
|
| 63 |
+
}
|
| 64 |
+
.header .button {
|
| 65 |
+
position: relative;
|
| 66 |
+
display: inline-block;
|
| 67 |
+
margin: 0 5px;
|
| 68 |
+
padding: 0;
|
| 69 |
+
border-radius: 5px 5px;
|
| 70 |
+
width: 30px;
|
| 71 |
+
height: 30px;
|
| 72 |
+
border: 0;
|
| 73 |
+
background-color: #fff;
|
| 74 |
+
vertical-align: middle;
|
| 75 |
+
}
|
| 76 |
+
.header .button.disabled img {
|
| 77 |
+
opacity: 0.5;
|
| 78 |
+
}
|
| 79 |
+
.tui-image-editor {
|
| 80 |
+
height: 100%;
|
| 81 |
+
}
|
| 82 |
+
.tui-image-editor-canvas-container {
|
| 83 |
+
margin: 0 auto;
|
| 84 |
+
top: 50%;
|
| 85 |
+
transform: translateY(-50%);
|
| 86 |
+
-ms-transform: translateY(-50%);
|
| 87 |
+
-moz-transform: translateY(-50%);
|
| 88 |
+
-webkit-transform: translateY(-50%);
|
| 89 |
+
overflow: hidden;
|
| 90 |
+
}
|
| 91 |
+
.tui-image-editor-controls {
|
| 92 |
+
position: fixed;
|
| 93 |
+
width: 100%;
|
| 94 |
+
left: 0;
|
| 95 |
+
bottom: 0;
|
| 96 |
+
background-color: #fff;
|
| 97 |
+
}
|
| 98 |
+
.tui-image-editor-controls .scrollable {
|
| 99 |
+
display: inline-block;
|
| 100 |
+
overflow-x: auto;
|
| 101 |
+
width: 100%;
|
| 102 |
+
height: 100%;
|
| 103 |
+
white-space: nowrap;
|
| 104 |
+
font-size: 0;
|
| 105 |
+
background-color: #000;
|
| 106 |
+
vertical-align: middle;
|
| 107 |
+
}
|
| 108 |
+
.tui-image-editor-controls .no-scrollable {
|
| 109 |
+
overflow-x: hidden;
|
| 110 |
+
}
|
| 111 |
+
.tui-image-editor-controls .menu-item {
|
| 112 |
+
display: inline-block;
|
| 113 |
+
height: 80px;
|
| 114 |
+
border-right: 1px solid #383838;
|
| 115 |
+
background-color: #ddd;
|
| 116 |
+
vertical-align: middle;
|
| 117 |
+
}
|
| 118 |
+
.tui-image-editor-controls .menu-button {
|
| 119 |
+
width: 80px;
|
| 120 |
+
height: 80px;
|
| 121 |
+
border: none;
|
| 122 |
+
vertical-align: middle;
|
| 123 |
+
background-color: #000;
|
| 124 |
+
color: #fff;
|
| 125 |
+
font-size: 12px;
|
| 126 |
+
font-weight: bold;
|
| 127 |
+
outline: 0;
|
| 128 |
+
}
|
| 129 |
+
.tui-image-editor-controls .submenu-button {
|
| 130 |
+
width: 80px;
|
| 131 |
+
height: 80px;
|
| 132 |
+
border: none;
|
| 133 |
+
background-color: #ddd;
|
| 134 |
+
vertical-align: middle;
|
| 135 |
+
}
|
| 136 |
+
.tui-image-editor-controls .hiddenmenu-button {
|
| 137 |
+
margin: 0 10px;
|
| 138 |
+
padding: 5px;
|
| 139 |
+
border: none;
|
| 140 |
+
color: #fff;
|
| 141 |
+
background-color: rgba(255, 255, 255, 0);
|
| 142 |
+
}
|
| 143 |
+
.tui-image-editor-controls .submenu {
|
| 144 |
+
display: none;
|
| 145 |
+
position: absolute;
|
| 146 |
+
top: 0;
|
| 147 |
+
left: 0;
|
| 148 |
+
width: 100%;
|
| 149 |
+
font-size: 0;
|
| 150 |
+
}
|
| 151 |
+
.tui-image-editor-controls .submenu.show {
|
| 152 |
+
display: block;
|
| 153 |
+
}
|
| 154 |
+
.tui-image-editor-controls .submenu .menu-item:last-child {
|
| 155 |
+
margin-right: 50px;
|
| 156 |
+
}
|
| 157 |
+
.tui-image-editor-controls .hiddenmenu {
|
| 158 |
+
position: absolute;
|
| 159 |
+
display: none;
|
| 160 |
+
padding: 40px;
|
| 161 |
+
width: 100%;
|
| 162 |
+
left: 0;
|
| 163 |
+
bottom: 80px;
|
| 164 |
+
background-color: rgba(0, 0, 0, 0.7);
|
| 165 |
+
text-align: center;
|
| 166 |
+
-webkit-box-sizing: border-box;
|
| 167 |
+
-moz-box-sizing: border-box;
|
| 168 |
+
box-sizing: border-box;
|
| 169 |
+
z-index: 9999;
|
| 170 |
+
}
|
| 171 |
+
.tui-image-editor-controls .hiddenmenu.show {
|
| 172 |
+
display: block;
|
| 173 |
+
}
|
| 174 |
+
.tui-image-editor-controls .hiddenmenu .top {
|
| 175 |
+
font-size: 12px;
|
| 176 |
+
color: #fff;
|
| 177 |
+
margin-bottom: 20px;
|
| 178 |
+
}
|
| 179 |
+
.tui-image-editor-controls .btn-prev {
|
| 180 |
+
display: inline-block;
|
| 181 |
+
width: 30px;
|
| 182 |
+
height: 80px;
|
| 183 |
+
background-color: #000;
|
| 184 |
+
color: #fff;
|
| 185 |
+
border: none;
|
| 186 |
+
vertical-align: middle;
|
| 187 |
+
}
|
| 188 |
+
.tui-image-editor-controls .tui-colorpicker-container {
|
| 189 |
+
display: inline-block;
|
| 190 |
+
}
|
| 191 |
+
.tui-image-editor-controls .msg {
|
| 192 |
+
position: absolute;
|
| 193 |
+
margin-left: 50%;
|
| 194 |
+
padding: 5px 10px;
|
| 195 |
+
left: -86px;
|
| 196 |
+
top: -50px;
|
| 197 |
+
border-radius: 5px 5px;
|
| 198 |
+
background-color: rgba(255, 255, 255, 0.5);
|
| 199 |
+
font-size: 12px;
|
| 200 |
+
}
|
| 201 |
+
.tui-image-editor-controls .msg.hide {
|
| 202 |
+
display: none;
|
| 203 |
+
}
|
apps/image-editor/examples/css/tui-example-style.css
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
body {
|
| 2 |
+
margin: 0;
|
| 3 |
+
padding: 0;
|
| 4 |
+
}
|
| 5 |
+
|
| 6 |
+
.code-description {
|
| 7 |
+
padding: 22px 52px;
|
| 8 |
+
background-color: rgba(81, 92, 230, 0.1);
|
| 9 |
+
line-height: 1.4em;
|
| 10 |
+
}
|
| 11 |
+
|
| 12 |
+
.code-description,
|
| 13 |
+
.code-description a {
|
| 14 |
+
font-family: Arial;
|
| 15 |
+
font-size: 14px;
|
| 16 |
+
color: #515ce6;
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
.code-html {
|
| 20 |
+
padding: 20px 52px;
|
| 21 |
+
}
|
apps/image-editor/examples/example01-includeUi.html
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8" />
|
| 5 |
+
<title>0. Design</title>
|
| 6 |
+
<link
|
| 7 |
+
type="text/css"
|
| 8 |
+
href="https://uicdn.toast.com/tui-color-picker/v2.2.6/tui-color-picker.css"
|
| 9 |
+
rel="stylesheet"
|
| 10 |
+
/>
|
| 11 |
+
<link type="text/css" href="../dist/tui-image-editor.css" rel="stylesheet" />
|
| 12 |
+
<style>
|
| 13 |
+
@import url(http://fonts.googleapis.com/css?family=Noto+Sans);
|
| 14 |
+
html,
|
| 15 |
+
body {
|
| 16 |
+
height: 100%;
|
| 17 |
+
margin: 0;
|
| 18 |
+
}
|
| 19 |
+
</style>
|
| 20 |
+
</head>
|
| 21 |
+
<body>
|
| 22 |
+
<div id="tui-image-editor-container"></div>
|
| 23 |
+
<script
|
| 24 |
+
type="text/javascript"
|
| 25 |
+
src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.4.0/fabric.js"
|
| 26 |
+
></script>
|
| 27 |
+
<script
|
| 28 |
+
type="text/javascript"
|
| 29 |
+
src="https://uicdn.toast.com/tui.code-snippet/v1.5.0/tui-code-snippet.min.js"
|
| 30 |
+
></script>
|
| 31 |
+
<script
|
| 32 |
+
type="text/javascript"
|
| 33 |
+
src="https://uicdn.toast.com/tui-color-picker/v2.2.6/tui-color-picker.js"
|
| 34 |
+
></script>
|
| 35 |
+
<script
|
| 36 |
+
type="text/javascript"
|
| 37 |
+
src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"
|
| 38 |
+
></script>
|
| 39 |
+
<script type="text/javascript" src="../dist/tui-image-editor.js"></script>
|
| 40 |
+
<script type="text/javascript" src="js/theme/white-theme.js"></script>
|
| 41 |
+
<script type="text/javascript" src="js/theme/black-theme.js"></script>
|
| 42 |
+
<script>
|
| 43 |
+
// Image editor
|
| 44 |
+
var imageEditor = new tui.ImageEditor('#tui-image-editor-container', {
|
| 45 |
+
includeUI: {
|
| 46 |
+
loadImage: {
|
| 47 |
+
path: 'img/sampleImage2.png',
|
| 48 |
+
name: 'SampleImage',
|
| 49 |
+
},
|
| 50 |
+
theme: blackTheme, // or whiteTheme
|
| 51 |
+
initMenu: 'filter',
|
| 52 |
+
menuBarPosition: 'bottom',
|
| 53 |
+
},
|
| 54 |
+
cssMaxWidth: 700,
|
| 55 |
+
cssMaxHeight: 500,
|
| 56 |
+
usageStatistics: false,
|
| 57 |
+
});
|
| 58 |
+
window.onresize = function () {
|
| 59 |
+
imageEditor.ui.resizeEditor();
|
| 60 |
+
};
|
| 61 |
+
</script>
|
| 62 |
+
</body>
|
| 63 |
+
</html>
|
apps/image-editor/examples/example02-useApiDirect.html
ADDED
|
@@ -0,0 +1,380 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8" />
|
| 5 |
+
<title>1. Basic</title>
|
| 6 |
+
<link
|
| 7 |
+
type="text/css"
|
| 8 |
+
href="https://uicdn.toast.com/tui-color-picker/v2.2.6/tui-color-picker.css"
|
| 9 |
+
rel="stylesheet"
|
| 10 |
+
/>
|
| 11 |
+
<link type="text/css" href="css/service-basic.css" rel="stylesheet" />
|
| 12 |
+
</head>
|
| 13 |
+
<body>
|
| 14 |
+
<div class="body-container">
|
| 15 |
+
<div class="tui-image-editor-controls">
|
| 16 |
+
<div class="header">
|
| 17 |
+
<img class="logo" src="img/TOAST UI Component.png" />
|
| 18 |
+
<span class="name"> Image Editor</span>
|
| 19 |
+
<ul class="menu">
|
| 20 |
+
<li class="menu-item border input-wrapper">
|
| 21 |
+
Load
|
| 22 |
+
<input type="file" accept="image/*" id="input-image-file" />
|
| 23 |
+
</li>
|
| 24 |
+
<li class="menu-item border" id="btn-download">Download</li>
|
| 25 |
+
</ul>
|
| 26 |
+
</div>
|
| 27 |
+
<ul class="menu">
|
| 28 |
+
<li class="menu-item disabled" id="btn-undo">Undo</li>
|
| 29 |
+
<li class="menu-item disabled" id="btn-redo">Redo</li>
|
| 30 |
+
<li class="menu-item" id="btn-clear-objects">ClearObjects</li>
|
| 31 |
+
<li class="menu-item" id="btn-remove-active-object">RemoveActiveObject</li>
|
| 32 |
+
<li class="menu-item" id="btn-crop">Crop</li>
|
| 33 |
+
<li class="menu-item" id="btn-flip">Flip</li>
|
| 34 |
+
<li class="menu-item" id="btn-rotation">Rotation</li>
|
| 35 |
+
<li class="menu-item" id="btn-draw-line">DrawLine</li>
|
| 36 |
+
<li class="menu-item" id="btn-draw-shape">Shape</li>
|
| 37 |
+
<li class="menu-item" id="btn-add-icon">Icon</li>
|
| 38 |
+
<li class="menu-item" id="btn-text">Text</li>
|
| 39 |
+
<li class="menu-item" id="btn-mask-filter">Mask</li>
|
| 40 |
+
<li class="menu-item" id="btn-image-filter">Filter</li>
|
| 41 |
+
</ul>
|
| 42 |
+
<div class="sub-menu-container" id="crop-sub-menu">
|
| 43 |
+
<ul class="menu">
|
| 44 |
+
<li class="menu-item" id="btn-apply-crop">Apply</li>
|
| 45 |
+
<li class="menu-item" id="btn-cancel-crop">Cancel</li>
|
| 46 |
+
</ul>
|
| 47 |
+
</div>
|
| 48 |
+
<div class="sub-menu-container" id="flip-sub-menu">
|
| 49 |
+
<ul class="menu">
|
| 50 |
+
<li class="menu-item" id="btn-flip-x">FlipX</li>
|
| 51 |
+
<li class="menu-item" id="btn-flip-y">FlipY</li>
|
| 52 |
+
<li class="menu-item" id="btn-reset-flip">Reset</li>
|
| 53 |
+
<li class="menu-item close">Close</li>
|
| 54 |
+
</ul>
|
| 55 |
+
</div>
|
| 56 |
+
<div class="sub-menu-container" id="rotation-sub-menu">
|
| 57 |
+
<ul class="menu">
|
| 58 |
+
<li class="menu-item" id="btn-rotate-clockwise">Clockwise(30)</li>
|
| 59 |
+
<li class="menu-item" id="btn-rotate-counter-clockwise">Counter-Clockwise(-30)</li>
|
| 60 |
+
<li class="menu-item no-pointer">
|
| 61 |
+
<label>
|
| 62 |
+
Range input
|
| 63 |
+
<input id="input-rotation-range" type="range" min="-360" value="0" max="360" />
|
| 64 |
+
</label>
|
| 65 |
+
</li>
|
| 66 |
+
<li class="menu-item close">Close</li>
|
| 67 |
+
</ul>
|
| 68 |
+
</div>
|
| 69 |
+
<div class="sub-menu-container menu" id="draw-line-sub-menu">
|
| 70 |
+
<ul class="menu">
|
| 71 |
+
<li class="menu-item">
|
| 72 |
+
<label>
|
| 73 |
+
<input type="radio" name="select-line-type" value="freeDrawing" checked="checked" />
|
| 74 |
+
Free drawing
|
| 75 |
+
</label>
|
| 76 |
+
<label>
|
| 77 |
+
<input type="radio" name="select-line-type" value="lineDrawing" />
|
| 78 |
+
Straight line
|
| 79 |
+
</label>
|
| 80 |
+
</li>
|
| 81 |
+
<li class="menu-item">
|
| 82 |
+
<div id="tui-brush-color-picker">Brush color</div>
|
| 83 |
+
</li>
|
| 84 |
+
<li class="menu-item">
|
| 85 |
+
<label class="menu-item no-pointer">
|
| 86 |
+
Brush width
|
| 87 |
+
<input id="input-brush-width-range" type="range" min="5" max="30" value="12" />
|
| 88 |
+
</label>
|
| 89 |
+
</li>
|
| 90 |
+
<li class="menu-item close">Close</li>
|
| 91 |
+
</ul>
|
| 92 |
+
</div>
|
| 93 |
+
<div class="sub-menu-container" id="draw-shape-sub-menu">
|
| 94 |
+
<ul class="menu">
|
| 95 |
+
<li class="menu-item">
|
| 96 |
+
<label>
|
| 97 |
+
<input type="radio" name="select-shape-type" value="rect" checked="checked" />
|
| 98 |
+
rect
|
| 99 |
+
</label>
|
| 100 |
+
<label>
|
| 101 |
+
<input type="radio" name="select-shape-type" value="circle" />
|
| 102 |
+
circle
|
| 103 |
+
</label>
|
| 104 |
+
<label>
|
| 105 |
+
<input type="radio" name="select-shape-type" value="triangle" />
|
| 106 |
+
triangle
|
| 107 |
+
</label>
|
| 108 |
+
</li>
|
| 109 |
+
<li class="menu-item">
|
| 110 |
+
<select name="select-color-type">
|
| 111 |
+
<option value="fill">Fill</option>
|
| 112 |
+
<option value="stroke">Stroke</option>
|
| 113 |
+
</select>
|
| 114 |
+
<label>
|
| 115 |
+
<input
|
| 116 |
+
type="radio"
|
| 117 |
+
name="input-check-fill"
|
| 118 |
+
id="input-check-transparent"
|
| 119 |
+
value="transparent"
|
| 120 |
+
/>
|
| 121 |
+
transparent
|
| 122 |
+
</label>
|
| 123 |
+
<label>
|
| 124 |
+
<input
|
| 125 |
+
type="radio"
|
| 126 |
+
name="input-check-fill"
|
| 127 |
+
id="input-check-filter"
|
| 128 |
+
value="filter"
|
| 129 |
+
/>
|
| 130 |
+
filter
|
| 131 |
+
</label>
|
| 132 |
+
<div id="tui-shape-color-picker"></div>
|
| 133 |
+
</li>
|
| 134 |
+
<li class="menu-item">
|
| 135 |
+
<label class="menu-item no-pointer">
|
| 136 |
+
Stroke width
|
| 137 |
+
<input id="input-stroke-width-range" type="range" min="0" max="300" value="12" />
|
| 138 |
+
</label>
|
| 139 |
+
</li>
|
| 140 |
+
<li class="menu-item close">Close</li>
|
| 141 |
+
</ul>
|
| 142 |
+
</div>
|
| 143 |
+
<div class="sub-menu-container" id="icon-sub-menu">
|
| 144 |
+
<ul class="menu">
|
| 145 |
+
<li class="menu-item">
|
| 146 |
+
<div id="tui-icon-color-picker">Icon color</div>
|
| 147 |
+
</li>
|
| 148 |
+
<li class="menu-item border" id="btn-register-icon">Register custom icon</li>
|
| 149 |
+
<li class="menu-item icon-text" data-icon-type="arrow">➡</li>
|
| 150 |
+
<li class="menu-item icon-text" data-icon-type="cancel">✖</li>
|
| 151 |
+
<li class="menu-item close">Close</li>
|
| 152 |
+
</ul>
|
| 153 |
+
</div>
|
| 154 |
+
<div class="sub-menu-container" id="text-sub-menu">
|
| 155 |
+
<ul class="menu">
|
| 156 |
+
<li class="menu-item">
|
| 157 |
+
<div>
|
| 158 |
+
<button class="btn-text-style" data-style-type="b">Bold</button>
|
| 159 |
+
<button class="btn-text-style" data-style-type="i">Italic</button>
|
| 160 |
+
<button class="btn-text-style" data-style-type="u">Underline</button>
|
| 161 |
+
</div>
|
| 162 |
+
<div>
|
| 163 |
+
<button class="btn-text-style" data-style-type="l">Left</button>
|
| 164 |
+
<button class="btn-text-style" data-style-type="c">Center</button>
|
| 165 |
+
<button class="btn-text-style" data-style-type="r">Right</button>
|
| 166 |
+
</div>
|
| 167 |
+
</li>
|
| 168 |
+
<li class="menu-item">
|
| 169 |
+
<label class="no-pointer">
|
| 170 |
+
<input id="input-font-size-range" type="range" min="10" max="100" value="10" />
|
| 171 |
+
</label>
|
| 172 |
+
</li>
|
| 173 |
+
<li class="menu-item">
|
| 174 |
+
<div id="tui-text-color-picker">Text color</div>
|
| 175 |
+
</li>
|
| 176 |
+
<li class="menu-item close">Close</li>
|
| 177 |
+
</ul>
|
| 178 |
+
</div>
|
| 179 |
+
<div class="sub-menu-container" id="filter-sub-menu">
|
| 180 |
+
<ul class="menu">
|
| 181 |
+
<li class="menu-item border input-wrapper">
|
| 182 |
+
Load Mask Image
|
| 183 |
+
<input type="file" accept="image/*" id="input-mask-image-file" />
|
| 184 |
+
</li>
|
| 185 |
+
<li class="menu-item" id="btn-apply-mask">Apply mask filter</li>
|
| 186 |
+
<li class="menu-item close">Close</li>
|
| 187 |
+
</ul>
|
| 188 |
+
</div>
|
| 189 |
+
<div class="sub-menu-container" id="image-filter-sub-menu">
|
| 190 |
+
<ul class="menu">
|
| 191 |
+
<li class="menu-item align-left-top">
|
| 192 |
+
<table>
|
| 193 |
+
<tbody>
|
| 194 |
+
<tr>
|
| 195 |
+
<td>
|
| 196 |
+
<label><input type="checkbox" id="input-check-grayscale" />Grayscale</label>
|
| 197 |
+
</td>
|
| 198 |
+
<td>
|
| 199 |
+
<label><input type="checkbox" id="input-check-invert" />Invert</label>
|
| 200 |
+
</td>
|
| 201 |
+
<td>
|
| 202 |
+
<label><input type="checkbox" id="input-check-sepia" />Sepia</label>
|
| 203 |
+
</td>
|
| 204 |
+
</tr>
|
| 205 |
+
<tr>
|
| 206 |
+
<td>
|
| 207 |
+
<label><input type="checkbox" id="input-check-sepia2" />Sepia2</label>
|
| 208 |
+
</td>
|
| 209 |
+
<td>
|
| 210 |
+
<label><input type="checkbox" id="input-check-blur" />Blur</label>
|
| 211 |
+
</td>
|
| 212 |
+
<td>
|
| 213 |
+
<label><input type="checkbox" id="input-check-sharpen" />Sharpen</label>
|
| 214 |
+
</td>
|
| 215 |
+
</tr>
|
| 216 |
+
<tr>
|
| 217 |
+
<td>
|
| 218 |
+
<label><input type="checkbox" id="input-check-emboss" />Emboss</label>
|
| 219 |
+
</td>
|
| 220 |
+
</tr>
|
| 221 |
+
</tbody>
|
| 222 |
+
</table>
|
| 223 |
+
</li>
|
| 224 |
+
<li class="menu-item align-left-top">
|
| 225 |
+
<p>
|
| 226 |
+
<label>
|
| 227 |
+
<input type="checkbox" id="input-check-remove-white" />
|
| 228 |
+
RemoveWhite
|
| 229 |
+
</label>
|
| 230 |
+
<br />
|
| 231 |
+
<label>
|
| 232 |
+
Distance
|
| 233 |
+
<input
|
| 234 |
+
class="range-narrow"
|
| 235 |
+
id="input-range-remove-white-distance"
|
| 236 |
+
type="range"
|
| 237 |
+
min="0"
|
| 238 |
+
value="10"
|
| 239 |
+
max="255"
|
| 240 |
+
/>
|
| 241 |
+
</label>
|
| 242 |
+
</p>
|
| 243 |
+
</li>
|
| 244 |
+
<li class="menu-item align-left-top">
|
| 245 |
+
<p>
|
| 246 |
+
<label><input type="checkbox" id="input-check-brightness" />Brightness</label><br />
|
| 247 |
+
<label>
|
| 248 |
+
Value
|
| 249 |
+
<input
|
| 250 |
+
class="range-narrow"
|
| 251 |
+
id="input-range-brightness-value"
|
| 252 |
+
type="range"
|
| 253 |
+
min="-255"
|
| 254 |
+
value="100"
|
| 255 |
+
max="255"
|
| 256 |
+
/>
|
| 257 |
+
</label>
|
| 258 |
+
</p>
|
| 259 |
+
</li>
|
| 260 |
+
<li class="menu-item align-left-top">
|
| 261 |
+
<p>
|
| 262 |
+
<label><input type="checkbox" id="input-check-noise" />Noise</label><br />
|
| 263 |
+
<label>
|
| 264 |
+
Value
|
| 265 |
+
<input
|
| 266 |
+
class="range-narrow"
|
| 267 |
+
id="input-range-noise-value"
|
| 268 |
+
type="range"
|
| 269 |
+
min="0"
|
| 270 |
+
value="100"
|
| 271 |
+
max="1000"
|
| 272 |
+
/>
|
| 273 |
+
</label>
|
| 274 |
+
</p>
|
| 275 |
+
</li>
|
| 276 |
+
<li class="menu-item align-left-top">
|
| 277 |
+
<p>
|
| 278 |
+
<label>
|
| 279 |
+
<input type="checkbox" id="input-check-color-filter" />
|
| 280 |
+
ColorFilter
|
| 281 |
+
</label>
|
| 282 |
+
<br />
|
| 283 |
+
<label>
|
| 284 |
+
Threshold
|
| 285 |
+
<input
|
| 286 |
+
class="range-narrow"
|
| 287 |
+
id="input-range-color-filter-value"
|
| 288 |
+
type="range"
|
| 289 |
+
min="0"
|
| 290 |
+
value="45"
|
| 291 |
+
max="255"
|
| 292 |
+
/>
|
| 293 |
+
</label>
|
| 294 |
+
</p>
|
| 295 |
+
</li>
|
| 296 |
+
<li class="menu-item align-left-top">
|
| 297 |
+
<p>
|
| 298 |
+
<label><input type="checkbox" id="input-check-pixelate" />Pixelate</label><br />
|
| 299 |
+
<label>
|
| 300 |
+
Value
|
| 301 |
+
<input
|
| 302 |
+
class="range-narrow"
|
| 303 |
+
id="input-range-pixelate-value"
|
| 304 |
+
type="range"
|
| 305 |
+
min="2"
|
| 306 |
+
value="4"
|
| 307 |
+
max="20"
|
| 308 |
+
/>
|
| 309 |
+
</label>
|
| 310 |
+
</p>
|
| 311 |
+
</li>
|
| 312 |
+
<li class="menu-item align-left-top">
|
| 313 |
+
<p>
|
| 314 |
+
<label><input type="checkbox" id="input-check-tint" />Tint</label><br />
|
| 315 |
+
</p>
|
| 316 |
+
<div id="tui-tint-color-picker"></div>
|
| 317 |
+
<label>
|
| 318 |
+
Opacity
|
| 319 |
+
<input
|
| 320 |
+
class="range-narrow"
|
| 321 |
+
id="input-range-tint-opacity-value"
|
| 322 |
+
type="range"
|
| 323 |
+
min="0"
|
| 324 |
+
value="1"
|
| 325 |
+
max="1"
|
| 326 |
+
step="0.1"
|
| 327 |
+
/>
|
| 328 |
+
</label>
|
| 329 |
+
</li>
|
| 330 |
+
<li class="menu-item align-left-top">
|
| 331 |
+
<p>
|
| 332 |
+
<label><input type="checkbox" id="input-check-multiply" />Multiply</label>
|
| 333 |
+
</p>
|
| 334 |
+
<div id="tui-multiply-color-picker"></div>
|
| 335 |
+
</li>
|
| 336 |
+
<li class="menu-item align-left-top">
|
| 337 |
+
<p>
|
| 338 |
+
<label><input type="checkbox" id="input-check-blend" />Blend</label>
|
| 339 |
+
</p>
|
| 340 |
+
<div id="tui-blend-color-picker"></div>
|
| 341 |
+
<select name="select-blend-type">
|
| 342 |
+
<option value="add" selected>Add</option>
|
| 343 |
+
<option value="diff">Diff</option>
|
| 344 |
+
<option value="diff">Subtract</option>
|
| 345 |
+
<option value="multiply">Multiply</option>
|
| 346 |
+
<option value="screen">Screen</option>
|
| 347 |
+
<option value="lighten">Lighten</option>
|
| 348 |
+
<option value="darken">Darken</option>
|
| 349 |
+
</select>
|
| 350 |
+
</li>
|
| 351 |
+
<li class="menu-item close">Close</li>
|
| 352 |
+
</ul>
|
| 353 |
+
</div>
|
| 354 |
+
</div>
|
| 355 |
+
<div class="tui-image-editor"></div>
|
| 356 |
+
</div>
|
| 357 |
+
<script
|
| 358 |
+
type="text/javascript"
|
| 359 |
+
src="https://api-storage.cloud.toast.com/v1/AUTH_e18353c4ea5746c097143946d0644e61/toast-ui-cdn/tui-image-editor/v3.11.0/example/fabric-v4.2.0.js"
|
| 360 |
+
></script>
|
| 361 |
+
<script
|
| 362 |
+
type="text/javascript"
|
| 363 |
+
src="https://uicdn.toast.com/tui.code-snippet/v1.5.0/tui-code-snippet.min.js"
|
| 364 |
+
></script>
|
| 365 |
+
<script
|
| 366 |
+
type="text/javascript"
|
| 367 |
+
src="https://uicdn.toast.com/tui-color-picker/v2.2.6/tui-color-picker.min.js"
|
| 368 |
+
></script>
|
| 369 |
+
<script
|
| 370 |
+
type="text/javascript"
|
| 371 |
+
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"
|
| 372 |
+
></script>
|
| 373 |
+
<script
|
| 374 |
+
type="text/javascript"
|
| 375 |
+
src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"
|
| 376 |
+
></script>
|
| 377 |
+
<script type="text/javascript" src="../dist/tui-image-editor.js"></script>
|
| 378 |
+
<script src="js/service-basic.js"></script>
|
| 379 |
+
</body>
|
| 380 |
+
</html>
|
apps/image-editor/examples/example03-mobile.html
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8" />
|
| 5 |
+
<meta name="viewport" content="width=device-width, user-scalable=no" />
|
| 6 |
+
<title>2. Mobile</title>
|
| 7 |
+
<link
|
| 8 |
+
type="text/css"
|
| 9 |
+
href="https://uicdn.toast.com/tui-color-picker/v2.2.6/tui-color-picker.css"
|
| 10 |
+
rel="stylesheet"
|
| 11 |
+
/>
|
| 12 |
+
<link type="text/css" href="css/service-mobile.css" rel="stylesheet" />
|
| 13 |
+
</head>
|
| 14 |
+
<body>
|
| 15 |
+
<!-- Image editor controls - top area -->
|
| 16 |
+
<div class="header">
|
| 17 |
+
<div>
|
| 18 |
+
<img class="logo" src="img/TOAST UI Component.png" /> <span class="name">Image Editor</span>
|
| 19 |
+
</div>
|
| 20 |
+
<div class="menu">
|
| 21 |
+
<span class="button">
|
| 22 |
+
<img src="img/openImage.png" style="margin-top: 5px" />
|
| 23 |
+
<input type="file" accept="image/*" id="input-image-file" />
|
| 24 |
+
</span>
|
| 25 |
+
<button class="button disabled" id="btn-undo"><img src="img/undo.png" /></button>
|
| 26 |
+
<button class="button disabled" id="btn-redo"><img src="img/redo.png" /></button>
|
| 27 |
+
<button class="button" id="btn-remove-active-object"><img src="img/remove.png" /></button>
|
| 28 |
+
<button class="button" id="btn-download"><img src="img/download.png" /></button>
|
| 29 |
+
</div>
|
| 30 |
+
</div>
|
| 31 |
+
<!-- Image editor area -->
|
| 32 |
+
<div class="tui-image-editor"></div>
|
| 33 |
+
<!-- Image editor controls - bottom area -->
|
| 34 |
+
<div class="tui-image-editor-controls">
|
| 35 |
+
<ul class="scrollable">
|
| 36 |
+
<li class="menu-item">
|
| 37 |
+
<button class="menu-button" id="btn-crop">Crop</button>
|
| 38 |
+
<div class="submenu">
|
| 39 |
+
<button class="btn-prev"><</button>
|
| 40 |
+
<ul class="scrollable">
|
| 41 |
+
<li class="menu-item">
|
| 42 |
+
<button class="submenu-button" id="btn-apply-crop">Apply</button>
|
| 43 |
+
</li>
|
| 44 |
+
</ul>
|
| 45 |
+
</div>
|
| 46 |
+
</li>
|
| 47 |
+
<li class="menu-item">
|
| 48 |
+
<button class="menu-button">Orientation</button>
|
| 49 |
+
<div class="submenu">
|
| 50 |
+
<button class="btn-prev"><</button>
|
| 51 |
+
<ul class="scrollable">
|
| 52 |
+
<li class="menu-item">
|
| 53 |
+
<button class="submenu-button" id="btn-rotate-clockwise">Rotate +90</button>
|
| 54 |
+
</li>
|
| 55 |
+
<li class="menu-item">
|
| 56 |
+
<button class="submenu-button" id="btn-rotate-counter-clockwise">Rotate -90</button>
|
| 57 |
+
</li>
|
| 58 |
+
<li class="menu-item">
|
| 59 |
+
<button class="submenu-button" id="btn-flip-x">FilpX</button>
|
| 60 |
+
</li>
|
| 61 |
+
<li class="menu-item">
|
| 62 |
+
<button class="submenu-button" id="btn-flip-y">FilpY</button>
|
| 63 |
+
</li>
|
| 64 |
+
</ul>
|
| 65 |
+
</div>
|
| 66 |
+
</li>
|
| 67 |
+
<li class="menu-item">
|
| 68 |
+
<button class="menu-button" id="btn-draw-line">Drawing</button>
|
| 69 |
+
<div class="submenu">
|
| 70 |
+
<button class="btn-prev"><</button>
|
| 71 |
+
<ul class="scrollable">
|
| 72 |
+
<li class="menu-item">
|
| 73 |
+
<button class="submenu-button" id="btn-free-drawing">Free<br />Drawing</button>
|
| 74 |
+
</li>
|
| 75 |
+
<li class="menu-item">
|
| 76 |
+
<button class="submenu-button" id="btn-line-drawing">Line<br />Drawing</button>
|
| 77 |
+
</li>
|
| 78 |
+
<li class="menu-item">
|
| 79 |
+
<button class="submenu-button" id="btn-change-size">Brush<br />Size</button>
|
| 80 |
+
<div class="hiddenmenu">
|
| 81 |
+
<input id="input-brush-range" type="range" min="10" max="100" value="50" />
|
| 82 |
+
</div>
|
| 83 |
+
</li>
|
| 84 |
+
<li class="menu-item">
|
| 85 |
+
<button class="submenu-button" id="btn-change-text-color">Brush<br />Color</button>
|
| 86 |
+
<div class="hiddenmenu">
|
| 87 |
+
<div id="tui-brush-color-picker"></div>
|
| 88 |
+
</div>
|
| 89 |
+
</li>
|
| 90 |
+
</ul>
|
| 91 |
+
</div>
|
| 92 |
+
</li>
|
| 93 |
+
<li class="menu-item">
|
| 94 |
+
<button class="menu-button" id="btn-draw-shape">Shape</button>
|
| 95 |
+
<div class="submenu">
|
| 96 |
+
<button class="btn-prev"><</button>
|
| 97 |
+
<ul class="scrollable">
|
| 98 |
+
<li class="menu-item">
|
| 99 |
+
<button class="submenu-button" id="btn-add-rect">Rectagle</button>
|
| 100 |
+
</li>
|
| 101 |
+
<li class="menu-item">
|
| 102 |
+
<button class="submenu-button" id="btn-add-square">Square</button>
|
| 103 |
+
</li>
|
| 104 |
+
<li class="menu-item">
|
| 105 |
+
<button class="submenu-button" id="btn-add-ellipse">Ellipse</button>
|
| 106 |
+
</li>
|
| 107 |
+
<li class="menu-item">
|
| 108 |
+
<button class="submenu-button" id="btn-add-circle">Circle</button>
|
| 109 |
+
</li>
|
| 110 |
+
<li class="menu-item">
|
| 111 |
+
<button class="submenu-button" id="btn-add-triangle">Triangle</button>
|
| 112 |
+
</li>
|
| 113 |
+
<li class="menu-item">
|
| 114 |
+
<button class="submenu-button" id="btn-stroke-size">Stroke<br />Size</button>
|
| 115 |
+
<div class="hiddenmenu">
|
| 116 |
+
<input id="input-stroke-range" type="range" min="1" max="100" value="10" />
|
| 117 |
+
</div>
|
| 118 |
+
</li>
|
| 119 |
+
<li class="menu-item">
|
| 120 |
+
<button class="submenu-button" id="btn-change-shape-color">Color</button>
|
| 121 |
+
<div class="hiddenmenu">
|
| 122 |
+
<div class="top">
|
| 123 |
+
<label for="fill-color"
|
| 124 |
+
><input
|
| 125 |
+
type="radio"
|
| 126 |
+
id="fill-color"
|
| 127 |
+
name="select-color-type"
|
| 128 |
+
value="fill"
|
| 129 |
+
checked="checked"
|
| 130 |
+
/>
|
| 131 |
+
Fill</label
|
| 132 |
+
>
|
| 133 |
+
<label for="stroke-color"
|
| 134 |
+
><input
|
| 135 |
+
type="radio"
|
| 136 |
+
id="stroke-color"
|
| 137 |
+
name="select-color-type"
|
| 138 |
+
value="stroke"
|
| 139 |
+
/>
|
| 140 |
+
Stroke</label
|
| 141 |
+
>
|
| 142 |
+
<label for="input-check-transparent"
|
| 143 |
+
><input type="checkbox" id="input-check-transparent" />Transparent</label
|
| 144 |
+
>
|
| 145 |
+
</div>
|
| 146 |
+
<div id="tui-shape-color-picker"></div>
|
| 147 |
+
</div>
|
| 148 |
+
</li>
|
| 149 |
+
</ul>
|
| 150 |
+
</div>
|
| 151 |
+
</li>
|
| 152 |
+
<li class="menu-item">
|
| 153 |
+
<button class="menu-button">Icon</button>
|
| 154 |
+
<div class="submenu">
|
| 155 |
+
<button class="btn-prev"><</button>
|
| 156 |
+
<ul class="scrollable">
|
| 157 |
+
<li class="menu-item">
|
| 158 |
+
<button class="submenu-button" id="btn-add-arrow-icon">Arrow<br />Icon</button>
|
| 159 |
+
</li>
|
| 160 |
+
<li class="menu-item">
|
| 161 |
+
<button class="submenu-button" id="btn-add-cancel-icon">Cancel<br />Icon</button>
|
| 162 |
+
</li>
|
| 163 |
+
<li class="menu-item">
|
| 164 |
+
<button class="submenu-button" id="btn-change-icon-color">Color</button>
|
| 165 |
+
<div class="hiddenmenu">
|
| 166 |
+
<div id="tui-icon-color-picker"></div>
|
| 167 |
+
</div>
|
| 168 |
+
</li>
|
| 169 |
+
</ul>
|
| 170 |
+
</div>
|
| 171 |
+
</li>
|
| 172 |
+
<li class="menu-item">
|
| 173 |
+
<button class="menu-button" id="btn-add-text">Text</button>
|
| 174 |
+
<div class="submenu">
|
| 175 |
+
<button class="btn-prev"><</button>
|
| 176 |
+
<ul class="scrollable">
|
| 177 |
+
<li class="menu-item">
|
| 178 |
+
<button class="submenu-button" id="btn-change-size">Size</button>
|
| 179 |
+
<div class="hiddenmenu">
|
| 180 |
+
<input id="input-text-size-range" type="range" min="10" max="240" value="120" />
|
| 181 |
+
</div>
|
| 182 |
+
</li>
|
| 183 |
+
<li class="menu-item">
|
| 184 |
+
<button class="submenu-button" id="btn-change-style">Style</button>
|
| 185 |
+
<div class="hiddenmenu">
|
| 186 |
+
<button class="hiddenmenu-button btn-change-text-style" data-style-type="bold">
|
| 187 |
+
<b>Bold</b>
|
| 188 |
+
</button>
|
| 189 |
+
<button class="hiddenmenu-button btn-change-text-style" data-style-type="italic">
|
| 190 |
+
<i>Italic</i>
|
| 191 |
+
</button>
|
| 192 |
+
<button
|
| 193 |
+
class="hiddenmenu-button btn-change-text-style"
|
| 194 |
+
data-style-type="underline"
|
| 195 |
+
>
|
| 196 |
+
<u>Underline</u>
|
| 197 |
+
</button>
|
| 198 |
+
</div>
|
| 199 |
+
</li>
|
| 200 |
+
<li class="menu-item">
|
| 201 |
+
<button class="submenu-button" id="btn-change-align">Align</button>
|
| 202 |
+
<div class="hiddenmenu">
|
| 203 |
+
<button class="hiddenmenu-button btn-change-text-style" data-style-type="left">
|
| 204 |
+
Left
|
| 205 |
+
</button>
|
| 206 |
+
<button class="hiddenmenu-button btn-change-text-style" data-style-type="center">
|
| 207 |
+
Center
|
| 208 |
+
</button>
|
| 209 |
+
<button class="hiddenmenu-button btn-change-text-style" data-style-type="right">
|
| 210 |
+
Right
|
| 211 |
+
</button>
|
| 212 |
+
</div>
|
| 213 |
+
</li>
|
| 214 |
+
<li class="menu-item">
|
| 215 |
+
<button class="submenu-button" id="btn-change-text-color">Color</button>
|
| 216 |
+
<div class="hiddenmenu">
|
| 217 |
+
<div id="tui-text-color-picker"></div>
|
| 218 |
+
</div>
|
| 219 |
+
</li>
|
| 220 |
+
</ul>
|
| 221 |
+
</div>
|
| 222 |
+
</li>
|
| 223 |
+
</ul>
|
| 224 |
+
<p class="msg">Menu Scrolling <b>Left ⇔ Right</b></p>
|
| 225 |
+
</div>
|
| 226 |
+
<script
|
| 227 |
+
type="text/javascript"
|
| 228 |
+
src="https://api-storage.cloud.toast.com/v1/AUTH_e18353c4ea5746c097143946d0644e61/toast-ui-cdn/tui-image-editor/v3.11.0/example/fabric-v4.2.0.js"
|
| 229 |
+
></script>
|
| 230 |
+
<script
|
| 231 |
+
type="text/javascript"
|
| 232 |
+
src="https://uicdn.toast.com/tui.code-snippet/v1.5.0/tui-code-snippet.min.js"
|
| 233 |
+
></script>
|
| 234 |
+
<script
|
| 235 |
+
type="text/javascript"
|
| 236 |
+
src="https://uicdn.toast.com/tui-color-picker/v2.2.6/tui-color-picker.min.js"
|
| 237 |
+
></script>
|
| 238 |
+
<script
|
| 239 |
+
type="text/javascript"
|
| 240 |
+
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"
|
| 241 |
+
></script>
|
| 242 |
+
<script
|
| 243 |
+
type="text/javascript"
|
| 244 |
+
src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"
|
| 245 |
+
></script>
|
| 246 |
+
<script type="text/javascript" src="../dist/tui-image-editor.js"></script>
|
| 247 |
+
<script src="js/service-mobile.js"></script>
|
| 248 |
+
</body>
|
| 249 |
+
</html>
|
apps/image-editor/examples/examples.json
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"example01-includeUi": {
|
| 3 |
+
"title": "1. Include ui"
|
| 4 |
+
},
|
| 5 |
+
"example02-useApiDirect": {
|
| 6 |
+
"title": "2. Use api direct (basic)"
|
| 7 |
+
},
|
| 8 |
+
"example03-mobile": {
|
| 9 |
+
"title": "3. Mobile"
|
| 10 |
+
}
|
| 11 |
+
}
|
apps/image-editor/examples/img/TOAST UI Component.png
ADDED
|
Git LFS Details
|
apps/image-editor/examples/img/bg.jpg
ADDED
|
Git LFS Details
|
apps/image-editor/examples/img/bg.png
ADDED
|
Git LFS Details
|
apps/image-editor/examples/img/download.png
ADDED
|
Git LFS Details
|
apps/image-editor/examples/img/mask.png
ADDED
|
Git LFS Details
|
apps/image-editor/examples/img/openImage.png
ADDED
|
Git LFS Details
|
apps/image-editor/examples/img/redo.png
ADDED
|
Git LFS Details
|
apps/image-editor/examples/img/remove.png
ADDED
|
Git LFS Details
|
apps/image-editor/examples/img/sampleImage.jpg
ADDED
|
Git LFS Details
|
apps/image-editor/examples/img/sampleImage2.png
ADDED
|
Git LFS Details
|
apps/image-editor/examples/img/undo.png
ADDED
|
Git LFS Details
|
apps/image-editor/examples/js/service-basic.js
ADDED
|
@@ -0,0 +1,922 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* eslint-disable vars-on-top,no-var,strict,prefer-template,prefer-arrow-callback,prefer-destructuring,object-shorthand,require-jsdoc,complexity,prefer-const,no-unused-vars */
|
| 2 |
+
var PIXELATE_FILTER_DEFAULT_VALUE = 20;
|
| 3 |
+
var supportingFileAPI = !!(window.File && window.FileList && window.FileReader);
|
| 4 |
+
var rImageType = /data:(image\/.+);base64,/;
|
| 5 |
+
var shapeOptions = {};
|
| 6 |
+
var shapeType;
|
| 7 |
+
var activeObjectId;
|
| 8 |
+
|
| 9 |
+
// Buttons
|
| 10 |
+
var $btns = $('.menu-item');
|
| 11 |
+
var $btnsActivatable = $btns.filter('.activatable');
|
| 12 |
+
var $inputImage = $('#input-image-file');
|
| 13 |
+
var $btnDownload = $('#btn-download');
|
| 14 |
+
|
| 15 |
+
var $btnUndo = $('#btn-undo');
|
| 16 |
+
var $btnRedo = $('#btn-redo');
|
| 17 |
+
var $btnClearObjects = $('#btn-clear-objects');
|
| 18 |
+
var $btnRemoveActiveObject = $('#btn-remove-active-object');
|
| 19 |
+
var $btnCrop = $('#btn-crop');
|
| 20 |
+
var $btnFlip = $('#btn-flip');
|
| 21 |
+
var $btnRotation = $('#btn-rotation');
|
| 22 |
+
var $btnDrawLine = $('#btn-draw-line');
|
| 23 |
+
var $btnDrawShape = $('#btn-draw-shape');
|
| 24 |
+
var $btnApplyCrop = $('#btn-apply-crop');
|
| 25 |
+
var $btnCancelCrop = $('#btn-cancel-crop');
|
| 26 |
+
var $btnFlipX = $('#btn-flip-x');
|
| 27 |
+
var $btnFlipY = $('#btn-flip-y');
|
| 28 |
+
var $btnResetFlip = $('#btn-reset-flip');
|
| 29 |
+
var $btnRotateClockwise = $('#btn-rotate-clockwise');
|
| 30 |
+
var $btnRotateCounterClockWise = $('#btn-rotate-counter-clockwise');
|
| 31 |
+
var $btnText = $('#btn-text');
|
| 32 |
+
var $btnTextStyle = $('.btn-text-style');
|
| 33 |
+
var $btnAddIcon = $('#btn-add-icon');
|
| 34 |
+
var $btnRegisterIcon = $('#btn-register-icon');
|
| 35 |
+
var $btnMaskFilter = $('#btn-mask-filter');
|
| 36 |
+
var $btnImageFilter = $('#btn-image-filter');
|
| 37 |
+
var $btnLoadMaskImage = $('#input-mask-image-file');
|
| 38 |
+
var $btnApplyMask = $('#btn-apply-mask');
|
| 39 |
+
var $btnClose = $('.close');
|
| 40 |
+
|
| 41 |
+
// Input etc.
|
| 42 |
+
var $inputRotationRange = $('#input-rotation-range');
|
| 43 |
+
var $inputBrushWidthRange = $('#input-brush-width-range');
|
| 44 |
+
var $inputFontSizeRange = $('#input-font-size-range');
|
| 45 |
+
var $inputStrokeWidthRange = $('#input-stroke-width-range');
|
| 46 |
+
var $inputCheckTransparent = $('#input-check-transparent');
|
| 47 |
+
var $inputCheckFilter = $('#input-check-filter');
|
| 48 |
+
var $inputCheckGrayscale = $('#input-check-grayscale');
|
| 49 |
+
var $inputCheckInvert = $('#input-check-invert');
|
| 50 |
+
var $inputCheckSepia = $('#input-check-sepia');
|
| 51 |
+
var $inputCheckSepia2 = $('#input-check-sepia2');
|
| 52 |
+
var $inputCheckBlur = $('#input-check-blur');
|
| 53 |
+
var $inputCheckSharpen = $('#input-check-sharpen');
|
| 54 |
+
var $inputCheckEmboss = $('#input-check-emboss');
|
| 55 |
+
var $inputCheckRemoveWhite = $('#input-check-remove-white');
|
| 56 |
+
var $inputRangeRemoveWhiteThreshold = $('#input-range-remove-white-threshold');
|
| 57 |
+
var $inputRangeRemoveWhiteDistance = $('#input-range-remove-white-distance');
|
| 58 |
+
var $inputCheckBrightness = $('#input-check-brightness');
|
| 59 |
+
var $inputRangeBrightnessValue = $('#input-range-brightness-value');
|
| 60 |
+
var $inputCheckNoise = $('#input-check-noise');
|
| 61 |
+
var $inputRangeNoiseValue = $('#input-range-noise-value');
|
| 62 |
+
var $inputCheckPixelate = $('#input-check-pixelate');
|
| 63 |
+
var $inputRangePixelateValue = $('#input-range-pixelate-value');
|
| 64 |
+
var $inputCheckTint = $('#input-check-tint');
|
| 65 |
+
var $inputRangeTintOpacityValue = $('#input-range-tint-opacity-value');
|
| 66 |
+
var $inputCheckMultiply = $('#input-check-multiply');
|
| 67 |
+
var $inputCheckBlend = $('#input-check-blend');
|
| 68 |
+
var $inputCheckColorFilter = $('#input-check-color-filter');
|
| 69 |
+
var $inputRangeColorFilterValue = $('#input-range-color-filter-value');
|
| 70 |
+
|
| 71 |
+
// Sub menus
|
| 72 |
+
var $displayingSubMenu = $();
|
| 73 |
+
var $cropSubMenu = $('#crop-sub-menu');
|
| 74 |
+
var $flipSubMenu = $('#flip-sub-menu');
|
| 75 |
+
var $rotationSubMenu = $('#rotation-sub-menu');
|
| 76 |
+
var $freeDrawingSubMenu = $('#free-drawing-sub-menu');
|
| 77 |
+
var $drawLineSubMenu = $('#draw-line-sub-menu');
|
| 78 |
+
var $drawShapeSubMenu = $('#draw-shape-sub-menu');
|
| 79 |
+
var $textSubMenu = $('#text-sub-menu');
|
| 80 |
+
var $iconSubMenu = $('#icon-sub-menu');
|
| 81 |
+
var $filterSubMenu = $('#filter-sub-menu');
|
| 82 |
+
var $imageFilterSubMenu = $('#image-filter-sub-menu');
|
| 83 |
+
|
| 84 |
+
// Select line type
|
| 85 |
+
var $selectLine = $('[name="select-line-type"]');
|
| 86 |
+
|
| 87 |
+
// Select shape type
|
| 88 |
+
var $selectShapeType = $('[name="select-shape-type"]');
|
| 89 |
+
|
| 90 |
+
// Select color of shape type
|
| 91 |
+
var $selectColorType = $('[name="select-color-type"]');
|
| 92 |
+
|
| 93 |
+
// Select blend type
|
| 94 |
+
var $selectBlendType = $('[name="select-blend-type"]');
|
| 95 |
+
|
| 96 |
+
// Image editor
|
| 97 |
+
var imageEditor = new tui.ImageEditor('.tui-image-editor', {
|
| 98 |
+
cssMaxWidth: 700,
|
| 99 |
+
cssMaxHeight: 500,
|
| 100 |
+
selectionStyle: {
|
| 101 |
+
cornerSize: 20,
|
| 102 |
+
rotatingPointOffset: 70,
|
| 103 |
+
},
|
| 104 |
+
});
|
| 105 |
+
|
| 106 |
+
// Color picker for free drawing
|
| 107 |
+
var brushColorpicker = tui.colorPicker.create({
|
| 108 |
+
container: $('#tui-brush-color-picker')[0],
|
| 109 |
+
color: '#000000',
|
| 110 |
+
});
|
| 111 |
+
|
| 112 |
+
// Color picker for text palette
|
| 113 |
+
var textColorpicker = tui.colorPicker.create({
|
| 114 |
+
container: $('#tui-text-color-picker')[0],
|
| 115 |
+
color: '#000000',
|
| 116 |
+
});
|
| 117 |
+
|
| 118 |
+
// Color picker for shape
|
| 119 |
+
var shapeColorpicker = tui.colorPicker.create({
|
| 120 |
+
container: $('#tui-shape-color-picker')[0],
|
| 121 |
+
color: '#000000',
|
| 122 |
+
});
|
| 123 |
+
|
| 124 |
+
// Color picker for icon
|
| 125 |
+
var iconColorpicker = tui.colorPicker.create({
|
| 126 |
+
container: $('#tui-icon-color-picker')[0],
|
| 127 |
+
color: '#000000',
|
| 128 |
+
});
|
| 129 |
+
|
| 130 |
+
var tintColorpicker = tui.colorPicker.create({
|
| 131 |
+
container: $('#tui-tint-color-picker')[0],
|
| 132 |
+
color: '#000000',
|
| 133 |
+
});
|
| 134 |
+
|
| 135 |
+
var multiplyColorpicker = tui.colorPicker.create({
|
| 136 |
+
container: $('#tui-multiply-color-picker')[0],
|
| 137 |
+
color: '#000000',
|
| 138 |
+
});
|
| 139 |
+
|
| 140 |
+
var blendColorpicker = tui.colorPicker.create({
|
| 141 |
+
container: $('#tui-blend-color-picker')[0],
|
| 142 |
+
color: '#00FF00',
|
| 143 |
+
});
|
| 144 |
+
|
| 145 |
+
// Common global functions
|
| 146 |
+
// HEX to RGBA
|
| 147 |
+
function hexToRGBa(hex, alpha) {
|
| 148 |
+
var r = parseInt(hex.slice(1, 3), 16);
|
| 149 |
+
var g = parseInt(hex.slice(3, 5), 16);
|
| 150 |
+
var b = parseInt(hex.slice(5, 7), 16);
|
| 151 |
+
var a = alpha || 1;
|
| 152 |
+
|
| 153 |
+
return 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';
|
| 154 |
+
}
|
| 155 |
+
|
| 156 |
+
function base64ToBlob(data) {
|
| 157 |
+
var mimeString = '';
|
| 158 |
+
var raw, uInt8Array, i, rawLength;
|
| 159 |
+
|
| 160 |
+
raw = data.replace(rImageType, function (header, imageType) {
|
| 161 |
+
mimeString = imageType;
|
| 162 |
+
|
| 163 |
+
return '';
|
| 164 |
+
});
|
| 165 |
+
|
| 166 |
+
raw = atob(raw);
|
| 167 |
+
rawLength = raw.length;
|
| 168 |
+
uInt8Array = new Uint8Array(rawLength); // eslint-disable-line
|
| 169 |
+
|
| 170 |
+
for (i = 0; i < rawLength; i += 1) {
|
| 171 |
+
uInt8Array[i] = raw.charCodeAt(i);
|
| 172 |
+
}
|
| 173 |
+
|
| 174 |
+
return new Blob([uInt8Array], { type: mimeString });
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
function resizeEditor() {
|
| 178 |
+
var $editor = $('.tui-image-editor');
|
| 179 |
+
var $container = $('.tui-image-editor-canvas-container');
|
| 180 |
+
var height = parseFloat($container.css('max-height'));
|
| 181 |
+
|
| 182 |
+
$editor.height(height);
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
function getBrushSettings() {
|
| 186 |
+
var brushWidth = parseInt($inputBrushWidthRange.val(), 10);
|
| 187 |
+
var brushColor = brushColorpicker.getColor();
|
| 188 |
+
|
| 189 |
+
return {
|
| 190 |
+
width: brushWidth,
|
| 191 |
+
color: hexToRGBa(brushColor, 0.5),
|
| 192 |
+
};
|
| 193 |
+
}
|
| 194 |
+
|
| 195 |
+
function activateShapeMode() {
|
| 196 |
+
if (imageEditor.getDrawingMode() !== 'SHAPE') {
|
| 197 |
+
imageEditor.stopDrawingMode();
|
| 198 |
+
imageEditor.startDrawingMode('SHAPE');
|
| 199 |
+
}
|
| 200 |
+
}
|
| 201 |
+
|
| 202 |
+
function activateIconMode() {
|
| 203 |
+
imageEditor.stopDrawingMode();
|
| 204 |
+
}
|
| 205 |
+
|
| 206 |
+
function activateTextMode() {
|
| 207 |
+
if (imageEditor.getDrawingMode() !== 'TEXT') {
|
| 208 |
+
imageEditor.stopDrawingMode();
|
| 209 |
+
imageEditor.startDrawingMode('TEXT');
|
| 210 |
+
}
|
| 211 |
+
}
|
| 212 |
+
|
| 213 |
+
function setTextToolbar(obj) {
|
| 214 |
+
var fontSize = obj.fontSize;
|
| 215 |
+
var fontColor = obj.fill;
|
| 216 |
+
|
| 217 |
+
$inputFontSizeRange.val(fontSize);
|
| 218 |
+
textColorpicker.setColor(fontColor);
|
| 219 |
+
}
|
| 220 |
+
|
| 221 |
+
function setIconToolbar(obj) {
|
| 222 |
+
var iconColor = obj.fill;
|
| 223 |
+
|
| 224 |
+
iconColorpicker.setColor(iconColor);
|
| 225 |
+
}
|
| 226 |
+
|
| 227 |
+
function setShapeToolbar(obj) {
|
| 228 |
+
var fillColor, isTransparent, isFilter;
|
| 229 |
+
var colorType = $selectColorType.val();
|
| 230 |
+
var changeValue = colorType === 'stroke' ? obj.stroke : obj.fill.type;
|
| 231 |
+
isTransparent = changeValue === 'transparent';
|
| 232 |
+
isFilter = changeValue === 'filter';
|
| 233 |
+
|
| 234 |
+
if (colorType === 'stroke') {
|
| 235 |
+
if (!isTransparent && !isFilter) {
|
| 236 |
+
shapeColorpicker.setColor(changeValue);
|
| 237 |
+
}
|
| 238 |
+
} else if (colorType === 'fill') {
|
| 239 |
+
if (!isTransparent && !isFilter) {
|
| 240 |
+
fillColor = obj.fill.color;
|
| 241 |
+
shapeColorpicker.setColor(fillColor);
|
| 242 |
+
}
|
| 243 |
+
}
|
| 244 |
+
|
| 245 |
+
$inputCheckTransparent.prop('checked', isTransparent);
|
| 246 |
+
$inputCheckFilter.prop('checked', isFilter);
|
| 247 |
+
$inputStrokeWidthRange.val(obj.strokeWidth);
|
| 248 |
+
}
|
| 249 |
+
|
| 250 |
+
function showSubMenu(type) {
|
| 251 |
+
var $submenu;
|
| 252 |
+
|
| 253 |
+
switch (type) {
|
| 254 |
+
case 'shape':
|
| 255 |
+
$submenu = $drawShapeSubMenu;
|
| 256 |
+
break;
|
| 257 |
+
case 'icon':
|
| 258 |
+
$submenu = $iconSubMenu;
|
| 259 |
+
break;
|
| 260 |
+
case 'text':
|
| 261 |
+
$submenu = $textSubMenu;
|
| 262 |
+
break;
|
| 263 |
+
default:
|
| 264 |
+
$submenu = 0;
|
| 265 |
+
}
|
| 266 |
+
|
| 267 |
+
$displayingSubMenu.hide();
|
| 268 |
+
$displayingSubMenu = $submenu.show();
|
| 269 |
+
}
|
| 270 |
+
|
| 271 |
+
function applyOrRemoveFilter(applying, type, options) {
|
| 272 |
+
if (applying) {
|
| 273 |
+
imageEditor.applyFilter(type, options).then(function (result) {
|
| 274 |
+
console.log(result);
|
| 275 |
+
});
|
| 276 |
+
} else {
|
| 277 |
+
imageEditor.removeFilter(type);
|
| 278 |
+
}
|
| 279 |
+
}
|
| 280 |
+
|
| 281 |
+
// Attach image editor custom events
|
| 282 |
+
imageEditor.on({
|
| 283 |
+
objectAdded: function (objectProps) {
|
| 284 |
+
console.info(objectProps);
|
| 285 |
+
},
|
| 286 |
+
undoStackChanged: function (length) {
|
| 287 |
+
if (length) {
|
| 288 |
+
$btnUndo.removeClass('disabled');
|
| 289 |
+
} else {
|
| 290 |
+
$btnUndo.addClass('disabled');
|
| 291 |
+
}
|
| 292 |
+
resizeEditor();
|
| 293 |
+
},
|
| 294 |
+
redoStackChanged: function (length) {
|
| 295 |
+
if (length) {
|
| 296 |
+
$btnRedo.removeClass('disabled');
|
| 297 |
+
} else {
|
| 298 |
+
$btnRedo.addClass('disabled');
|
| 299 |
+
}
|
| 300 |
+
resizeEditor();
|
| 301 |
+
},
|
| 302 |
+
objectScaled: function (obj) {
|
| 303 |
+
if (obj.type === 'text') {
|
| 304 |
+
$inputFontSizeRange.val(obj.fontSize);
|
| 305 |
+
}
|
| 306 |
+
},
|
| 307 |
+
addText: function (pos) {
|
| 308 |
+
imageEditor
|
| 309 |
+
.addText('Double Click', {
|
| 310 |
+
position: pos.originPosition,
|
| 311 |
+
})
|
| 312 |
+
.then(function (objectProps) {
|
| 313 |
+
console.log(objectProps);
|
| 314 |
+
});
|
| 315 |
+
},
|
| 316 |
+
objectActivated: function (obj) {
|
| 317 |
+
activeObjectId = obj.id;
|
| 318 |
+
if (obj.type === 'rect' || obj.type === 'circle' || obj.type === 'triangle') {
|
| 319 |
+
showSubMenu('shape');
|
| 320 |
+
setShapeToolbar(obj);
|
| 321 |
+
activateShapeMode();
|
| 322 |
+
} else if (obj.type === 'icon') {
|
| 323 |
+
showSubMenu('icon');
|
| 324 |
+
setIconToolbar(obj);
|
| 325 |
+
activateIconMode();
|
| 326 |
+
} else if (obj.type === 'text') {
|
| 327 |
+
showSubMenu('text');
|
| 328 |
+
setTextToolbar(obj);
|
| 329 |
+
activateTextMode();
|
| 330 |
+
}
|
| 331 |
+
},
|
| 332 |
+
mousedown: function (event, originPointer) {
|
| 333 |
+
if ($imageFilterSubMenu.is(':visible') && imageEditor.hasFilter('colorFilter')) {
|
| 334 |
+
imageEditor.applyFilter('colorFilter', {
|
| 335 |
+
x: parseInt(originPointer.x, 10),
|
| 336 |
+
y: parseInt(originPointer.y, 10),
|
| 337 |
+
});
|
| 338 |
+
}
|
| 339 |
+
},
|
| 340 |
+
});
|
| 341 |
+
|
| 342 |
+
// Attach button click event listeners
|
| 343 |
+
$btns.on('click', function () {
|
| 344 |
+
$btnsActivatable.removeClass('active');
|
| 345 |
+
});
|
| 346 |
+
|
| 347 |
+
$btnsActivatable.on('click', function () {
|
| 348 |
+
$(this).addClass('active');
|
| 349 |
+
});
|
| 350 |
+
|
| 351 |
+
$btnUndo.on('click', function () {
|
| 352 |
+
$displayingSubMenu.hide();
|
| 353 |
+
|
| 354 |
+
if (!$(this).hasClass('disabled')) {
|
| 355 |
+
imageEditor.discardSelection();
|
| 356 |
+
imageEditor.undo();
|
| 357 |
+
}
|
| 358 |
+
});
|
| 359 |
+
|
| 360 |
+
$btnRedo.on('click', function () {
|
| 361 |
+
$displayingSubMenu.hide();
|
| 362 |
+
|
| 363 |
+
if (!$(this).hasClass('disabled')) {
|
| 364 |
+
imageEditor.discardSelection();
|
| 365 |
+
imageEditor.redo();
|
| 366 |
+
}
|
| 367 |
+
});
|
| 368 |
+
|
| 369 |
+
$btnClearObjects.on('click', function () {
|
| 370 |
+
$displayingSubMenu.hide();
|
| 371 |
+
imageEditor.clearObjects();
|
| 372 |
+
});
|
| 373 |
+
|
| 374 |
+
$btnRemoveActiveObject.on('click', function () {
|
| 375 |
+
$displayingSubMenu.hide();
|
| 376 |
+
imageEditor.removeObject(activeObjectId);
|
| 377 |
+
});
|
| 378 |
+
|
| 379 |
+
$btnCrop.on('click', function () {
|
| 380 |
+
imageEditor.startDrawingMode('CROPPER');
|
| 381 |
+
$displayingSubMenu.hide();
|
| 382 |
+
$displayingSubMenu = $cropSubMenu.show();
|
| 383 |
+
});
|
| 384 |
+
|
| 385 |
+
$btnFlip.on('click', function () {
|
| 386 |
+
imageEditor.stopDrawingMode();
|
| 387 |
+
$displayingSubMenu.hide();
|
| 388 |
+
$displayingSubMenu = $flipSubMenu.show();
|
| 389 |
+
});
|
| 390 |
+
|
| 391 |
+
$btnRotation.on('click', function () {
|
| 392 |
+
imageEditor.stopDrawingMode();
|
| 393 |
+
$displayingSubMenu.hide();
|
| 394 |
+
$displayingSubMenu = $rotationSubMenu.show();
|
| 395 |
+
});
|
| 396 |
+
|
| 397 |
+
$btnClose.on('click', function () {
|
| 398 |
+
imageEditor.stopDrawingMode();
|
| 399 |
+
$displayingSubMenu.hide();
|
| 400 |
+
});
|
| 401 |
+
|
| 402 |
+
$btnApplyCrop.on('click', function () {
|
| 403 |
+
imageEditor.crop(imageEditor.getCropzoneRect()).then(function () {
|
| 404 |
+
imageEditor.stopDrawingMode();
|
| 405 |
+
resizeEditor();
|
| 406 |
+
});
|
| 407 |
+
});
|
| 408 |
+
|
| 409 |
+
$btnCancelCrop.on('click', function () {
|
| 410 |
+
imageEditor.stopDrawingMode();
|
| 411 |
+
});
|
| 412 |
+
|
| 413 |
+
$btnFlipX.on('click', function () {
|
| 414 |
+
imageEditor.flipX().then(function (status) {
|
| 415 |
+
console.log('flipX: ', status.flipX);
|
| 416 |
+
console.log('flipY: ', status.flipY);
|
| 417 |
+
console.log('angle: ', status.angle);
|
| 418 |
+
});
|
| 419 |
+
});
|
| 420 |
+
|
| 421 |
+
$btnFlipY.on('click', function () {
|
| 422 |
+
imageEditor.flipY().then(function (status) {
|
| 423 |
+
console.log('flipX: ', status.flipX);
|
| 424 |
+
console.log('flipY: ', status.flipY);
|
| 425 |
+
console.log('angle: ', status.angle);
|
| 426 |
+
});
|
| 427 |
+
});
|
| 428 |
+
|
| 429 |
+
$btnResetFlip.on('click', function () {
|
| 430 |
+
imageEditor.resetFlip().then(function (status) {
|
| 431 |
+
console.log('flipX: ', status.flipX);
|
| 432 |
+
console.log('flipY: ', status.flipY);
|
| 433 |
+
console.log('angle: ', status.angle);
|
| 434 |
+
});
|
| 435 |
+
});
|
| 436 |
+
|
| 437 |
+
$btnRotateClockwise.on('click', function () {
|
| 438 |
+
imageEditor.rotate(30);
|
| 439 |
+
});
|
| 440 |
+
|
| 441 |
+
$btnRotateCounterClockWise.on('click', function () {
|
| 442 |
+
imageEditor.rotate(-30);
|
| 443 |
+
});
|
| 444 |
+
|
| 445 |
+
$inputRotationRange.on('mousedown', function () {
|
| 446 |
+
var changeAngle = function () {
|
| 447 |
+
imageEditor.setAngle(parseInt($inputRotationRange.val(), 10))['catch'](function () {});
|
| 448 |
+
};
|
| 449 |
+
$(document).on('mousemove', changeAngle);
|
| 450 |
+
$(document).on('mouseup', function stopChangingAngle() {
|
| 451 |
+
$(document).off('mousemove', changeAngle);
|
| 452 |
+
$(document).off('mouseup', stopChangingAngle);
|
| 453 |
+
});
|
| 454 |
+
});
|
| 455 |
+
|
| 456 |
+
$inputRotationRange.on('change', function () {
|
| 457 |
+
imageEditor.setAngle(parseInt($inputRotationRange.val(), 10))['catch'](function () {});
|
| 458 |
+
});
|
| 459 |
+
|
| 460 |
+
$inputBrushWidthRange.on('change', function () {
|
| 461 |
+
imageEditor.setBrush({ width: parseInt(this.value, 10) });
|
| 462 |
+
});
|
| 463 |
+
|
| 464 |
+
$inputImage.on('change', function (event) {
|
| 465 |
+
var file;
|
| 466 |
+
|
| 467 |
+
if (!supportingFileAPI) {
|
| 468 |
+
alert('This browser does not support file-api');
|
| 469 |
+
}
|
| 470 |
+
|
| 471 |
+
file = event.target.files[0];
|
| 472 |
+
imageEditor.loadImageFromFile(file).then(function (result) {
|
| 473 |
+
console.log(result);
|
| 474 |
+
imageEditor.clearUndoStack();
|
| 475 |
+
});
|
| 476 |
+
});
|
| 477 |
+
|
| 478 |
+
$btnDownload.on('click', function () {
|
| 479 |
+
var imageName = imageEditor.getImageName();
|
| 480 |
+
var dataURL = imageEditor.toDataURL();
|
| 481 |
+
var blob, type, w;
|
| 482 |
+
|
| 483 |
+
if (supportingFileAPI) {
|
| 484 |
+
blob = base64ToBlob(dataURL);
|
| 485 |
+
type = blob.type.split('/')[1];
|
| 486 |
+
if (imageName.split('.').pop() !== type) {
|
| 487 |
+
imageName += '.' + type;
|
| 488 |
+
}
|
| 489 |
+
|
| 490 |
+
// Library: FileSaver - saveAs
|
| 491 |
+
saveAs(blob, imageName); // eslint-disable-line
|
| 492 |
+
} else {
|
| 493 |
+
alert('This browser needs a file-server');
|
| 494 |
+
w = window.open();
|
| 495 |
+
w.document.body.innerHTML = '<img src="' + dataURL + '">';
|
| 496 |
+
}
|
| 497 |
+
});
|
| 498 |
+
|
| 499 |
+
// control draw line mode
|
| 500 |
+
$btnDrawLine.on('click', function () {
|
| 501 |
+
imageEditor.stopDrawingMode();
|
| 502 |
+
$displayingSubMenu.hide();
|
| 503 |
+
$displayingSubMenu = $drawLineSubMenu.show();
|
| 504 |
+
$selectLine.eq(0).change();
|
| 505 |
+
});
|
| 506 |
+
|
| 507 |
+
$selectLine.on('change', function () {
|
| 508 |
+
var mode = $(this).val();
|
| 509 |
+
var settings = getBrushSettings();
|
| 510 |
+
|
| 511 |
+
imageEditor.stopDrawingMode();
|
| 512 |
+
if (mode === 'freeDrawing') {
|
| 513 |
+
imageEditor.startDrawingMode('FREE_DRAWING', settings);
|
| 514 |
+
} else {
|
| 515 |
+
imageEditor.startDrawingMode('LINE_DRAWING', settings);
|
| 516 |
+
}
|
| 517 |
+
});
|
| 518 |
+
|
| 519 |
+
brushColorpicker.on('selectColor', function (event) {
|
| 520 |
+
imageEditor.setBrush({
|
| 521 |
+
color: hexToRGBa(event.color, 0.5),
|
| 522 |
+
});
|
| 523 |
+
});
|
| 524 |
+
|
| 525 |
+
// control draw shape mode
|
| 526 |
+
$btnDrawShape.on('click', function () {
|
| 527 |
+
showSubMenu('shape');
|
| 528 |
+
|
| 529 |
+
// step 1. get options to draw shape from toolbar
|
| 530 |
+
shapeType = $('[name="select-shape-type"]:checked').val();
|
| 531 |
+
|
| 532 |
+
shapeOptions.stroke = '#000000';
|
| 533 |
+
shapeOptions.fill = '#ffffff';
|
| 534 |
+
|
| 535 |
+
shapeOptions.strokeWidth = Number($inputStrokeWidthRange.val());
|
| 536 |
+
|
| 537 |
+
// step 2. set options to draw shape
|
| 538 |
+
imageEditor.setDrawingShape(shapeType, shapeOptions);
|
| 539 |
+
|
| 540 |
+
// step 3. start drawing shape mode
|
| 541 |
+
activateShapeMode();
|
| 542 |
+
});
|
| 543 |
+
|
| 544 |
+
$selectShapeType.on('change', function () {
|
| 545 |
+
shapeType = $(this).val();
|
| 546 |
+
|
| 547 |
+
imageEditor.setDrawingShape(shapeType);
|
| 548 |
+
});
|
| 549 |
+
$selectColorType.on('change', function () {
|
| 550 |
+
var colorType = $(this).val();
|
| 551 |
+
if (colorType === 'stroke') {
|
| 552 |
+
$inputCheckFilter.prop('disabled', true);
|
| 553 |
+
$inputCheckFilter.prop('checked', false);
|
| 554 |
+
} else {
|
| 555 |
+
$inputCheckTransparent.prop('disabled', false);
|
| 556 |
+
$inputCheckFilter.prop('disabled', false);
|
| 557 |
+
}
|
| 558 |
+
});
|
| 559 |
+
|
| 560 |
+
$inputCheckTransparent.on('change', onChangeShapeFill);
|
| 561 |
+
$inputCheckFilter.on('change', onChangeShapeFill);
|
| 562 |
+
shapeColorpicker.on('selectColor', function (event) {
|
| 563 |
+
$inputCheckTransparent.prop('checked', false);
|
| 564 |
+
$inputCheckFilter.prop('checked', false);
|
| 565 |
+
onChangeShapeFill(event);
|
| 566 |
+
});
|
| 567 |
+
|
| 568 |
+
function onChangeShapeFill(event) {
|
| 569 |
+
var colorType = $selectColorType.val();
|
| 570 |
+
var isTransparent = $inputCheckTransparent.prop('checked');
|
| 571 |
+
var isFilter = $inputCheckFilter.prop('checked');
|
| 572 |
+
var shapeOption;
|
| 573 |
+
|
| 574 |
+
if (event.color) {
|
| 575 |
+
shapeOption = event.color;
|
| 576 |
+
} else if (isTransparent) {
|
| 577 |
+
shapeOption = 'transparent';
|
| 578 |
+
} else if (isFilter) {
|
| 579 |
+
shapeOption = {
|
| 580 |
+
type: 'filter',
|
| 581 |
+
filter: [{ pixelate: PIXELATE_FILTER_DEFAULT_VALUE }],
|
| 582 |
+
};
|
| 583 |
+
}
|
| 584 |
+
|
| 585 |
+
if (colorType === 'stroke') {
|
| 586 |
+
imageEditor.changeShape(activeObjectId, {
|
| 587 |
+
stroke: shapeOption,
|
| 588 |
+
});
|
| 589 |
+
} else if (colorType === 'fill') {
|
| 590 |
+
imageEditor.changeShape(activeObjectId, {
|
| 591 |
+
fill: shapeOption,
|
| 592 |
+
});
|
| 593 |
+
}
|
| 594 |
+
|
| 595 |
+
imageEditor.setDrawingShape(shapeType, shapeOptions);
|
| 596 |
+
}
|
| 597 |
+
|
| 598 |
+
$inputStrokeWidthRange.on('change', function () {
|
| 599 |
+
var strokeWidth = Number($(this).val());
|
| 600 |
+
|
| 601 |
+
imageEditor.changeShape(activeObjectId, {
|
| 602 |
+
strokeWidth: strokeWidth,
|
| 603 |
+
});
|
| 604 |
+
|
| 605 |
+
imageEditor.setDrawingShape(shapeType, shapeOptions);
|
| 606 |
+
});
|
| 607 |
+
|
| 608 |
+
// control text mode
|
| 609 |
+
$btnText.on('click', function () {
|
| 610 |
+
showSubMenu('text');
|
| 611 |
+
activateTextMode();
|
| 612 |
+
});
|
| 613 |
+
|
| 614 |
+
$inputFontSizeRange.on('change', function () {
|
| 615 |
+
imageEditor.changeTextStyle(activeObjectId, {
|
| 616 |
+
fontSize: parseInt(this.value, 10),
|
| 617 |
+
});
|
| 618 |
+
});
|
| 619 |
+
|
| 620 |
+
$btnTextStyle.on('click', function (e) {
|
| 621 |
+
// eslint-disable-line
|
| 622 |
+
var styleType = $(this).attr('data-style-type');
|
| 623 |
+
var styleObj;
|
| 624 |
+
|
| 625 |
+
e.stopPropagation();
|
| 626 |
+
|
| 627 |
+
switch (styleType) {
|
| 628 |
+
case 'b':
|
| 629 |
+
styleObj = { fontWeight: 'bold' };
|
| 630 |
+
break;
|
| 631 |
+
case 'i':
|
| 632 |
+
styleObj = { fontStyle: 'italic' };
|
| 633 |
+
break;
|
| 634 |
+
case 'u':
|
| 635 |
+
styleObj = { underline: true };
|
| 636 |
+
break;
|
| 637 |
+
case 'l':
|
| 638 |
+
styleObj = { textAlign: 'left' };
|
| 639 |
+
break;
|
| 640 |
+
case 'c':
|
| 641 |
+
styleObj = { textAlign: 'center' };
|
| 642 |
+
break;
|
| 643 |
+
case 'r':
|
| 644 |
+
styleObj = { textAlign: 'right' };
|
| 645 |
+
break;
|
| 646 |
+
default:
|
| 647 |
+
styleObj = {};
|
| 648 |
+
}
|
| 649 |
+
|
| 650 |
+
imageEditor.changeTextStyle(activeObjectId, styleObj);
|
| 651 |
+
});
|
| 652 |
+
|
| 653 |
+
textColorpicker.on('selectColor', function (event) {
|
| 654 |
+
imageEditor.changeTextStyle(activeObjectId, {
|
| 655 |
+
fill: event.color,
|
| 656 |
+
});
|
| 657 |
+
});
|
| 658 |
+
|
| 659 |
+
// control icon
|
| 660 |
+
$btnAddIcon.on('click', function () {
|
| 661 |
+
showSubMenu('icon');
|
| 662 |
+
activateIconMode();
|
| 663 |
+
});
|
| 664 |
+
|
| 665 |
+
function onClickIconSubMenu(event) {
|
| 666 |
+
var element = event.target || event.srcElement;
|
| 667 |
+
var iconType = $(element).attr('data-icon-type');
|
| 668 |
+
|
| 669 |
+
imageEditor.once('mousedown', function (e, originPointer) {
|
| 670 |
+
imageEditor
|
| 671 |
+
.addIcon(iconType, {
|
| 672 |
+
left: originPointer.x,
|
| 673 |
+
top: originPointer.y,
|
| 674 |
+
})
|
| 675 |
+
.then(function (objectProps) {
|
| 676 |
+
// console.log(objectProps);
|
| 677 |
+
});
|
| 678 |
+
});
|
| 679 |
+
}
|
| 680 |
+
|
| 681 |
+
$btnRegisterIcon.on('click', function () {
|
| 682 |
+
$iconSubMenu
|
| 683 |
+
.find('.menu-item')
|
| 684 |
+
.eq(3)
|
| 685 |
+
.after('<li id="customArrow" class="menu-item icon-text" data-icon-type="customArrow">↑</li>');
|
| 686 |
+
|
| 687 |
+
imageEditor.registerIcons({
|
| 688 |
+
customArrow: 'M 60 0 L 120 60 H 90 L 75 45 V 180 H 45 V 45 L 30 60 H 0 Z',
|
| 689 |
+
});
|
| 690 |
+
|
| 691 |
+
$btnRegisterIcon.off('click');
|
| 692 |
+
|
| 693 |
+
$iconSubMenu.on('click', '#customArrow', onClickIconSubMenu);
|
| 694 |
+
});
|
| 695 |
+
|
| 696 |
+
$iconSubMenu.on('click', '.icon-text', onClickIconSubMenu);
|
| 697 |
+
|
| 698 |
+
iconColorpicker.on('selectColor', function (event) {
|
| 699 |
+
imageEditor.changeIconColor(activeObjectId, event.color);
|
| 700 |
+
});
|
| 701 |
+
|
| 702 |
+
// control mask filter
|
| 703 |
+
$btnMaskFilter.on('click', function () {
|
| 704 |
+
imageEditor.stopDrawingMode();
|
| 705 |
+
$displayingSubMenu.hide();
|
| 706 |
+
|
| 707 |
+
$displayingSubMenu = $filterSubMenu.show();
|
| 708 |
+
});
|
| 709 |
+
|
| 710 |
+
$btnImageFilter.on('click', function () {
|
| 711 |
+
var filters = {
|
| 712 |
+
grayscale: $inputCheckGrayscale,
|
| 713 |
+
invert: $inputCheckInvert,
|
| 714 |
+
sepia: $inputCheckSepia,
|
| 715 |
+
sepia2: $inputCheckSepia2,
|
| 716 |
+
blur: $inputCheckBlur,
|
| 717 |
+
shapren: $inputCheckSharpen,
|
| 718 |
+
emboss: $inputCheckEmboss,
|
| 719 |
+
removeWhite: $inputCheckRemoveWhite,
|
| 720 |
+
brightness: $inputCheckBrightness,
|
| 721 |
+
noise: $inputCheckNoise,
|
| 722 |
+
pixelate: $inputCheckPixelate,
|
| 723 |
+
tint: $inputCheckTint,
|
| 724 |
+
multiply: $inputCheckMultiply,
|
| 725 |
+
blend: $inputCheckBlend,
|
| 726 |
+
colorFilter: $inputCheckColorFilter,
|
| 727 |
+
};
|
| 728 |
+
|
| 729 |
+
tui.util.forEach(filters, function ($value, key) {
|
| 730 |
+
$value.prop('checked', imageEditor.hasFilter(key));
|
| 731 |
+
});
|
| 732 |
+
$displayingSubMenu.hide();
|
| 733 |
+
|
| 734 |
+
$displayingSubMenu = $imageFilterSubMenu.show();
|
| 735 |
+
});
|
| 736 |
+
|
| 737 |
+
$btnLoadMaskImage.on('change', function () {
|
| 738 |
+
var file;
|
| 739 |
+
var imgUrl;
|
| 740 |
+
|
| 741 |
+
if (!supportingFileAPI) {
|
| 742 |
+
alert('This browser does not support file-api');
|
| 743 |
+
}
|
| 744 |
+
|
| 745 |
+
file = event.target.files[0];
|
| 746 |
+
|
| 747 |
+
if (file) {
|
| 748 |
+
imgUrl = URL.createObjectURL(file);
|
| 749 |
+
|
| 750 |
+
imageEditor.loadImageFromURL(imageEditor.toDataURL(), 'FilterImage').then(function () {
|
| 751 |
+
imageEditor.addImageObject(imgUrl).then(function (objectProps) {
|
| 752 |
+
URL.revokeObjectURL(file);
|
| 753 |
+
console.log(objectProps);
|
| 754 |
+
});
|
| 755 |
+
});
|
| 756 |
+
}
|
| 757 |
+
});
|
| 758 |
+
|
| 759 |
+
$btnApplyMask.on('click', function () {
|
| 760 |
+
imageEditor
|
| 761 |
+
.applyFilter('mask', {
|
| 762 |
+
maskObjId: activeObjectId,
|
| 763 |
+
})
|
| 764 |
+
.then(function (result) {
|
| 765 |
+
console.log(result);
|
| 766 |
+
});
|
| 767 |
+
});
|
| 768 |
+
|
| 769 |
+
$inputCheckGrayscale.on('change', function () {
|
| 770 |
+
applyOrRemoveFilter(this.checked, 'Grayscale', null);
|
| 771 |
+
});
|
| 772 |
+
|
| 773 |
+
$inputCheckInvert.on('change', function () {
|
| 774 |
+
applyOrRemoveFilter(this.checked, 'Invert', null);
|
| 775 |
+
});
|
| 776 |
+
|
| 777 |
+
$inputCheckSepia.on('change', function () {
|
| 778 |
+
applyOrRemoveFilter(this.checked, 'Sepia', null);
|
| 779 |
+
});
|
| 780 |
+
|
| 781 |
+
$inputCheckSepia2.on('change', function () {
|
| 782 |
+
applyOrRemoveFilter(this.checked, 'vintage', null);
|
| 783 |
+
});
|
| 784 |
+
|
| 785 |
+
$inputCheckBlur.on('change', function () {
|
| 786 |
+
applyOrRemoveFilter(this.checked, 'Blur', { blur: 0.1 });
|
| 787 |
+
});
|
| 788 |
+
|
| 789 |
+
$inputCheckSharpen.on('change', function () {
|
| 790 |
+
applyOrRemoveFilter(this.checked, 'Sharpen', null);
|
| 791 |
+
});
|
| 792 |
+
|
| 793 |
+
$inputCheckEmboss.on('change', function () {
|
| 794 |
+
applyOrRemoveFilter(this.checked, 'Emboss', null);
|
| 795 |
+
});
|
| 796 |
+
|
| 797 |
+
$inputCheckRemoveWhite.on('change', function () {
|
| 798 |
+
applyOrRemoveFilter(this.checked, 'removeColor', {
|
| 799 |
+
color: '#FFFFFF',
|
| 800 |
+
useAlpha: false,
|
| 801 |
+
distance: parseInt($inputRangeRemoveWhiteDistance.val(), 10) / 255,
|
| 802 |
+
});
|
| 803 |
+
});
|
| 804 |
+
|
| 805 |
+
$inputRangeRemoveWhiteDistance.on('change', function () {
|
| 806 |
+
applyOrRemoveFilter($inputCheckRemoveWhite.is(':checked'), 'removeColor', {
|
| 807 |
+
distance: parseInt(this.value, 10) / 255,
|
| 808 |
+
});
|
| 809 |
+
});
|
| 810 |
+
|
| 811 |
+
$inputCheckBrightness.on('change', function () {
|
| 812 |
+
applyOrRemoveFilter(this.checked, 'brightness', {
|
| 813 |
+
brightness: parseInt($inputRangeBrightnessValue.val(), 10) / 255,
|
| 814 |
+
});
|
| 815 |
+
});
|
| 816 |
+
|
| 817 |
+
$inputRangeBrightnessValue.on('change', function () {
|
| 818 |
+
applyOrRemoveFilter($inputCheckBrightness.is(':checked'), 'brightness', {
|
| 819 |
+
brightness: parseInt(this.value, 10) / 255,
|
| 820 |
+
});
|
| 821 |
+
});
|
| 822 |
+
|
| 823 |
+
$inputCheckNoise.on('change', function () {
|
| 824 |
+
applyOrRemoveFilter(this.checked, 'noise', {
|
| 825 |
+
noise: parseInt($inputRangeNoiseValue.val(), 10),
|
| 826 |
+
});
|
| 827 |
+
});
|
| 828 |
+
|
| 829 |
+
$inputRangeNoiseValue.on('change', function () {
|
| 830 |
+
applyOrRemoveFilter($inputCheckNoise.is(':checked'), 'noise', {
|
| 831 |
+
noise: parseInt(this.value, 10),
|
| 832 |
+
});
|
| 833 |
+
});
|
| 834 |
+
|
| 835 |
+
$inputCheckPixelate.on('change', function () {
|
| 836 |
+
applyOrRemoveFilter(this.checked, 'pixelate', {
|
| 837 |
+
blocksize: parseInt($inputRangePixelateValue.val(), 10),
|
| 838 |
+
});
|
| 839 |
+
});
|
| 840 |
+
|
| 841 |
+
$inputRangePixelateValue.on('change', function () {
|
| 842 |
+
applyOrRemoveFilter($inputCheckPixelate.is(':checked'), 'pixelate', {
|
| 843 |
+
blocksize: parseInt(this.value, 10),
|
| 844 |
+
});
|
| 845 |
+
});
|
| 846 |
+
|
| 847 |
+
$inputCheckTint.on('change', function () {
|
| 848 |
+
applyOrRemoveFilter(this.checked, 'blendColor', {
|
| 849 |
+
mode: 'tint',
|
| 850 |
+
color: tintColorpicker.getColor(),
|
| 851 |
+
alpha: parseFloat($inputRangeTintOpacityValue.val()),
|
| 852 |
+
});
|
| 853 |
+
});
|
| 854 |
+
|
| 855 |
+
tintColorpicker.on('selectColor', function (e) {
|
| 856 |
+
applyOrRemoveFilter($inputCheckTint.is(':checked'), 'blendColor', {
|
| 857 |
+
color: e.color,
|
| 858 |
+
});
|
| 859 |
+
});
|
| 860 |
+
|
| 861 |
+
$inputRangeTintOpacityValue.on('change', function () {
|
| 862 |
+
applyOrRemoveFilter($inputCheckTint.is(':checked'), 'blendColor', {
|
| 863 |
+
alpha: parseFloat($inputRangeTintOpacityValue.val()),
|
| 864 |
+
});
|
| 865 |
+
});
|
| 866 |
+
|
| 867 |
+
$inputCheckMultiply.on('change', function () {
|
| 868 |
+
applyOrRemoveFilter(this.checked, 'blendColor', {
|
| 869 |
+
color: multiplyColorpicker.getColor(),
|
| 870 |
+
});
|
| 871 |
+
});
|
| 872 |
+
|
| 873 |
+
multiplyColorpicker.on('selectColor', function (e) {
|
| 874 |
+
applyOrRemoveFilter($inputCheckMultiply.is(':checked'), 'blendColor', {
|
| 875 |
+
color: e.color,
|
| 876 |
+
});
|
| 877 |
+
});
|
| 878 |
+
|
| 879 |
+
$inputCheckBlend.on('change', function () {
|
| 880 |
+
applyOrRemoveFilter(this.checked, 'blendColor', {
|
| 881 |
+
mode: $selectBlendType.val(),
|
| 882 |
+
color: blendColorpicker.getColor(),
|
| 883 |
+
});
|
| 884 |
+
});
|
| 885 |
+
|
| 886 |
+
blendColorpicker.on('selectColor', function (e) {
|
| 887 |
+
applyOrRemoveFilter($inputCheckBlend.is(':checked'), 'blendColor', {
|
| 888 |
+
color: e.color,
|
| 889 |
+
});
|
| 890 |
+
});
|
| 891 |
+
|
| 892 |
+
$selectBlendType.on('change', function () {
|
| 893 |
+
applyOrRemoveFilter($inputCheckBlend.is(':checked'), 'blendColor', {
|
| 894 |
+
mode: this.value,
|
| 895 |
+
});
|
| 896 |
+
});
|
| 897 |
+
|
| 898 |
+
$inputCheckColorFilter.on('change', function () {
|
| 899 |
+
applyOrRemoveFilter(this.checked, 'removeColor', {
|
| 900 |
+
color: '#FFFFFF',
|
| 901 |
+
distance: $inputRangeColorFilterValue.val() / 255,
|
| 902 |
+
});
|
| 903 |
+
});
|
| 904 |
+
|
| 905 |
+
$inputRangeColorFilterValue.on('change', function () {
|
| 906 |
+
applyOrRemoveFilter($inputCheckColorFilter.is(':checked'), 'removeColor', {
|
| 907 |
+
distance: this.value / 255,
|
| 908 |
+
});
|
| 909 |
+
});
|
| 910 |
+
|
| 911 |
+
// Etc..
|
| 912 |
+
|
| 913 |
+
// Load sample image
|
| 914 |
+
imageEditor.loadImageFromURL('img/sampleImage.jpg', 'SampleImage').then(function (sizeValue) {
|
| 915 |
+
console.log(sizeValue);
|
| 916 |
+
imageEditor.clearUndoStack();
|
| 917 |
+
});
|
| 918 |
+
|
| 919 |
+
// IE9 Unselectable
|
| 920 |
+
$('.menu').on('selectstart', function () {
|
| 921 |
+
return false;
|
| 922 |
+
});
|
apps/image-editor/examples/js/service-mobile.js
ADDED
|
@@ -0,0 +1,595 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* eslint-disable vars-on-top,no-var,strict,prefer-template,prefer-arrow-callback,prefer-destructuring,object-shorthand,require-jsdoc,complexity */
|
| 2 |
+
'use strict';
|
| 3 |
+
|
| 4 |
+
var MAX_RESOLUTION = 3264 * 2448; // 8MP (Mega Pixel)
|
| 5 |
+
|
| 6 |
+
var supportingFileAPI = !!(window.File && window.FileList && window.FileReader);
|
| 7 |
+
var rImageType = /data:(image\/.+);base64,/;
|
| 8 |
+
var shapeOpt = {
|
| 9 |
+
fill: '#fff',
|
| 10 |
+
stroke: '#000',
|
| 11 |
+
strokeWidth: 10,
|
| 12 |
+
};
|
| 13 |
+
var activeObjectId;
|
| 14 |
+
|
| 15 |
+
// Selector of image editor controls
|
| 16 |
+
var submenuClass = '.submenu';
|
| 17 |
+
var hiddenmenuClass = '.hiddenmenu';
|
| 18 |
+
|
| 19 |
+
var $controls = $('.tui-image-editor-controls');
|
| 20 |
+
var $menuButtons = $controls.find('.menu-button');
|
| 21 |
+
var $submenuButtons = $controls.find('.submenu-button');
|
| 22 |
+
var $btnShowMenu = $controls.find('.btn-prev');
|
| 23 |
+
var $msg = $controls.find('.msg');
|
| 24 |
+
|
| 25 |
+
var $subMenus = $controls.find(submenuClass);
|
| 26 |
+
var $hiddenMenus = $controls.find(hiddenmenuClass);
|
| 27 |
+
|
| 28 |
+
// Image editor controls - top menu buttons
|
| 29 |
+
var $inputImage = $('#input-image-file');
|
| 30 |
+
var $btnDownload = $('#btn-download');
|
| 31 |
+
var $btnUndo = $('#btn-undo');
|
| 32 |
+
var $btnRedo = $('#btn-redo');
|
| 33 |
+
var $btnRemoveActiveObject = $('#btn-remove-active-object');
|
| 34 |
+
|
| 35 |
+
// Image editor controls - bottom menu buttons
|
| 36 |
+
var $btnCrop = $('#btn-crop');
|
| 37 |
+
var $btnAddText = $('#btn-add-text');
|
| 38 |
+
|
| 39 |
+
// Image editor controls - bottom submenu buttons
|
| 40 |
+
var $btnApplyCrop = $('#btn-apply-crop');
|
| 41 |
+
var $btnFlipX = $('#btn-flip-x');
|
| 42 |
+
var $btnFlipY = $('#btn-flip-y');
|
| 43 |
+
var $btnRotateClockwise = $('#btn-rotate-clockwise');
|
| 44 |
+
var $btnRotateCounterClockWise = $('#btn-rotate-counter-clockwise');
|
| 45 |
+
var $btnAddArrowIcon = $('#btn-add-arrow-icon');
|
| 46 |
+
var $btnAddCancelIcon = $('#btn-add-cancel-icon');
|
| 47 |
+
var $btnAddCustomIcon = $('#btn-add-custom-icon');
|
| 48 |
+
var $btnFreeDrawing = $('#btn-free-drawing');
|
| 49 |
+
var $btnLineDrawing = $('#btn-line-drawing');
|
| 50 |
+
var $btnAddRect = $('#btn-add-rect');
|
| 51 |
+
var $btnAddSquare = $('#btn-add-square');
|
| 52 |
+
var $btnAddEllipse = $('#btn-add-ellipse');
|
| 53 |
+
var $btnAddCircle = $('#btn-add-circle');
|
| 54 |
+
var $btnAddTriangle = $('#btn-add-triangle');
|
| 55 |
+
var $btnChangeTextStyle = $('.btn-change-text-style');
|
| 56 |
+
|
| 57 |
+
// Image editor controls - etc.
|
| 58 |
+
var $inputTextSizeRange = $('#input-text-size-range');
|
| 59 |
+
var $inputBrushWidthRange = $('#input-brush-range');
|
| 60 |
+
var $inputStrokeWidthRange = $('#input-stroke-range');
|
| 61 |
+
var $inputCheckTransparent = $('#input-check-transparent');
|
| 62 |
+
|
| 63 |
+
// Colorpicker
|
| 64 |
+
var iconColorpicker = tui.colorPicker.create({
|
| 65 |
+
container: $('#tui-icon-color-picker')[0],
|
| 66 |
+
color: '#000000',
|
| 67 |
+
});
|
| 68 |
+
|
| 69 |
+
var textColorpicker = tui.colorPicker.create({
|
| 70 |
+
container: $('#tui-text-color-picker')[0],
|
| 71 |
+
color: '#000000',
|
| 72 |
+
});
|
| 73 |
+
|
| 74 |
+
var brushColorpicker = tui.colorPicker.create({
|
| 75 |
+
container: $('#tui-brush-color-picker')[0],
|
| 76 |
+
color: '#000000',
|
| 77 |
+
});
|
| 78 |
+
|
| 79 |
+
var shapeColorpicker = tui.colorPicker.create({
|
| 80 |
+
container: $('#tui-shape-color-picker')[0],
|
| 81 |
+
color: '#000000',
|
| 82 |
+
});
|
| 83 |
+
|
| 84 |
+
// Create image editor
|
| 85 |
+
var imageEditor = new tui.ImageEditor('.tui-image-editor', {
|
| 86 |
+
cssMaxWidth: document.documentElement.clientWidth,
|
| 87 |
+
cssMaxHeight: document.documentElement.clientHeight,
|
| 88 |
+
selectionStyle: {
|
| 89 |
+
cornerSize: 50,
|
| 90 |
+
rotatingPointOffset: 100,
|
| 91 |
+
},
|
| 92 |
+
});
|
| 93 |
+
|
| 94 |
+
var $displayingSubMenu, $displayingHiddenMenu;
|
| 95 |
+
|
| 96 |
+
function hexToRGBa(hex, alpha) {
|
| 97 |
+
var r = parseInt(hex.slice(1, 3), 16);
|
| 98 |
+
var g = parseInt(hex.slice(3, 5), 16);
|
| 99 |
+
var b = parseInt(hex.slice(5, 7), 16);
|
| 100 |
+
var a = alpha || 1;
|
| 101 |
+
|
| 102 |
+
return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + a + ')';
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
function base64ToBlob(data) {
|
| 106 |
+
var mimeString = '';
|
| 107 |
+
var raw, uInt8Array, i, rawLength;
|
| 108 |
+
|
| 109 |
+
raw = data.replace(rImageType, function (header, imageType) {
|
| 110 |
+
mimeString = imageType;
|
| 111 |
+
|
| 112 |
+
return '';
|
| 113 |
+
});
|
| 114 |
+
|
| 115 |
+
raw = atob(raw);
|
| 116 |
+
rawLength = raw.length;
|
| 117 |
+
uInt8Array = new Uint8Array(rawLength); // eslint-disable-line
|
| 118 |
+
|
| 119 |
+
for (i = 0; i < rawLength; i += 1) {
|
| 120 |
+
uInt8Array[i] = raw.charCodeAt(i);
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
return new Blob([uInt8Array], { type: mimeString });
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
function getBrushSettings() {
|
| 127 |
+
var brushWidth = $inputBrushWidthRange.val();
|
| 128 |
+
var brushColor = brushColorpicker.getColor();
|
| 129 |
+
|
| 130 |
+
return {
|
| 131 |
+
width: brushWidth,
|
| 132 |
+
color: hexToRGBa(brushColor, 0.5),
|
| 133 |
+
};
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
function activateShapeMode() {
|
| 137 |
+
imageEditor.stopDrawingMode();
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
function activateIconMode() {
|
| 141 |
+
imageEditor.stopDrawingMode();
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
function activateTextMode() {
|
| 145 |
+
if (imageEditor.getDrawingMode() !== 'TEXT') {
|
| 146 |
+
imageEditor.stopDrawingMode();
|
| 147 |
+
imageEditor.startDrawingMode('TEXT');
|
| 148 |
+
}
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
function setTextToolbar(obj) {
|
| 152 |
+
var fontSize = obj.fontSize;
|
| 153 |
+
var fontColor = obj.fill;
|
| 154 |
+
|
| 155 |
+
$inputTextSizeRange.val(fontSize);
|
| 156 |
+
textColorpicker.setColor(fontColor);
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
function setIconToolbar(obj) {
|
| 160 |
+
var iconColor = obj.fill;
|
| 161 |
+
|
| 162 |
+
iconColorpicker.setColor(iconColor);
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
function setShapeToolbar(obj) {
|
| 166 |
+
var strokeColor, fillColor, isTransparent;
|
| 167 |
+
var colorType = $('[name="select-color-type"]:checked').val();
|
| 168 |
+
|
| 169 |
+
if (colorType === 'stroke') {
|
| 170 |
+
strokeColor = obj.stroke;
|
| 171 |
+
isTransparent = strokeColor === 'transparent';
|
| 172 |
+
|
| 173 |
+
if (!isTransparent) {
|
| 174 |
+
shapeColorpicker.setColor(strokeColor);
|
| 175 |
+
}
|
| 176 |
+
} else if (colorType === 'fill') {
|
| 177 |
+
fillColor = obj.fill;
|
| 178 |
+
isTransparent = fillColor === 'transparent';
|
| 179 |
+
|
| 180 |
+
if (!isTransparent) {
|
| 181 |
+
shapeColorpicker.setColor(fillColor);
|
| 182 |
+
}
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
$inputCheckTransparent.prop('checked', isTransparent);
|
| 186 |
+
$inputStrokeWidthRange.val(obj.strokeWith);
|
| 187 |
+
}
|
| 188 |
+
|
| 189 |
+
function showSubMenu(type) {
|
| 190 |
+
var index;
|
| 191 |
+
|
| 192 |
+
switch (type) {
|
| 193 |
+
case 'shape':
|
| 194 |
+
index = 3;
|
| 195 |
+
break;
|
| 196 |
+
case 'icon':
|
| 197 |
+
index = 4;
|
| 198 |
+
break;
|
| 199 |
+
case 'text':
|
| 200 |
+
index = 5;
|
| 201 |
+
break;
|
| 202 |
+
default:
|
| 203 |
+
index = 0;
|
| 204 |
+
}
|
| 205 |
+
|
| 206 |
+
$displayingSubMenu.hide();
|
| 207 |
+
$displayingHiddenMenu.hide();
|
| 208 |
+
|
| 209 |
+
$displayingSubMenu = $menuButtons.eq(index).parent().find(submenuClass).show();
|
| 210 |
+
}
|
| 211 |
+
|
| 212 |
+
// Bind custom event of image editor
|
| 213 |
+
imageEditor.on({
|
| 214 |
+
undoStackChanged: function (length) {
|
| 215 |
+
if (length) {
|
| 216 |
+
$btnUndo.removeClass('disabled');
|
| 217 |
+
} else {
|
| 218 |
+
$btnUndo.addClass('disabled');
|
| 219 |
+
}
|
| 220 |
+
},
|
| 221 |
+
redoStackChanged: function (length) {
|
| 222 |
+
if (length) {
|
| 223 |
+
$btnRedo.removeClass('disabled');
|
| 224 |
+
} else {
|
| 225 |
+
$btnRedo.addClass('disabled');
|
| 226 |
+
}
|
| 227 |
+
},
|
| 228 |
+
objectScaled: function (obj) {
|
| 229 |
+
if (obj.type === 'text') {
|
| 230 |
+
$inputTextSizeRange.val(obj.fontSize);
|
| 231 |
+
}
|
| 232 |
+
},
|
| 233 |
+
objectActivated: function (obj) {
|
| 234 |
+
activeObjectId = obj.id;
|
| 235 |
+
if (obj.type === 'rect' || obj.type === 'circle' || obj.type === 'triangle') {
|
| 236 |
+
showSubMenu('shape');
|
| 237 |
+
setShapeToolbar(obj);
|
| 238 |
+
activateShapeMode();
|
| 239 |
+
} else if (obj.type === 'icon') {
|
| 240 |
+
showSubMenu('icon');
|
| 241 |
+
setIconToolbar(obj);
|
| 242 |
+
activateIconMode();
|
| 243 |
+
} else if (obj.type === 'text') {
|
| 244 |
+
showSubMenu('text');
|
| 245 |
+
setTextToolbar(obj);
|
| 246 |
+
activateTextMode();
|
| 247 |
+
}
|
| 248 |
+
},
|
| 249 |
+
});
|
| 250 |
+
|
| 251 |
+
// Image editor controls action
|
| 252 |
+
$menuButtons.on('click', function () {
|
| 253 |
+
$displayingSubMenu = $(this).parent().find(submenuClass).show();
|
| 254 |
+
$displayingHiddenMenu = $(this).parent().find(hiddenmenuClass);
|
| 255 |
+
});
|
| 256 |
+
|
| 257 |
+
$submenuButtons.on('click', function () {
|
| 258 |
+
$displayingHiddenMenu.hide();
|
| 259 |
+
$displayingHiddenMenu = $(this).parent().find(hiddenmenuClass).show();
|
| 260 |
+
});
|
| 261 |
+
|
| 262 |
+
$btnShowMenu.on('click', function () {
|
| 263 |
+
$displayingSubMenu.hide();
|
| 264 |
+
$displayingHiddenMenu.hide();
|
| 265 |
+
$msg.show();
|
| 266 |
+
|
| 267 |
+
imageEditor.stopDrawingMode();
|
| 268 |
+
});
|
| 269 |
+
|
| 270 |
+
// Image load action
|
| 271 |
+
$inputImage.on('change', function (event) {
|
| 272 |
+
var file;
|
| 273 |
+
var img;
|
| 274 |
+
var resolution;
|
| 275 |
+
|
| 276 |
+
if (!supportingFileAPI) {
|
| 277 |
+
alert('This browser does not support file-api');
|
| 278 |
+
}
|
| 279 |
+
|
| 280 |
+
file = event.target.files[0];
|
| 281 |
+
|
| 282 |
+
if (file) {
|
| 283 |
+
img = new Image();
|
| 284 |
+
|
| 285 |
+
img.onload = function () {
|
| 286 |
+
resolution = this.width * this.height;
|
| 287 |
+
|
| 288 |
+
if (resolution <= MAX_RESOLUTION) {
|
| 289 |
+
imageEditor.loadImageFromFile(file).then(function () {
|
| 290 |
+
imageEditor.clearUndoStack();
|
| 291 |
+
});
|
| 292 |
+
} else {
|
| 293 |
+
alert("Loaded image's resolution is too large!\nRecommended resolution is 3264 * 2448!");
|
| 294 |
+
}
|
| 295 |
+
|
| 296 |
+
URL.revokeObjectURL(file);
|
| 297 |
+
};
|
| 298 |
+
|
| 299 |
+
img.src = URL.createObjectURL(file);
|
| 300 |
+
}
|
| 301 |
+
});
|
| 302 |
+
|
| 303 |
+
// Undo action
|
| 304 |
+
$btnUndo.on('click', function () {
|
| 305 |
+
if (!$(this).hasClass('disabled')) {
|
| 306 |
+
imageEditor.undo();
|
| 307 |
+
}
|
| 308 |
+
});
|
| 309 |
+
|
| 310 |
+
// Redo action
|
| 311 |
+
$btnRedo.on('click', function () {
|
| 312 |
+
if (!$(this).hasClass('disabled')) {
|
| 313 |
+
imageEditor.redo();
|
| 314 |
+
}
|
| 315 |
+
});
|
| 316 |
+
|
| 317 |
+
// Remove active object action
|
| 318 |
+
$btnRemoveActiveObject.on('click', function () {
|
| 319 |
+
imageEditor.removeObject(activeObjectId);
|
| 320 |
+
});
|
| 321 |
+
|
| 322 |
+
// Download action
|
| 323 |
+
$btnDownload.on('click', function () {
|
| 324 |
+
var imageName = imageEditor.getImageName();
|
| 325 |
+
var dataURL = imageEditor.toDataURL();
|
| 326 |
+
var blob, type, w;
|
| 327 |
+
|
| 328 |
+
if (supportingFileAPI) {
|
| 329 |
+
blob = base64ToBlob(dataURL);
|
| 330 |
+
type = blob.type.split('/')[1];
|
| 331 |
+
if (imageName.split('.').pop() !== type) {
|
| 332 |
+
imageName += '.' + type;
|
| 333 |
+
}
|
| 334 |
+
|
| 335 |
+
// Library: FileSaver - saveAs
|
| 336 |
+
saveAs(blob, imageName); // eslint-disable-line
|
| 337 |
+
} else {
|
| 338 |
+
alert('This browser needs a file-server');
|
| 339 |
+
w = window.open();
|
| 340 |
+
w.document.body.innerHTML = '<img src=' + dataURL + '>';
|
| 341 |
+
}
|
| 342 |
+
});
|
| 343 |
+
|
| 344 |
+
// Crop menu action
|
| 345 |
+
$btnCrop.on('click', function () {
|
| 346 |
+
imageEditor.startDrawingMode('CROPPER');
|
| 347 |
+
});
|
| 348 |
+
|
| 349 |
+
$btnApplyCrop.on('click', function () {
|
| 350 |
+
imageEditor.crop(imageEditor.getCropzoneRect()).then(function () {
|
| 351 |
+
imageEditor.stopDrawingMode();
|
| 352 |
+
$subMenus.removeClass('show');
|
| 353 |
+
$hiddenMenus.removeClass('show');
|
| 354 |
+
});
|
| 355 |
+
});
|
| 356 |
+
|
| 357 |
+
// Orientation menu action
|
| 358 |
+
$btnRotateClockwise.on('click', function () {
|
| 359 |
+
imageEditor.rotate(90);
|
| 360 |
+
});
|
| 361 |
+
|
| 362 |
+
$btnRotateCounterClockWise.on('click', function () {
|
| 363 |
+
imageEditor.rotate(-90);
|
| 364 |
+
});
|
| 365 |
+
|
| 366 |
+
$btnFlipX.on('click', function () {
|
| 367 |
+
imageEditor.flipX();
|
| 368 |
+
});
|
| 369 |
+
|
| 370 |
+
$btnFlipY.on('click', function () {
|
| 371 |
+
imageEditor.flipY();
|
| 372 |
+
});
|
| 373 |
+
|
| 374 |
+
// Icon menu action
|
| 375 |
+
$btnAddArrowIcon.on('click', function () {
|
| 376 |
+
imageEditor.addIcon('arrow');
|
| 377 |
+
});
|
| 378 |
+
|
| 379 |
+
$btnAddCancelIcon.on('click', function () {
|
| 380 |
+
imageEditor.addIcon('cancel');
|
| 381 |
+
});
|
| 382 |
+
|
| 383 |
+
$btnAddCustomIcon.on('click', function () {
|
| 384 |
+
imageEditor.addIcon('customArrow');
|
| 385 |
+
});
|
| 386 |
+
|
| 387 |
+
iconColorpicker.on('selectColor', function (event) {
|
| 388 |
+
imageEditor.changeIconColor(activeObjectId, event.color);
|
| 389 |
+
});
|
| 390 |
+
|
| 391 |
+
// Text menu action
|
| 392 |
+
$btnAddText.on('click', function () {
|
| 393 |
+
var initText = 'DoubleClick';
|
| 394 |
+
|
| 395 |
+
imageEditor.startDrawingMode('TEXT');
|
| 396 |
+
imageEditor.addText(initText, {
|
| 397 |
+
styles: {
|
| 398 |
+
fontSize: parseInt($inputTextSizeRange.val(), 10),
|
| 399 |
+
},
|
| 400 |
+
});
|
| 401 |
+
});
|
| 402 |
+
|
| 403 |
+
$btnChangeTextStyle.on('click', function () {
|
| 404 |
+
var styleType = $(this).attr('data-style-type');
|
| 405 |
+
var styleObj = {};
|
| 406 |
+
var styleObjKey;
|
| 407 |
+
|
| 408 |
+
switch (styleType) {
|
| 409 |
+
case 'bold':
|
| 410 |
+
styleObjKey = 'fontWeight';
|
| 411 |
+
break;
|
| 412 |
+
case 'italic':
|
| 413 |
+
styleObjKey = 'fontStyle';
|
| 414 |
+
break;
|
| 415 |
+
case 'underline':
|
| 416 |
+
styleObjKey = 'underline';
|
| 417 |
+
break;
|
| 418 |
+
case 'left':
|
| 419 |
+
styleObjKey = 'textAlign';
|
| 420 |
+
break;
|
| 421 |
+
case 'center':
|
| 422 |
+
styleObjKey = 'textAlign';
|
| 423 |
+
break;
|
| 424 |
+
case 'right':
|
| 425 |
+
styleObjKey = 'textAlign';
|
| 426 |
+
break;
|
| 427 |
+
default:
|
| 428 |
+
styleObjKey = '';
|
| 429 |
+
}
|
| 430 |
+
|
| 431 |
+
styleObj[styleObjKey] = styleType;
|
| 432 |
+
|
| 433 |
+
imageEditor.changeTextStyle(activeObjectId, styleObj);
|
| 434 |
+
});
|
| 435 |
+
|
| 436 |
+
$inputTextSizeRange.on('change', function () {
|
| 437 |
+
imageEditor.changeTextStyle(activeObjectId, {
|
| 438 |
+
fontSize: parseInt($(this).val(), 10),
|
| 439 |
+
});
|
| 440 |
+
});
|
| 441 |
+
|
| 442 |
+
textColorpicker.on('selectColor', function (event) {
|
| 443 |
+
imageEditor.changeTextStyle(activeObjectId, {
|
| 444 |
+
fill: event.color,
|
| 445 |
+
});
|
| 446 |
+
});
|
| 447 |
+
|
| 448 |
+
// Draw line menu action
|
| 449 |
+
$btnFreeDrawing.on('click', function () {
|
| 450 |
+
var settings = getBrushSettings();
|
| 451 |
+
|
| 452 |
+
imageEditor.stopDrawingMode();
|
| 453 |
+
imageEditor.startDrawingMode('FREE_DRAWING', settings);
|
| 454 |
+
});
|
| 455 |
+
|
| 456 |
+
$btnLineDrawing.on('click', function () {
|
| 457 |
+
var settings = getBrushSettings();
|
| 458 |
+
|
| 459 |
+
imageEditor.stopDrawingMode();
|
| 460 |
+
imageEditor.startDrawingMode('LINE_DRAWING', settings);
|
| 461 |
+
});
|
| 462 |
+
|
| 463 |
+
$inputBrushWidthRange.on('change', function () {
|
| 464 |
+
imageEditor.setBrush({
|
| 465 |
+
width: parseInt($(this).val(), 10),
|
| 466 |
+
});
|
| 467 |
+
});
|
| 468 |
+
|
| 469 |
+
brushColorpicker.on('selectColor', function (event) {
|
| 470 |
+
imageEditor.setBrush({
|
| 471 |
+
color: hexToRGBa(event.color, 0.5),
|
| 472 |
+
});
|
| 473 |
+
});
|
| 474 |
+
|
| 475 |
+
// Add shape menu action
|
| 476 |
+
$btnAddRect.on('click', function () {
|
| 477 |
+
imageEditor.addShape(
|
| 478 |
+
'rect',
|
| 479 |
+
tui.util.extend(
|
| 480 |
+
{
|
| 481 |
+
width: 500,
|
| 482 |
+
height: 300,
|
| 483 |
+
},
|
| 484 |
+
shapeOpt
|
| 485 |
+
)
|
| 486 |
+
);
|
| 487 |
+
});
|
| 488 |
+
|
| 489 |
+
$btnAddSquare.on('click', function () {
|
| 490 |
+
imageEditor.addShape(
|
| 491 |
+
'rect',
|
| 492 |
+
tui.util.extend(
|
| 493 |
+
{
|
| 494 |
+
width: 400,
|
| 495 |
+
height: 400,
|
| 496 |
+
isRegular: true,
|
| 497 |
+
},
|
| 498 |
+
shapeOpt
|
| 499 |
+
)
|
| 500 |
+
);
|
| 501 |
+
});
|
| 502 |
+
|
| 503 |
+
$btnAddEllipse.on('click', function () {
|
| 504 |
+
imageEditor.addShape(
|
| 505 |
+
'circle',
|
| 506 |
+
tui.util.extend(
|
| 507 |
+
{
|
| 508 |
+
rx: 300,
|
| 509 |
+
ry: 200,
|
| 510 |
+
},
|
| 511 |
+
shapeOpt
|
| 512 |
+
)
|
| 513 |
+
);
|
| 514 |
+
});
|
| 515 |
+
|
| 516 |
+
$btnAddCircle.on('click', function () {
|
| 517 |
+
imageEditor.addShape(
|
| 518 |
+
'circle',
|
| 519 |
+
tui.util.extend(
|
| 520 |
+
{
|
| 521 |
+
rx: 200,
|
| 522 |
+
ry: 200,
|
| 523 |
+
isRegular: true,
|
| 524 |
+
},
|
| 525 |
+
shapeOpt
|
| 526 |
+
)
|
| 527 |
+
);
|
| 528 |
+
});
|
| 529 |
+
|
| 530 |
+
$btnAddTriangle.on('click', function () {
|
| 531 |
+
imageEditor.addShape(
|
| 532 |
+
'triangle',
|
| 533 |
+
tui.util.extend(
|
| 534 |
+
{
|
| 535 |
+
width: 500,
|
| 536 |
+
height: 400,
|
| 537 |
+
isRegular: true,
|
| 538 |
+
},
|
| 539 |
+
shapeOpt
|
| 540 |
+
)
|
| 541 |
+
);
|
| 542 |
+
});
|
| 543 |
+
|
| 544 |
+
$inputStrokeWidthRange.on('change', function () {
|
| 545 |
+
imageEditor.changeShape(activeObjectId, {
|
| 546 |
+
strokeWidth: parseInt($(this).val(), 10),
|
| 547 |
+
});
|
| 548 |
+
});
|
| 549 |
+
|
| 550 |
+
$inputCheckTransparent.on('change', function () {
|
| 551 |
+
var colorType = $('[name="select-color-type"]:checked').val();
|
| 552 |
+
var isTransparent = $(this).prop('checked');
|
| 553 |
+
var color;
|
| 554 |
+
|
| 555 |
+
if (!isTransparent) {
|
| 556 |
+
color = shapeColorpicker.getColor();
|
| 557 |
+
} else {
|
| 558 |
+
color = 'transparent';
|
| 559 |
+
}
|
| 560 |
+
|
| 561 |
+
if (colorType === 'stroke') {
|
| 562 |
+
imageEditor.changeShape(activeObjectId, {
|
| 563 |
+
stroke: color,
|
| 564 |
+
});
|
| 565 |
+
} else if (colorType === 'fill') {
|
| 566 |
+
imageEditor.changeShape(activeObjectId, {
|
| 567 |
+
fill: color,
|
| 568 |
+
});
|
| 569 |
+
}
|
| 570 |
+
});
|
| 571 |
+
|
| 572 |
+
shapeColorpicker.on('selectColor', function (event) {
|
| 573 |
+
var colorType = $('[name="select-color-type"]:checked').val();
|
| 574 |
+
var isTransparent = $inputCheckTransparent.prop('checked');
|
| 575 |
+
var color = event.color;
|
| 576 |
+
|
| 577 |
+
if (isTransparent) {
|
| 578 |
+
return;
|
| 579 |
+
}
|
| 580 |
+
|
| 581 |
+
if (colorType === 'stroke') {
|
| 582 |
+
imageEditor.changeShape(activeObjectId, {
|
| 583 |
+
stroke: color,
|
| 584 |
+
});
|
| 585 |
+
} else if (colorType === 'fill') {
|
| 586 |
+
imageEditor.changeShape(activeObjectId, {
|
| 587 |
+
fill: color,
|
| 588 |
+
});
|
| 589 |
+
}
|
| 590 |
+
});
|
| 591 |
+
|
| 592 |
+
// Load sample image
|
| 593 |
+
imageEditor.loadImageFromURL('img/sampleImage.jpg', 'SampleImage').then(function () {
|
| 594 |
+
imageEditor.clearUndoStack();
|
| 595 |
+
});
|
apps/image-editor/examples/js/theme/black-theme.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
var blackTheme = {
|
| 2 |
+
'common.bi.image': 'https://uicdn.toast.com/toastui/img/tui-image-editor-bi.png',
|
| 3 |
+
'common.bisize.width': '251px',
|
| 4 |
+
'common.bisize.height': '21px',
|
| 5 |
+
'common.backgroundImage': 'none',
|
| 6 |
+
'common.backgroundColor': '#1e1e1e',
|
| 7 |
+
'common.border': '0px',
|
| 8 |
+
|
| 9 |
+
// header
|
| 10 |
+
'header.backgroundImage': 'none',
|
| 11 |
+
'header.backgroundColor': 'transparent',
|
| 12 |
+
'header.border': '0px',
|
| 13 |
+
|
| 14 |
+
// load button
|
| 15 |
+
'loadButton.backgroundColor': '#fff',
|
| 16 |
+
'loadButton.border': '1px solid #ddd',
|
| 17 |
+
'loadButton.color': '#222',
|
| 18 |
+
'loadButton.fontFamily': "'Noto Sans', sans-serif",
|
| 19 |
+
'loadButton.fontSize': '12px',
|
| 20 |
+
|
| 21 |
+
// download button
|
| 22 |
+
'downloadButton.backgroundColor': '#fdba3b',
|
| 23 |
+
'downloadButton.border': '1px solid #fdba3b',
|
| 24 |
+
'downloadButton.color': '#fff',
|
| 25 |
+
'downloadButton.fontFamily': "'Noto Sans', sans-serif",
|
| 26 |
+
'downloadButton.fontSize': '12px',
|
| 27 |
+
|
| 28 |
+
// main icons
|
| 29 |
+
'menu.normalIcon.color': '#8a8a8a',
|
| 30 |
+
'menu.activeIcon.color': '#555555',
|
| 31 |
+
'menu.disabledIcon.color': '#434343',
|
| 32 |
+
'menu.hoverIcon.color': '#e9e9e9',
|
| 33 |
+
'menu.iconSize.width': '24px',
|
| 34 |
+
'menu.iconSize.height': '24px',
|
| 35 |
+
|
| 36 |
+
// submenu icons
|
| 37 |
+
'submenu.normalIcon.color': '#8a8a8a',
|
| 38 |
+
'submenu.activeIcon.color': '#e9e9e9',
|
| 39 |
+
'submenu.iconSize.width': '32px',
|
| 40 |
+
'submenu.iconSize.height': '32px',
|
| 41 |
+
|
| 42 |
+
// submenu primary color
|
| 43 |
+
'submenu.backgroundColor': '#1e1e1e',
|
| 44 |
+
'submenu.partition.color': '#3c3c3c',
|
| 45 |
+
|
| 46 |
+
// submenu labels
|
| 47 |
+
'submenu.normalLabel.color': '#8a8a8a',
|
| 48 |
+
'submenu.normalLabel.fontWeight': 'lighter',
|
| 49 |
+
'submenu.activeLabel.color': '#fff',
|
| 50 |
+
'submenu.activeLabel.fontWeight': 'lighter',
|
| 51 |
+
|
| 52 |
+
// checkbox style
|
| 53 |
+
'checkbox.border': '0px',
|
| 54 |
+
'checkbox.backgroundColor': '#fff',
|
| 55 |
+
|
| 56 |
+
// range style
|
| 57 |
+
'range.pointer.color': '#fff',
|
| 58 |
+
'range.bar.color': '#666',
|
| 59 |
+
'range.subbar.color': '#d1d1d1',
|
| 60 |
+
|
| 61 |
+
'range.disabledPointer.color': '#414141',
|
| 62 |
+
'range.disabledBar.color': '#282828',
|
| 63 |
+
'range.disabledSubbar.color': '#414141',
|
| 64 |
+
|
| 65 |
+
'range.value.color': '#fff',
|
| 66 |
+
'range.value.fontWeight': 'lighter',
|
| 67 |
+
'range.value.fontSize': '11px',
|
| 68 |
+
'range.value.border': '1px solid #353535',
|
| 69 |
+
'range.value.backgroundColor': '#151515',
|
| 70 |
+
'range.title.color': '#fff',
|
| 71 |
+
'range.title.fontWeight': 'lighter',
|
| 72 |
+
|
| 73 |
+
// colorpicker style
|
| 74 |
+
'colorpicker.button.border': '1px solid #1e1e1e',
|
| 75 |
+
'colorpicker.title.color': '#fff',
|
| 76 |
+
};
|
apps/image-editor/examples/js/theme/white-theme.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
var whiteTheme = {
|
| 2 |
+
'common.bi.image': 'https://uicdn.toast.com/toastui/img/tui-image-editor-bi.png',
|
| 3 |
+
'common.bisize.width': '251px',
|
| 4 |
+
'common.bisize.height': '21px',
|
| 5 |
+
'common.backgroundImage': './img/bg.png',
|
| 6 |
+
'common.backgroundColor': '#fff',
|
| 7 |
+
'common.border': '1px solid #c1c1c1',
|
| 8 |
+
|
| 9 |
+
// header
|
| 10 |
+
'header.backgroundImage': 'none',
|
| 11 |
+
'header.backgroundColor': 'transparent',
|
| 12 |
+
'header.border': '0px',
|
| 13 |
+
|
| 14 |
+
// load button
|
| 15 |
+
'loadButton.backgroundColor': '#fff',
|
| 16 |
+
'loadButton.border': '1px solid #ddd',
|
| 17 |
+
'loadButton.color': '#222',
|
| 18 |
+
'loadButton.fontFamily': "'Noto Sans', sans-serif",
|
| 19 |
+
'loadButton.fontSize': '12px',
|
| 20 |
+
|
| 21 |
+
// download button
|
| 22 |
+
'downloadButton.backgroundColor': '#fdba3b',
|
| 23 |
+
'downloadButton.border': '1px solid #fdba3b',
|
| 24 |
+
'downloadButton.color': '#fff',
|
| 25 |
+
'downloadButton.fontFamily': "'Noto Sans', sans-serif",
|
| 26 |
+
'downloadButton.fontSize': '12px',
|
| 27 |
+
|
| 28 |
+
// main icons
|
| 29 |
+
'menu.normalIcon.color': '#8a8a8a',
|
| 30 |
+
'menu.activeIcon.color': '#555555',
|
| 31 |
+
'menu.disabledIcon.color': '#434343',
|
| 32 |
+
'menu.hoverIcon.color': '#e9e9e9',
|
| 33 |
+
'menu.iconSize.width': '24px',
|
| 34 |
+
'menu.iconSize.height': '24px',
|
| 35 |
+
|
| 36 |
+
// submenu icons
|
| 37 |
+
'submenu.normalIcon.color': '#8a8a8a',
|
| 38 |
+
'submenu.activeIcon.color': '#555555',
|
| 39 |
+
'submenu.iconSize.width': '32px',
|
| 40 |
+
'submenu.iconSize.height': '32px',
|
| 41 |
+
|
| 42 |
+
// submenu primary color
|
| 43 |
+
'submenu.backgroundColor': 'transparent',
|
| 44 |
+
'submenu.partition.color': '#e5e5e5',
|
| 45 |
+
|
| 46 |
+
// submenu labels
|
| 47 |
+
'submenu.normalLabel.color': '#858585',
|
| 48 |
+
'submenu.normalLabel.fontWeight': 'normal',
|
| 49 |
+
'submenu.activeLabel.color': '#000',
|
| 50 |
+
'submenu.activeLabel.fontWeight': 'normal',
|
| 51 |
+
|
| 52 |
+
// checkbox style
|
| 53 |
+
'checkbox.border': '1px solid #ccc',
|
| 54 |
+
'checkbox.backgroundColor': '#fff',
|
| 55 |
+
|
| 56 |
+
// rango style
|
| 57 |
+
'range.pointer.color': '#333',
|
| 58 |
+
'range.bar.color': '#ccc',
|
| 59 |
+
'range.subbar.color': '#606060',
|
| 60 |
+
|
| 61 |
+
'range.disabledPointer.color': '#d3d3d3',
|
| 62 |
+
'range.disabledBar.color': 'rgba(85,85,85,0.06)',
|
| 63 |
+
'range.disabledSubbar.color': 'rgba(51,51,51,0.2)',
|
| 64 |
+
|
| 65 |
+
'range.value.color': '#000',
|
| 66 |
+
'range.value.fontWeight': 'normal',
|
| 67 |
+
'range.value.fontSize': '11px',
|
| 68 |
+
'range.value.border': '0',
|
| 69 |
+
'range.value.backgroundColor': '#f5f5f5',
|
| 70 |
+
'range.title.color': '#000',
|
| 71 |
+
'range.title.fontWeight': 'lighter',
|
| 72 |
+
|
| 73 |
+
// colorpicker style
|
| 74 |
+
'colorpicker.button.border': '0px',
|
| 75 |
+
'colorpicker.title.color': '#000',
|
| 76 |
+
};
|
apps/image-editor/index.d.ts
ADDED
|
@@ -0,0 +1,334 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Type definitions for TOAST UI Image Editor v3.15.2
|
| 2 |
+
// TypeScript Version: 3.2.2
|
| 3 |
+
|
| 4 |
+
declare namespace tuiImageEditor {
|
| 5 |
+
type AngleType = number;
|
| 6 |
+
|
| 7 |
+
interface IThemeConfig {
|
| 8 |
+
'common.bi.image'?: string;
|
| 9 |
+
'common.bisize.width'?: string;
|
| 10 |
+
'common.bisize.height'?: string;
|
| 11 |
+
'common.backgroundImage'?: string;
|
| 12 |
+
'common.backgroundColor'?: string;
|
| 13 |
+
'common.border'?: string;
|
| 14 |
+
'header.backgroundImage'?: string;
|
| 15 |
+
'header.backgroundColor'?: string;
|
| 16 |
+
'header.border'?: string;
|
| 17 |
+
'loadButton.backgroundColor'?: string;
|
| 18 |
+
'loadButton.border'?: string;
|
| 19 |
+
'loadButton.color'?: string;
|
| 20 |
+
'loadButton.fontFamily'?: string;
|
| 21 |
+
'loadButton.fontSize'?: string;
|
| 22 |
+
'downloadButton.backgroundColor'?: string;
|
| 23 |
+
'downloadButton.border'?: string;
|
| 24 |
+
'downloadButton.color'?: string;
|
| 25 |
+
'downloadButton.fontFamily'?: string;
|
| 26 |
+
'downloadButton.fontSize'?: string;
|
| 27 |
+
'menu.normalIcon.path'?: string;
|
| 28 |
+
'menu.normalIcon.name'?: string;
|
| 29 |
+
'menu.activeIcon.path'?: string;
|
| 30 |
+
'menu.activeIcon.name'?: string;
|
| 31 |
+
'menu.iconSize.width'?: string;
|
| 32 |
+
'menu.iconSize.height'?: string;
|
| 33 |
+
'submenu.backgroundColor'?: string;
|
| 34 |
+
'submenu.partition.color'?: string;
|
| 35 |
+
'submenu.normalIcon.path'?: string;
|
| 36 |
+
'submenu.normalIcon.name'?: string;
|
| 37 |
+
'submenu.activeIcon.path'?: string;
|
| 38 |
+
'submenu.activeIcon.name'?: string;
|
| 39 |
+
'submenu.iconSize.width'?: string;
|
| 40 |
+
'submenu.iconSize.height'?: string;
|
| 41 |
+
'submenu.normalLabel.color'?: string;
|
| 42 |
+
'submenu.normalLabel.fontWeight'?: string;
|
| 43 |
+
'submenu.activeLabel.color'?: string;
|
| 44 |
+
'submenu.activeLabel.fontWeight'?: string;
|
| 45 |
+
'checkbox.border'?: string;
|
| 46 |
+
'checkbox.backgroundColor'?: string;
|
| 47 |
+
'range.pointer.color'?: string;
|
| 48 |
+
'range.bar.color'?: string;
|
| 49 |
+
'range.subbar.color'?: string;
|
| 50 |
+
'range.value.color'?: string;
|
| 51 |
+
'range.value.fontWeight'?: string;
|
| 52 |
+
'range.value.fontSize'?: string;
|
| 53 |
+
'range.value.border'?: string;
|
| 54 |
+
'range.value.backgroundColor'?: string;
|
| 55 |
+
'range.title.color'?: string;
|
| 56 |
+
'range.title.fontWeight'?: string;
|
| 57 |
+
'colorpicker.button.border'?: string;
|
| 58 |
+
'colorpicker.title.color'?: string;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
interface IIconInfo {
|
| 62 |
+
[propName: string]: string;
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
interface IIconOptions {
|
| 66 |
+
fill?: string;
|
| 67 |
+
left?: number;
|
| 68 |
+
top?: number;
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
interface IShapeOptions {
|
| 72 |
+
fill?: string;
|
| 73 |
+
stroke?: string;
|
| 74 |
+
strokeWidth?: number;
|
| 75 |
+
width?: number;
|
| 76 |
+
height?: number;
|
| 77 |
+
rx?: number;
|
| 78 |
+
ry?: number;
|
| 79 |
+
left?: number;
|
| 80 |
+
top?: number;
|
| 81 |
+
isRegular?: boolean;
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
interface IGenerateTextOptions {
|
| 85 |
+
styles?: ITextStyleConfig;
|
| 86 |
+
position?: {
|
| 87 |
+
x: number;
|
| 88 |
+
y: number;
|
| 89 |
+
};
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
type IFilterOptions =
|
| 93 |
+
| { blur: number }
|
| 94 |
+
| { brightness: number }
|
| 95 |
+
| { noise: number }
|
| 96 |
+
| { blocksize: number }
|
| 97 |
+
| { color: string; distance: number; useAlpha?: boolean }
|
| 98 |
+
| { mode: string; color: string; alpha?: number }
|
| 99 |
+
| { maskObjId: number };
|
| 100 |
+
|
| 101 |
+
interface ITextStyleConfig {
|
| 102 |
+
fill?: string;
|
| 103 |
+
fontFamily?: string;
|
| 104 |
+
fontSize?: number;
|
| 105 |
+
fontStyle?: string;
|
| 106 |
+
fontWeight?: string;
|
| 107 |
+
textAlign?: string;
|
| 108 |
+
textDecoration?: string;
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
interface IRectConfig {
|
| 112 |
+
left: number;
|
| 113 |
+
top: number;
|
| 114 |
+
width: number;
|
| 115 |
+
height: number;
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
interface ICanvasSize {
|
| 119 |
+
width: number;
|
| 120 |
+
height: number;
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
interface IBrushOptions {
|
| 124 |
+
width: number;
|
| 125 |
+
color: string;
|
| 126 |
+
}
|
| 127 |
+
|
| 128 |
+
interface IPositionConfig {
|
| 129 |
+
x: number;
|
| 130 |
+
y: number;
|
| 131 |
+
originX: string;
|
| 132 |
+
originY: string;
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
interface IToDataURLOptions {
|
| 136 |
+
format?: string;
|
| 137 |
+
quality?: number;
|
| 138 |
+
multiplier?: number;
|
| 139 |
+
left?: number;
|
| 140 |
+
top?: number;
|
| 141 |
+
width?: number;
|
| 142 |
+
height?: number;
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
interface IGraphicObjectProps {
|
| 146 |
+
id?: number;
|
| 147 |
+
type?: string;
|
| 148 |
+
text?: string;
|
| 149 |
+
left?: string | number;
|
| 150 |
+
top?: string | number;
|
| 151 |
+
width?: string | number;
|
| 152 |
+
height?: string | number;
|
| 153 |
+
fill?: string;
|
| 154 |
+
stroke?: string;
|
| 155 |
+
strokeWidth?: string | number;
|
| 156 |
+
fontFamily?: string;
|
| 157 |
+
fontSize?: number;
|
| 158 |
+
fontStyle?: string;
|
| 159 |
+
fontWeight?: string;
|
| 160 |
+
textAlign?: string;
|
| 161 |
+
textDecoration?: string;
|
| 162 |
+
opacity?: number;
|
| 163 |
+
[propName: string]: number | string | boolean | undefined;
|
| 164 |
+
}
|
| 165 |
+
|
| 166 |
+
interface IIncludeUIOptions {
|
| 167 |
+
loadImage?: {
|
| 168 |
+
path: string;
|
| 169 |
+
name: string;
|
| 170 |
+
};
|
| 171 |
+
theme?: IThemeConfig;
|
| 172 |
+
menu?: string[];
|
| 173 |
+
initMenu?: string;
|
| 174 |
+
uiSize?: {
|
| 175 |
+
width: string;
|
| 176 |
+
height: string;
|
| 177 |
+
};
|
| 178 |
+
menuBarPosition?: string;
|
| 179 |
+
usageStatistics?: boolean;
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
interface ISelectionStyleConfig {
|
| 183 |
+
cornerStyle?: string;
|
| 184 |
+
cornerSize?: number;
|
| 185 |
+
cornerColor?: string;
|
| 186 |
+
cornerStrokeColor?: string;
|
| 187 |
+
transparentCorners?: boolean;
|
| 188 |
+
lineWidth?: number;
|
| 189 |
+
borderColor?: string;
|
| 190 |
+
rotatingPointOffset?: number;
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
interface IObjectProps {
|
| 194 |
+
// icon, shape
|
| 195 |
+
fill: string;
|
| 196 |
+
height: number;
|
| 197 |
+
id: number;
|
| 198 |
+
left: number;
|
| 199 |
+
opacity: number;
|
| 200 |
+
stroke: string | null;
|
| 201 |
+
strokeWidth: number | null;
|
| 202 |
+
top: number;
|
| 203 |
+
type: string;
|
| 204 |
+
width: number;
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
interface ITextObjectProps extends IObjectProps {
|
| 208 |
+
fontFamily: string;
|
| 209 |
+
fontSize: string;
|
| 210 |
+
fontStyle: string;
|
| 211 |
+
text: string;
|
| 212 |
+
textAlign: string;
|
| 213 |
+
textDecoration: string;
|
| 214 |
+
}
|
| 215 |
+
|
| 216 |
+
interface IFilterResolveObject {
|
| 217 |
+
type: string;
|
| 218 |
+
action: string;
|
| 219 |
+
}
|
| 220 |
+
|
| 221 |
+
interface ICropResolveObject {
|
| 222 |
+
oldWidth: number;
|
| 223 |
+
oldHeight: number;
|
| 224 |
+
newWidth: number;
|
| 225 |
+
newHeight: number;
|
| 226 |
+
}
|
| 227 |
+
|
| 228 |
+
interface IFlipXYResolveObject {
|
| 229 |
+
flipX: boolean;
|
| 230 |
+
flipY: boolean;
|
| 231 |
+
angle: AngleType;
|
| 232 |
+
}
|
| 233 |
+
|
| 234 |
+
interface IOptions {
|
| 235 |
+
includeUI?: IIncludeUIOptions;
|
| 236 |
+
cssMaxWidth?: number;
|
| 237 |
+
cssMaxHeight?: number;
|
| 238 |
+
usageStatistics?: boolean;
|
| 239 |
+
selectionStyle?: ISelectionStyleConfig;
|
| 240 |
+
}
|
| 241 |
+
|
| 242 |
+
interface IUIDimension {
|
| 243 |
+
height?: string;
|
| 244 |
+
width?: string;
|
| 245 |
+
}
|
| 246 |
+
|
| 247 |
+
interface IImageDimension {
|
| 248 |
+
oldHeight?: number;
|
| 249 |
+
oldWidth?: number;
|
| 250 |
+
newHeight?: number;
|
| 251 |
+
newWidth?: number;
|
| 252 |
+
}
|
| 253 |
+
|
| 254 |
+
interface IEditorSize {
|
| 255 |
+
uiSize?: IUIDimension;
|
| 256 |
+
imageSize?: IImageDimension;
|
| 257 |
+
}
|
| 258 |
+
|
| 259 |
+
interface UI {
|
| 260 |
+
resizeEditor(dimension: IEditorSize): Promise<void>;
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
class ImageEditor {
|
| 264 |
+
constructor(wrapper: string | Element, options: IOptions);
|
| 265 |
+
public ui: UI;
|
| 266 |
+
|
| 267 |
+
public addIcon(type: string, options?: IIconOptions): Promise<IObjectProps>;
|
| 268 |
+
public addImageObject(imgUrl: string): Promise<void>;
|
| 269 |
+
public addShape(type: string, options?: IShapeOptions): Promise<IObjectProps>;
|
| 270 |
+
public addText(text: string, options?: IGenerateTextOptions): Promise<ITextObjectProps>;
|
| 271 |
+
public applyFilter(
|
| 272 |
+
type: string,
|
| 273 |
+
options?: IFilterOptions,
|
| 274 |
+
isSilent?: boolean
|
| 275 |
+
): Promise<IFilterResolveObject>;
|
| 276 |
+
public changeCursor(cursorType: string): void;
|
| 277 |
+
public changeIconColor(id: number, color: string): Promise<void>;
|
| 278 |
+
public changeSelectableAll(selectable: boolean): void;
|
| 279 |
+
public changeShape(id: number, options?: IShapeOptions, isSilent?: boolean): Promise<void>;
|
| 280 |
+
public changeText(id: number, text?: string): Promise<void>;
|
| 281 |
+
public changeTextStyle(
|
| 282 |
+
id: number,
|
| 283 |
+
styleObj: ITextStyleConfig,
|
| 284 |
+
isSilent?: boolean
|
| 285 |
+
): Promise<void>;
|
| 286 |
+
public clearObjects(): Promise<void>;
|
| 287 |
+
public clearRedoStack(): void;
|
| 288 |
+
public clearUndoStack(): void;
|
| 289 |
+
public crop(rect: IRectConfig): Promise<ICropResolveObject>;
|
| 290 |
+
public deactivateAll(): void;
|
| 291 |
+
public destroy(): void;
|
| 292 |
+
public discardSelection(): void;
|
| 293 |
+
public flipX(): Promise<IFlipXYResolveObject>;
|
| 294 |
+
public flipY(): Promise<IFlipXYResolveObject>;
|
| 295 |
+
public getCanvasSize(): ICanvasSize;
|
| 296 |
+
public getCropzoneRect(): IRectConfig;
|
| 297 |
+
public getDrawingMode(): string;
|
| 298 |
+
public getImageName(): string;
|
| 299 |
+
public getObjectPosition(id: number, originX: string, originY: string): ICanvasSize;
|
| 300 |
+
public getObjectProperties(
|
| 301 |
+
id: number,
|
| 302 |
+
keys: string | string[] | IGraphicObjectProps
|
| 303 |
+
): IGraphicObjectProps;
|
| 304 |
+
public hasFilter(type: string): boolean;
|
| 305 |
+
public isEmptyRedoStack(): boolean;
|
| 306 |
+
public isEmptyUndoStack(): boolean;
|
| 307 |
+
public loadImageFromFile(imgFile: File, imageName?: string): Promise<ICropResolveObject>;
|
| 308 |
+
public loadImageFromURL(url: string, imageName?: string): Promise<ICropResolveObject>;
|
| 309 |
+
public redo(iterationCount: number): Promise<any>;
|
| 310 |
+
public registerIcons(infos: IIconInfo): void;
|
| 311 |
+
public removeActiveObject(): void;
|
| 312 |
+
public removeFilter(type?: string): Promise<IFilterResolveObject>;
|
| 313 |
+
public removeObject(id: number): Promise<void>;
|
| 314 |
+
public resetFlip(): Promise<IFlipXYResolveObject>;
|
| 315 |
+
public resizeCanvasDimension(dimension: ICanvasSize): Promise<void>;
|
| 316 |
+
public rotate(angle: AngleType, isSilent?: boolean): Promise<AngleType>;
|
| 317 |
+
public setAngle(angle: AngleType, isSilent?: boolean): Promise<AngleType>;
|
| 318 |
+
public setBrush(option: IBrushOptions): void;
|
| 319 |
+
public setCropzoneRect(mode?: number): void;
|
| 320 |
+
public setDrawingShape(type: string, options?: IShapeOptions): void;
|
| 321 |
+
public setObjectPosition(id: number, posInfo?: IPositionConfig): Promise<void>;
|
| 322 |
+
public setObjectProperties(id: number, keyValue?: IGraphicObjectProps): Promise<void>;
|
| 323 |
+
public setObjectPropertiesQuietly(id: number, keyValue?: IGraphicObjectProps): Promise<void>;
|
| 324 |
+
public startDrawingMode(mode: string, option?: { width?: number; color?: string }): boolean;
|
| 325 |
+
public stopDrawingMode(): void;
|
| 326 |
+
public toDataURL(options?: IToDataURLOptions): string;
|
| 327 |
+
public undo(iterationCount: number): Promise<any>;
|
| 328 |
+
public on(eventName: string, handler: (...args: any[]) => void): void;
|
| 329 |
+
}
|
| 330 |
+
}
|
| 331 |
+
|
| 332 |
+
declare module 'tui-image-editor' {
|
| 333 |
+
export = tuiImageEditor.ImageEditor;
|
| 334 |
+
}
|
apps/image-editor/jest-setup.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
import 'jest-canvas-mock';
|
apps/image-editor/jest.config.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const path = require('path');
|
| 2 |
+
const setupFile = path.resolve(__dirname, './jest-setup.js');
|
| 3 |
+
|
| 4 |
+
module.exports = {
|
| 5 |
+
moduleFileExtensions: ['js'],
|
| 6 |
+
testEnvironment: 'jsdom',
|
| 7 |
+
transform: {
|
| 8 |
+
'^.+\\.js$': 'jest-esm-transformer',
|
| 9 |
+
'^.+\\.svg$': '<rootDir>/__mocks__/svgMock.js',
|
| 10 |
+
},
|
| 11 |
+
transformIgnorePatterns: ['<rootDir>/node_modules/'],
|
| 12 |
+
testMatch: ['<rootDir>/**/*.spec.js'],
|
| 13 |
+
clearMocks: true,
|
| 14 |
+
moduleNameMapper: {
|
| 15 |
+
'^@/(.*)$': '<rootDir>/src/js/$1',
|
| 16 |
+
'^@css/(.*)$': '<rootDir>/src/css/$1',
|
| 17 |
+
'^@svg/(.*)$': '<rootDir>/src/svg/$1',
|
| 18 |
+
'^fixtures/(.*)$': '<rootDir>/__mocks__/fileMock.js',
|
| 19 |
+
},
|
| 20 |
+
setupFiles: [setupFile],
|
| 21 |
+
};
|