Showing preview only (968K chars total). Download the full file or copy to clipboard to get everything.
Repository: nhn/tui.image-editor
Branch: master
Commit: 9ee993e21135
Files: 223
Total size: 905.1 KB
Directory structure:
gitextract__edmw0b4/
├── .editorconfig
├── .eslintrc.js
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── feature_request.md
│ │ └── question.md
│ ├── auto-comment.yml
│ ├── composite-actions/
│ │ ├── build-package/
│ │ │ └── action.yml
│ │ ├── install-dependencies/
│ │ │ └── action.yml
│ │ ├── publish-cdn/
│ │ │ └── action.yml
│ │ ├── publish-docs/
│ │ │ └── action.yml
│ │ └── publish-package/
│ │ └── action.yml
│ ├── stale.yml
│ └── workflows/
│ ├── detectRuntimeError.yml
│ ├── publish-docs.yml
│ ├── publish-npm.yml
│ └── publish-wrapper.yml
├── .gitignore
├── .prettierrc
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE.md
├── LICENSE
├── README.md
├── apps/
│ ├── image-editor/
│ │ ├── README.md
│ │ ├── __mocks__/
│ │ │ ├── fileMock.js
│ │ │ └── svgMock.js
│ │ ├── createConfigVariable.js
│ │ ├── examples/
│ │ │ ├── css/
│ │ │ │ ├── service-basic.css
│ │ │ │ ├── service-mobile.css
│ │ │ │ └── tui-example-style.css
│ │ │ ├── example01-includeUi.html
│ │ │ ├── example02-useApiDirect.html
│ │ │ ├── example03-mobile.html
│ │ │ ├── examples.json
│ │ │ └── js/
│ │ │ ├── service-basic.js
│ │ │ ├── service-mobile.js
│ │ │ └── theme/
│ │ │ ├── black-theme.js
│ │ │ └── white-theme.js
│ │ ├── index.d.ts
│ │ ├── jest-setup.js
│ │ ├── jest.config.js
│ │ ├── makesvg.js
│ │ ├── package.json
│ │ ├── scripts/
│ │ │ ├── publishToCDN.js
│ │ │ └── updateWrapper.js
│ │ ├── src/
│ │ │ ├── css/
│ │ │ │ ├── buttons.styl
│ │ │ │ ├── checkbox.styl
│ │ │ │ ├── colorpicker.styl
│ │ │ │ ├── gridtable.styl
│ │ │ │ ├── icon.styl
│ │ │ │ ├── index.styl
│ │ │ │ ├── main.styl
│ │ │ │ ├── position.styl
│ │ │ │ ├── range.styl
│ │ │ │ └── submenu.styl
│ │ │ ├── index.js
│ │ │ └── js/
│ │ │ ├── action.js
│ │ │ ├── command/
│ │ │ │ ├── addIcon.js
│ │ │ │ ├── addImageObject.js
│ │ │ │ ├── addObject.js
│ │ │ │ ├── addShape.js
│ │ │ │ ├── addText.js
│ │ │ │ ├── applyFilter.js
│ │ │ │ ├── changeIconColor.js
│ │ │ │ ├── changeSelection.js
│ │ │ │ ├── changeShape.js
│ │ │ │ ├── changeText.js
│ │ │ │ ├── changeTextStyle.js
│ │ │ │ ├── clearObjects.js
│ │ │ │ ├── flip.js
│ │ │ │ ├── loadImage.js
│ │ │ │ ├── removeFilter.js
│ │ │ │ ├── removeObject.js
│ │ │ │ ├── resize.js
│ │ │ │ ├── resizeCanvasDimension.js
│ │ │ │ ├── rotate.js
│ │ │ │ ├── setObjectPosition.js
│ │ │ │ └── setObjectProperties.js
│ │ │ ├── component/
│ │ │ │ ├── cropper.js
│ │ │ │ ├── filter.js
│ │ │ │ ├── flip.js
│ │ │ │ ├── freeDrawing.js
│ │ │ │ ├── icon.js
│ │ │ │ ├── imageLoader.js
│ │ │ │ ├── line.js
│ │ │ │ ├── resize.js
│ │ │ │ ├── rotation.js
│ │ │ │ ├── shape.js
│ │ │ │ ├── text.js
│ │ │ │ └── zoom.js
│ │ │ ├── consts.js
│ │ │ ├── drawingMode/
│ │ │ │ ├── cropper.js
│ │ │ │ ├── freeDrawing.js
│ │ │ │ ├── icon.js
│ │ │ │ ├── lineDrawing.js
│ │ │ │ ├── resize.js
│ │ │ │ ├── shape.js
│ │ │ │ ├── text.js
│ │ │ │ └── zoom.js
│ │ │ ├── extension/
│ │ │ │ ├── arrowLine.js
│ │ │ │ ├── blur.js
│ │ │ │ ├── colorFilter.js
│ │ │ │ ├── cropzone.js
│ │ │ │ ├── emboss.js
│ │ │ │ ├── mask.js
│ │ │ │ └── sharpen.js
│ │ │ ├── factory/
│ │ │ │ ├── command.js
│ │ │ │ └── errorMessage.js
│ │ │ ├── graphics.js
│ │ │ ├── helper/
│ │ │ │ ├── imagetracer.js
│ │ │ │ ├── selectionModifyHelper.js
│ │ │ │ ├── shapeFilterFillHelper.js
│ │ │ │ └── shapeResizeHelper.js
│ │ │ ├── imageEditor.js
│ │ │ ├── interface/
│ │ │ │ ├── command.js
│ │ │ │ ├── component.js
│ │ │ │ └── drawingMode.js
│ │ │ ├── invoker.js
│ │ │ ├── polyfill.js
│ │ │ ├── ui/
│ │ │ │ ├── crop.js
│ │ │ │ ├── draw.js
│ │ │ │ ├── filter.js
│ │ │ │ ├── flip.js
│ │ │ │ ├── history.js
│ │ │ │ ├── icon.js
│ │ │ │ ├── locale/
│ │ │ │ │ └── locale.js
│ │ │ │ ├── mask.js
│ │ │ │ ├── panelMenu.js
│ │ │ │ ├── resize.js
│ │ │ │ ├── rotate.js
│ │ │ │ ├── shape.js
│ │ │ │ ├── submenuBase.js
│ │ │ │ ├── template/
│ │ │ │ │ ├── controls.js
│ │ │ │ │ ├── mainContainer.js
│ │ │ │ │ ├── style.js
│ │ │ │ │ └── submenu/
│ │ │ │ │ ├── crop.js
│ │ │ │ │ ├── draw.js
│ │ │ │ │ ├── filter.js
│ │ │ │ │ ├── flip.js
│ │ │ │ │ ├── history.js
│ │ │ │ │ ├── icon.js
│ │ │ │ │ ├── mask.js
│ │ │ │ │ ├── resize.js
│ │ │ │ │ ├── rotate.js
│ │ │ │ │ ├── shape.js
│ │ │ │ │ ├── text.js
│ │ │ │ │ └── zoom.js
│ │ │ │ ├── text.js
│ │ │ │ ├── theme/
│ │ │ │ │ ├── standard.js
│ │ │ │ │ └── theme.js
│ │ │ │ └── tools/
│ │ │ │ ├── colorpicker.js
│ │ │ │ └── range.js
│ │ │ ├── ui.js
│ │ │ └── util.js
│ │ ├── tests/
│ │ │ ├── __snapshots__/
│ │ │ │ ├── arrowLine.spec.js.snap
│ │ │ │ ├── shape.spec.js.snap
│ │ │ │ ├── text.spec.js.snap
│ │ │ │ └── theme.spec.js.snap
│ │ │ ├── action.spec.js
│ │ │ ├── arrowLine.spec.js
│ │ │ ├── command.spec.js
│ │ │ ├── cropper.spec.js
│ │ │ ├── cropzone.spec.js
│ │ │ ├── drawingMode.spec.js
│ │ │ ├── filter.spec.js
│ │ │ ├── flip.spec.js
│ │ │ ├── graphics.spec.js
│ │ │ ├── history.spec.js
│ │ │ ├── icon.spec.js
│ │ │ ├── imageEditor.spec.js
│ │ │ ├── index.js
│ │ │ ├── invoker.spec.js
│ │ │ ├── line.spec.js
│ │ │ ├── promiseApi.spec.js
│ │ │ ├── resize.spec.js
│ │ │ ├── rotation.spec.js
│ │ │ ├── selectionModifyHelper.spec.js
│ │ │ ├── shape.spec.js
│ │ │ ├── text.spec.js
│ │ │ ├── theme.spec.js
│ │ │ ├── types/
│ │ │ │ ├── tsconfig.json
│ │ │ │ └── type-tests.ts
│ │ │ ├── ui.spec.js
│ │ │ ├── uiRange.spec.js
│ │ │ └── zoom.spec.js
│ │ ├── tsBannerGenerator.js
│ │ ├── tuidoc.config.json
│ │ ├── webpack.common.config.js
│ │ ├── webpack.config.js
│ │ ├── webpack.dev.config.js
│ │ └── webpack.prod.config.js
│ ├── react-image-editor/
│ │ ├── .babelrc.json
│ │ ├── .eslintrc.js
│ │ ├── .storybook/
│ │ │ ├── main.js
│ │ │ └── preview.js
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.js
│ │ ├── stories/
│ │ │ └── index.stories.js
│ │ └── webpack.config.js
│ └── vue-image-editor/
│ ├── .eslintrc.js
│ ├── .storybook/
│ │ ├── main.js
│ │ └── preview.js
│ ├── README.md
│ ├── package.json
│ ├── src/
│ │ ├── ImageEditor.vue
│ │ └── index.js
│ ├── stories/
│ │ └── index.stories.js
│ ├── vue.config.js
│ └── webpack.config.js
├── babel.config.json
├── bower.json
├── docs/
│ ├── Apply-Mobile-Version-Image.md
│ ├── Apply-Mobile-Version.md
│ ├── Basic-Tutorial.md
│ ├── COMMIT_MESSAGE_CONVENTION.md
│ ├── ISSUE_TEMPLATE.md
│ ├── ImageEditor-2.0.0-Migration-guide.md
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── Reference.md
│ └── Structure.md
├── lerna.json
└── package.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
================================================
FILE: .eslintrc.js
================================================
module.exports = {
root: true,
extends: ['tui/es6', 'plugin:jest/recommended', 'plugin:prettier/recommended'],
plugins: ['jest', 'prettier'],
env: {
browser: true,
amd: true,
node: true,
es6: true,
jest: true,
'jest/globals': true,
},
parser: '@babel/eslint-parser',
parserOptions: {
sourceType: 'module',
babelOptions: {
rootMode: 'upward',
},
},
ignorePatterns: ['node_modules/*', 'dist', 'examples'],
rules: {
'prefer-destructuring': [
'error',
{
VariableDeclarator: { array: true, object: true },
AssignmentExpression: { array: false, object: false },
},
],
},
overrides: [
{
files: ['*.spec.js'],
rules: {
'max-nested-callbacks': ['error', { max: 5 }],
'dot-notation': ['error', { allowKeywords: true }],
'no-undefined': 'off',
'jest/expect-expect': ['error', { assertFunctionNames: ['expect', 'assert*'] }],
},
},
],
};
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: Bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: Enhancement, Need Discussion
assignees: ''
---
<!--
Thank you for your contribution.
When it comes to write an issue, please, use the template below.
To use the template is mandatory for submit new issue and we won't reply the issue that without the template.
And you can write template's contents in Korean also.
-->
<!-- TEMPLATE -->
## Version
<!-- Write the version of the imageEditor you are currently using. -->
## Development Environment
<!-- Write the browser type, OS and so on -->
## Current Behavior
<!-- Write a description of the current operation. You can add sample code, 'CodePen' or 'jsfiddle' links. -->
```js
// Write example code
```
## Expected Behavior
<!-- Write a description of the future action. -->
================================================
FILE: .github/ISSUE_TEMPLATE/question.md
================================================
---
name: Question
about: Create a question about imageEditor
title: ''
labels: Question
assignees: ''
---
<!--
To make it easier for us to help you, please include as much useful information as possible.
Useful Links:
- tutorial: https://github.com/nhn/tui.image-editor/tree/master/docs
- API/Example: https://nhn.github.io/tui.image-editor/latest
Before opening a new issue, please search existing issues https://github.com/nhn/tui.image-editor/issues
-->
**Summary**
A clear and concise description of what the question is.
**Screenshots**
If applicable, add screenshots to help explain your question.
**Version**
Write the version of the imageEditor you are currently using.
**Additional context**
Add any other context about the problem here.
================================================
FILE: .github/auto-comment.yml
================================================
# Comment to a new issue.
issuesOpened: >
Thank you for raising an issue.
We will try and get back to you as soon as possible.
Please make sure you have filled out issue respecting our form **in English** and given us as much context as possible.
**If not, the issue will be closed or not replied.**
================================================
FILE: .github/composite-actions/build-package/action.yml
================================================
name: 'Build'
description: 'Build package'
inputs:
ROOT_CACHE_KEY:
description: 'Key of root dependencies cache'
required: true
BUILD_CACHE_KEY:
description: 'Key of build cache'
required: true
runs:
using: 'composite'
steps:
- name: Use Node.js 15.x
uses: actions/setup-node@v1
with:
node-version: '15.x'
registry-url: https://registry.npmjs.org/
- name: Check root dependencies cache
uses: actions/cache@v2
with:
path: ./node_modules
key: ${{ inputs.ROOT_CACHE_KEY }}
- name: Install package dependencies and remove package-lock file
working-directory: ./apps/image-editor
run: |
npm install && rm -rf ./package-lock.json
shell: bash
- name: Check build cache
uses: actions/cache@v2
id: cache_built_packages
with:
path: ./apps/image-editor/dist
key: ${{ inputs.BUILD_CACHE_KEY }}
- name: Build package
working-directory: ./apps/image-editor
run: |
if echo ${{ steps.cache_built_packages.outputs.cache-hit }} | grep -c "true"
then
echo "Cache hit - skipping building"
else
npm run build
fi
shell: bash
================================================
FILE: .github/composite-actions/install-dependencies/action.yml
================================================
name: 'Install root dependencies using cache'
description: 'Set Node.js version and install node_modules'
outputs:
root_cache_key:
description: 'Key of root dependencies cache'
value: ${{ steps.root_lockfile_hash.outputs.hash }}
runs:
using: 'composite'
steps:
- name: Use Node.js 15.x
uses: actions/setup-node@v1
with:
node-version: '15.x'
registry-url: https://registry.npmjs.org/
- name: Compute root dependencies cache key
id: root_lockfile_hash
run: echo "::set-output name=hash::${{ hashFiles('package-lock.json') }}"
shell: bash
- name: Check root dependencies cache
uses: actions/cache@v2
id: root_cache_dependencies
with:
path: ./node_modules
key: ${{ steps.root_lockfile_hash.outputs.hash }}
- name: Install root dependencies
run: |
if echo ${{ steps.root_cache_dependencies.outputs.cache-hit }} | grep -c "true"
then
echo "Cache hit - skipping root dependency installation"
else
npm install
fi
shell: bash
================================================
FILE: .github/composite-actions/publish-cdn/action.yml
================================================
name: 'Publish CDN'
description: 'Publish CDN'
inputs:
ROOT_CACHE_KEY:
description: 'Key of root dependencies cache'
required: true
BUILD_CACHE_KEY:
description: 'Key of build cache'
required: true
TOAST_CLOUD_TENANTID:
description: 'Tenant id for CDN'
required: true
TOAST_CLOUD_STORAGEID:
description: 'Storage id for CDN'
required: true
TOAST_CLOUD_USERNAME:
description: 'User name for CDN'
required: true
TOAST_CLOUD_PASSWORD:
description: 'password for CDN'
required: true
runs:
using: 'composite'
steps:
- name: Use Node.js 15.x
uses: actions/setup-node@v1
with:
node-version: '15.x'
registry-url: https://registry.npmjs.org/
- name: Check root dependencies cache
uses: actions/cache@v2
with:
path: ./node_modules
key: ${{ inputs.ROOT_CACHE_KEY }}
- name: Install package dependencies and remove package-lock file
working-directory: ./apps/image-editor
run: |
npm install && rm -rf ./package-lock.json
shell: bash
- name: Check build cache
uses: actions/cache@v2
with:
path: ./apps/image-editor/dist
key: ${{ inputs.BUILD_CACHE_KEY }}
- name: Upload files to CDN
working-directory: ./apps/image-editor
run: |
npm run publish:cdn
env:
TOAST_CLOUD_TENANTID: ${{ inputs.TOAST_CLOUD_TENANTID }}
TOAST_CLOUD_STORAGEID: ${{ inputs.TOAST_CLOUD_STORAGEID }}
TOAST_CLOUD_USERNAME: ${{ inputs.TOAST_CLOUD_USERNAME }}
TOAST_CLOUD_PASSWORD: ${{ inputs.TOAST_CLOUD_PASSWORD }}
shell: bash
================================================
FILE: .github/composite-actions/publish-docs/action.yml
================================================
name: 'Publish docs'
description: 'Publish docs'
inputs:
ROOT_CACHE_KEY:
description: 'Key of root dependencies cache'
required: true
BUILD_CACHE_KEY:
description: 'Key of build'
required: true
GITHUB_TOKEN:
description: 'Github token'
required: true
runs:
using: 'composite'
steps:
- name: Use Node.js 15.x
uses: actions/setup-node@v1
with:
node-version: '15.x'
registry-url: https://registry.npmjs.org/
- name: Get package version
id: version
uses: PostHog/check-package-version@v2
with:
path: ./apps/image-editor/
- name: Check root dependencies cache
uses: actions/cache@v2
with:
path: ./node_modules
key: ${{ inputs.ROOT_CACHE_KEY }}
- name: Install package dependencies and remove package-lock file
working-directory: ./apps/image-editor
run: |
npm install && rm -rf ./package-lock.json
shell: bash
- name: Check build cache
uses: actions/cache@v2
with:
path: ./apps/image-editor/dist
key: ${{ inputs.BUILD_CACHE_KEY }}
- name: Install toast-ui doc
run: npm i -g @toast-ui/doc
shell: bash
- name: Run doc
working-directory: ./apps/image-editor
run: |
npm run doc
mv _${{ steps.version.outputs.committed-version }} ../../_${{ steps.version.outputs.committed-version }}
mv -i _latest ../../_latest
rm -rf tmpdoc
git stash --include-untracked
shell: bash
- name: Checkout gh-pages branch
uses: actions/checkout@v2
with:
ref: gh-pages
- name: Commit files
run: |
git config --local user.name "lja1018"
git config --local user.email "jaeeon.lim@nhn.com"
rm -rf latest
rm -rf ${{ steps.version.outputs.committed-version }}
git stash pop
mv _${{ steps.version.outputs.committed-version }} ${{ steps.version.outputs.committed-version }}
mv -i _latest latest
git add .
git commit -m "v${{ steps.version.outputs.committed-version }}"
shell: bash
- name: Push changes
uses: ad-m/github-push-action@master
with:
github_token: ${{ inputs.GITHUB_TOKEN }}
branch: gh-pages
- name: Checkout branch
uses: actions/checkout@v2
with:
ref: master
================================================
FILE: .github/composite-actions/publish-package/action.yml
================================================
name: 'Publish package'
description: 'Publish package'
inputs:
ROOT_CACHE_KEY:
description: 'Key of root dependencies cache'
required: true
BUILD_CACHE_KEY:
description: 'Key of build cache'
required: true
NODE_AUTH_TOKEN:
description: 'NPM authorization token'
required: true
runs:
using: 'composite'
steps:
- name: Use Node.js 15.x
uses: actions/setup-node@v1
with:
node-version: '15.x'
registry-url: https://registry.npmjs.org/
- name: Checkout production branch
uses: actions/checkout@v2
with:
ref: production
- name: Check root dependencies cache
uses: actions/cache@v2
with:
path: ./node_modules
key: ${{ inputs.ROOT_CACHE_KEY }}
- name: Install package dependencies and remove package-lock file
working-directory: ./apps/image-editor
run: |
npm install && rm -rf ./package-lock.json
shell: bash
- name: Check build cache
uses: actions/cache@v2
with:
path: ./apps/image-editor/dist
key: ${{ inputs.BUILD_CACHE_KEY }}
- name: Publish package
working-directory: ./apps/image-editor
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ inputs.NODE_AUTH_TOKEN }}
shell: bash
================================================
FILE: .github/stale.yml
================================================
# Configuration for probot-stale - https://github.com/probot/stale
# Number of days of inactivity before an Issue or Pull Request becomes stale
daysUntilStale: 30
# Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
daysUntilClose: 7
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
exemptLabels:
- Feature
- Enhancement
- Bug
- NHN Cloud
# Label to use when marking as stale
staleLabel: inactive
# Comment to post when marking as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as inactive because there hasn’t been much going on it lately.
It is going to be closed after 7 days. Thanks!
# Comment to post when removing the stale label.
# unmarkComment: >
# Your comment here.
# Comment to post when closing a stale Issue or Pull Request.
closeComment: >
This issue will be closed due to inactivity. Thanks for your contribution!
================================================
FILE: .github/workflows/detectRuntimeError.yml
================================================
name: detect runtime error
on:
schedule:
- cron: '0 22 * * *'
jobs:
detectError:
runs-on: ubuntu-latest
env:
WORKING_DIRECTORY: ./apps/image-editor
steps:
- name: checkout repository
uses: actions/checkout@v2
- name: create config variable
working-directory: ${{ env.WORKING_DIRECTORY }}
run: |
node createConfigVariable.js
- name: set global error variable
working-directory: ${{ env.WORKING_DIRECTORY }}
run: |
errorVariable=`cat ./errorVariable.txt`
echo "ERROR_VARIABLE=$errorVariable" >> $GITHUB_ENV
- name: set url
working-directory: ${{ env.WORKING_DIRECTORY }}
shell: bash
run: |
url=`cat ./url.txt`
echo "URLS=$url" >> $GITHUB_ENV
- name: detect runtime error
uses: nhn/toast-ui.detect-runtime-error-actions@v1.0.1
with:
global-error-log-variable: ${{ env.ERROR_VARIABLE }}
urls: ${{ env.URLS }}
env:
BROWSERSTACK_USERNAME: ${{secrets.BROWSERSTACK_USERNAME}}
BROWSERSTACK_ACCESS_KEY: ${{secrets.BROWSERSTACK_ACCESS_KEY}}
================================================
FILE: .github/workflows/publish-docs.yml
================================================
name: Publish docs
on: [workflow_dispatch]
env:
BUILD_CACHE_KEY: ${{ github.sha }}
jobs:
install-dependencies:
name: Install dependencies
runs-on: ubuntu-latest
steps:
- name: Checkout branch
uses: actions/checkout@v2
- name: Install dependencies
id: cache-keys
uses: ./.github/composite-actions/install-dependencies
outputs:
root_cache_key: ${{ steps.cache-keys.outputs.root_cache_key }}
build:
name: Build package using cache
needs: [install-dependencies]
runs-on: ubuntu-latest
steps:
- name: Checkout branch
uses: actions/checkout@v2
with:
ref: production
- name: build
uses: ./.github/composite-actions/build-package
with:
ROOT_CACHE_KEY: ${{ needs.install-dependencies.outputs.root_cache_key }}
BUILD_CACHE_KEY: ${{ env.BUILD_CACHE_KEY }}
outputs:
root_cache_key: ${{ needs.install-dependencies.outputs.root_cache_key }}
publish-docs:
needs: [build]
name: Publish docs
runs-on: ubuntu-latest
steps:
- name: Checkout branch
uses: actions/checkout@v2
with:
ref: production
- name: Publish docs
uses: ./.github/composite-actions/publish-docs
with:
ROOT_CACHE_KEY: ${{ needs.build.outputs.root_cache_key }}
BUILD_CACHE_KEY: ${{ env.BUILD_CACHE_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .github/workflows/publish-npm.yml
================================================
name: Publish NPM
on: [workflow_dispatch]
env:
BUILD_CACHE_KEY: ${{ github.sha }}
jobs:
check-version:
name: Check package version
runs-on: ubuntu-latest
steps:
- name: Checkout production branch
uses: actions/checkout@v2
- name: Check package version
id: check
uses: PostHog/check-package-version@v2
with:
path: ./apps/image-editor/
- name: Cancel actions when version is unchanged
uses: andymckay/cancel-action@0.2
if: steps.check.outputs.is-new-version == 'false'
install-dependencies:
name: Install dependencies
needs: [check-version]
runs-on: ubuntu-latest
steps:
- name: Checkout production branch
uses: actions/checkout@v2
- name: Install dependencies
id: cache-keys
uses: ./.github/composite-actions/install-dependencies
outputs:
root_cache_key: ${{ steps.cache-keys.outputs.root_cache_key }}
build:
name: Build package using cache
needs: [install-dependencies]
runs-on: ubuntu-latest
steps:
- name: Checkout production branch
uses: actions/checkout@v2
with:
ref: production
- name: build
uses: ./.github/composite-actions/build-package
with:
ROOT_CACHE_KEY: ${{ needs.install-dependencies.outputs.root_cache_key }}
BUILD_CACHE_KEY: ${{ env.BUILD_CACHE_KEY }}
- name: Get package version
id: version
uses: PostHog/check-package-version@v2
with:
path: ./apps/image-editor/
- name: Commit files
run: |
git config --local user.name "lja1018"
git config --local user.email "jaeeon.lim@nhn.com"
git add .
git commit -m "chore: update version to v${{ steps.version.outputs.committed-version }}"
shell: bash
- name: Push built file
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: production
outputs:
root_cache_key: ${{ needs.install-dependencies.outputs.root_cache_key }}
push-tag:
needs: [build]
name: Push tag
runs-on: ubuntu-latest
steps:
- name: Checkout production branch
uses: actions/checkout@v2
with:
ref: production
- name: Use Node.js 15.x
uses: actions/setup-node@v1
with:
node-version: '15.x'
registry-url: https://registry.npmjs.org/
- name: Get package version
id: version
uses: PostHog/check-package-version@v2
with:
path: ./apps/image-editor/
- name: Create Tag
run: |
git config --local user.name "lja1018"
git config --local user.email "jaeeon.lim@nhn.com"
git tag v${{ steps.version.outputs.committed-version }}
- name: Push tag
run: |
git push origin v${{ steps.version.outputs.committed-version }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
publish-package:
needs: [build]
name: Publish package
runs-on: ubuntu-latest
steps:
- name: Checkout production branch
uses: actions/checkout@v2
with:
ref: production
- name: Publish package
uses: ./.github/composite-actions/publish-package
with:
ROOT_CACHE_KEY: ${{ needs.build.outputs.root_cache_key }}
BUILD_CACHE_KEY: ${{ env.BUILD_CACHE_KEY }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
publish-cdn:
needs: [build]
name: Publish CDN
runs-on: ubuntu-latest
steps:
- name: Checkout production branch
uses: actions/checkout@v2
with:
ref: production
- name: Publish CDN
uses: ./.github/composite-actions/publish-cdn
with:
ROOT_CACHE_KEY: ${{ needs.build.outputs.root_cache_key }}
BUILD_CACHE_KEY: ${{ env.BUILD_CACHE_KEY }}
TOAST_CLOUD_TENANTID: ${{ secrets.TOAST_CLOUD_TENANTID }}
TOAST_CLOUD_STORAGEID: ${{ secrets.TOAST_CLOUD_STORAGEID }}
TOAST_CLOUD_USERNAME: ${{ secrets.TOAST_CLOUD_USERNAME }}
TOAST_CLOUD_PASSWORD: ${{ secrets.TOAST_CLOUD_PASSWORD }}
publish-docs:
needs: [build]
name: Publish docs
runs-on: ubuntu-latest
steps:
- name: Checkout production branch
uses: actions/checkout@v2
with:
ref: production
- name: Publish docs
uses: ./.github/composite-actions/publish-docs
with:
ROOT_CACHE_KEY: ${{ needs.build.outputs.root_cache_key }}
BUILD_CACHE_KEY: ${{ env.BUILD_CACHE_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .github/workflows/publish-wrapper.yml
================================================
name: Publish wrapper
on: [workflow_dispatch]
env:
WORKING_DIRECTORY: ./apps/image-editor
REACT_WRAPPER_DIRECTORY: ./apps/react-image-editor
VUE_WRAPPER_DIRECTORY: ./apps/vue-image-editor
jobs:
publish-wrapper:
runs-on: ubuntu-latest
steps:
- name: Checkout branch
uses: actions/checkout@v2
- name: Install root dependencies
uses: ./.github/composite-actions/install-dependencies
- name: Use Node.js 15.x
uses: actions/setup-node@v1
with:
node-version: '15.x'
registry-url: https://registry.npmjs.org/
- name: Get package version
id: version
uses: PostHog/check-package-version@v2
with:
path: ${{ env.WORKING_DIRECTORY }}/
- name: Update version of wrappers in package.json
working-directory: ${{ env.WORKING_DIRECTORY }}
run: |
npm run update:wrapper
- name: Update lock file of react wrapper
working-directory: ${{ env.REACT_WRAPPER_DIRECTORY }}
run: |
npm install
- name: Build react wrapper
working-directory: ${{ env.REACT_WRAPPER_DIRECTORY }}
run: |
npm run build
- name: Update lock file of Vue wrapper
working-directory: ${{ env.VUE_WRAPPER_DIRECTORY }}
run: |
npm install
- name: Build vue wrapper
working-directory: ${{ env.VUE_WRAPPER_DIRECTORY }}
run: |
npm run build
- name: Commit files
run: |
rm -rf ./apps/react-image-editor/package-lock.json
rm -rf ./apps/vue-image-editor/package-lock.json
git config --local user.name "lja1018"
git config --local user.email "jaeeon.lim@nhn.com"
git add .
git commit -m "chore: update version of wrappers to v${{ steps.version.outputs.committed-version }}"
- name: Push changes
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: master
- name: Publish react wrapper
working-directory: ${{ env.REACT_WRAPPER_DIRECTORY }}
run: |
npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
- name: Publish vue wrapper
working-directory: ${{ env.VUE_WRAPPER_DIRECTORY }}
run: |
npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
================================================
FILE: .gitignore
================================================
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directory
# Deployed apps should consider commenting this line out:
# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
node_modules
# Bower Components
bower_components
lib
#JSDOC
doc
# IDEA
.idea
*.iml
# Window
Thumbs.db
Desktop.ini
# MAC
.DS_Store
# SVN
.svn
# eclipse
.project
.metadata
# build
build
# Atom
tags
.ctags
.tern-project
# etc
.agignore
*.swp
etc
temp
api
.tern-port
*.vim
.\#*
.vscode
dist
!_*/dist/
================================================
FILE: .prettierrc
================================================
{
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"quoteProps": "as-needed",
"jsxSingleQuote": false,
"trailingComma": "es5",
"arrowParens": "always",
"endOfLine": "lf",
"bracketSpacing": true,
"jsxBracketSameLine": false,
"requirePragma": false,
"insertPragma": false,
"proseWrap": "preserve",
"vueIndentScriptAndStyle": false
}
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
education, socio-economic status, nationality, personal appearance, race,
religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
- The use of sexualized language or imagery and unwelcome sexual attention or
advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic
address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at dl_javascript@nhn.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to TOAST UI
First off, thanks for taking the time to contribute! 🎉 😘 ✨
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.
## Reporting Bugs
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.
Explain the problem and include additional details to help maintainers reproduce the problem:
- **Use a clear and descriptive title** for the issue to identify the problem.
- **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.
- **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.
- **Describe the behavior you observed after following the steps** and point out what exactly is the problem with that behavior.
- **Explain which behavior you expected to see instead and why.**
- **Include screenshots and animated GIFs** which show you following the described steps and clearly demonstrate the problem.
## Suggesting Enhancements
In case you want to suggest for TOAST UI ImageEditor, please follow this guideline to help maintainers and the community understand your suggestion.
Before creating suggestions, please check [issue list](../../labels/enhancement) if there's already a request.
Create an issue and provide the following information:
- **Use a clear and descriptive title** for the issue to identify the suggestion.
- **Provide a step-by-step description of the suggested enhancement** in as many details as possible.
- **Provide specific examples to demonstrate the steps.** Include copy/pasteable snippets which you use in those examples, as Markdown code blocks.
- **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.
- **Explain why this enhancement would be useful** to most TOAST UI users.
- **List some other image editors or applications where this enhancement exists.**
## First Code Contribution
Unsure where to begin contributing to TOAST UI? You can start by looking through these `document`, `good first issue` and `help wanted` issues:
- **document issues**: issues which should be reviewed or improved.
- **good first issues**: issues which should only require a few lines of code, and a test or two.
- **help wanted issues**: issues which should be a bit more involved than beginner issues.
## Pull Requests
### Development WorkFlow
- Set up your development environment
- Make change from a right branch
- Be sure the code passes `npm run lint`, `npm run test`
- Make a pull request
### Development environment
- Prepare your machine node and it's packages installed.
- Checkout our repository
- Install dependencies by `npm install && bower install`
- Start webpack-dev-server by `npm run serve`
### Make changes
#### Checkout a branch
- **develop**: PR base branch. merge features, updates for next minor or major release
- **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.
- **production**: lastest release branch with distribution files. never make a PR on this
- **gh-pages**: API docs, examples and demo
#### Check Code Style
Run `npm run eslint` and make sure all the tests pass.
#### Test
Run `npm run test` and verify all the tests pass.
If you are adding new commands or features, they must include tests.
If you are changing functionality, update the tests if you need to.
#### Commit
Follow our [commit message conventions](./docs/COMMIT_MESSAGE_CONVENTION.md).
### Yes! Pull request
Make your pull request, then describe your changes.
#### Title
Follow other PR title format on below.
```
<Type>: Short Description (fix #111)
<Type>: Short Description (fix #123, #111, #122)
<Type>: Short Description (ref #111)
```
- capitalize first letter of Type
- use present tense: 'change' not 'changed' or 'changes'
#### Description
If it has related to issues, add links to the issues(like `#123`) in the description.
Fill in the [Pull Request Template](./docs/PULL_REQUEST_TEMPLATE.md) by check your case.
## Code of Conduct
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.
> 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)
================================================
FILE: ISSUE_TEMPLATE.md
================================================
<!--
Thank you for your contribution.
When it comes to write an issue, please, use the template below.
To use the template is mandatory for submit new issue and we won't reply the issue that without the template.
And you can write template's contents in Korean also.
-->
<!-- TEMPLATE -->
## Version
<!-- Write the version of the grid you are currently using. -->
## Development Environment
<!-- Write the browser type, OS and so on -->
## Current Behavior
<!-- Write a description of the current operation. You can add example code, 'CodePen' or 'jsfiddle' links. -->
```js
// Write example code
```
## Expected Behavior
<!-- Write a description of the future action. -->
================================================
FILE: LICENSE
================================================
The MIT License
Copyright (c) 2019 NHN Cloud Corp.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: README.md
================================================
# 
> Full featured image editor using HTML5 Canvas. It's easy to use and provides powerful filters.
[](https://github.com/nhn/tui.image-editor/releases/latest)
[](https://www.npmjs.com/package/tui-image-editor)
[](https://github.com/nhn/tui.image-editor/blob/master/LICENSE)
[](https://github.com/nhn/tui.image-editor/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22)
[](https://github.com/nhn)
[](https://lerna.js.org/)
## 📦 Packages
- [toast-ui.image-editor](https://github.com/nhn/tui.image-editor/tree/master/apps/image-editor
) - Plain JavaScript component implemented by [NHN Cloud](https://github.com/nhn).
- [toast-ui.vue-image-editor](https://github.com/nhn/tui.image-editor/tree/master/apps/vue-image-editor
) - **Vue** wrapper component is powered by [NHN Cloud](https://github.com/nhn).
- [toast-ui.react-image-editor](https://github.com/nhn/tui.image-editor/tree/master/apps/react-image-editor
) - **React** wrapper component is powered by [NHN Cloud](https://github.com/nhn).

## 🚩 Table of Contents
- [!Toast UI ImageEditor](#)
- [📦 Packages](#packages)
- [🚩 Table of Contents](#-table-of-contents)
- [🌏 Browser Support](#-browser-support)
- [💪 Has full features that stick to the basic.](#-has-full-features-that-stick-to-the-basic)
- [Photo manipulation](#photo-manipulation)
- [Integration function](#integration-function)
- [Powerful filter function](#powerful-filter-function)
- [🙆 Easy to apply the size and design you want](#-easy-to-apply-the-size-and-design-you-want)
- [Can be used everywhere.](#can-be-used-everywhere)
- [Nice default & Fully customizable Themes](#nice-default--fully-customizable-themes)
- [🎨 Features](#-features)
- [🔧 Pull Request Steps](#-pull-request-steps)
- [Setup](#setup)
- [Pull Request](#pull-request)
- [📙 Documents](#-documents)
- [💬 Contributing](#-contributing)
- [🔩 Dependency](#-dependency)
- [🍞 TOAST UI Family](#-toast-ui-family)
- [🚀 Used By](#-used-by)
- [📜 License](#-license)
## 🌏 Browser Support
| <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 |
| :--------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------: |
| Yes | 10+ | Yes | Yes | Yes |
## 💪 Has full features that stick to the basic.
### Photo manipulation
- Crop, Flip, Rotation, Drawing, Shape, Icon, Text, Mask Filter, Image Filter
### Integration function
- Download, Image Load, Undo, Redo, Reset, Delete Object(Shape, Line, Mask Image...)
<table>
<tbody>
<tr>
<th width="20%">Crop</th>
<th width="20%">Flip</th>
<th width="20%">Rotation</th>
<th width="20%">Drawing</th>
<th width="20%">Shape</th>
</tr>
<tr>
<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>
<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>
<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>
<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>
<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>
</tr>
<tr>
<th>Icon</th>
<th>Text</th>
<th>Mask</th>
<th>Filter</th>
<th></th>
</tr>
<tr>
<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>
<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>
<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>
<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>
<td></td>
</tr>
</tbody>
</table>
### Powerful filter function
- Grayscale, Invert, Sepia, Blur Sharpen, Emboss, RemoveWhite, Brightness, Noise, Pixelate, ColorFilter, Tint, Multiply, Blend
| Grayscale | Noise | Emboss | Pixelate |
| ------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
|  |  |  |  |
| Sepia | Sepia2 | Blend-righten | Blend-diff | Invert |
| -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
|  |  |  |  |  |
| Multifly | Tint | Brightness | Remove-white | Sharpen |
| ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
|  |  |  |  |  |
## 🙆 Easy to apply the size and design you want
### Can be used everywhere.
- Widely supported in browsers including IE10.
- Option to support various display sizes.
(allows you to use the editor features on your web pages at least over **550 \* 450 sizes**)

### Nice default & Fully customizable Themes
- Has a white and black theme, and you can modify the theme file to customize it.
- Has an API so that you can create your own instead of the built-in.
| black - top | black - bottom | white - left | white - right |
| --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
|  |  |  |  |
## 🎨 Features
- Load image to canvas
- Undo/Redo (With shortcut)
- Crop
- Flip
- Rotation
- Resize
- Free drawing
- Line drawing
- Shape
- Icon
- Text
- Mask Filter
- Image Filter
## 🔧 Pull Request Steps
TOAST UI products are open source, so you can create a pull request(PR) after you fix issues.
Run npm scripts and develop yourself with the following process.
### Setup
Fork `develop` branch into your personal repository.
Clone it to local computer. Install node modules.
Before starting development, you should check if there are any errors.
```sh
$ git clone https://github.com/{your-personal-repo}/[[repo name]].git
$ cd [[repo name]]
$ npm install
```
### Pull Request
Before uploading your PR, run test one last time to check if there are any errors.
If it has no errors, commit and then push it!
For more information on PR's steps, please see links in the Contributing section.
## 📙 Documents
- [Getting Started](https://github.com/nhn/tui.image-editor/tree/master/docs/Basic-Tutorial.md)
- [Tutorial](https://github.com/nhn/tui.image-editor/tree/master/docs)
- [Example](http://nhn.github.io/tui.image-editor/latest/tutorial-example01-includeUi)
- [API](http://nhn.github.io/tui.image-editor/latest)
## 💬 Contributing
- [Code of Conduct](https://github.com/nhn/tui.image-editor/blob/master/CODE_OF_CONDUCT.md)
- [Contributing guideline](https://github.com/nhn/tui.image-editor/blob/master/CONTRIBUTING.md)
- [Issue guideline](https://github.com/nhn/tui.image-editor/blob/master/ISSUE_TEMPLATE.md)
- [Commit convention](https://github.com/nhn/tui.image-editor/blob/production/docs/COMMIT_MESSAGE_CONVENTION.md)
## 🔩 Dependency
- [fabric.js](https://github.com/fabricjs/fabric.js/releases) = 4.2.0
- [tui.code-snippet](https://github.com/nhn/tui.code-snippet/releases/tag/v1.5.0) >= 1.5.0
- [tui.color-picker](https://github.com/nhn/tui.color-picker/releases/tag/v2.2.6) >= 2.2.6
## 🍞 TOAST UI Family
- [TOAST UI Editor](https://github.com/nhn/tui.editor)
- [TOAST UI Grid](https://github.com/nhn/tui.grid)
- [TOAST UI Chart](https://github.com/nhn/tui.chart)
- [TOAST UI Calendar](https://github.com/nhn/tui.calendar)
- [TOAST UI Components](https://github.com/nhn)
## 🚀 Used By
- [NHN Dooray! - Collaboration Service (Project, Messenger, Mail, Calendar, Drive, Wiki, Contacts)](https://dooray.com/home/)
- [Catalyst](https://catalystapp.co/)
## 📜 License
[MIT LICENSE](https://github.com/nhn/tui.image-editor/blob/master/LICENSE)
================================================
FILE: apps/image-editor/README.md
================================================
# 
> Full featured image editor using HTML5 Canvas. It's easy to use and provides powerful filters.
[](https://www.npmjs.com/package/tui-image-editor)
## 🚩 Table of Contents
- [Collect statistics on the use of open source](#Collect-statistics-on-the-use-of-open-source)
- [Install](#-install)
- [Via Package Manager](#via-package-manager)
- [Via Contents Delivery Network (CDN)](#via-contents-delivery-network-cdn)
- [Download Source Files](#download-source-files)
- [Usage](#-usage)
- [HTML](#html)
- [JavaScript](#javascript)
- [Menu svg icon setting](#menu-svg-icon-setting)
- [TypeScript](#typescript)
## Collect statistics on the use of open source
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.
```js
const options = {
//...
usageStatistics: false,
};
const imageEditor = new tui.ImageEditor('#tui-image-editor-container', options);
```
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:
```js
tui.usageStatistics = false;
```
## 💾 Install
The TOAST UI products can be installed by using the package manager or downloading the source directly.
However, we highly recommend using the package manager.
### Via Package Manager
You can find TOAST UI products via [npm](https://www.npmjs.com/) and [bower](https://bower.io/) package managers.
Install by using the commands provided by each package manager.
When using npm, be sure [Node.js](https://nodejs.org) is installed in the environment.
#### npm
##### 1. ImageEditor installation
```sh
$ npm install --save tui-image-editor # Latest version
$ npm install --save tui-image-editor@<version> # Specific version
```
##### 2. If the installation of the `fabric.js` dependency module does not go smoothly
To solve the problem, you need to refer to [Some Steps](https://github.com/fabricjs/fabric.js#install-with-npm) to solve the problem.
#### bower
```sh
$ bower install tui-image-editor # Latest version
$ bower install tui-image-editor#<tag> # Specific version
```
### Via Contents Delivery Network (CDN)
TOAST UI products are available over the CDN powered by [NHN Cloud](https://www.toast.com).
You can use the CDN as below.
```html
<link
rel="stylesheet"
href="https://uicdn.toast.com/tui-image-editor/latest/tui-image-editor.css"
/>
<script src="https://uicdn.toast.com/tui-image-editor/latest/tui-image-editor.js"></script>
```
If you want to use a specific version, use the tag name instead of `latest` in the URL.
The CDN directory has the following structure.
```
tui-image-editor/
├─ latest/
│ ├─ tui-image-editor.js
│ ├─ tui-image-editor.min.js
│ └─ tui-image-editor.css
├─ v3.1.0/
│ ├─ ...
```
### Download Source Files
- [Download bundle files from `dist` folder](https://github.com/nhn/tui.image-editor/tree/production/dist)
- [Download all sources for each version](https://github.com/nhn/tui.image-editor/releases)
## 🔨 Usage
### HTML
Add the container element where TOAST UI ImageEditor will be created.
```html
<body>
...
<div id="tui-image-editor"></div>
...
</body>
```
### javascript
Add dependencies & initialize ImageEditor class with given element to make an image editor.
```javascript
const ImageEditor = require('tui-image-editor');
const FileSaver = require('file-saver'); //to download edited image to local. Use after npm install file-saver
const blackTheme = require('./js/theme/black-theme.js');
const locale_ru_RU = {
// override default English locale to your custom
Crop: 'Обзрезать',
'Delete-all': 'Удалить всё',
// etc...
};
const instance = new ImageEditor(document.querySelector('#tui-image-editor'), {
includeUI: {
loadImage: {
path: 'img/sampleImage.jpg',
name: 'SampleImage',
},
locale: locale_ru_RU,
theme: blackTheme, // or whiteTheme
initMenu: 'filter',
menuBarPosition: 'bottom',
},
cssMaxWidth: 700,
cssMaxHeight: 500,
selectionStyle: {
cornerSize: 20,
rotatingPointOffset: 70,
},
});
```
Or
```javascript
const ImageEditor = require('tui-image-editor');
const instance = new ImageEditor(document.querySelector('#tui-image-editor'), {
cssMaxWidth: 700,
cssMaxHeight: 500,
selectionStyle: {
cornerSize: 20,
rotatingPointOffset: 70,
},
});
```
### Menu svg icon setting
#### There are two ways to set icons.
1. **Use default svg built** into imageEditor without setting svg file path (Features added since version v3.9.0).
2. There is a way to use the **actual physical svg file** and **set the file location manually**.
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).
### TypeScript
If you use TypeScript, You must `import module = require('module')` on importing.
[`export =` and `import = require()`](https://www.typescriptlang.org/docs/handbook/modules.html#export--and-import--require)
```typescript
import ImageEditor = require('tui-image-editor');
const FileSaver = require('file-saver'); //to download edited image to local. Use after npm install file-saver
const instance = new ImageEditor(document.querySelector('#tui-image-editor'), {
cssMaxWidth: 700,
cssMaxHeight: 500,
selectionStyle: {
cornerSize: 20,
rotatingPointOffset: 70,
},
});
```
See [details](https://nhn.github.io/tui.image-editor/latest) for additional information.
================================================
FILE: apps/image-editor/__mocks__/fileMock.js
================================================
const path = require('path');
module.exports = {
process(src, filename) {
return `module.exports = ${JSON.stringify(path.basename(filename))};`;
},
};
================================================
FILE: apps/image-editor/__mocks__/svgMock.js
================================================
module.exports = {
process() {
return `module.exports = 'PGRlZnMgaWQ9InR1aS1pbWFnZS1lZGl0b3Itc3ZnLWRlZmF1bHQtaWNvbnMiPg=='`;
},
};
================================================
FILE: apps/image-editor/createConfigVariable.js
================================================
const fs = require('fs');
const path = require('path');
const config = require(path.resolve(__dirname, 'tuidoc.config.json'));
const examples = config.examples || {};
const { filePath, globalErrorLogVariable } = examples;
/**
* Get Examples Url
*/
function getTestUrls() {
if (!filePath) {
throw Error('not exist examples path at tuidoc.config.json');
}
const urlPrefix = 'http://nhn.github.io/tui.image-editor/latest';
const testUrls = fs.readdirSync(filePath).reduce((urls, fileName) => {
if (/html$/.test(fileName)) {
urls.push(`${urlPrefix}/${filePath}/${fileName}`);
}
return urls;
}, []);
fs.writeFileSync('url.txt', testUrls.join(', '));
}
function getGlobalVariable() {
if (!globalErrorLogVariable) {
throw Error('not exist examples path at tuidoc.config.json');
}
fs.writeFileSync('errorVariable.txt', globalErrorLogVariable);
}
getTestUrls();
getGlobalVariable();
================================================
FILE: apps/image-editor/examples/css/service-basic.css
================================================
.border {
border: 1px solid black;
}
.body-container {
width: 1000px;
}
.tui-image-editor-controls {
min-height: 250px;
}
.menu {
padding: 0;
margin-bottom: 5px;
text-align: center;
color: #544b61;
font-weight: 400;
list-style-type: none;
user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-webkit-user-select: none;
}
.logo {
margin: 0 auto;
width: 300px;
vertical-align: middle;
}
.header .name {
padding: 10px;
line-height: 50px;
font-size: 30px;
font-weight: 100;
vertical-align: middle;
}
.header .menu {
display: inline-block;
}
.menu-item {
padding: 10px;
display: inline-block;
cursor: pointer;
vertical-align: middle;
}
.menu-item a {
text-decoration: none;
}
.menu-item.no-pointer {
cursor: default;
}
.menu-item.active,
.menu-item:hover {
background-color: #f3f3f3;
}
.menu-item.disabled {
cursor: default;
color: #bfbebe;
}
.align-left-top {
text-align: left;
vertical-align: top;
}
.range-narrow {
width: 80px;
}
.sub-menu-container {
font-size: 14px;
margin-bottom: 1em;
display: none;
}
.tui-image-editor {
height: 500px;
}
.tui-image-editor-canvas-container {
margin: 0 auto;
top: 50%;
transform: translateY(-50%);
-ms-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-webkit-transform: translateY(-50%);
border: 1px dashed black;
overflow: hidden;
}
.tui-colorpicker-container {
margin: 5px auto 0;
}
.tui-colorpicker-palette-toggle-slider {
display: none;
}
.input-wrapper {
position: relative;
}
.input-wrapper input {
cursor: pointer;
position: absolute;
font-size: 999px;
left: 0;
top: 0;
opacity: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
.btn-text-style {
padding: 5px;
margin: 3px 1px;
border: 1px dashed #bfbebe;
outline: 0;
background-color: #eee;
cursor: pointer;
}
.icon-text {
font-size: 20px;
}
.select-line-type {
outline: 0;
vertical-align: middle;
}
#tui-color-picker {
display: inline-block;
vertical-align: middle;
}
#tui-text-palette {
display: none;
position: absolute;
padding: 10px;
border: 1px solid #bfbebe;
background-color: #fff;
z-index: 9999;
}
================================================
FILE: apps/image-editor/examples/css/service-mobile.css
================================================
html,
body {
margin: 0;
padding: 0;
height: 100%;
overflow: hidden;
background-color: #383838;
font-family: Sans-Serif;
}
ul,
li {
list-style: none;
margin: 0;
padding: 0;
}
input[type='button'],
button {
-webkit-appearance: none;
-moz-appearance: none;
background-color: #fff;
}
input[type='file'] {
position: absolute;
margin: 0;
padding: 0;
top: 0;
left: 0;
width: 100%;
height: 100%;
cursor: pointer;
opacity: 0;
filter: alpha(opacity=0);
}
.header {
position: fixed;
left: 0;
top: 0;
width: 100%;
background-color: #fff;
text-align: center;
z-index: 9999;
}
.header .logo {
margin: 10px 5px;
width: 180px;
vertical-align: middle;
}
.header .name {
font-size: 16px;
font-weight: bold;
}
.header .menu {
padding: 10px;
background-color: #000;
}
.header .menu input {
opacity: 0;
}
.header .menu img {
width: 20px;
height: 20px;
vertical-align: middle;
}
.header .button {
position: relative;
display: inline-block;
margin: 0 5px;
padding: 0;
border-radius: 5px 5px;
width: 30px;
height: 30px;
border: 0;
background-color: #fff;
vertical-align: middle;
}
.header .button.disabled img {
opacity: 0.5;
}
.tui-image-editor {
height: 100%;
}
.tui-image-editor-canvas-container {
margin: 0 auto;
top: 50%;
transform: translateY(-50%);
-ms-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-webkit-transform: translateY(-50%);
overflow: hidden;
}
.tui-image-editor-controls {
position: fixed;
width: 100%;
left: 0;
bottom: 0;
background-color: #fff;
}
.tui-image-editor-controls .scrollable {
display: inline-block;
overflow-x: auto;
width: 100%;
height: 100%;
white-space: nowrap;
font-size: 0;
background-color: #000;
vertical-align: middle;
}
.tui-image-editor-controls .no-scrollable {
overflow-x: hidden;
}
.tui-image-editor-controls .menu-item {
display: inline-block;
height: 80px;
border-right: 1px solid #383838;
background-color: #ddd;
vertical-align: middle;
}
.tui-image-editor-controls .menu-button {
width: 80px;
height: 80px;
border: none;
vertical-align: middle;
background-color: #000;
color: #fff;
font-size: 12px;
font-weight: bold;
outline: 0;
}
.tui-image-editor-controls .submenu-button {
width: 80px;
height: 80px;
border: none;
background-color: #ddd;
vertical-align: middle;
}
.tui-image-editor-controls .hiddenmenu-button {
margin: 0 10px;
padding: 5px;
border: none;
color: #fff;
background-color: rgba(255, 255, 255, 0);
}
.tui-image-editor-controls .submenu {
display: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
font-size: 0;
}
.tui-image-editor-controls .submenu.show {
display: block;
}
.tui-image-editor-controls .submenu .menu-item:last-child {
margin-right: 50px;
}
.tui-image-editor-controls .hiddenmenu {
position: absolute;
display: none;
padding: 40px;
width: 100%;
left: 0;
bottom: 80px;
background-color: rgba(0, 0, 0, 0.7);
text-align: center;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
z-index: 9999;
}
.tui-image-editor-controls .hiddenmenu.show {
display: block;
}
.tui-image-editor-controls .hiddenmenu .top {
font-size: 12px;
color: #fff;
margin-bottom: 20px;
}
.tui-image-editor-controls .btn-prev {
display: inline-block;
width: 30px;
height: 80px;
background-color: #000;
color: #fff;
border: none;
vertical-align: middle;
}
.tui-image-editor-controls .tui-colorpicker-container {
display: inline-block;
}
.tui-image-editor-controls .msg {
position: absolute;
margin-left: 50%;
padding: 5px 10px;
left: -86px;
top: -50px;
border-radius: 5px 5px;
background-color: rgba(255, 255, 255, 0.5);
font-size: 12px;
}
.tui-image-editor-controls .msg.hide {
display: none;
}
================================================
FILE: apps/image-editor/examples/css/tui-example-style.css
================================================
body {
margin: 0;
padding: 0;
}
.code-description {
padding: 22px 52px;
background-color: rgba(81, 92, 230, 0.1);
line-height: 1.4em;
}
.code-description,
.code-description a {
font-family: Arial;
font-size: 14px;
color: #515ce6;
}
.code-html {
padding: 20px 52px;
}
================================================
FILE: apps/image-editor/examples/example01-includeUi.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>0. Design</title>
<link
type="text/css"
href="https://uicdn.toast.com/tui-color-picker/v2.2.6/tui-color-picker.css"
rel="stylesheet"
/>
<link type="text/css" href="../dist/tui-image-editor.css" rel="stylesheet" />
<style>
@import url(http://fonts.googleapis.com/css?family=Noto+Sans);
html,
body {
height: 100%;
margin: 0;
}
</style>
</head>
<body>
<div id="tui-image-editor-container"></div>
<script
type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.4.0/fabric.js"
></script>
<script
type="text/javascript"
src="https://uicdn.toast.com/tui.code-snippet/v1.5.0/tui-code-snippet.min.js"
></script>
<script
type="text/javascript"
src="https://uicdn.toast.com/tui-color-picker/v2.2.6/tui-color-picker.js"
></script>
<script
type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"
></script>
<script type="text/javascript" src="../dist/tui-image-editor.js"></script>
<script type="text/javascript" src="js/theme/white-theme.js"></script>
<script type="text/javascript" src="js/theme/black-theme.js"></script>
<script>
// Image editor
var imageEditor = new tui.ImageEditor('#tui-image-editor-container', {
includeUI: {
loadImage: {
path: 'img/sampleImage2.png',
name: 'SampleImage',
},
theme: blackTheme, // or whiteTheme
initMenu: 'filter',
menuBarPosition: 'bottom',
},
cssMaxWidth: 700,
cssMaxHeight: 500,
usageStatistics: false,
});
window.onresize = function () {
imageEditor.ui.resizeEditor();
};
</script>
</body>
</html>
================================================
FILE: apps/image-editor/examples/example02-useApiDirect.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>1. Basic</title>
<link
type="text/css"
href="https://uicdn.toast.com/tui-color-picker/v2.2.6/tui-color-picker.css"
rel="stylesheet"
/>
<link type="text/css" href="css/service-basic.css" rel="stylesheet" />
</head>
<body>
<div class="body-container">
<div class="tui-image-editor-controls">
<div class="header">
<img class="logo" src="img/TOAST UI Component.png" />
<span class="name"> Image Editor</span>
<ul class="menu">
<li class="menu-item border input-wrapper">
Load
<input type="file" accept="image/*" id="input-image-file" />
</li>
<li class="menu-item border" id="btn-download">Download</li>
</ul>
</div>
<ul class="menu">
<li class="menu-item disabled" id="btn-undo">Undo</li>
<li class="menu-item disabled" id="btn-redo">Redo</li>
<li class="menu-item" id="btn-clear-objects">ClearObjects</li>
<li class="menu-item" id="btn-remove-active-object">RemoveActiveObject</li>
<li class="menu-item" id="btn-crop">Crop</li>
<li class="menu-item" id="btn-flip">Flip</li>
<li class="menu-item" id="btn-rotation">Rotation</li>
<li class="menu-item" id="btn-draw-line">DrawLine</li>
<li class="menu-item" id="btn-draw-shape">Shape</li>
<li class="menu-item" id="btn-add-icon">Icon</li>
<li class="menu-item" id="btn-text">Text</li>
<li class="menu-item" id="btn-mask-filter">Mask</li>
<li class="menu-item" id="btn-image-filter">Filter</li>
</ul>
<div class="sub-menu-container" id="crop-sub-menu">
<ul class="menu">
<li class="menu-item" id="btn-apply-crop">Apply</li>
<li class="menu-item" id="btn-cancel-crop">Cancel</li>
</ul>
</div>
<div class="sub-menu-container" id="flip-sub-menu">
<ul class="menu">
<li class="menu-item" id="btn-flip-x">FlipX</li>
<li class="menu-item" id="btn-flip-y">FlipY</li>
<li class="menu-item" id="btn-reset-flip">Reset</li>
<li class="menu-item close">Close</li>
</ul>
</div>
<div class="sub-menu-container" id="rotation-sub-menu">
<ul class="menu">
<li class="menu-item" id="btn-rotate-clockwise">Clockwise(30)</li>
<li class="menu-item" id="btn-rotate-counter-clockwise">Counter-Clockwise(-30)</li>
<li class="menu-item no-pointer">
<label>
Range input
<input id="input-rotation-range" type="range" min="-360" value="0" max="360" />
</label>
</li>
<li class="menu-item close">Close</li>
</ul>
</div>
<div class="sub-menu-container menu" id="draw-line-sub-menu">
<ul class="menu">
<li class="menu-item">
<label>
<input type="radio" name="select-line-type" value="freeDrawing" checked="checked" />
Free drawing
</label>
<label>
<input type="radio" name="select-line-type" value="lineDrawing" />
Straight line
</label>
</li>
<li class="menu-item">
<div id="tui-brush-color-picker">Brush color</div>
</li>
<li class="menu-item">
<label class="menu-item no-pointer">
Brush width
<input id="input-brush-width-range" type="range" min="5" max="30" value="12" />
</label>
</li>
<li class="menu-item close">Close</li>
</ul>
</div>
<div class="sub-menu-container" id="draw-shape-sub-menu">
<ul class="menu">
<li class="menu-item">
<label>
<input type="radio" name="select-shape-type" value="rect" checked="checked" />
rect
</label>
<label>
<input type="radio" name="select-shape-type" value="circle" />
circle
</label>
<label>
<input type="radio" name="select-shape-type" value="triangle" />
triangle
</label>
</li>
<li class="menu-item">
<select name="select-color-type">
<option value="fill">Fill</option>
<option value="stroke">Stroke</option>
</select>
<label>
<input
type="radio"
name="input-check-fill"
id="input-check-transparent"
value="transparent"
/>
transparent
</label>
<label>
<input
type="radio"
name="input-check-fill"
id="input-check-filter"
value="filter"
/>
filter
</label>
<div id="tui-shape-color-picker"></div>
</li>
<li class="menu-item">
<label class="menu-item no-pointer">
Stroke width
<input id="input-stroke-width-range" type="range" min="0" max="300" value="12" />
</label>
</li>
<li class="menu-item close">Close</li>
</ul>
</div>
<div class="sub-menu-container" id="icon-sub-menu">
<ul class="menu">
<li class="menu-item">
<div id="tui-icon-color-picker">Icon color</div>
</li>
<li class="menu-item border" id="btn-register-icon">Register custom icon</li>
<li class="menu-item icon-text" data-icon-type="arrow">➡</li>
<li class="menu-item icon-text" data-icon-type="cancel">✖</li>
<li class="menu-item close">Close</li>
</ul>
</div>
<div class="sub-menu-container" id="text-sub-menu">
<ul class="menu">
<li class="menu-item">
<div>
<button class="btn-text-style" data-style-type="b">Bold</button>
<button class="btn-text-style" data-style-type="i">Italic</button>
<button class="btn-text-style" data-style-type="u">Underline</button>
</div>
<div>
<button class="btn-text-style" data-style-type="l">Left</button>
<button class="btn-text-style" data-style-type="c">Center</button>
<button class="btn-text-style" data-style-type="r">Right</button>
</div>
</li>
<li class="menu-item">
<label class="no-pointer">
<input id="input-font-size-range" type="range" min="10" max="100" value="10" />
</label>
</li>
<li class="menu-item">
<div id="tui-text-color-picker">Text color</div>
</li>
<li class="menu-item close">Close</li>
</ul>
</div>
<div class="sub-menu-container" id="filter-sub-menu">
<ul class="menu">
<li class="menu-item border input-wrapper">
Load Mask Image
<input type="file" accept="image/*" id="input-mask-image-file" />
</li>
<li class="menu-item" id="btn-apply-mask">Apply mask filter</li>
<li class="menu-item close">Close</li>
</ul>
</div>
<div class="sub-menu-container" id="image-filter-sub-menu">
<ul class="menu">
<li class="menu-item align-left-top">
<table>
<tbody>
<tr>
<td>
<label><input type="checkbox" id="input-check-grayscale" />Grayscale</label>
</td>
<td>
<label><input type="checkbox" id="input-check-invert" />Invert</label>
</td>
<td>
<label><input type="checkbox" id="input-check-sepia" />Sepia</label>
</td>
</tr>
<tr>
<td>
<label><input type="checkbox" id="input-check-sepia2" />Sepia2</label>
</td>
<td>
<label><input type="checkbox" id="input-check-blur" />Blur</label>
</td>
<td>
<label><input type="checkbox" id="input-check-sharpen" />Sharpen</label>
</td>
</tr>
<tr>
<td>
<label><input type="checkbox" id="input-check-emboss" />Emboss</label>
</td>
</tr>
</tbody>
</table>
</li>
<li class="menu-item align-left-top">
<p>
<label>
<input type="checkbox" id="input-check-remove-white" />
RemoveWhite
</label>
<br />
<label>
Distance
<input
class="range-narrow"
id="input-range-remove-white-distance"
type="range"
min="0"
value="10"
max="255"
/>
</label>
</p>
</li>
<li class="menu-item align-left-top">
<p>
<label><input type="checkbox" id="input-check-brightness" />Brightness</label><br />
<label>
Value
<input
class="range-narrow"
id="input-range-brightness-value"
type="range"
min="-255"
value="100"
max="255"
/>
</label>
</p>
</li>
<li class="menu-item align-left-top">
<p>
<label><input type="checkbox" id="input-check-noise" />Noise</label><br />
<label>
Value
<input
class="range-narrow"
id="input-range-noise-value"
type="range"
min="0"
value="100"
max="1000"
/>
</label>
</p>
</li>
<li class="menu-item align-left-top">
<p>
<label>
<input type="checkbox" id="input-check-color-filter" />
ColorFilter
</label>
<br />
<label>
Threshold
<input
class="range-narrow"
id="input-range-color-filter-value"
type="range"
min="0"
value="45"
max="255"
/>
</label>
</p>
</li>
<li class="menu-item align-left-top">
<p>
<label><input type="checkbox" id="input-check-pixelate" />Pixelate</label><br />
<label>
Value
<input
class="range-narrow"
id="input-range-pixelate-value"
type="range"
min="2"
value="4"
max="20"
/>
</label>
</p>
</li>
<li class="menu-item align-left-top">
<p>
<label><input type="checkbox" id="input-check-tint" />Tint</label><br />
</p>
<div id="tui-tint-color-picker"></div>
<label>
Opacity
<input
class="range-narrow"
id="input-range-tint-opacity-value"
type="range"
min="0"
value="1"
max="1"
step="0.1"
/>
</label>
</li>
<li class="menu-item align-left-top">
<p>
<label><input type="checkbox" id="input-check-multiply" />Multiply</label>
</p>
<div id="tui-multiply-color-picker"></div>
</li>
<li class="menu-item align-left-top">
<p>
<label><input type="checkbox" id="input-check-blend" />Blend</label>
</p>
<div id="tui-blend-color-picker"></div>
<select name="select-blend-type">
<option value="add" selected>Add</option>
<option value="diff">Diff</option>
<option value="diff">Subtract</option>
<option value="multiply">Multiply</option>
<option value="screen">Screen</option>
<option value="lighten">Lighten</option>
<option value="darken">Darken</option>
</select>
</li>
<li class="menu-item close">Close</li>
</ul>
</div>
</div>
<div class="tui-image-editor"></div>
</div>
<script
type="text/javascript"
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"
></script>
<script
type="text/javascript"
src="https://uicdn.toast.com/tui.code-snippet/v1.5.0/tui-code-snippet.min.js"
></script>
<script
type="text/javascript"
src="https://uicdn.toast.com/tui-color-picker/v2.2.6/tui-color-picker.min.js"
></script>
<script
type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"
></script>
<script
type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"
></script>
<script type="text/javascript" src="../dist/tui-image-editor.js"></script>
<script src="js/service-basic.js"></script>
</body>
</html>
================================================
FILE: apps/image-editor/examples/example03-mobile.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>2. Mobile</title>
<link
type="text/css"
href="https://uicdn.toast.com/tui-color-picker/v2.2.6/tui-color-picker.css"
rel="stylesheet"
/>
<link type="text/css" href="css/service-mobile.css" rel="stylesheet" />
</head>
<body>
<!-- Image editor controls - top area -->
<div class="header">
<div>
<img class="logo" src="img/TOAST UI Component.png" /> <span class="name">Image Editor</span>
</div>
<div class="menu">
<span class="button">
<img src="img/openImage.png" style="margin-top: 5px" />
<input type="file" accept="image/*" id="input-image-file" />
</span>
<button class="button disabled" id="btn-undo"><img src="img/undo.png" /></button>
<button class="button disabled" id="btn-redo"><img src="img/redo.png" /></button>
<button class="button" id="btn-remove-active-object"><img src="img/remove.png" /></button>
<button class="button" id="btn-download"><img src="img/download.png" /></button>
</div>
</div>
<!-- Image editor area -->
<div class="tui-image-editor"></div>
<!-- Image editor controls - bottom area -->
<div class="tui-image-editor-controls">
<ul class="scrollable">
<li class="menu-item">
<button class="menu-button" id="btn-crop">Crop</button>
<div class="submenu">
<button class="btn-prev"><</button>
<ul class="scrollable">
<li class="menu-item">
<button class="submenu-button" id="btn-apply-crop">Apply</button>
</li>
</ul>
</div>
</li>
<li class="menu-item">
<button class="menu-button">Orientation</button>
<div class="submenu">
<button class="btn-prev"><</button>
<ul class="scrollable">
<li class="menu-item">
<button class="submenu-button" id="btn-rotate-clockwise">Rotate +90</button>
</li>
<li class="menu-item">
<button class="submenu-button" id="btn-rotate-counter-clockwise">Rotate -90</button>
</li>
<li class="menu-item">
<button class="submenu-button" id="btn-flip-x">FilpX</button>
</li>
<li class="menu-item">
<button class="submenu-button" id="btn-flip-y">FilpY</button>
</li>
</ul>
</div>
</li>
<li class="menu-item">
<button class="menu-button" id="btn-draw-line">Drawing</button>
<div class="submenu">
<button class="btn-prev"><</button>
<ul class="scrollable">
<li class="menu-item">
<button class="submenu-button" id="btn-free-drawing">Free<br />Drawing</button>
</li>
<li class="menu-item">
<button class="submenu-button" id="btn-line-drawing">Line<br />Drawing</button>
</li>
<li class="menu-item">
<button class="submenu-button" id="btn-change-size">Brush<br />Size</button>
<div class="hiddenmenu">
<input id="input-brush-range" type="range" min="10" max="100" value="50" />
</div>
</li>
<li class="menu-item">
<button class="submenu-button" id="btn-change-text-color">Brush<br />Color</button>
<div class="hiddenmenu">
<div id="tui-brush-color-picker"></div>
</div>
</li>
</ul>
</div>
</li>
<li class="menu-item">
<button class="menu-button" id="btn-draw-shape">Shape</button>
<div class="submenu">
<button class="btn-prev"><</button>
<ul class="scrollable">
<li class="menu-item">
<button class="submenu-button" id="btn-add-rect">Rectagle</button>
</li>
<li class="menu-item">
<button class="submenu-button" id="btn-add-square">Square</button>
</li>
<li class="menu-item">
<button class="submenu-button" id="btn-add-ellipse">Ellipse</button>
</li>
<li class="menu-item">
<button class="submenu-button" id="btn-add-circle">Circle</button>
</li>
<li class="menu-item">
<button class="submenu-button" id="btn-add-triangle">Triangle</button>
</li>
<li class="menu-item">
<button class="submenu-button" id="btn-stroke-size">Stroke<br />Size</button>
<div class="hiddenmenu">
<input id="input-stroke-range" type="range" min="1" max="100" value="10" />
</div>
</li>
<li class="menu-item">
<button class="submenu-button" id="btn-change-shape-color">Color</button>
<div class="hiddenmenu">
<div class="top">
<label for="fill-color"
><input
type="radio"
id="fill-color"
name="select-color-type"
value="fill"
checked="checked"
/>
Fill</label
>
<label for="stroke-color"
><input
type="radio"
id="stroke-color"
name="select-color-type"
value="stroke"
/>
Stroke</label
>
<label for="input-check-transparent"
><input type="checkbox" id="input-check-transparent" />Transparent</label
>
</div>
<div id="tui-shape-color-picker"></div>
</div>
</li>
</ul>
</div>
</li>
<li class="menu-item">
<button class="menu-button">Icon</button>
<div class="submenu">
<button class="btn-prev"><</button>
<ul class="scrollable">
<li class="menu-item">
<button class="submenu-button" id="btn-add-arrow-icon">Arrow<br />Icon</button>
</li>
<li class="menu-item">
<button class="submenu-button" id="btn-add-cancel-icon">Cancel<br />Icon</button>
</li>
<li class="menu-item">
<button class="submenu-button" id="btn-change-icon-color">Color</button>
<div class="hiddenmenu">
<div id="tui-icon-color-picker"></div>
</div>
</li>
</ul>
</div>
</li>
<li class="menu-item">
<button class="menu-button" id="btn-add-text">Text</button>
<div class="submenu">
<button class="btn-prev"><</button>
<ul class="scrollable">
<li class="menu-item">
<button class="submenu-button" id="btn-change-size">Size</button>
<div class="hiddenmenu">
<input id="input-text-size-range" type="range" min="10" max="240" value="120" />
</div>
</li>
<li class="menu-item">
<button class="submenu-button" id="btn-change-style">Style</button>
<div class="hiddenmenu">
<button class="hiddenmenu-button btn-change-text-style" data-style-type="bold">
<b>Bold</b>
</button>
<button class="hiddenmenu-button btn-change-text-style" data-style-type="italic">
<i>Italic</i>
</button>
<button
class="hiddenmenu-button btn-change-text-style"
data-style-type="underline"
>
<u>Underline</u>
</button>
</div>
</li>
<li class="menu-item">
<button class="submenu-button" id="btn-change-align">Align</button>
<div class="hiddenmenu">
<button class="hiddenmenu-button btn-change-text-style" data-style-type="left">
Left
</button>
<button class="hiddenmenu-button btn-change-text-style" data-style-type="center">
Center
</button>
<button class="hiddenmenu-button btn-change-text-style" data-style-type="right">
Right
</button>
</div>
</li>
<li class="menu-item">
<button class="submenu-button" id="btn-change-text-color">Color</button>
<div class="hiddenmenu">
<div id="tui-text-color-picker"></div>
</div>
</li>
</ul>
</div>
</li>
</ul>
<p class="msg">Menu Scrolling <b>Left ⇔ Right</b></p>
</div>
<script
type="text/javascript"
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"
></script>
<script
type="text/javascript"
src="https://uicdn.toast.com/tui.code-snippet/v1.5.0/tui-code-snippet.min.js"
></script>
<script
type="text/javascript"
src="https://uicdn.toast.com/tui-color-picker/v2.2.6/tui-color-picker.min.js"
></script>
<script
type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"
></script>
<script
type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"
></script>
<script type="text/javascript" src="../dist/tui-image-editor.js"></script>
<script src="js/service-mobile.js"></script>
</body>
</html>
================================================
FILE: apps/image-editor/examples/examples.json
================================================
{
"example01-includeUi": {
"title": "1. Include ui"
},
"example02-useApiDirect": {
"title": "2. Use api direct (basic)"
},
"example03-mobile": {
"title": "3. Mobile"
}
}
================================================
FILE: apps/image-editor/examples/js/service-basic.js
================================================
/* 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 */
var PIXELATE_FILTER_DEFAULT_VALUE = 20;
var supportingFileAPI = !!(window.File && window.FileList && window.FileReader);
var rImageType = /data:(image\/.+);base64,/;
var shapeOptions = {};
var shapeType;
var activeObjectId;
// Buttons
var $btns = $('.menu-item');
var $btnsActivatable = $btns.filter('.activatable');
var $inputImage = $('#input-image-file');
var $btnDownload = $('#btn-download');
var $btnUndo = $('#btn-undo');
var $btnRedo = $('#btn-redo');
var $btnClearObjects = $('#btn-clear-objects');
var $btnRemoveActiveObject = $('#btn-remove-active-object');
var $btnCrop = $('#btn-crop');
var $btnFlip = $('#btn-flip');
var $btnRotation = $('#btn-rotation');
var $btnDrawLine = $('#btn-draw-line');
var $btnDrawShape = $('#btn-draw-shape');
var $btnApplyCrop = $('#btn-apply-crop');
var $btnCancelCrop = $('#btn-cancel-crop');
var $btnFlipX = $('#btn-flip-x');
var $btnFlipY = $('#btn-flip-y');
var $btnResetFlip = $('#btn-reset-flip');
var $btnRotateClockwise = $('#btn-rotate-clockwise');
var $btnRotateCounterClockWise = $('#btn-rotate-counter-clockwise');
var $btnText = $('#btn-text');
var $btnTextStyle = $('.btn-text-style');
var $btnAddIcon = $('#btn-add-icon');
var $btnRegisterIcon = $('#btn-register-icon');
var $btnMaskFilter = $('#btn-mask-filter');
var $btnImageFilter = $('#btn-image-filter');
var $btnLoadMaskImage = $('#input-mask-image-file');
var $btnApplyMask = $('#btn-apply-mask');
var $btnClose = $('.close');
// Input etc.
var $inputRotationRange = $('#input-rotation-range');
var $inputBrushWidthRange = $('#input-brush-width-range');
var $inputFontSizeRange = $('#input-font-size-range');
var $inputStrokeWidthRange = $('#input-stroke-width-range');
var $inputCheckTransparent = $('#input-check-transparent');
var $inputCheckFilter = $('#input-check-filter');
var $inputCheckGrayscale = $('#input-check-grayscale');
var $inputCheckInvert = $('#input-check-invert');
var $inputCheckSepia = $('#input-check-sepia');
var $inputCheckSepia2 = $('#input-check-sepia2');
var $inputCheckBlur = $('#input-check-blur');
var $inputCheckSharpen = $('#input-check-sharpen');
var $inputCheckEmboss = $('#input-check-emboss');
var $inputCheckRemoveWhite = $('#input-check-remove-white');
var $inputRangeRemoveWhiteThreshold = $('#input-range-remove-white-threshold');
var $inputRangeRemoveWhiteDistance = $('#input-range-remove-white-distance');
var $inputCheckBrightness = $('#input-check-brightness');
var $inputRangeBrightnessValue = $('#input-range-brightness-value');
var $inputCheckNoise = $('#input-check-noise');
var $inputRangeNoiseValue = $('#input-range-noise-value');
var $inputCheckPixelate = $('#input-check-pixelate');
var $inputRangePixelateValue = $('#input-range-pixelate-value');
var $inputCheckTint = $('#input-check-tint');
var $inputRangeTintOpacityValue = $('#input-range-tint-opacity-value');
var $inputCheckMultiply = $('#input-check-multiply');
var $inputCheckBlend = $('#input-check-blend');
var $inputCheckColorFilter = $('#input-check-color-filter');
var $inputRangeColorFilterValue = $('#input-range-color-filter-value');
// Sub menus
var $displayingSubMenu = $();
var $cropSubMenu = $('#crop-sub-menu');
var $flipSubMenu = $('#flip-sub-menu');
var $rotationSubMenu = $('#rotation-sub-menu');
var $freeDrawingSubMenu = $('#free-drawing-sub-menu');
var $drawLineSubMenu = $('#draw-line-sub-menu');
var $drawShapeSubMenu = $('#draw-shape-sub-menu');
var $textSubMenu = $('#text-sub-menu');
var $iconSubMenu = $('#icon-sub-menu');
var $filterSubMenu = $('#filter-sub-menu');
var $imageFilterSubMenu = $('#image-filter-sub-menu');
// Select line type
var $selectLine = $('[name="select-line-type"]');
// Select shape type
var $selectShapeType = $('[name="select-shape-type"]');
// Select color of shape type
var $selectColorType = $('[name="select-color-type"]');
// Select blend type
var $selectBlendType = $('[name="select-blend-type"]');
// Image editor
var imageEditor = new tui.ImageEditor('.tui-image-editor', {
cssMaxWidth: 700,
cssMaxHeight: 500,
selectionStyle: {
cornerSize: 20,
rotatingPointOffset: 70,
},
});
// Color picker for free drawing
var brushColorpicker = tui.colorPicker.create({
container: $('#tui-brush-color-picker')[0],
color: '#000000',
});
// Color picker for text palette
var textColorpicker = tui.colorPicker.create({
container: $('#tui-text-color-picker')[0],
color: '#000000',
});
// Color picker for shape
var shapeColorpicker = tui.colorPicker.create({
container: $('#tui-shape-color-picker')[0],
color: '#000000',
});
// Color picker for icon
var iconColorpicker = tui.colorPicker.create({
container: $('#tui-icon-color-picker')[0],
color: '#000000',
});
var tintColorpicker = tui.colorPicker.create({
container: $('#tui-tint-color-picker')[0],
color: '#000000',
});
var multiplyColorpicker = tui.colorPicker.create({
container: $('#tui-multiply-color-picker')[0],
color: '#000000',
});
var blendColorpicker = tui.colorPicker.create({
container: $('#tui-blend-color-picker')[0],
color: '#00FF00',
});
// Common global functions
// HEX to RGBA
function hexToRGBa(hex, alpha) {
var r = parseInt(hex.slice(1, 3), 16);
var g = parseInt(hex.slice(3, 5), 16);
var b = parseInt(hex.slice(5, 7), 16);
var a = alpha || 1;
return 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';
}
function base64ToBlob(data) {
var mimeString = '';
var raw, uInt8Array, i, rawLength;
raw = data.replace(rImageType, function (header, imageType) {
mimeString = imageType;
return '';
});
raw = atob(raw);
rawLength = raw.length;
uInt8Array = new Uint8Array(rawLength); // eslint-disable-line
for (i = 0; i < rawLength; i += 1) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], { type: mimeString });
}
function resizeEditor() {
var $editor = $('.tui-image-editor');
var $container = $('.tui-image-editor-canvas-container');
var height = parseFloat($container.css('max-height'));
$editor.height(height);
}
function getBrushSettings() {
var brushWidth = parseInt($inputBrushWidthRange.val(), 10);
var brushColor = brushColorpicker.getColor();
return {
width: brushWidth,
color: hexToRGBa(brushColor, 0.5),
};
}
function activateShapeMode() {
if (imageEditor.getDrawingMode() !== 'SHAPE') {
imageEditor.stopDrawingMode();
imageEditor.startDrawingMode('SHAPE');
}
}
function activateIconMode() {
imageEditor.stopDrawingMode();
}
function activateTextMode() {
if (imageEditor.getDrawingMode() !== 'TEXT') {
imageEditor.stopDrawingMode();
imageEditor.startDrawingMode('TEXT');
}
}
function setTextToolbar(obj) {
var fontSize = obj.fontSize;
var fontColor = obj.fill;
$inputFontSizeRange.val(fontSize);
textColorpicker.setColor(fontColor);
}
function setIconToolbar(obj) {
var iconColor = obj.fill;
iconColorpicker.setColor(iconColor);
}
function setShapeToolbar(obj) {
var fillColor, isTransparent, isFilter;
var colorType = $selectColorType.val();
var changeValue = colorType === 'stroke' ? obj.stroke : obj.fill.type;
isTransparent = changeValue === 'transparent';
isFilter = changeValue === 'filter';
if (colorType === 'stroke') {
if (!isTransparent && !isFilter) {
shapeColorpicker.setColor(changeValue);
}
} else if (colorType === 'fill') {
if (!isTransparent && !isFilter) {
fillColor = obj.fill.color;
shapeColorpicker.setColor(fillColor);
}
}
$inputCheckTransparent.prop('checked', isTransparent);
$inputCheckFilter.prop('checked', isFilter);
$inputStrokeWidthRange.val(obj.strokeWidth);
}
function showSubMenu(type) {
var $submenu;
switch (type) {
case 'shape':
$submenu = $drawShapeSubMenu;
break;
case 'icon':
$submenu = $iconSubMenu;
break;
case 'text':
$submenu = $textSubMenu;
break;
default:
$submenu = 0;
}
$displayingSubMenu.hide();
$displayingSubMenu = $submenu.show();
}
function applyOrRemoveFilter(applying, type, options) {
if (applying) {
imageEditor.applyFilter(type, options).then(function (result) {
console.log(result);
});
} else {
imageEditor.removeFilter(type);
}
}
// Attach image editor custom events
imageEditor.on({
objectAdded: function (objectProps) {
console.info(objectProps);
},
undoStackChanged: function (length) {
if (length) {
$btnUndo.removeClass('disabled');
} else {
$btnUndo.addClass('disabled');
}
resizeEditor();
},
redoStackChanged: function (length) {
if (length) {
$btnRedo.removeClass('disabled');
} else {
$btnRedo.addClass('disabled');
}
resizeEditor();
},
objectScaled: function (obj) {
if (obj.type === 'text') {
$inputFontSizeRange.val(obj.fontSize);
}
},
addText: function (pos) {
imageEditor
.addText('Double Click', {
position: pos.originPosition,
})
.then(function (objectProps) {
console.log(objectProps);
});
},
objectActivated: function (obj) {
activeObjectId = obj.id;
if (obj.type === 'rect' || obj.type === 'circle' || obj.type === 'triangle') {
showSubMenu('shape');
setShapeToolbar(obj);
activateShapeMode();
} else if (obj.type === 'icon') {
showSubMenu('icon');
setIconToolbar(obj);
activateIconMode();
} else if (obj.type === 'text') {
showSubMenu('text');
setTextToolbar(obj);
activateTextMode();
}
},
mousedown: function (event, originPointer) {
if ($imageFilterSubMenu.is(':visible') && imageEditor.hasFilter('colorFilter')) {
imageEditor.applyFilter('colorFilter', {
x: parseInt(originPointer.x, 10),
y: parseInt(originPointer.y, 10),
});
}
},
});
// Attach button click event listeners
$btns.on('click', function () {
$btnsActivatable.removeClass('active');
});
$btnsActivatable.on('click', function () {
$(this).addClass('active');
});
$btnUndo.on('click', function () {
$displayingSubMenu.hide();
if (!$(this).hasClass('disabled')) {
imageEditor.discardSelection();
imageEditor.undo();
}
});
$btnRedo.on('click', function () {
$displayingSubMenu.hide();
if (!$(this).hasClass('disabled')) {
imageEditor.discardSelection();
imageEditor.redo();
}
});
$btnClearObjects.on('click', function () {
$displayingSubMenu.hide();
imageEditor.clearObjects();
});
$btnRemoveActiveObject.on('click', function () {
$displayingSubMenu.hide();
imageEditor.removeObject(activeObjectId);
});
$btnCrop.on('click', function () {
imageEditor.startDrawingMode('CROPPER');
$displayingSubMenu.hide();
$displayingSubMenu = $cropSubMenu.show();
});
$btnFlip.on('click', function () {
imageEditor.stopDrawingMode();
$displayingSubMenu.hide();
$displayingSubMenu = $flipSubMenu.show();
});
$btnRotation.on('click', function () {
imageEditor.stopDrawingMode();
$displayingSubMenu.hide();
$displayingSubMenu = $rotationSubMenu.show();
});
$btnClose.on('click', function () {
imageEditor.stopDrawingMode();
$displayingSubMenu.hide();
});
$btnApplyCrop.on('click', function () {
imageEditor.crop(imageEditor.getCropzoneRect()).then(function () {
imageEditor.stopDrawingMode();
resizeEditor();
});
});
$btnCancelCrop.on('click', function () {
imageEditor.stopDrawingMode();
});
$btnFlipX.on('click', function () {
imageEditor.flipX().then(function (status) {
console.log('flipX: ', status.flipX);
console.log('flipY: ', status.flipY);
console.log('angle: ', status.angle);
});
});
$btnFlipY.on('click', function () {
imageEditor.flipY().then(function (status) {
console.log('flipX: ', status.flipX);
console.log('flipY: ', status.flipY);
console.log('angle: ', status.angle);
});
});
$btnResetFlip.on('click', function () {
imageEditor.resetFlip().then(function (status) {
console.log('flipX: ', status.flipX);
console.log('flipY: ', status.flipY);
console.log('angle: ', status.angle);
});
});
$btnRotateClockwise.on('click', function () {
imageEditor.rotate(30);
});
$btnRotateCounterClockWise.on('click', function () {
imageEditor.rotate(-30);
});
$inputRotationRange.on('mousedown', function () {
var changeAngle = function () {
imageEditor.setAngle(parseInt($inputRotationRange.val(), 10))['catch'](function () {});
};
$(document).on('mousemove', changeAngle);
$(document).on('mouseup', function stopChangingAngle() {
$(document).off('mousemove', changeAngle);
$(document).off('mouseup', stopChangingAngle);
});
});
$inputRotationRange.on('change', function () {
imageEditor.setAngle(parseInt($inputRotationRange.val(), 10))['catch'](function () {});
});
$inputBrushWidthRange.on('change', function () {
imageEditor.setBrush({ width: parseInt(this.value, 10) });
});
$inputImage.on('change', function (event) {
var file;
if (!supportingFileAPI) {
alert('This browser does not support file-api');
}
file = event.target.files[0];
imageEditor.loadImageFromFile(file).then(function (result) {
console.log(result);
imageEditor.clearUndoStack();
});
});
$btnDownload.on('click', function () {
var imageName = imageEditor.getImageName();
var dataURL = imageEditor.toDataURL();
var blob, type, w;
if (supportingFileAPI) {
blob = base64ToBlob(dataURL);
type = blob.type.split('/')[1];
if (imageName.split('.').pop() !== type) {
imageName += '.' + type;
}
// Library: FileSaver - saveAs
saveAs(blob, imageName); // eslint-disable-line
} else {
alert('This browser needs a file-server');
w = window.open();
w.document.body.innerHTML = '<img src="' + dataURL + '">';
}
});
// control draw line mode
$btnDrawLine.on('click', function () {
imageEditor.stopDrawingMode();
$displayingSubMenu.hide();
$displayingSubMenu = $drawLineSubMenu.show();
$selectLine.eq(0).change();
});
$selectLine.on('change', function () {
var mode = $(this).val();
var settings = getBrushSettings();
imageEditor.stopDrawingMode();
if (mode === 'freeDrawing') {
imageEditor.startDrawingMode('FREE_DRAWING', settings);
} else {
imageEditor.startDrawingMode('LINE_DRAWING', settings);
}
});
brushColorpicker.on('selectColor', function (event) {
imageEditor.setBrush({
color: hexToRGBa(event.color, 0.5),
});
});
// control draw shape mode
$btnDrawShape.on('click', function () {
showSubMenu('shape');
// step 1. get options to draw shape from toolbar
shapeType = $('[name="select-shape-type"]:checked').val();
shapeOptions.stroke = '#000000';
shapeOptions.fill = '#ffffff';
shapeOptions.strokeWidth = Number($inputStrokeWidthRange.val());
// step 2. set options to draw shape
imageEditor.setDrawingShape(shapeType, shapeOptions);
// step 3. start drawing shape mode
activateShapeMode();
});
$selectShapeType.on('change', function () {
shapeType = $(this).val();
imageEditor.setDrawingShape(shapeType);
});
$selectColorType.on('change', function () {
var colorType = $(this).val();
if (colorType === 'stroke') {
$inputCheckFilter.prop('disabled', true);
$inputCheckFilter.prop('checked', false);
} else {
$inputCheckTransparent.prop('disabled', false);
$inputCheckFilter.prop('disabled', false);
}
});
$inputCheckTransparent.on('change', onChangeShapeFill);
$inputCheckFilter.on('change', onChangeShapeFill);
shapeColorpicker.on('selectColor', function (event) {
$inputCheckTransparent.prop('checked', false);
$inputCheckFilter.prop('checked', false);
onChangeShapeFill(event);
});
function onChangeShapeFill(event) {
var colorType = $selectColorType.val();
var isTransparent = $inputCheckTransparent.prop('checked');
var isFilter = $inputCheckFilter.prop('checked');
var shapeOption;
if (event.color) {
shapeOption = event.color;
} else if (isTransparent) {
shapeOption = 'transparent';
} else if (isFilter) {
shapeOption = {
type: 'filter',
filter: [{ pixelate: PIXELATE_FILTER_DEFAULT_VALUE }],
};
}
if (colorType === 'stroke') {
imageEditor.changeShape(activeObjectId, {
stroke: shapeOption,
});
} else if (colorType === 'fill') {
imageEditor.changeShape(activeObjectId, {
fill: shapeOption,
});
}
imageEditor.setDrawingShape(shapeType, shapeOptions);
}
$inputStrokeWidthRange.on('change', function () {
var strokeWidth = Number($(this).val());
imageEditor.changeShape(activeObjectId, {
strokeWidth: strokeWidth,
});
imageEditor.setDrawingShape(shapeType, shapeOptions);
});
// control text mode
$btnText.on('click', function () {
showSubMenu('text');
activateTextMode();
});
$inputFontSizeRange.on('change', function () {
imageEditor.changeTextStyle(activeObjectId, {
fontSize: parseInt(this.value, 10),
});
});
$btnTextStyle.on('click', function (e) {
// eslint-disable-line
var styleType = $(this).attr('data-style-type');
var styleObj;
e.stopPropagation();
switch (styleType) {
case 'b':
styleObj = { fontWeight: 'bold' };
break;
case 'i':
styleObj = { fontStyle: 'italic' };
break;
case 'u':
styleObj = { underline: true };
break;
case 'l':
styleObj = { textAlign: 'left' };
break;
case 'c':
styleObj = { textAlign: 'center' };
break;
case 'r':
styleObj = { textAlign: 'right' };
break;
default:
styleObj = {};
}
imageEditor.changeTextStyle(activeObjectId, styleObj);
});
textColorpicker.on('selectColor', function (event) {
imageEditor.changeTextStyle(activeObjectId, {
fill: event.color,
});
});
// control icon
$btnAddIcon.on('click', function () {
showSubMenu('icon');
activateIconMode();
});
function onClickIconSubMenu(event) {
var element = event.target || event.srcElement;
var iconType = $(element).attr('data-icon-type');
imageEditor.once('mousedown', function (e, originPointer) {
imageEditor
.addIcon(iconType, {
left: originPointer.x,
top: originPointer.y,
})
.then(function (objectProps) {
// console.log(objectProps);
});
});
}
$btnRegisterIcon.on('click', function () {
$iconSubMenu
.find('.menu-item')
.eq(3)
.after('<li id="customArrow" class="menu-item icon-text" data-icon-type="customArrow">↑</li>');
imageEditor.registerIcons({
customArrow: 'M 60 0 L 120 60 H 90 L 75 45 V 180 H 45 V 45 L 30 60 H 0 Z',
});
$btnRegisterIcon.off('click');
$iconSubMenu.on('click', '#customArrow', onClickIconSubMenu);
});
$iconSubMenu.on('click', '.icon-text', onClickIconSubMenu);
iconColorpicker.on('selectColor', function (event) {
imageEditor.changeIconColor(activeObjectId, event.color);
});
// control mask filter
$btnMaskFilter.on('click', function () {
imageEditor.stopDrawingMode();
$displayingSubMenu.hide();
$displayingSubMenu = $filterSubMenu.show();
});
$btnImageFilter.on('click', function () {
var filters = {
grayscale: $inputCheckGrayscale,
invert: $inputCheckInvert,
sepia: $inputCheckSepia,
sepia2: $inputCheckSepia2,
blur: $inputCheckBlur,
shapren: $inputCheckSharpen,
emboss: $inputCheckEmboss,
removeWhite: $inputCheckRemoveWhite,
brightness: $inputCheckBrightness,
noise: $inputCheckNoise,
pixelate: $inputCheckPixelate,
tint: $inputCheckTint,
multiply: $inputCheckMultiply,
blend: $inputCheckBlend,
colorFilter: $inputCheckColorFilter,
};
tui.util.forEach(filters, function ($value, key) {
$value.prop('checked', imageEditor.hasFilter(key));
});
$displayingSubMenu.hide();
$displayingSubMenu = $imageFilterSubMenu.show();
});
$btnLoadMaskImage.on('change', function () {
var file;
var imgUrl;
if (!supportingFileAPI) {
alert('This browser does not support file-api');
}
file = event.target.files[0];
if (file) {
imgUrl = URL.createObjectURL(file);
imageEditor.loadImageFromURL(imageEditor.toDataURL(), 'FilterImage').then(function () {
imageEditor.addImageObject(imgUrl).then(function (objectProps) {
URL.revokeObjectURL(file);
console.log(objectProps);
});
});
}
});
$btnApplyMask.on('click', function () {
imageEditor
.applyFilter('mask', {
maskObjId: activeObjectId,
})
.then(function (result) {
console.log(result);
});
});
$inputCheckGrayscale.on('change', function () {
applyOrRemoveFilter(this.checked, 'Grayscale', null);
});
$inputCheckInvert.on('change', function () {
applyOrRemoveFilter(this.checked, 'Invert', null);
});
$inputCheckSepia.on('change', function () {
applyOrRemoveFilter(this.checked, 'Sepia', null);
});
$inputCheckSepia2.on('change', function () {
applyOrRemoveFilter(this.checked, 'vintage', null);
});
$inputCheckBlur.on('change', function () {
applyOrRemoveFilter(this.checked, 'Blur', { blur: 0.1 });
});
$inputCheckSharpen.on('change', function () {
applyOrRemoveFilter(this.checked, 'Sharpen', null);
});
$inputCheckEmboss.on('change', function () {
applyOrRemoveFilter(this.checked, 'Emboss', null);
});
$inputCheckRemoveWhite.on('change', function () {
applyOrRemoveFilter(this.checked, 'removeColor', {
color: '#FFFFFF',
useAlpha: false,
distance: parseInt($inputRangeRemoveWhiteDistance.val(), 10) / 255,
});
});
$inputRangeRemoveWhiteDistance.on('change', function () {
applyOrRemoveFilter($inputCheckRemoveWhite.is(':checked'), 'removeColor', {
distance: parseInt(this.value, 10) / 255,
});
});
$inputCheckBrightness.on('change', function () {
applyOrRemoveFilter(this.checked, 'brightness', {
brightness: parseInt($inputRangeBrightnessValue.val(), 10) / 255,
});
});
$inputRangeBrightnessValue.on('change', function () {
applyOrRemoveFilter($inputCheckBrightness.is(':checked'), 'brightness', {
brightness: parseInt(this.value, 10) / 255,
});
});
$inputCheckNoise.on('change', function () {
applyOrRemoveFilter(this.checked, 'noise', {
noise: parseInt($inputRangeNoiseValue.val(), 10),
});
});
$inputRangeNoiseValue.on('change', function () {
applyOrRemoveFilter($inputCheckNoise.is(':checked'), 'noise', {
noise: parseInt(this.value, 10),
});
});
$inputCheckPixelate.on('change', function () {
applyOrRemoveFilter(this.checked, 'pixelate', {
blocksize: parseInt($inputRangePixelateValue.val(), 10),
});
});
$inputRangePixelateValue.on('change', function () {
applyOrRemoveFilter($inputCheckPixelate.is(':checked'), 'pixelate', {
blocksize: parseInt(this.value, 10),
});
});
$inputCheckTint.on('change', function () {
applyOrRemoveFilter(this.checked, 'blendColor', {
mode: 'tint',
color: tintColorpicker.getColor(),
alpha: parseFloat($inputRangeTintOpacityValue.val()),
});
});
tintColorpicker.on('selectColor', function (e) {
applyOrRemoveFilter($inputCheckTint.is(':checked'), 'blendColor', {
color: e.color,
});
});
$inputRangeTintOpacityValue.on('change', function () {
applyOrRemoveFilter($inputCheckTint.is(':checked'), 'blendColor', {
alpha: parseFloat($inputRangeTintOpacityValue.val()),
});
});
$inputCheckMultiply.on('change', function () {
applyOrRemoveFilter(this.checked, 'blendColor', {
color: multiplyColorpicker.getColor(),
});
});
multiplyColorpicker.on('selectColor', function (e) {
applyOrRemoveFilter($inputCheckMultiply.is(':checked'), 'blendColor', {
color: e.color,
});
});
$inputCheckBlend.on('change', function () {
applyOrRemoveFilter(this.checked, 'blendColor', {
mode: $selectBlendType.val(),
color: blendColorpicker.getColor(),
});
});
blendColorpicker.on('selectColor', function (e) {
applyOrRemoveFilter($inputCheckBlend.is(':checked'), 'blendColor', {
color: e.color,
});
});
$selectBlendType.on('change', function () {
applyOrRemoveFilter($inputCheckBlend.is(':checked'), 'blendColor', {
mode: this.value,
});
});
$inputCheckColorFilter.on('change', function () {
applyOrRemoveFilter(this.checked, 'removeColor', {
color: '#FFFFFF',
distance: $inputRangeColorFilterValue.val() / 255,
});
});
$inputRangeColorFilterValue.on('change', function () {
applyOrRemoveFilter($inputCheckColorFilter.is(':checked'), 'removeColor', {
distance: this.value / 255,
});
});
// Etc..
// Load sample image
imageEditor.loadImageFromURL('img/sampleImage.jpg', 'SampleImage').then(function (sizeValue) {
console.log(sizeValue);
imageEditor.clearUndoStack();
});
// IE9 Unselectable
$('.menu').on('selectstart', function () {
return false;
});
================================================
FILE: apps/image-editor/examples/js/service-mobile.js
================================================
/* eslint-disable vars-on-top,no-var,strict,prefer-template,prefer-arrow-callback,prefer-destructuring,object-shorthand,require-jsdoc,complexity */
'use strict';
var MAX_RESOLUTION = 3264 * 2448; // 8MP (Mega Pixel)
var supportingFileAPI = !!(window.File && window.FileList && window.FileReader);
var rImageType = /data:(image\/.+);base64,/;
var shapeOpt = {
fill: '#fff',
stroke: '#000',
strokeWidth: 10,
};
var activeObjectId;
// Selector of image editor controls
var submenuClass = '.submenu';
var hiddenmenuClass = '.hiddenmenu';
var $controls = $('.tui-image-editor-controls');
var $menuButtons = $controls.find('.menu-button');
var $submenuButtons = $controls.find('.submenu-button');
var $btnShowMenu = $controls.find('.btn-prev');
var $msg = $controls.find('.msg');
var $subMenus = $controls.find(submenuClass);
var $hiddenMenus = $controls.find(hiddenmenuClass);
// Image editor controls - top menu buttons
var $inputImage = $('#input-image-file');
var $btnDownload = $('#btn-download');
var $btnUndo = $('#btn-undo');
var $btnRedo = $('#btn-redo');
var $btnRemoveActiveObject = $('#btn-remove-active-object');
// Image editor controls - bottom menu buttons
var $btnCrop = $('#btn-crop');
var $btnAddText = $('#btn-add-text');
// Image editor controls - bottom submenu buttons
var $btnApplyCrop = $('#btn-apply-crop');
var $btnFlipX = $('#btn-flip-x');
var $btnFlipY = $('#btn-flip-y');
var $btnRotateClockwise = $('#btn-rotate-clockwise');
var $btnRotateCounterClockWise = $('#btn-rotate-counter-clockwise');
var $btnAddArrowIcon = $('#btn-add-arrow-icon');
var $btnAddCancelIcon = $('#btn-add-cancel-icon');
var $btnAddCustomIcon = $('#btn-add-custom-icon');
var $btnFreeDrawing = $('#btn-free-drawing');
var $btnLineDrawing = $('#btn-line-drawing');
var $btnAddRect = $('#btn-add-rect');
var $btnAddSquare = $('#btn-add-square');
var $btnAddEllipse = $('#btn-add-ellipse');
var $btnAddCircle = $('#btn-add-circle');
var $btnAddTriangle = $('#btn-add-triangle');
var $btnChangeTextStyle = $('.btn-change-text-style');
// Image editor controls - etc.
var $inputTextSizeRange = $('#input-text-size-range');
var $inputBrushWidthRange = $('#input-brush-range');
var $inputStrokeWidthRange = $('#input-stroke-range');
var $inputCheckTransparent = $('#input-check-transparent');
// Colorpicker
var iconColorpicker = tui.colorPicker.create({
container: $('#tui-icon-color-picker')[0],
color: '#000000',
});
var textColorpicker = tui.colorPicker.create({
container: $('#tui-text-color-picker')[0],
color: '#000000',
});
var brushColorpicker = tui.colorPicker.create({
container: $('#tui-brush-color-picker')[0],
color: '#000000',
});
var shapeColorpicker = tui.colorPicker.create({
container: $('#tui-shape-color-picker')[0],
color: '#000000',
});
// Create image editor
var imageEditor = new tui.ImageEditor('.tui-image-editor', {
cssMaxWidth: document.documentElement.clientWidth,
cssMaxHeight: document.documentElement.clientHeight,
selectionStyle: {
cornerSize: 50,
rotatingPointOffset: 100,
},
});
var $displayingSubMenu, $displayingHiddenMenu;
function hexToRGBa(hex, alpha) {
var r = parseInt(hex.slice(1, 3), 16);
var g = parseInt(hex.slice(3, 5), 16);
var b = parseInt(hex.slice(5, 7), 16);
var a = alpha || 1;
return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + a + ')';
}
function base64ToBlob(data) {
var mimeString = '';
var raw, uInt8Array, i, rawLength;
raw = data.replace(rImageType, function (header, imageType) {
mimeString = imageType;
return '';
});
raw = atob(raw);
rawLength = raw.length;
uInt8Array = new Uint8Array(rawLength); // eslint-disable-line
for (i = 0; i < rawLength; i += 1) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], { type: mimeString });
}
function getBrushSettings() {
var brushWidth = $inputBrushWidthRange.val();
var brushColor = brushColorpicker.getColor();
return {
width: brushWidth,
color: hexToRGBa(brushColor, 0.5),
};
}
function activateShapeMode() {
imageEditor.stopDrawingMode();
}
function activateIconMode() {
imageEditor.stopDrawingMode();
}
function activateTextMode() {
if (imageEditor.getDrawingMode() !== 'TEXT') {
imageEditor.stopDrawingMode();
imageEditor.startDrawingMode('TEXT');
}
}
function setTextToolbar(obj) {
var fontSize = obj.fontSize;
var fontColor = obj.fill;
$inputTextSizeRange.val(fontSize);
textColorpicker.setColor(fontColor);
}
function setIconToolbar(obj) {
var iconColor = obj.fill;
iconColorpicker.setColor(iconColor);
}
function setShapeToolbar(obj) {
var strokeColor, fillColor, isTransparent;
var colorType = $('[name="select-color-type"]:checked').val();
if (colorType === 'stroke') {
strokeColor = obj.stroke;
isTransparent = strokeColor === 'transparent';
if (!isTransparent) {
shapeColorpicker.setColor(strokeColor);
}
} else if (colorType === 'fill') {
fillColor = obj.fill;
isTransparent = fillColor === 'transparent';
if (!isTransparent) {
shapeColorpicker.setColor(fillColor);
}
}
$inputCheckTransparent.prop('checked', isTransparent);
$inputStrokeWidthRange.val(obj.strokeWith);
}
function showSubMenu(type) {
var index;
switch (type) {
case 'shape':
index = 3;
break;
case 'icon':
index = 4;
break;
case 'text':
index = 5;
break;
default:
index = 0;
}
$displayingSubMenu.hide();
$displayingHiddenMenu.hide();
$displayingSubMenu = $menuButtons.eq(index).parent().find(submenuClass).show();
}
// Bind custom event of image editor
imageEditor.on({
undoStackChanged: function (length) {
if (length) {
$btnUndo.removeClass('disabled');
} else {
$btnUndo.addClass('disabled');
}
},
redoStackChanged: function (length) {
if (length) {
$btnRedo.removeClass('disabled');
} else {
$btnRedo.addClass('disabled');
}
},
objectScaled: function (obj) {
if (obj.type === 'text') {
$inputTextSizeRange.val(obj.fontSize);
}
},
objectActivated: function (obj) {
activeObjectId = obj.id;
if (obj.type === 'rect' || obj.type === 'circle' || obj.type === 'triangle') {
showSubMenu('shape');
setShapeToolbar(obj);
activateShapeMode();
} else if (obj.type === 'icon') {
showSubMenu('icon');
setIconToolbar(obj);
activateIconMode();
} else if (obj.type === 'text') {
showSubMenu('text');
setTextToolbar(obj);
activateTextMode();
}
},
});
// Image editor controls action
$menuButtons.on('click', function () {
$displayingSubMenu = $(this).parent().find(submenuClass).show();
$displayingHiddenMenu = $(this).parent().find(hiddenmenuClass);
});
$submenuButtons.on('click', function () {
$displayingHiddenMenu.hide();
$displayingHiddenMenu = $(this).parent().find(hiddenmenuClass).show();
});
$btnShowMenu.on('click', function () {
$displayingSubMenu.hide();
$displayingHiddenMenu.hide();
$msg.show();
imageEditor.stopDrawingMode();
});
// Image load action
$inputImage.on('change', function (event) {
var file;
var img;
var resolution;
if (!supportingFileAPI) {
alert('This browser does not support file-api');
}
file = event.target.files[0];
if (file) {
img = new Image();
img.onload = function () {
resolution = this.width * this.height;
if (resolution <= MAX_RESOLUTION) {
imageEditor.loadImageFromFile(file).then(function () {
imageEditor.clearUndoStack();
});
} else {
alert("Loaded image's resolution is too large!\nRecommended resolution is 3264 * 2448!");
}
URL.revokeObjectURL(file);
};
img.src = URL.createObjectURL(file);
}
});
// Undo action
$btnUndo.on('click', function () {
if (!$(this).hasClass('disabled')) {
imageEditor.undo();
}
});
// Redo action
$btnRedo.on('click', function () {
if (!$(this).hasClass('disabled')) {
imageEditor.redo();
}
});
// Remove active object action
$btnRemoveActiveObject.on('click', function () {
imageEditor.removeObject(activeObjectId);
});
// Download action
$btnDownload.on('click', function () {
var imageName = imageEditor.getImageName();
var dataURL = imageEditor.toDataURL();
var blob, type, w;
if (supportingFileAPI) {
blob = base64ToBlob(dataURL);
type = blob.type.split('/')[1];
if (imageName.split('.').pop() !== type) {
imageName += '.' + type;
}
// Library: FileSaver - saveAs
saveAs(blob, imageName); // eslint-disable-line
} else {
alert('This browser needs a file-server');
w = window.open();
w.document.body.innerHTML = '<img src=' + dataURL + '>';
}
});
// Crop menu action
$btnCrop.on('click', function () {
imageEditor.startDrawingMode('CROPPER');
});
$btnApplyCrop.on('click', function () {
imageEditor.crop(imageEditor.getCropzoneRect()).then(function () {
imageEditor.stopDrawingMode();
$subMenus.removeClass('show');
$hiddenMenus.removeClass('show');
});
});
// Orientation menu action
$btnRotateClockwise.on('click', function () {
imageEditor.rotate(90);
});
$btnRotateCounterClockWise.on('click', function () {
imageEditor.rotate(-90);
});
$btnFlipX.on('click', function () {
imageEditor.flipX();
});
$btnFlipY.on('click', function () {
imageEditor.flipY();
});
// Icon menu action
$btnAddArrowIcon.on('click', function () {
imageEditor.addIcon('arrow');
});
$btnAddCancelIcon.on('click', function () {
imageEditor.addIcon('cancel');
});
$btnAddCustomIcon.on('click', function () {
imageEditor.addIcon('customArrow');
});
iconColorpicker.on('selectColor', function (event) {
imageEditor.changeIconColor(activeObjectId, event.color);
});
// Text menu action
$btnAddText.on('click', function () {
var initText = 'DoubleClick';
imageEditor.startDrawingMode('TEXT');
imageEditor.addText(initText, {
styles: {
fontSize: parseInt($inputTextSizeRange.val(), 10),
},
});
});
$btnChangeTextStyle.on('click', function () {
var styleType = $(this).attr('data-style-type');
var styleObj = {};
var styleObjKey;
switch (styleType) {
case 'bold':
styleObjKey = 'fontWeight';
break;
case 'italic':
styleObjKey = 'fontStyle';
break;
case 'underline':
styleObjKey = 'underline';
break;
case 'left':
styleObjKey = 'textAlign';
break;
case 'center':
styleObjKey = 'textAlign';
break;
case 'right':
styleObjKey = 'textAlign';
break;
default:
styleObjKey = '';
}
styleObj[styleObjKey] = styleType;
imageEditor.changeTextStyle(activeObjectId, styleObj);
});
$inputTextSizeRange.on('change', function () {
imageEditor.changeTextStyle(activeObjectId, {
fontSize: parseInt($(this).val(), 10),
});
});
textColorpicker.on('selectColor', function (event) {
imageEditor.changeTextStyle(activeObjectId, {
fill: event.color,
});
});
// Draw line menu action
$btnFreeDrawing.on('click', function () {
var settings = getBrushSettings();
imageEditor.stopDrawingMode();
imageEditor.startDrawingMode('FREE_DRAWING', settings);
});
$btnLineDrawing.on('click', function () {
var settings = getBrushSettings();
imageEditor.stopDrawingMode();
imageEditor.startDrawingMode('LINE_DRAWING', settings);
});
$inputBrushWidthRange.on('change', function () {
imageEditor.setBrush({
width: parseInt($(this).val(), 10),
});
});
brushColorpicker.on('selectColor', function (event) {
imageEditor.setBrush({
color: hexToRGBa(event.color, 0.5),
});
});
// Add shape menu action
$btnAddRect.on('click', function () {
imageEditor.addShape(
'rect',
tui.util.extend(
{
width: 500,
height: 300,
},
shapeOpt
)
);
});
$btnAddSquare.on('click', function () {
imageEditor.addShape(
'rect',
tui.util.extend(
{
width: 400,
height: 400,
isRegular: true,
},
shapeOpt
)
);
});
$btnAddEllipse.on('click', function () {
imageEditor.addShape(
'circle',
tui.util.extend(
{
rx: 300,
ry: 200,
},
shapeOpt
)
);
});
$btnAddCircle.on('click', function () {
imageEditor.addShape(
'circle',
tui.util.extend(
{
rx: 200,
ry: 200,
isRegular: true,
},
shapeOpt
)
);
});
$btnAddTriangle.on('click', function () {
imageEditor.addShape(
'triangle',
tui.util.extend(
{
width: 500,
height: 400,
isRegular: true,
},
shapeOpt
)
);
});
$inputStrokeWidthRange.on('change', function () {
imageEditor.changeShape(activeObjectId, {
strokeWidth: parseInt($(this).val(), 10),
});
});
$inputCheckTransparent.on('change', function () {
var colorType = $('[name="select-color-type"]:checked').val();
var isTransparent = $(this).prop('checked');
var color;
if (!isTransparent) {
color = shapeColorpicker.getColor();
} else {
color = 'transparent';
}
if (colorType === 'stroke') {
imageEditor.changeShape(activeObjectId, {
stroke: color,
});
} else if (colorType === 'fill') {
imageEditor.changeShape(activeObjectId, {
fill: color,
});
}
});
shapeColorpicker.on('selectColor', function (event) {
var colorType = $('[name="select-color-type"]:checked').val();
var isTransparent = $inputCheckTransparent.prop('checked');
var color = event.color;
if (isTransparent) {
return;
}
if (colorType === 'stroke') {
imageEditor.changeShape(activeObjectId, {
stroke: color,
});
} else if (colorType === 'fill') {
imageEditor.changeShape(activeObjectId, {
fill: color,
});
}
});
// Load sample image
imageEditor.loadImageFromURL('img/sampleImage.jpg', 'SampleImage').then(function () {
imageEditor.clearUndoStack();
});
================================================
FILE: apps/image-editor/examples/js/theme/black-theme.js
================================================
var blackTheme = {
'common.bi.image': 'https://uicdn.toast.com/toastui/img/tui-image-editor-bi.png',
'common.bisize.width': '251px',
'common.bisize.height': '21px',
'common.backgroundImage': 'none',
'common.backgroundColor': '#1e1e1e',
'common.border': '0px',
// header
'header.backgroundImage': 'none',
'header.backgroundColor': 'transparent',
'header.border': '0px',
// load button
'loadButton.backgroundColor': '#fff',
'loadButton.border': '1px solid #ddd',
'loadButton.color': '#222',
'loadButton.fontFamily': "'Noto Sans', sans-serif",
'loadButton.fontSize': '12px',
// download button
'downloadButton.backgroundColor': '#fdba3b',
'downloadButton.border': '1px solid #fdba3b',
'downloadButton.color': '#fff',
'downloadButton.fontFamily': "'Noto Sans', sans-serif",
'downloadButton.fontSize': '12px',
// main icons
'menu.normalIcon.color': '#8a8a8a',
'menu.activeIcon.color': '#555555',
'menu.disabledIcon.color': '#434343',
'menu.hoverIcon.color': '#e9e9e9',
'menu.iconSize.width': '24px',
'menu.iconSize.height': '24px',
// submenu icons
'submenu.normalIcon.color': '#8a8a8a',
'submenu.activeIcon.color': '#e9e9e9',
'submenu.iconSize.width': '32px',
'submenu.iconSize.height': '32px',
// submenu primary color
'submenu.backgroundColor': '#1e1e1e',
'submenu.partition.color': '#3c3c3c',
// submenu labels
'submenu.normalLabel.color': '#8a8a8a',
'submenu.normalLabel.fontWeight': 'lighter',
'submenu.activeLabel.color': '#fff',
'submenu.activeLabel.fontWeight': 'lighter',
// checkbox style
'checkbox.border': '0px',
'checkbox.backgroundColor': '#fff',
// range style
'range.pointer.color': '#fff',
'range.bar.color': '#666',
'range.subbar.color': '#d1d1d1',
'range.disabledPointer.color': '#414141',
'range.disabledBar.color': '#282828',
'range.disabledSubbar.color': '#414141',
'range.value.color': '#fff',
'range.value.fontWeight': 'lighter',
'range.value.fontSize': '11px',
'range.value.border': '1px solid #353535',
'range.value.backgroundColor': '#151515',
'range.title.color': '#fff',
'range.title.fontWeight': 'lighter',
// colorpicker style
'colorpicker.button.border': '1px solid #1e1e1e',
'colorpicker.title.color': '#fff',
};
================================================
FILE: apps/image-editor/examples/js/theme/white-theme.js
================================================
var whiteTheme = {
'common.bi.image': 'https://uicdn.toast.com/toastui/img/tui-image-editor-bi.png',
'common.bisize.width': '251px',
'common.bisize.height': '21px',
'common.backgroundImage': './img/bg.png',
'common.backgroundColor': '#fff',
'common.border': '1px solid #c1c1c1',
// header
'header.backgroundImage': 'none',
'header.backgroundColor': 'transparent',
'header.border': '0px',
// load button
'loadButton.backgroundColor': '#fff',
'loadButton.border': '1px solid #ddd',
'loadButton.color': '#222',
'loadButton.fontFamily': "'Noto Sans', sans-serif",
'loadButton.fontSize': '12px',
// download button
'downloadButton.backgroundColor': '#fdba3b',
'downloadButton.border': '1px solid #fdba3b',
'downloadButton.color': '#fff',
'downloadButton.fontFamily': "'Noto Sans', sans-serif",
'downloadButton.fontSize': '12px',
// main icons
'menu.normalIcon.color': '#8a8a8a',
'menu.activeIcon.color': '#555555',
'menu.disabledIcon.color': '#434343',
'menu.hoverIcon.color': '#e9e9e9',
'menu.iconSize.width': '24px',
'menu.iconSize.height': '24px',
// submenu icons
'submenu.normalIcon.color': '#8a8a8a',
'submenu.activeIcon.color': '#555555',
'submenu.iconSize.width': '32px',
'submenu.iconSize.height': '32px',
// submenu primary color
'submenu.backgroundColor': 'transparent',
'submenu.partition.color': '#e5e5e5',
// submenu labels
'submenu.normalLabel.color': '#858585',
'submenu.normalLabel.fontWeight': 'normal',
'submenu.activeLabel.color': '#000',
'submenu.activeLabel.fontWeight': 'normal',
// checkbox style
'checkbox.border': '1px solid #ccc',
'checkbox.backgroundColor': '#fff',
// rango style
'range.pointer.color': '#333',
'range.bar.color': '#ccc',
'range.subbar.color': '#606060',
'range.disabledPointer.color': '#d3d3d3',
'range.disabledBar.color': 'rgba(85,85,85,0.06)',
'range.disabledSubbar.color': 'rgba(51,51,51,0.2)',
'range.value.color': '#000',
'range.value.fontWeight': 'normal',
'range.value.fontSize': '11px',
'range.value.border': '0',
'range.value.backgroundColor': '#f5f5f5',
'range.title.color': '#000',
'range.title.fontWeight': 'lighter',
// colorpicker style
'colorpicker.button.border': '0px',
'colorpicker.title.color': '#000',
};
================================================
FILE: apps/image-editor/index.d.ts
================================================
// Type definitions for TOAST UI Image Editor v3.15.2
// TypeScript Version: 3.2.2
declare namespace tuiImageEditor {
type AngleType = number;
interface IThemeConfig {
'common.bi.image'?: string;
'common.bisize.width'?: string;
'common.bisize.height'?: string;
'common.backgroundImage'?: string;
'common.backgroundColor'?: string;
'common.border'?: string;
'header.backgroundImage'?: string;
'header.backgroundColor'?: string;
'header.border'?: string;
'loadButton.backgroundColor'?: string;
'loadButton.border'?: string;
'loadButton.color'?: string;
'loadButton.fontFamily'?: string;
'loadButton.fontSize'?: string;
'downloadButton.backgroundColor'?: string;
'downloadButton.border'?: string;
'downloadButton.color'?: string;
'downloadButton.fontFamily'?: string;
'downloadButton.fontSize'?: string;
'menu.normalIcon.path'?: string;
'menu.normalIcon.name'?: string;
'menu.activeIcon.path'?: string;
'menu.activeIcon.name'?: string;
'menu.iconSize.width'?: string;
'menu.iconSize.height'?: string;
'submenu.backgroundColor'?: string;
'submenu.partition.color'?: string;
'submenu.normalIcon.path'?: string;
'submenu.normalIcon.name'?: string;
'submenu.activeIcon.path'?: string;
'submenu.activeIcon.name'?: string;
'submenu.iconSize.width'?: string;
'submenu.iconSize.height'?: string;
'submenu.normalLabel.color'?: string;
'submenu.normalLabel.fontWeight'?: string;
'submenu.activeLabel.color'?: string;
'submenu.activeLabel.fontWeight'?: string;
'checkbox.border'?: string;
'checkbox.backgroundColor'?: string;
'range.pointer.color'?: string;
'range.bar.color'?: string;
'range.subbar.color'?: string;
'range.value.color'?: string;
'range.value.fontWeight'?: string;
'range.value.fontSize'?: string;
'range.value.border'?: string;
'range.value.backgroundColor'?: string;
'range.title.color'?: string;
'range.title.fontWeight'?: string;
'colorpicker.button.border'?: string;
'colorpicker.title.color'?: string;
}
interface IIconInfo {
[propName: string]: string;
}
interface IIconOptions {
fill?: string;
left?: number;
top?: number;
}
interface IShapeOptions {
fill?: string;
stroke?: string;
strokeWidth?: number;
width?: number;
height?: number;
rx?: number;
ry?: number;
left?: number;
top?: number;
isRegular?: boolean;
}
interface IGenerateTextOptions {
styles?: ITextStyleConfig;
position?: {
x: number;
y: number;
};
}
type IFilterOptions =
| { blur: number }
| { brightness: number }
| { noise: number }
| { blocksize: number }
| { color: string; distance: number; useAlpha?: boolean }
| { mode: string; color: string; alpha?: number }
| { maskObjId: number };
interface ITextStyleConfig {
fill?: string;
fontFamily?: string;
fontSize?: number;
fontStyle?: string;
fontWeight?: string;
textAlign?: string;
textDecoration?: string;
}
interface IRectConfig {
left: number;
top: number;
width: number;
height: number;
}
interface ICanvasSize {
width: number;
height: number;
}
interface IBrushOptions {
width: number;
color: string;
}
interface IPositionConfig {
x: number;
y: number;
originX: string;
originY: string;
}
interface IToDataURLOptions {
format?: string;
quality?: number;
multiplier?: number;
left?: number;
top?: number;
width?: number;
height?: number;
}
interface IGraphicObjectProps {
id?: number;
type?: string;
text?: string;
left?: string | number;
top?: string | number;
width?: string | number;
height?: string | number;
fill?: string;
stroke?: string;
strokeWidth?: string | number;
fontFamily?: string;
fontSize?: number;
fontStyle?: string;
fontWeight?: string;
textAlign?: string;
textDecoration?: string;
opacity?: number;
[propName: string]: number | string | boolean | undefined;
}
interface IIncludeUIOptions {
loadImage?: {
path: string;
name: string;
};
theme?: IThemeConfig;
menu?: string[];
initMenu?: string;
uiSize?: {
width: string;
height: string;
};
menuBarPosition?: string;
usageStatistics?: boolean;
}
interface ISelectionStyleConfig {
cornerStyle?: string;
cornerSize?: number;
cornerColor?: string;
cornerStrokeColor?: string;
transparentCorners?: boolean;
lineWidth?: number;
borderColor?: string;
rotatingPointOffset?: number;
}
interface IObjectProps {
// icon, shape
fill: string;
height: number;
id: number;
left: number;
opacity: number;
stroke: string | null;
strokeWidth: number | null;
top: number;
type: string;
width: number;
}
interface ITextObjectProps extends IObjectProps {
fontFamily: string;
fontSize: string;
fontStyle: string;
text: string;
textAlign: string;
textDecoration: string;
}
interface IFilterResolveObject {
type: string;
action: string;
}
interface ICropResolveObject {
oldWidth: number;
oldHeight: number;
newWidth: number;
newHeight: number;
}
interface IFlipXYResolveObject {
flipX: boolean;
flipY: boolean;
angle: AngleType;
}
interface IOptions {
includeUI?: IIncludeUIOptions;
cssMaxWidth?: number;
cssMaxHeight?: number;
usageStatistics?: boolean;
selectionStyle?: ISelectionStyleConfig;
}
interface IUIDimension {
height?: string;
width?: string;
}
interface IImageDimension {
oldHeight?: number;
oldWidth?: number;
newHeight?: number;
newWidth?: number;
}
interface IEditorSize {
uiSize?: IUIDimension;
imageSize?: IImageDimension;
}
interface UI {
resizeEditor(dimension: IEditorSize): Promise<void>;
}
class ImageEditor {
constructor(wrapper: string | Element, options: IOptions);
public ui: UI;
public addIcon(type: string, options?: IIconOptions): Promise<IObjectProps>;
public addImageObject(imgUrl: string): Promise<void>;
public addShape(type: string, options?: IShapeOptions): Promise<IObjectProps>;
public addText(text: string, options?: IGenerateTextOptions): Promise<ITextObjectProps>;
public applyFilter(
type: string,
options?: IFilterOptions,
isSilent?: boolean
): Promise<IFilterResolveObject>;
public changeCursor(cursorType: string): void;
public changeIconColor(id: number, color: string): Promise<void>;
public changeSelectableAll(selectable: boolean): void;
public changeShape(id: number, options?: IShapeOptions, isSilent?: boolean): Promise<void>;
public changeText(id: number, text?: string): Promise<void>;
public changeTextStyle(
id: number,
styleObj: ITextStyleConfig,
isSilent?: boolean
): Promise<void>;
public clearObjects(): Promise<void>;
public clearRedoStack(): void;
public clearUndoStack(): void;
public crop(rect: IRectConfig): Promise<ICropResolveObject>;
public deactivateAll(): void;
public destroy(): void;
public discardSelection(): void;
public flipX(): Promise<IFlipXYResolveObject>;
public flipY(): Promise<IFlipXYResolveObject>;
public getCanvasSize(): ICanvasSize;
public getCropzoneRect(): IRectConfig;
public getDrawingMode(): string;
public getImageName(): string;
public getObjectPosition(id: number, originX: string, originY: string): ICanvasSize;
public getObjectProperties(
id: number,
keys: string | string[] | IGraphicObjectProps
): IGraphicObjectProps;
public hasFilter(type: string): boolean;
public isEmptyRedoStack(): boolean;
public isEmptyUndoStack(): boolean;
public loadImageFromFile(imgFile: File, imageName?: string): Promise<ICropResolveObject>;
public loadImageFromURL(url: string, imageName?: string): Promise<ICropResolveObject>;
public redo(iterationCount: number): Promise<any>;
public registerIcons(infos: IIconInfo): void;
public removeActiveObject(): void;
public removeFilter(type?: string): Promise<IFilterResolveObject>;
public removeObject(id: number): Promise<void>;
public resetFlip(): Promise<IFlipXYResolveObject>;
public resizeCanvasDimension(dimension: ICanvasSize): Promise<void>;
public rotate(angle: AngleType, isSilent?: boolean): Promise<AngleType>;
public setAngle(angle: AngleType, isSilent?: boolean): Promise<AngleType>;
public setBrush(option: IBrushOptions): void;
public setCropzoneRect(mode?: number): void;
public setDrawingShape(type: string, options?: IShapeOptions): void;
public setObjectPosition(id: number, posInfo?: IPositionConfig): Promise<void>;
public setObjectProperties(id: number, keyValue?: IGraphicObjectProps): Promise<void>;
public setObjectPropertiesQuietly(id: number, keyValue?: IGraphicObjectProps): Promise<void>;
public startDrawingMode(mode: string, option?: { width?: number; color?: string }): boolean;
public stopDrawingMode(): void;
public toDataURL(options?: IToDataURLOptions): string;
public undo(iterationCount: number): Promise<any>;
public on(eventName: string, handler: (...args: any[]) => void): void;
}
}
declare module 'tui-image-editor' {
export = tuiImageEditor.ImageEditor;
}
================================================
FILE: apps/image-editor/jest-setup.js
================================================
import 'jest-canvas-mock';
================================================
FILE: apps/image-editor/jest.config.js
================================================
const path = require('path');
const setupFile = path.resolve(__dirname, './jest-setup.js');
module.exports = {
moduleFileExtensions: ['js'],
testEnvironment: 'jsdom',
transform: {
'^.+\\.js$': 'jest-esm-transformer',
'^.+\\.svg$': '<rootDir>/__mocks__/svgMock.js',
},
transformIgnorePatterns: ['<rootDir>/node_modules/'],
testMatch: ['<rootDir>/**/*.spec.js'],
clearMocks: true,
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/js/$1',
'^@css/(.*)$': '<rootDir>/src/css/$1',
'^@svg/(.*)$': '<rootDir>/src/svg/$1',
'^fixtures/(.*)$': '<rootDir>/__mocks__/fileMock.js',
},
setupFiles: [setupFile],
};
================================================
FILE: apps/image-editor/makesvg.js
================================================
/* eslint-disable */
const fs = require('fs');
const mkdirp = require('mkdirp');
const svgstore = require('svgstore');
const svgDir = './src/svg';
function getFileList(dir) {
const targetDir = `${svgDir}/${dir}`;
const sprites = svgstore();
fs.readdir(targetDir, (err, files) => {
if (!files) return;
files.forEach((file) => {
if (file.match(/^\./)) return;
const id = `${dir}-${file.replace(/\.svg$/, '')}`;
const svg = fs.readFileSync(`${targetDir}/${file}`);
sprites.add(id, svg);
});
fs.writeFileSync(`./dist/svg/${dir}.svg`, sprites);
});
}
mkdirp('./dist/svg').then((path) => {
if (path) {
fs.readdir(svgDir, (err, dirs) => {
dirs.forEach((dir) => {
getFileList(dir);
});
});
}
});
================================================
FILE: apps/image-editor/package.json
================================================
{
"name": "tui-image-editor",
"version": "3.15.3",
"description": "TOAST UI ImageEditor",
"keywords": [
"nhn",
"nhn cloud",
"tui",
"component",
"image",
"editor",
"canvas",
"fabric"
],
"main": "dist/tui-image-editor.js",
"files": [
"src",
"dist",
"index.d.ts"
],
"scripts": {
"test": "jest --forceExit --detectOpenHandles",
"test:types": "tsc --project tests/types",
"build": "npm run build:clean && npm run build:svg && npm run build:prod && npm run build:minify && node tsBannerGenerator.js",
"build:clean": "rm -rf ./dist",
"build:prod": "webpack",
"build:minify": "webpack --env minify",
"build:svg": "node makesvg.js",
"serve": "webpack serve",
"doc:dev": "tuidoc --serv",
"doc": "tuidoc",
"update:wrapper": "node scripts/updateWrapper.js",
"publish:cdn": "node scripts/publishToCDN.js"
},
"homepage": "https://github.com/nhn/tui.image-editor",
"bugs": "https://github.com/nhn/tui.image-editor/issues",
"author": "NHN Cloud. FE Development Lab <dl_javascript@nhn.com>",
"repository": {
"type": "git",
"url": "https://github.com/nhn/tui.image-editor.git"
},
"license": "MIT",
"browserslist": [
"last 2 versions",
"not ie <= 9"
],
"dependencies": {
"fabric": "^4.2.0",
"tui-code-snippet": "^2.3.3",
"tui-color-picker": "^2.2.6"
}
}
================================================
FILE: apps/image-editor/scripts/publishToCDN.js
================================================
/* eslint-disable */
const path = require('path');
const fs = require('fs');
const fetch = require('node-fetch');
const pkg = require('../package.json');
const LOCAL_DIST_PATH = path.join(__dirname, '../dist');
const STORAGE_API_URL = 'https://api-storage.cloud.toast.com/v1';
const IDENTITY_API_URL = 'https://api-identity.infrastructure.cloud.toast.com/v2.0';
const TOAST_CLOUD_TENANTID = process.env.TOAST_CLOUD_TENANTID;
const TOAST_CLOUD_STORAGEID = process.env.TOAST_CLOUD_STORAGEID;
const TOAST_CLOUD_USERNAME = process.env.TOAST_CLOUD_USERNAME;
const TOAST_CLOUD_PASSWORD = process.env.TOAST_CLOUD_PASSWORD;
async function getTOASTCloudContainer(token) {
const response = await fetch(`${STORAGE_API_URL}/${TOAST_CLOUD_STORAGEID}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'X-Auth-Token': token,
},
});
const container = await response.text();
return `${container.trim()}/tui-image-editor`;
}
async function getTOASTCloudToken() {
const data = {
auth: {
tenantId: TOAST_CLOUD_TENANTID,
passwordCredentials: {
username: TOAST_CLOUD_USERNAME,
password: TOAST_CLOUD_PASSWORD,
},
},
};
const response = await fetch(`${IDENTITY_API_URL}/tokens`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
});
const result = await response.json();
return result.access.token.id;
}
function publishToCdn(token, localPath, cdnPath) {
const files = fs.readdirSync(localPath);
files.forEach((fileName) => {
const objectPath = `${cdnPath}/${fileName}`;
if (fileName.match(/.(js|css|svg)$/)) {
const readStream = fs.createReadStream(`${localPath}/${fileName}`);
const contentType = /css$/.test(fileName)
? 'text/css'
: /js$/.test(fileName)
? 'text/javascript'
: 'image/svg+xml';
fetch(`${STORAGE_API_URL}/${objectPath}`, {
method: 'PUT',
headers: {
'Content-Type': contentType,
'X-Auth-Token': token,
},
body: readStream,
});
} else {
publishToCdn(token, `${localPath}/${fileName}`, objectPath);
}
});
}
async function publish() {
const token = await getTOASTCloudToken();
const container = await getTOASTCloudContainer(token);
const cdnPath = `${TOAST_CLOUD_STORAGEID}/${container}`;
[`v${pkg.version}`, 'latest'].forEach((dir) => {
publishToCdn(token, LOCAL_DIST_PATH, `${cdnPath}/${dir}`);
});
}
publish();
================================================
FILE: apps/image-editor/scripts/updateWrapper.js
================================================
/* eslint-disable */
const path = require('path');
const fs = require('fs');
const CORE_PACKAGE_JSON_PATH = path.join(__dirname, '../package.json');
const REACT_PACKAGE_JSON_PATH = path.join(__dirname, '../../react-image-editor/package.json');
const VUE_PACKAGE_JSON_PATH = path.join(__dirname, '../../vue-image-editor/package.json');
const corePackage = require(CORE_PACKAGE_JSON_PATH);
const reactPackage = require(REACT_PACKAGE_JSON_PATH);
const vuePackage = require(VUE_PACKAGE_JSON_PATH);
const version = corePackage.version;
reactPackage.version = version;
reactPackage.dependencies['tui-image-editor'] = `^${version}`;
fs.writeFileSync(REACT_PACKAGE_JSON_PATH, `${JSON.stringify(reactPackage, null, 2)}\n`);
vuePackage.version = version;
vuePackage.dependencies['tui-image-editor'] = `^${version}`;
fs.writeFileSync(VUE_PACKAGE_JSON_PATH, `${JSON.stringify(vuePackage, null, 2)}\n`);
================================================
FILE: apps/image-editor/src/css/buttons.styl
================================================
/* ICON BUTTON */
.tie-icon-add-button
&.icon-bubble .{prefix}-button[data-icontype="icon-bubble"] svg > use.active,
&.icon-heart .{prefix}-button[data-icontype="icon-heart"] svg > use.active,
&.icon-location .{prefix}-button[data-icontype="icon-location"] svg > use.active,
&.icon-polygon .{prefix}-button[data-icontype="icon-polygon"] svg > use.active,
&.icon-star .{prefix}-button[data-icontype="icon-star"] svg > use.active,
&.icon-star-2 .{prefix}-button[data-icontype="icon-star-2"] svg > use.active,
&.icon-arrow-3 .{prefix}-button[data-icontype="icon-arrow-3"] svg > use.active,
&.icon-arrow-2 .{prefix}-button[data-icontype="icon-arrow-2"] svg > use.active,
&.icon-arrow .{prefix}-button[data-icontype="icon-arrow"] svg > use.active,
&.icon-bubble .{prefix}-button[data-icontype="icon-bubble"] svg > use.active
display: block;
/* DRAW BUTTON */
.tie-draw-line-select-button
&.line .{prefix}-button.line svg > use.normal,
&.free .{prefix}-button.free svg > use.normal
display: none;
&.line .{prefix}-button.line svg > use.active,
&.free .{prefix}-button.free svg > use.active
display: block;
/* FLIP BUTTON */
.tie-flip-button
&.resetFlip .{prefix}-button.resetFlip,
&.flipX .{prefix}-button.flipX,
&.flipY .{prefix}-button.flipY
svg > use.normal
display: none;
svg > use.active
display: block;
/* MASK BUTTON */
.tie-mask-apply.apply.active .{prefix}-button.apply
label
color: #fff;
svg > use.active
display: block;
/* CROP BUTTON */
.tie-crop-button,
.tie-crop-preset-button
.{prefix}-button.apply
margin-right: 24px;
.{prefix}-button.preset.active svg > use.active
display: block;
.{prefix}-button.apply.active svg > use.active
display: block;
/* RESIZE BUTTON */
.tie-resize-button,
.tie-resize-preset-button
.{prefix}-button.apply
margin-right: 24px;
.{prefix}-button.preset.active svg > use.active
display: block;
.{prefix}-button.apply.active svg > use.active
display: block;
/* SHAPE BUTTON */
.tie-shape-button
&.rect .{prefix}-button.rect,
&.circle .{prefix}-button.circle,
&.triangle .{prefix}-button.triangle
svg > use.normal
display: none;
svg > use.active
display: block;
/* TEXT BUTTON */
.tie-text-effect-button
.{prefix}-button.active svg > use.active
display: block;
.tie-text-align-button
&.tie-text-align-left .{prefix}-button.left svg > use.active,
&.tie-text-align-center .{prefix}-button.center svg > use.active,
&.tie-text-align-right .{prefix}-button.right svg > use.active
display: block;
.tie-mask-image-file,
.tie-icon-image-file
opacity: 0;
position: absolute;
width: 100%;
height: 100%;
border: 1px solid green;
cursor: inherit;
left: 0;
top: 0;
/* FLIP BUTTON */
.tie-zoom-button
&.resetFlip .{prefix}-button.resetFlip,
&.flipX .{prefix}-button.flipX,
&.flipY .{prefix}-button.flipY
svg > use.normal
display: none;
svg > use.active
display: block;
================================================
FILE: apps/image-editor/src/css/checkbox.styl
================================================
/* VIRTUAL CHECKBOX */
.{prefix}-container
.filter-color-item
display: inline-block;
.tui-image-editor-checkbox
display: block;
.{prefix}-checkbox-wrap
display: inline-block !important;
text-align: left;
.{prefix}-checkbox-wrap.fixed-width
width: 187px;
white-space: normal;
.{prefix}-checkbox
display: inline-block;
margin: 1px 0 1px 0;
input
width: 14px;
height: 14px;
opacity: 0;
> label > span
color: #fff;
height: 14px;
position: relative;
input + label:before,
> label > span:before
content: '';
position: absolute;
width: 14px;
height: 14px;
background-color: #fff;
top: 6px;
left: -19px;
display: inline-block;
margin: 0;
text-align: center;
font-size: 11px;
border: 0;
border-radius: 2px;
padding-top: 1px;
box-sizing: border-box;
input[type='checkbox']:checked + span:before
background-size: cover;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IArs4c6QAAAMBJREFUKBWVkjEOwjAMRe2WgZW7IIHEDdhghhuwcQ42rlJugAQS54Cxa5cq1QM5TUpByZfS2j9+dlJVt/tX5ZxbS4ZU9VLkQvSHKTIGRaVJYFmKrBbTCJxE2UgCdDzMZDkHrOV6b95V0US6UmgKodujEZbJg0B0ZgEModO5lrY1TMQf1TpyJGBEjD+E2NPN7ukIUDiF/BfEXgRiGEw8NgkffYGYwCi808fpn/6OvfUfsDr/Vc1IfRf8sKnFVqeiVQfDu0tf/nWH9gAAAABJRU5ErkJggg==');
.{prefix}-selectlist-wrap
position: relative;
select
width: 100%;
height: 28px;
margin-top: 4px;
border: 0;
outline: 0;
border-radius: 0;
border: 1px solid #cbdbdb;
background-color: #fff;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
padding: 0 7px 0 10px;
.{prefix}-selectlist
display: none;
position: relative;
top: -1px;
border: 1px solid #ccc;
background-color: #fff;
border-top: 0px;
padding: 4px 0;
li
display: block;
text-align: left;
padding: 7px 10px;
font-family: 'Noto Sans', sans-serif;
li:hover
background-color: rgba(81, 92, 230, 0.05);
.{prefix}-selectlist-wrap:before
content: '';
position: absolute;
display: inline-block;
width: 14px;
height: 14px;
right: 5px;
top: 10px;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IArs4c6QAAAHlJREFUKBVjYBgFOEOAEVkmPDxc89+/f6eAYjzI4kD2FyYmJrOVK1deh4kzwRggGiQBVJCELAZig8SQNYHEmEEEMrh69eo1HR0dfqCYJUickZGxf9WqVf3IakBsFBthklpaWmVA9mEQhrJhUoTp0NBQCRAmrHL4qgAAuu4cWZOZIGsAAAAASUVORK5CYII=');
background-size: cover;
.{prefix}-selectlist-wrap select::-ms-expand
display:none;
================================================
FILE: apps/image-editor/src/css/colorpicker.styl
================================================
/* COLOR PICKER */
.{prefix}-container
div.tui-colorpicker-clearfix
width: 159px;
height: 28px;
border: 1px solid #d5d5d5;
border-radius: 2px;
background-color: #f5f5f5;
margin-top: 6px;
padding: 4px 7px 4px 7px;
.tui-colorpicker-palette-hex
width: 114px;
background-color: #f5f5f5;
border: 0;
font-size: 11px;
margin-top: 2px;
font-family: 'Noto Sans', sans-serif;
.tui-colorpicker-palette-hex[value='#ffffff'] + .tui-colorpicker-palette-preview,
.tui-colorpicker-palette-hex[value=''] + .tui-colorpicker-palette-preview
border: 1px solid #ccc;
.tui-colorpicker-palette-hex[value=''] + .tui-colorpicker-palette-preview
background-size: cover;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAdBJREFUWAnFl0FuwjAQRZ0ukiugHqFSOQNdseuKW3ALzkA4BateICvUGyCxrtRFd4WuunH/TzykaYJrnLEYaTJJsP2+x8GZZCbQrLU5mj7Bn+EP8HvnCObd+R7xBV5lWfaNON4AnsA38E94qLEt+0yiFaBzAV/Bv+Cxxr4co7hKCDpw1q9wLeNYYdlAwyn8TYt8Hme3+8D5ozcTaMCZ68PXa2tnM2sbEcOZAJhrrpl2DAcTOGNjZPSfCdzkw6JrfbiMv+osBe4y9WOedhm4jZfhbENWuxS44H9Wz/xw4WzqLOAqh1+zycgAwzEMzr5k5gaHOa9ULBwuuDkFlHI1Kl4PJ66kgIpnoywOTmRFAYcbwYk9UMApWkD8zAV5ihcwHk4Rx7gl0IFTQL0EFc+CTQ9OZHWH3YhlVJiVpTHbrTGLhTHLZVgff6s9lyBsI9KduSS83oj+34rTwJutmBmCnMsvozRwZqB5GTkBw6/jdPDu69iJ6BYk6eCcfbcgcQIK/MByaaiMqm8rHcjol2TnpWDhyAKSGdA3FrxtJUToX0ODqatetfGE+8tyEUOV8GY5dGRwLP/MBS4RHQr4bT7NRAQjlcOTfZxmv2G+c4hI8nn+Ax5PG/zhI393AAAAAElFTkSuQmCC');
.tui-colorpicker-palette-preview
border-radius: 100%;
float: left;
width: 17px;
height: 17px;
border: 0;
.color-picker-control
position: absolute;
display: none;
z-index: 99;
width: 192px;
background-color: #fff;
box-shadow: 0 3px 22px 6px rgba(0, 0, 0, .15);
padding: 16px;
border-radius: 2px;
.tui-colorpicker-palette-toggle-slider
display: none;
.tui-colorpicker-palette-button
border: 0;
border-radius: 100%;
margin: 2px;
background-size: cover;
font-size: 1px;
&[title='#ffffff']
border: 1px solid #ccc;
&[title='']
border: 1px solid #ccc;
.triangle
width: 0;
height: 0;
border-right: 7px solid transparent;
border-top: 8px solid #fff;
border-left: 7px solid transparent;
position: absolute;
bottom: -8px;
left: 84px;
.tui-colorpicker-container,
.tui-colorpicker-palette-container ul,
.tui-colorpicker-palette-container
width: 100%;
height: auto;
.filter-color-item
.color-picker-control label
font-color: #333;
font-weight: normal;
margin-right: 7pxleft
.tui-image-editor-checkbox
margin-top: 0;
input + label:before,
> label:before
left: -16px;
.color-picker
width: 100%;
height: auto;
.color-picker-value
width: 32px;
height: 32px;
border: 0px;
border-radius: 100%;
margin: auto;
margin-bottom: 1px;
&.transparent
border: 1px solid #cbcbcb;
background-size: cover;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAdBJREFUWAnFl0FuwjAQRZ0ukiugHqFSOQNdseuKW3ALzkA4BateICvUGyCxrtRFd4WuunH/TzykaYJrnLEYaTJJsP2+x8GZZCbQrLU5mj7Bn+EP8HvnCObd+R7xBV5lWfaNON4AnsA38E94qLEt+0yiFaBzAV/Bv+Cxxr4co7hKCDpw1q9wLeNYYdlAwyn8TYt8Hme3+8D5ozcTaMCZ68PXa2tnM2sbEcOZAJhrrpl2DAcTOGNjZPSfCdzkw6JrfbiMv+osBe4y9WOedhm4jZfhbENWuxS44H9Wz/xw4WzqLOAqh1+zycgAwzEMzr5k5gaHOa9ULBwuuDkFlHI1Kl4PJ66kgIpnoywOTmRFAYcbwYk9UMApWkD8zAV5ihcwHk4Rx7gl0IFTQL0EFc+CTQ9OZHWH3YhlVJiVpTHbrTGLhTHLZVgff6s9lyBsI9KduSS83oj+34rTwJutmBmCnMsvozRwZqB5GTkBw6/jdPDu69iJ6BYk6eCcfbcgcQIK/MByaaiMqm8rHcjol2TnpWDhyAKSGdA3FrxtJUToX0ODqatetfGE+8tyEUOV8GY5dGRwLP/MBS4RHQr4bT7NRAQjlcOTfZxmv2G+c4hI8nn+Ax5PG/zhI393AAAAAElFTkSuQmCC');
.color-picker-value + label
color: #fff;
.{prefix}-submenu svg > use
display: none;
.{prefix}-submenu svg > use.normal
display: block;
================================================
FILE: apps/image-editor/src/css/gridtable.styl
================================================
/* GRID VISUAL OF FLIP AND ROTATE MENU */
.{prefix}-container
.{prefix}-grid-visual
display: none;
position: absolute;
width: 100%;
height: 100%;
border: 1px solid rgba(255,255,255,0.7);
.{prefix}-main.{prefix}-menu-flip,
.{prefix}-main.{prefix}-menu-rotate
.tui-image-editor
transition: none;
.{prefix}-main.{prefix}-menu-flip .{prefix}-grid-visual,
.{prefix}-main.{prefix}-menu-rotate .{prefix}-grid-visual,
.{prefix}-main.{prefix}-menu-resize .{prefix}-grid-visual
display: block;
.{prefix}-grid-visual
table
width: 100%;
height: 100%;
border-collapse: collapse;
td
border: 1px solid rgba(255,255,255,0.3);
td.dot:before
content: '';
position: absolute;
box-sizing: border-box;
width: 10px;
height: 10px;
border: 0;
box-shadow: 0 0 1px 0 rgba(0,0,0,0.3);
border-radius: 100%;
background-color: #fff;
td.dot.left-top:before
top: -5px;
left: -5px;
td.dot.right-top:before
top: -5px;
right: -5px;
td.dot.left-bottom:before
bottom: -5px;
left: -5px;
td.dot.right-bottom:before
bottom: -5px;
right: -5px;
================================================
FILE: apps/image-editor/src/css/icon.styl
================================================
/* ICON */
.{prefix}-container
.tie-icon-add-button .{prefix}-button
min-width: 42px;
.svg_ic-menu
.svg_ic-helpmenu
width: 24px;
height: 24px;
.svg_ic-submenu
width: 32px;
height: 32px;
.svg_img-bi
width: 257px;
height: 26px;
.{prefix}-help-menu
.{prefix}-controls
svg > use
display: none;
.enabled svg:hover > use.hover
.normal svg:hover > use.hover
display: block;
.active svg:hover > use.hover
display: none;
.on svg > use.hover,
.opened svg > use.hover
display: block;
svg > use.normal
display: block;
.active svg > use.active
display: block;
.enabled svg > use.enabled
display: block;
.active svg > use.normal,
.enabled svg > use.normal
display: none;
.help svg > use.disabled,
.help.enabled svg > use.normal
display: block;
.help.enabled svg > use.disabled
display: none;
.{prefix}-controls:hover
z-index: 3;
================================================
FILE: apps/image-editor/src/css/index.styl
================================================
prefix = 'tui-image-editor'
@import 'main.styl'
@import 'gridtable.styl'
@import 'submenu.styl'
@import 'checkbox.styl'
@import 'range.styl'
@import 'position.styl'
@import 'icon.styl'
@import 'colorpicker.styl'
@import 'buttons.styl'
.{prefix}-container.top
&.{prefix}-top-optimization
.{prefix}-controls ul
text-align: right;
.{prefix}-controls-logo
display: none;
================================================
FILE: apps/image-editor/src/css/main.styl
================================================
body > textarea
position: fixed !important;
+prefix-classes(prefix)
.-container
margin: 0;
padding: 0;
box-sizing: border-box;
min-height: 300px;
height: 100%;
position: relative;
background-color: #282828;
overflow: hidden;
letter-spacing: 0.3px;
div, ul, label, input, li
box-sizing: border-box;
margin: 0;
padding: 0;
-ms-user-select: none;
-moz-user-select: -moz-none;
-khtml-user-select: none;
-webkit-user-select: none;
user-select: none;
.-header
/* BUTTON AND LOGO */
min-width: 533px;
position: absolute;
background-color: #151515;
top: 0;
width: 100%;
.-header-buttons,
.-controls-buttons
float: right;
margin: 8px;
.-header-logo,
.-controls-logo
float: left;
width: 30%;
padding: 17px;
.-controls-logo,
.-controls-buttons
width: 270px;
height: 100%;
display: none;
.-header-buttons button,
.-header-buttons div,
.-controls-buttons button,
.-controls-buttons div
display: inline-block;
position: relative;
width: 120px;
height: 40px;
padding: 0;
line-height: 40px;
outline: none;
border-radius: 20px;
border: 1px solid #ddd;
font-family: 'Noto Sans', sans-serif;
font-size: 12px;
font-weight: bold;
cursor: pointer;
vertical-align: middle;
letter-spacing: 0.3px;
text-align: center;
.-download-btn
background-color: #fdba3b;
border-color: #fdba3b;
color: #fff;
.-load-btn
position: absolute;
left: 0;
right: 0;
display: inline-block;
top: 0;
bottom: 0;
width: 100%;
cursor: pointer;
opacity: 0;
.-main-container
position: absolute;
width: 100%;
top: 0;
bottom: 64px;
.-main
position: absolute;
text-align: center;
top: 64px;
bottom: 0;
right: 0;
left: 0;
.-wrap
position: absolute;
bottom: 0;
width: 100%;
overflow: auto;
.-size-wrap
display: table;
width: 100%;
height: 100%
.-align-wrap
display: table-cell;
vertical-align: middle;
.
position: relative;
display: inline-block;
/* BIG MENU */
.{prefix}-container
.{prefix}-menu, .{prefix}-help-menu
width: auto;
list-style: none;
padding: 0;
margin: 0 auto;
display: table-cell;
text-align: center;
vertical-align: middle;
white-space: nowrap;
> .{prefix}-item
position: relative;
display: inline-block;
border-radius: 2px;
padding: 7px 8px 3px 8px;
cursor: pointer;
margin: 0 4px;
> .{prefix}-item[tooltip-content]:hover
&:before
content: '';
position: absolute;
display: inline-block;
margin: 0 auto 0;
width: 0;
height: 0;
border-right: 7px solid transparent;
border-top: 7px solid #2f2f2f;
border-left: 7px solid transparent;
left: 13px;
top: -2px;
&:after
content: attr(tooltip-content);
position: absolute;
display: inline-block;
background-color: #2f2f2f;
color: #fff;
padding: 5px 8px;
font-size: 11px;
font-weight: lighter;
border-radius: 3px;
max-height: 23px;
top: -25px;
left: 0;
min-width: 24px;
> .{prefix}-item.active
background-color: #fff;
transition: all .3s ease;
.{prefix}-wrap
position: absolute;
================================================
FILE: apps/image-editor/src/css/position.styl
================================================
/* POSITION LEFT */
.{prefix}-container
&.left
.{prefix}-menu
> .{prefix}-item[tooltip-content]
&:before
left: 28px;
top: 11px;
border-right: 7px solid #2f2f2f;
border-top: 7px solid transparent;
border-bottom: 7px solid transparent;
&:after
top: 7px;
left: 42px;
white-space: nowrap;
.{prefix}-submenu
left: 0;
height: 100%;
width: 248px;
.{prefix}-main-container
left: 64px;
width: calc(100% - 64px);
height: 100%;
.{prefix}-controls
width: 64px;
height: 100%;
display: table;
/* POSITION LEFT & RIGHT */
.{prefix}-container
&.left, &.right
.{prefix}-menu
white-space: inherit;
.{prefix}-submenu
white-space: normal;
> div
vertical-align: middle;
.{prefix}-controls li
display: inline-block;
margin: 4px auto;
.{prefix}-icpartition
position: relative;
top: -7px;
width: 24px;
height: 1px;
.{prefix}-submenu
.{prefix}-partition
display: block;
width: 75%;
margin: auto;
> div
border-left: 0;
height:10px;
border-bottom: 1px solid #3c3c3c;
width: 100%;
margin: 0;
.{prefix}-submenu-align
margin-right: 0;
.{prefix}-submenu-item
li
margin-top: 15px;
.tui-colorpicker-clearfix li
margin-top: 0;
.{prefix}-checkbox-wrap.fixed-width
width: 182px;
white-space: normal;
.{prefix}-range-wrap.{prefix}-newline label.range
display: block;
text-align: left;
width: 75%;
margin: auto;
.{prefix}-range
width: 136px;
/* POSITION RIGHT */
.{prefix}-container
&.right
.{prefix}-menu
> .{prefix}-item[tooltip-content]
&:before
left: -3px;
top: 11px;
border-left: 7px solid #2f2f2f;
border-top: 7px solid transparent;
border-bottom: 7px solid transparent;
&:after
top: 7px;
left: unset;
right: 43px;
white-space: nowrap;
.{prefix}-submenu
right: 0;
height: 100%;
width: 248px;
.{prefix}-main-container
right: 64px;
width: calc(100% - 64px);
height: 100%;
.{prefix}-controls
right: 0;
width: 64px;
height: 100%;
display: table;
/* POSITION TOP & BOTTOM */
.{prefix}-container
&.top, &.bottom
.{prefix}-submenu
.{prefix}-partition.only-left-right
display: none;
/* POSITION BOTTOM */
.{prefix}-container
&.bottom .tui-image-editor-submenu > div
padding-bottom: 24px;
/* POSITION TOP */
.{prefix}-container
&.top
.color-picker-control .triangle
top: -8px;
border-right: 7px solid transparent;
border-top: 0px;
border-left: 7px solid transparent;
border-bottom: 8px solid #fff;
.{prefix}-size-wrap
height: 100%;
.{prefix}-main-container
bottom: 0;
.{prefix}-menu
> .{prefix}-item[tooltip-content]
&:before
left: 13px;
border-top: 0;
border-bottom: 7px solid #2f2f2f;
top: 33px;
&:after
top: 38px;
.{prefix}-submenu
top: 0;
bottom: auto;
> div
padding-top: 24px;
vertical-align: top;
.{prefix}-controls-logo
display: table-cell;
.{prefix}-controls-buttons
display: table-cell;
.{prefix}-main
top: 64px;
height: calc(100% - 64px);
.{prefix}-controls
top: 0;
bottom: inherit;
/* HELP MENUBAR POSITION TOP */
.{prefix}-container
.{prefix}-help-menu
&.top
white-space: nowrap;
width: 506px;
height: 40px;
top: 8px;
left: 50%;
transform: translateX(-50%);
.tie-panel-history
top: 45px;
.opened .tie-panel-history:before
border-right: 8px solid transparent;
border-left: 8px solid transparent;
border-bottom: 8px solid #fff;
left: 90px;
top: -8px;
> .{prefix}-item[tooltip-content]
&:before
left: 13px;
top: 35px;
border: none;
border-bottom: 7px solid #2f2f2f;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
&:after
top: 41px;
left: -4px;
white-space: nowrap;
> .{prefix}-item[tooltip-content].opened
&:before,
&:after
content: none;
/* HELP MENUBAR POSITION BOTTOM */
.{prefix}-container
.{prefix}-help-menu
&.bottom
white-space: nowrap;
width: 506px;
height: 40px;
bottom: 8px;
left: 50%;
transform: translateX(-50%);
.tie-panel-history
bottom: 45px;
.opened .tie-panel-history:before
border-right: 8px solid transparent;
border-left: 8px solid transparent;
border-top: 8px solid #fff;
left: 90px;
bottom: -8px;
> .{prefix}-item[tooltip-content]
&:before
left: 13px;
top: auto;
bottom: 36px;
border: none;
border-top: 7px solid #2f2f2f;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
&:after
top: auto;
left: -4px;
bottom: 41px;
white-space: nowrap;
> .{prefix}-item[tooltip-content].opened
&:before,
&:after
content: none;
/* HELP MENUBAR POSITION LEFT */
.{prefix}-container
.{prefix}-help-menu
&.left
white-space: inherit;
width: 40px;
height: 506px;
left: 8px;
top: 50%;
transform: translateY(-50%);
.tie-panel-history
left: 140px;
top: -4px;
.opened .tie-panel-history:before
border-top: 8px solid transparent;
border-bottom: 8px solid transparent;
border-right: 8px solid #fff;
left: -8px;
top: 14px;
.{prefix}-item
margin: 4px auto;
padding: 6px 8px;
> .{prefix}-item[tooltip-content]
&:before
left: 27px;
top: 11px;
border: none;
border-right: 7px solid #2f2f2f;
border-top: 7px solid transparent;
border-bottom: 7px solid transparent;
&:after
top: 7px;
left: 40px;
white-space: nowrap;
> .{prefix}-item[tooltip-content].opened
&:before,
&:after
content: none;
/* HELP MENUBAR POSITION RIGHT */
.{prefix}-container
.{prefix}-help-menu
&.right
white-space: inherit;
width: 40px;
height: 506px;
right: 8px;
top: 50%;
transform: translateY(-50%);
.tie-panel-history
right: -30px;
top: -4px;
.opened .tie-panel-history:before
border-top: 8px solid transparent;
border-bottom: 8px solid transparent;
border-left: 8px solid #fff;
right: -8px;
top: 14px;
.{prefix}-item
margin: 4px auto;
padding: 6px 8px;
> .{prefix}-item[tooltip-content]
&:before
left: -6px;
top: 11px;
border: none;
border-left: 7px solid #2f2f2f;
border-top: 7px solid transparent;
border-bottom: 7px solid transparent;
&:after
top: 7px;
left: auto;
right: 39px;
white-space: nowrap;
> .{prefix}-item[tooltip-content].opened
&:before,
&:after
content: none;
================================================
FILE: apps/image-editor/src/css/range.styl
================================================
/* VIRTUAL RANGE */
.{prefix}-container
.{prefix}-virtual-range-bar
.{prefix}-virtual-range-subbar
.{prefix}-virtual-range-pointer
.{prefix}-disabled
background-color: red;
.{prefix}-range
position: relative;
top: 5px;
width: 166px;
height: 17px;
display: inline-block;
.{prefix}-virtual-range-bar
top: 7px;
position: absolute;
width: 100%;
height: 2px;
background-color: #666666;
.{prefix}-virtual-range-subbar
position: absolute;
height: 100%;
left: 0;
right: 0;
background-color: #d1d1d1;
.{prefix}-virtual-range-pointer
position: absolute;
cursor: pointer;
top: -5px;
left: 0;
width: 12px;
height: 12px;
background-color: #fff;
border-radius: 100%;
.{prefix}-range-wrap
display: inline-block;
margin-left: 4px;
&.short .tui-image-editor-range
width: 100px;
.color-picker-control
.{prefix}-range
width: 108px;
margin-left: 10px;
.{prefix}-virtual-range-pointer
background-color: #333;
.{prefix}-virtual-range-bar
background-color: #ccc;
.{prefix}-virtual-range-subbar
background-color: #606060;
.{prefix}-range-wrap.{prefix}-newline.short
margin-top: -2px;
margin-left: 19px;
label
color: #8e8e8e;
font-weight: normal;
.{prefix}-range-wrap label
vertical-align: baseline;
font-size: 11px;
margin-right: 7px;
color: #fff;
.{prefix}-range-value
cursor: default;
width: 40px;
height: 24px;
outline: none;
border-radius: 2px;
box-shadow: none;
border: 1px solid #d5d5d5;
text-align: center;
background-color: #1c1c1c;
color: #fff;
font-weight: lighter;
vertical-align: baseline;
font-family: 'Noto Sans', sans-serif;
margin-top: 15px;
margin-left: 4px;
.{prefix}-controls
position: absolute;
background-color: #151515;
width: 100%;
height: 64px;
display: table;
bottom: 0;
z-index: 2;
.{prefix}-icpartition
display: inline-block;
background-color: #444;
width: 1px;
height: 24px;
================================================
FILE: apps/image-editor/src/css/submenu.styl
================================================
/* SUBMENU */
.{prefix}-container
.{prefix}-submenu
display: none;
position: absolute;
bottom: 0;
width:100%;
height: 150px;
white-space: nowrap;
z-index: 2;
.{prefix}-button:hover svg > use.active
display: block;
.{prefix}-submenu-item
li
display: inline-block;
vertical-align: top;
.{prefix}-newline
display: block;
margin-top: 0;
.{prefix}-button
position: relative;
cursor: pointer;
display: inline-block;
font-weight: normal;
font-size: 11px;
margin: 0 9px 0 9px;
.{prefix}-button.preset
margin: 0 9px 20px 5px;
label > span
display: inline-block;
cursor: pointer;
padding-top: 5px;
font-family: "Noto Sans", sans-serif;
font-size: 11px;
.{prefix}-button.apply label,
.{prefix}-button.cancel label
vertical-align: 7px;
> div
display: none;
vertical-align: bottom;
.{prefix}-submenu-style
opacity: 0.95;
z-index: -1;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: block;
.{prefix}-partition > div
width: 1px;
height: 52px;
border-left: 1px solid #3c3c3c;
margin: 0 8px 0 8px;
.{prefix}-main.{prefix}-menu-filter .{prefix}-partition > div
height: 108px;
margin: 0 29px 0 0px;
.{prefix}-submenu-align
text-align: left;
margin-right: 30px;
label > span
width: 55px;
white-space: nowrap;
.{prefix}-submenu-align:first-child
margin-right: 0;
label > span
width: 70px;
.{prefix}-main.{prefix}-menu-crop .{prefix}-submenu > div.{prefix}-menu-crop,
.{prefix}-main.{prefix}-menu-resize .{prefix}-submenu > div.{prefix}-menu-resize,
.{prefix}-main.{prefix}-menu-flip .{prefix}-submenu > div.{prefix}-menu-flip,
.{prefix}-main.{prefix}-menu-rotate .{prefix}-submenu > div.{prefix}-menu-rotate,
.{prefix}-main.{prefix}-menu-shape .{prefix}-submenu > div.{prefix}-menu-shape,
.{prefix}-main.{prefix}-menu-text .{prefix}-submenu > div.{prefix}-menu-text,
.{prefix}-main.{prefix}-menu-mask .{prefix}-submenu > div.{prefix}-menu-mask,
.{prefix}-main.{prefix}-menu-icon .{prefix}-submenu > div.{prefix}-menu-icon,
.{prefix}-main.{prefix}-menu-draw .{prefix}-submenu > div.{prefix}-menu-draw,
.{prefix}-main.{prefix}-menu-filter .{prefix}-submenu > div.{prefix}-menu-filter,
.{prefix}-main.{prefix}-menu-zoom .{prefix}-submenu > div.{prefix}-menu-zoom
display: table-cell;
.{prefix}-main.{prefix}-menu-crop,
.{prefix}-main.{prefix}-menu-resize,
.{prefix}-main.{prefix}-menu-flip,
.{prefix}-main.{prefix}-menu-rotate,
.{prefix}-main.{prefix}-menu-shape,
.{prefix}-main.{prefix}-menu-text,
.{prefix}-main.{prefix}-menu-mask,
.{prefix}-main.{prefix}-menu-icon,
.{prefix}-main.{prefix}-menu-draw,
.{prefix}-main.{prefix}-menu-filter,
.{prefix}-main.{prefix}-menu-zoom
.{prefix}-submenu
display: table;
/* Help menu bar */
.{prefix}-container
.{prefix}-help-menu
list-style: none;
padding: 0;
margin: 0 auto;
text-align: center;
vertical-align: middle;
border-radius: 20px;
background-color: rgba(255, 255, 255, 0.06);
z-index: 2;
position: absolute;
.tie-panel-history
display: none;
background-color: #fff;
color: #444;
position: absolute;
width: 196px;
height: 276px;
padding: 4px 2px;
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.15);
cursor: auto;
transform: translateX(calc(-50% + 12px));
.history-list
height: 268px;
padding: 0;
overflow: hidden scroll;
list-style: none;
.history-item
height: 24px;
font-size: 11px;
line-height: 24px;
.{prefix}-history-item
position: relative;
height: 24px;
cursor: pointer;
svg
width: 24px;
height: 24px;
span
display: inline-block;
width: 128px;
height: 24px;
text-align: left;
.history-item-icon
display: inline-block;
width: 24px;
height: 24px;
position: absolute;
top: 6px;
left: 6px;
.history-item-checkbox
display: none;
width: 24px;
height: 24px;
position: absolute;
top: 5px;
right: -6px;
&.selected-item
background-color: rgba(119, 119, 119, 0.12);
.history-item-checkbox
display: inline-block;
&.disabled-item
color: #333;
opacity: 0.3;
.opened .tie-panel-history
display: block;
&:before
content: '';
position: absolute;
display: inline-block;
margin: 0 auto;
width: 0;
height: 0;
================================================
FILE: apps/image-editor/src/index.js
================================================
import '@/polyfill';
import ImageEditor from '@/imageEditor';
import '@css/index.styl';
// commands
import '@/command/addIcon';
import '@/command/addImageObject';
import '@/command/addObject';
import '@/command/addShape';
import '@/command/addText';
import '@/command/applyFilter';
import '@/command/changeIconColor';
import '@/command/changeShape';
import '@/command/changeText';
import '@/command/changeTextStyle';
import '@/command/clearObjects';
import '@/command/flip';
import '@/command/loadImage';
import '@/command/removeFilter';
import '@/command/removeObject';
import '@/command/resizeCanvasDimension';
import '@/command/rotate';
import '@/command/setObjectProperties';
import '@/command/setObjectPosition';
import '@/command/changeSelection';
import '@/command/resize';
export default ImageEditor;
export { ImageEditor };
================================================
FILE: apps/image-editor/src/js/action.js
================================================
import extend from 'tui-code-snippet/object/extend';
import Imagetracer from '@/helper/imagetracer';
import { isSupportFileApi, base64ToBlob, toInteger, isEmptyCropzone, includes } from '@/util';
import { eventNames, historyNames, drawingModes, drawingMenuNames, zoomModes } from '@/consts';
export default {
/**
* Get ui actions
* @returns {Object} actions for ui
* @private
*/
getActions() {
return {
main: this._mainAction(),
shape: this._shapeAction(),
crop: this._cropAction(),
resize: this._resizeAction(),
flip: this._flipAction(),
rotate: this._rotateAction(),
text: this._textAction(),
mask: this._maskAction(),
draw: this._drawAction(),
icon: this._iconAction(),
filter: this._filterAction(),
history: this._historyAction(),
};
},
/**
* Main Action
* @returns {Object} actions for ui main
* @private
*/
_mainAction() {
const exitCropOnAction = () => {
if (this.ui.submenu === 'crop') {
this.stopDrawingMode();
this.ui.changeMenu('crop');
}
};
const setAngleRangeBarOnAction = (angle) => {
if (this.ui.submenu === 'rotate') {
this.ui.rotate.setRangeBarAngle('setAngle', angle);
}
};
const setFilterStateRangeBarOnAction = (filterOptions) => {
if (this.ui.submenu === 'filter') {
this.ui.filter.setFilterState(filterOptions);
}
};
const onEndUndoRedo = (result) => {
setAngleRangeBarOnAction(result);
setFilterStateRangeBarOnAction(result);
return result;
};
const toggleZoomMode = () => {
const zoomMode = this._graphics.getZoomMode();
this.stopDrawingMode();
if (zoomMode !== zoomModes.ZOOM) {
this.startDrawingMode(drawingModes.ZOOM);
this._graphics.startZoomInMode();
} else {
this._graphics.endZoomInMode();
}
};
const toggleHandMode = () => {
const zoomMode = this._graphics.getZoomMode();
this.stopDrawingMode();
if (zoomMode !== zoomModes.HAND) {
this.startDrawingMode(drawingModes.ZOOM);
this._graphics.startHandMode();
} else {
this._graphics.endHandMode();
}
};
const initFilterState = () => {
if (this.ui.filter) {
this.ui.filter.initFilterCheckBoxState();
}
};
return extend(
{
initLoadImage: (imagePath, imageName) =>
this.loadImageFromURL(imagePath, imageName).then((sizeValue) => {
exitCropOnAction();
this.ui.initializeImgUrl = imagePath;
this.ui.resizeEditor({ imageSize: sizeValue });
this.clearUndoStack();
this._invoker.fire(eventNames.EXECUTE_COMMAND, historyNames.LOAD_IMAGE);
}),
undo: () => {
if (!this.isEmptyUndoStack()) {
exitCropOnAction();
this.deactivateAll();
this.undo().then(onEndUndoRedo);
}
},
redo: () => {
if (!this.isEmptyRedoStack()) {
exitCropOnAction();
this.deactivateAll();
this.redo().then(onEndUndoRedo);
}
},
reset: () => {
exitCropOnAction();
this.loadImageFromURL(this.ui.initializeImgUrl, 'resetImage').then((sizeValue) => {
exitCropOnAction();
initFilterState();
this.ui.resizeEditor({ imageSize: sizeValue });
this.clearUndoStack();
this._initHistory();
});
},
delete: () => {
this.ui.changeHelpButtonEnabled('delete', false);
exitCropOnAction();
this.removeActiveObject();
this.activeObjectId = null;
},
deleteAll: () => {
exitCropOnAction();
this.clearObjects();
this.ui.changeHelpButtonEnabled('delete', false);
this.ui.changeHelpButtonEnabled('deleteAll', false);
},
load: (file) => {
if (!isSupportFileApi()) {
alert('This browser does not support file-api');
}
this.ui.initializeImgUrl = URL.createObjectURL(file);
this.loadImageFromFile(file)
.then((sizeValue) => {
exitCropOnAction();
initFilterState();
this.clearUndoStack();
this.ui.activeMenuEvent();
this.ui.resizeEditor({ imageSize: sizeValue });
this._clearHistory();
this._invoker.fire(eventNames.EXECUTE_COMMAND, historyNames.LOAD_IMAGE);
})
['catch']((message) => Promise.reject(message));
},
download: () => {
const dataURL = this.toDataURL();
let imageName = this.getImageName();
let blob, type, w;
if (isSupportFileApi() && window.saveAs) {
blob = base64ToBlob(dataURL);
type = blob.type.split('/')[1];
if (imageNam
gitextract__edmw0b4/ ├── .editorconfig ├── .eslintrc.js ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.md │ │ ├── feature_request.md │ │ └── question.md │ ├── auto-comment.yml │ ├── composite-actions/ │ │ ├── build-package/ │ │ │ └── action.yml │ │ ├── install-dependencies/ │ │ │ └── action.yml │ │ ├── publish-cdn/ │ │ │ └── action.yml │ │ ├── publish-docs/ │ │ │ └── action.yml │ │ └── publish-package/ │ │ └── action.yml │ ├── stale.yml │ └── workflows/ │ ├── detectRuntimeError.yml │ ├── publish-docs.yml │ ├── publish-npm.yml │ └── publish-wrapper.yml ├── .gitignore ├── .prettierrc ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md ├── LICENSE ├── README.md ├── apps/ │ ├── image-editor/ │ │ ├── README.md │ │ ├── __mocks__/ │ │ │ ├── fileMock.js │ │ │ └── svgMock.js │ │ ├── createConfigVariable.js │ │ ├── examples/ │ │ │ ├── css/ │ │ │ │ ├── service-basic.css │ │ │ │ ├── service-mobile.css │ │ │ │ └── tui-example-style.css │ │ │ ├── example01-includeUi.html │ │ │ ├── example02-useApiDirect.html │ │ │ ├── example03-mobile.html │ │ │ ├── examples.json │ │ │ └── js/ │ │ │ ├── service-basic.js │ │ │ ├── service-mobile.js │ │ │ └── theme/ │ │ │ ├── black-theme.js │ │ │ └── white-theme.js │ │ ├── index.d.ts │ │ ├── jest-setup.js │ │ ├── jest.config.js │ │ ├── makesvg.js │ │ ├── package.json │ │ ├── scripts/ │ │ │ ├── publishToCDN.js │ │ │ └── updateWrapper.js │ │ ├── src/ │ │ │ ├── css/ │ │ │ │ ├── buttons.styl │ │ │ │ ├── checkbox.styl │ │ │ │ ├── colorpicker.styl │ │ │ │ ├── gridtable.styl │ │ │ │ ├── icon.styl │ │ │ │ ├── index.styl │ │ │ │ ├── main.styl │ │ │ │ ├── position.styl │ │ │ │ ├── range.styl │ │ │ │ └── submenu.styl │ │ │ ├── index.js │ │ │ └── js/ │ │ │ ├── action.js │ │ │ ├── command/ │ │ │ │ ├── addIcon.js │ │ │ │ ├── addImageObject.js │ │ │ │ ├── addObject.js │ │ │ │ ├── addShape.js │ │ │ │ ├── addText.js │ │ │ │ ├── applyFilter.js │ │ │ │ ├── changeIconColor.js │ │ │ │ ├── changeSelection.js │ │ │ │ ├── changeShape.js │ │ │ │ ├── changeText.js │ │ │ │ ├── changeTextStyle.js │ │ │ │ ├── clearObjects.js │ │ │ │ ├── flip.js │ │ │ │ ├── loadImage.js │ │ │ │ ├── removeFilter.js │ │ │ │ ├── removeObject.js │ │ │ │ ├── resize.js │ │ │ │ ├── resizeCanvasDimension.js │ │ │ │ ├── rotate.js │ │ │ │ ├── setObjectPosition.js │ │ │ │ └── setObjectProperties.js │ │ │ ├── component/ │ │ │ │ ├── cropper.js │ │ │ │ ├── filter.js │ │ │ │ ├── flip.js │ │ │ │ ├── freeDrawing.js │ │ │ │ ├── icon.js │ │ │ │ ├── imageLoader.js │ │ │ │ ├── line.js │ │ │ │ ├── resize.js │ │ │ │ ├── rotation.js │ │ │ │ ├── shape.js │ │ │ │ ├── text.js │ │ │ │ └── zoom.js │ │ │ ├── consts.js │ │ │ ├── drawingMode/ │ │ │ │ ├── cropper.js │ │ │ │ ├── freeDrawing.js │ │ │ │ ├── icon.js │ │ │ │ ├── lineDrawing.js │ │ │ │ ├── resize.js │ │ │ │ ├── shape.js │ │ │ │ ├── text.js │ │ │ │ └── zoom.js │ │ │ ├── extension/ │ │ │ │ ├── arrowLine.js │ │ │ │ ├── blur.js │ │ │ │ ├── colorFilter.js │ │ │ │ ├── cropzone.js │ │ │ │ ├── emboss.js │ │ │ │ ├── mask.js │ │ │ │ └── sharpen.js │ │ │ ├── factory/ │ │ │ │ ├── command.js │ │ │ │ └── errorMessage.js │ │ │ ├── graphics.js │ │ │ ├── helper/ │ │ │ │ ├── imagetracer.js │ │ │ │ ├── selectionModifyHelper.js │ │ │ │ ├── shapeFilterFillHelper.js │ │ │ │ └── shapeResizeHelper.js │ │ │ ├── imageEditor.js │ │ │ ├── interface/ │ │ │ │ ├── command.js │ │ │ │ ├── component.js │ │ │ │ └── drawingMode.js │ │ │ ├── invoker.js │ │ │ ├── polyfill.js │ │ │ ├── ui/ │ │ │ │ ├── crop.js │ │ │ │ ├── draw.js │ │ │ │ ├── filter.js │ │ │ │ ├── flip.js │ │ │ │ ├── history.js │ │ │ │ ├── icon.js │ │ │ │ ├── locale/ │ │ │ │ │ └── locale.js │ │ │ │ ├── mask.js │ │ │ │ ├── panelMenu.js │ │ │ │ ├── resize.js │ │ │ │ ├── rotate.js │ │ │ │ ├── shape.js │ │ │ │ ├── submenuBase.js │ │ │ │ ├── template/ │ │ │ │ │ ├── controls.js │ │ │ │ │ ├── mainContainer.js │ │ │ │ │ ├── style.js │ │ │ │ │ └── submenu/ │ │ │ │ │ ├── crop.js │ │ │ │ │ ├── draw.js │ │ │ │ │ ├── filter.js │ │ │ │ │ ├── flip.js │ │ │ │ │ ├── history.js │ │ │ │ │ ├── icon.js │ │ │ │ │ ├── mask.js │ │ │ │ │ ├── resize.js │ │ │ │ │ ├── rotate.js │ │ │ │ │ ├── shape.js │ │ │ │ │ ├── text.js │ │ │ │ │ └── zoom.js │ │ │ │ ├── text.js │ │ │ │ ├── theme/ │ │ │ │ │ ├── standard.js │ │ │ │ │ └── theme.js │ │ │ │ └── tools/ │ │ │ │ ├── colorpicker.js │ │ │ │ └── range.js │ │ │ ├── ui.js │ │ │ └── util.js │ │ ├── tests/ │ │ │ ├── __snapshots__/ │ │ │ │ ├── arrowLine.spec.js.snap │ │ │ │ ├── shape.spec.js.snap │ │ │ │ ├── text.spec.js.snap │ │ │ │ └── theme.spec.js.snap │ │ │ ├── action.spec.js │ │ │ ├── arrowLine.spec.js │ │ │ ├── command.spec.js │ │ │ ├── cropper.spec.js │ │ │ ├── cropzone.spec.js │ │ │ ├── drawingMode.spec.js │ │ │ ├── filter.spec.js │ │ │ ├── flip.spec.js │ │ │ ├── graphics.spec.js │ │ │ ├── history.spec.js │ │ │ ├── icon.spec.js │ │ │ ├── imageEditor.spec.js │ │ │ ├── index.js │ │ │ ├── invoker.spec.js │ │ │ ├── line.spec.js │ │ │ ├── promiseApi.spec.js │ │ │ ├── resize.spec.js │ │ │ ├── rotation.spec.js │ │ │ ├── selectionModifyHelper.spec.js │ │ │ ├── shape.spec.js │ │ │ ├── text.spec.js │ │ │ ├── theme.spec.js │ │ │ ├── types/ │ │ │ │ ├── tsconfig.json │ │ │ │ └── type-tests.ts │ │ │ ├── ui.spec.js │ │ │ ├── uiRange.spec.js │ │ │ └── zoom.spec.js │ │ ├── tsBannerGenerator.js │ │ ├── tuidoc.config.json │ │ ├── webpack.common.config.js │ │ ├── webpack.config.js │ │ ├── webpack.dev.config.js │ │ └── webpack.prod.config.js │ ├── react-image-editor/ │ │ ├── .babelrc.json │ │ ├── .eslintrc.js │ │ ├── .storybook/ │ │ │ ├── main.js │ │ │ └── preview.js │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ └── index.js │ │ ├── stories/ │ │ │ └── index.stories.js │ │ └── webpack.config.js │ └── vue-image-editor/ │ ├── .eslintrc.js │ ├── .storybook/ │ │ ├── main.js │ │ └── preview.js │ ├── README.md │ ├── package.json │ ├── src/ │ │ ├── ImageEditor.vue │ │ └── index.js │ ├── stories/ │ │ └── index.stories.js │ ├── vue.config.js │ └── webpack.config.js ├── babel.config.json ├── bower.json ├── docs/ │ ├── Apply-Mobile-Version-Image.md │ ├── Apply-Mobile-Version.md │ ├── Basic-Tutorial.md │ ├── COMMIT_MESSAGE_CONVENTION.md │ ├── ISSUE_TEMPLATE.md │ ├── ImageEditor-2.0.0-Migration-guide.md │ ├── PULL_REQUEST_TEMPLATE.md │ ├── Reference.md │ └── Structure.md ├── lerna.json └── package.json
SYMBOL INDEX (1077 symbols across 97 files)
FILE: apps/image-editor/__mocks__/fileMock.js
method process (line 4) | process(src, filename) {
FILE: apps/image-editor/__mocks__/svgMock.js
method process (line 2) | process() {
FILE: apps/image-editor/createConfigVariable.js
function getTestUrls (line 10) | function getTestUrls() {
function getGlobalVariable (line 28) | function getGlobalVariable() {
FILE: apps/image-editor/examples/js/service-basic.js
function hexToRGBa (line 147) | function hexToRGBa(hex, alpha) {
function base64ToBlob (line 156) | function base64ToBlob(data) {
function resizeEditor (line 177) | function resizeEditor() {
function getBrushSettings (line 185) | function getBrushSettings() {
function activateShapeMode (line 195) | function activateShapeMode() {
function activateIconMode (line 202) | function activateIconMode() {
function activateTextMode (line 206) | function activateTextMode() {
function setTextToolbar (line 213) | function setTextToolbar(obj) {
function setIconToolbar (line 221) | function setIconToolbar(obj) {
function setShapeToolbar (line 227) | function setShapeToolbar(obj) {
function showSubMenu (line 250) | function showSubMenu(type) {
function applyOrRemoveFilter (line 271) | function applyOrRemoveFilter(applying, type, options) {
function onChangeShapeFill (line 568) | function onChangeShapeFill(event) {
function onClickIconSubMenu (line 665) | function onClickIconSubMenu(event) {
FILE: apps/image-editor/examples/js/service-mobile.js
function hexToRGBa (line 96) | function hexToRGBa(hex, alpha) {
function base64ToBlob (line 105) | function base64ToBlob(data) {
function getBrushSettings (line 126) | function getBrushSettings() {
function activateShapeMode (line 136) | function activateShapeMode() {
function activateIconMode (line 140) | function activateIconMode() {
function activateTextMode (line 144) | function activateTextMode() {
function setTextToolbar (line 151) | function setTextToolbar(obj) {
function setIconToolbar (line 159) | function setIconToolbar(obj) {
function setShapeToolbar (line 165) | function setShapeToolbar(obj) {
function showSubMenu (line 189) | function showSubMenu(type) {
FILE: apps/image-editor/index.d.ts
type AngleType (line 5) | type AngleType = number;
type IThemeConfig (line 7) | interface IThemeConfig {
type IIconInfo (line 61) | interface IIconInfo {
type IIconOptions (line 65) | interface IIconOptions {
type IShapeOptions (line 71) | interface IShapeOptions {
type IGenerateTextOptions (line 84) | interface IGenerateTextOptions {
type IFilterOptions (line 92) | type IFilterOptions =
type ITextStyleConfig (line 101) | interface ITextStyleConfig {
type IRectConfig (line 111) | interface IRectConfig {
type ICanvasSize (line 118) | interface ICanvasSize {
type IBrushOptions (line 123) | interface IBrushOptions {
type IPositionConfig (line 128) | interface IPositionConfig {
type IToDataURLOptions (line 135) | interface IToDataURLOptions {
type IGraphicObjectProps (line 145) | interface IGraphicObjectProps {
type IIncludeUIOptions (line 166) | interface IIncludeUIOptions {
type ISelectionStyleConfig (line 182) | interface ISelectionStyleConfig {
type IObjectProps (line 193) | interface IObjectProps {
type ITextObjectProps (line 207) | interface ITextObjectProps extends IObjectProps {
type IFilterResolveObject (line 216) | interface IFilterResolveObject {
type ICropResolveObject (line 221) | interface ICropResolveObject {
type IFlipXYResolveObject (line 228) | interface IFlipXYResolveObject {
type IOptions (line 234) | interface IOptions {
type IUIDimension (line 242) | interface IUIDimension {
type IImageDimension (line 247) | interface IImageDimension {
type IEditorSize (line 254) | interface IEditorSize {
type UI (line 259) | interface UI {
class ImageEditor (line 263) | class ImageEditor {
FILE: apps/image-editor/makesvg.js
function getFileList (line 7) | function getFileList(dir) {
FILE: apps/image-editor/scripts/publishToCDN.js
constant LOCAL_DIST_PATH (line 7) | const LOCAL_DIST_PATH = path.join(__dirname, '../dist');
constant STORAGE_API_URL (line 8) | const STORAGE_API_URL = 'https://api-storage.cloud.toast.com/v1';
constant IDENTITY_API_URL (line 9) | const IDENTITY_API_URL = 'https://api-identity.infrastructure.cloud.toas...
constant TOAST_CLOUD_TENANTID (line 11) | const TOAST_CLOUD_TENANTID = process.env.TOAST_CLOUD_TENANTID;
constant TOAST_CLOUD_STORAGEID (line 12) | const TOAST_CLOUD_STORAGEID = process.env.TOAST_CLOUD_STORAGEID;
constant TOAST_CLOUD_USERNAME (line 13) | const TOAST_CLOUD_USERNAME = process.env.TOAST_CLOUD_USERNAME;
constant TOAST_CLOUD_PASSWORD (line 14) | const TOAST_CLOUD_PASSWORD = process.env.TOAST_CLOUD_PASSWORD;
function getTOASTCloudContainer (line 16) | async function getTOASTCloudContainer(token) {
function getTOASTCloudToken (line 29) | async function getTOASTCloudToken() {
function publishToCdn (line 50) | function publishToCdn(token, localPath, cdnPath) {
function publish (line 78) | async function publish() {
FILE: apps/image-editor/scripts/updateWrapper.js
constant CORE_PACKAGE_JSON_PATH (line 5) | const CORE_PACKAGE_JSON_PATH = path.join(__dirname, '../package.json');
constant REACT_PACKAGE_JSON_PATH (line 6) | const REACT_PACKAGE_JSON_PATH = path.join(__dirname, '../../react-image-...
constant VUE_PACKAGE_JSON_PATH (line 7) | const VUE_PACKAGE_JSON_PATH = path.join(__dirname, '../../vue-image-edit...
FILE: apps/image-editor/src/js/action.js
method getActions (line 12) | getActions() {
method _mainAction (line 34) | _mainAction() {
method _iconAction (line 193) | _iconAction() {
method _drawAction (line 243) | _drawAction() {
method _maskAction (line 269) | _maskAction() {
method _textAction (line 295) | _textAction() {
method _rotateAction (line 313) | _rotateAction() {
method _shapeAction (line 336) | _shapeAction() {
method _cropAction (line 357) | _cropAction() {
method _resizeAction (line 414) | _resizeAction() {
method _flipAction (line 491) | _flipAction() {
method _filterAction (line 505) | _filterAction() {
method setReAction (line 523) | setReAction() {
method _historyAction (line 634) | _historyAction() {
method _commonAction (line 646) | _commonAction() {
method mixin (line 683) | mixin(ImageEditor) {
FILE: apps/image-editor/src/js/command/addIcon.js
method execute (line 19) | execute(graphics, type, options) {
method undo (line 33) | undo(graphics) {
FILE: apps/image-editor/src/js/command/addImageObject.js
method execute (line 13) | execute(graphics, imgUrl) {
method undo (line 25) | undo(graphics) {
FILE: apps/image-editor/src/js/command/addObject.js
method execute (line 13) | execute(graphics, object) {
method undo (line 29) | undo(graphics, object) {
FILE: apps/image-editor/src/js/command/addShape.js
method execute (line 26) | execute(graphics, type, options) {
method undo (line 42) | undo(graphics) {
FILE: apps/image-editor/src/js/command/addText.js
method execute (line 30) | execute(graphics, text, options) {
method undo (line 64) | undo(graphics) {
FILE: apps/image-editor/src/js/command/applyFilter.js
function makeUndoData (line 20) | function makeUndoData(type, prevfilterOption, options) {
method execute (line 44) | execute(graphics, type, options, isSilent) {
method undo (line 72) | undo(graphics, type) {
FILE: apps/image-editor/src/js/command/changeIconColor.js
method execute (line 16) | execute(graphics, id, color) {
method undo (line 36) | undo(graphics) {
FILE: apps/image-editor/src/js/command/changeSelection.js
method execute (line 8) | execute(graphics, props) {
method undo (line 20) | undo(graphics) {
FILE: apps/image-editor/src/js/command/changeShape.js
function makeUndoData (line 19) | function makeUndoData(options, targetObj) {
method execute (line 53) | execute(graphics, id, options, isSilent) {
method undo (line 74) | undo(graphics) {
FILE: apps/image-editor/src/js/command/changeText.js
method execute (line 16) | execute(graphics, id, text) {
method undo (line 34) | undo(graphics) {
FILE: apps/image-editor/src/js/command/changeTextStyle.js
function makeUndoData (line 19) | function makeUndoData(styles, targetObj) {
method execute (line 50) | execute(graphics, id, styles, isSilent) {
method undo (line 70) | undo(graphics) {
FILE: apps/image-editor/src/js/command/clearObjects.js
method execute (line 12) | execute(graphics) {
method undo (line 24) | undo(graphics) {
FILE: apps/image-editor/src/js/command/flip.js
method execute (line 15) | execute(graphics, type) {
method undo (line 27) | undo(graphics) {
FILE: apps/image-editor/src/js/command/loadImage.js
method execute (line 16) | execute(graphics, imageName, imgUrl) {
method undo (line 45) | undo(graphics) {
FILE: apps/image-editor/src/js/command/removeFilter.js
method execute (line 15) | execute(graphics, type) {
method undo (line 28) | undo(graphics, type) {
FILE: apps/image-editor/src/js/command/removeObject.js
method execute (line 13) | execute(graphics, id) {
method undo (line 28) | undo(graphics) {
FILE: apps/image-editor/src/js/command/resize.js
method execute (line 15) | execute(graphics, dimensions) {
method undo (line 32) | undo(graphics) {
FILE: apps/image-editor/src/js/command/resizeCanvasDimension.js
method execute (line 13) | execute(graphics, dimension) {
method undo (line 30) | undo(graphics) {
FILE: apps/image-editor/src/js/command/rotate.js
function makeUndoData (line 17) | function makeUndoData(rotationComp) {
method execute (line 34) | execute(graphics, type, angle, isSilent) {
method undo (line 50) | undo(graphics) {
FILE: apps/image-editor/src/js/command/setObjectPosition.js
method execute (line 18) | execute(graphics, id, posInfo) {
method undo (line 38) | undo(graphics) {
FILE: apps/image-editor/src/js/command/setObjectProperties.js
method execute (line 22) | execute(graphics, id, props) {
method undo (line 44) | undo(graphics, id) {
FILE: apps/image-editor/src/js/component/cropper.js
constant MOUSE_MOVE_THRESHOLD (line 8) | const MOUSE_MOVE_THRESHOLD = 10;
constant DEFAULT_OPTION (line 9) | const DEFAULT_OPTION = {
class Cropper (line 24) | class Cropper extends Component {
method constructor (line 25) | constructor(graphics) {
method start (line 73) | start() {
method end (line 115) | end() {
method changeVisibility (line 140) | changeVisibility(visible) {
method _onFabricMouseDown (line 151) | _onFabricMouseDown(fEvent) {
method _onFabricMouseMove (line 175) | _onFabricMouseMove(fEvent) {
method _calcRectDimensionFromPoint (line 198) | _calcRectDimensionFromPoint(x, y, presetRatio = null) {
method _onFabricMouseUp (line 267) | _onFabricMouseUp() {
method getCroppedImageData (line 288) | getCroppedImageData(cropRect) {
method getCropzoneRect (line 315) | getCropzoneRect() {
method setCropzoneRect (line 334) | setCropzoneRect(presetRatio) {
method _getPresetPropertiesForCropSize (line 358) | _getPresetPropertiesForCropSize(presetRatio) {
method _onKeyDown (line 389) | _onKeyDown(e) {
method _onKeyUp (line 400) | _onKeyUp(e) {
FILE: apps/image-editor/src/js/component/filter.js
class Filter (line 26) | class Filter extends Component {
method constructor (line 27) | constructor(graphics) {
method add (line 37) | add(type, options) {
method remove (line 68) | remove(type) {
method hasFilter (line 96) | hasFilter(type) {
method getOptions (line 105) | getOptions(type) {
method _changeFilterValues (line 121) | _changeFilterValues(imgFilter, options) {
method _apply (line 140) | _apply(sourceImg, callback) {
method _getSourceImage (line 153) | _getSourceImage() {
method _createFilter (line 165) | _createFilter(sourceImg, type, options) {
method _getFilter (line 186) | _getFilter(sourceImg, type) {
method _removeFilter (line 212) | _removeFilter(sourceImg, type) {
method _getFabricFilterType (line 224) | _getFabricFilterType(type) {
FILE: apps/image-editor/src/js/component/flip.js
class Flip (line 12) | class Flip extends Component {
method constructor (line 13) | constructor(graphics) {
method getCurrentSetting (line 21) | getCurrentSetting() {
method set (line 35) | set(newSetting) {
method _invertAngle (line 61) | _invertAngle(isChangingFlipX, isChangingFlipY) {
method _flipObjects (line 80) | _flipObjects(isChangingFlipX, isChangingFlipY) {
method reset (line 112) | reset() {
method flipX (line 123) | flipX() {
method flipY (line 136) | flipY() {
FILE: apps/image-editor/src/js/component/freeDrawing.js
class FreeDrawing (line 12) | class FreeDrawing extends Component {
method constructor (line 13) | constructor(graphics) {
method start (line 33) | start(setting) {
method setBrush (line 44) | setBrush(setting) {
method end (line 59) | end() {
FILE: apps/image-editor/src/js/component/icon.js
class Icon (line 21) | class Icon extends Component {
method constructor (line 22) | constructor(graphics) {
method setStates (line 69) | setStates(type, iconColor) {
method start (line 78) | start() {
method end (line 88) | end() {
method add (line 106) | add(type, options) {
method registerPaths (line 140) | registerPaths(pathInfos) {
method setColor (line 155) | setColor(color, obj) {
method getColor (line 169) | getColor(obj) {
method _createIcon (line 178) | _createIcon(path) {
method _onFabricMouseDown (line 187) | _onFabricMouseDown(fEvent) {
method _onFabricMouseMove (line 209) | _onFabricMouseMove(fEvent) {
method _onFabricMouseUp (line 233) | _onFabricMouseUp() {
FILE: apps/image-editor/src/js/component/imageLoader.js
class ImageLoader (line 16) | class ImageLoader extends Component {
method constructor (line 17) | constructor(graphics) {
method load (line 27) | load(imageName, img) {
method _setBackgroundImage (line 59) | _setBackgroundImage(img) {
FILE: apps/image-editor/src/js/component/line.js
class Line (line 14) | class Line extends Component {
method constructor (line 15) | constructor(graphics) {
method setHeadOption (line 48) | setHeadOption(setting) {
method start (line 63) | start(setting = {}) {
method setBrush (line 87) | setBrush(setting) {
method end (line 103) | end() {
method _onFabricMouseDown (line 123) | _onFabricMouseDown(fEvent) {
method _onFabricMouseMove (line 152) | _onFabricMouseMove(fEvent) {
method _onFabricMouseUp (line 170) | _onFabricMouseUp() {
method _createLineEventObjectProperties (line 188) | _createLineEventObjectProperties() {
FILE: apps/image-editor/src/js/component/resize.js
class Resize (line 11) | class Resize extends Component {
method constructor (line 12) | constructor(graphics) {
method getCurrentDimensions (line 34) | getCurrentDimensions() {
method getOriginalDimensions (line 48) | getOriginalDimensions() {
method setOriginalDimensions (line 56) | setOriginalDimensions(dimensions) {
method resize (line 65) | resize(dimensions) {
method start (line 92) | start() {
method end (line 100) | end() {}
FILE: apps/image-editor/src/js/component/rotation.js
class Rotation (line 12) | class Rotation extends Component {
method constructor (line 13) | constructor(graphics) {
method getCurrentAngle (line 21) | getCurrentAngle() {
method setAngle (line 35) | setAngle(angle) {
method _rotateForEachObject (line 57) | _rotateForEachObject(oldImageCenter, newImageCenter, angleDiff) {
method rotate (line 84) | rotate(additionalAngle) {
FILE: apps/image-editor/src/js/component/shape.js
constant SHAPE_INIT_OPTIONS (line 30) | const SHAPE_INIT_OPTIONS = extend(
constant DEFAULT_TYPE (line 42) | const DEFAULT_TYPE = 'rect';
constant DEFAULT_WIDTH (line 43) | const DEFAULT_WIDTH = 20;
constant DEFAULT_HEIGHT (line 44) | const DEFAULT_HEIGHT = 20;
function makeFabricFillOption (line 54) | function makeFabricFillOption(options, canvasImage, createStaticCanvas) {
class Shape (line 81) | class Shape extends Component {
method constructor (line 82) | constructor(graphics) {
method start (line 145) | start() {
method end (line 165) | end() {
method setStates (line 196) | setStates(type, options) {
method add (line 219) | add(type, options) {
method change (line 253) | change(shapeObj, options) {
method makeFillPropertyForUserEvent (line 279) | makeFillPropertyForUserEvent(shapeObj) {
method processForCopiedObject (line 302) | processForCopiedObject(shapeObj, originalShapeObj) {
method _createInstance (line 324) | _createInstance(type, options) {
method _extendOptions (line 357) | _extendOptions(options) {
method _bindEventOnShape (line 371) | _bindEventOnShape(shapeObj) {
method _onFabricMouseDown (line 425) | _onFabricMouseDown(fEvent) {
method _onFabricMouseMove (line 447) | _onFabricMouseMove(fEvent) {
method _onFabricMouseUp (line 481) | _onFabricMouseUp() {
method _onKeyDown (line 512) | _onKeyDown(e) {
method _onKeyUp (line 527) | _onKeyUp(e) {
method _resetPositionFillFilter (line 542) | _resetPositionFillFilter(shapeObj) {
method _fillFilterRePositionInGroupSelection (line 582) | _fillFilterRePositionInGroupSelection(shapeObj, activeSelection) {
FILE: apps/image-editor/src/js/component/text.js
constant DBCLICK_TIME (line 21) | const DBCLICK_TIME = 500;
class Text (line 30) | class Text extends Component {
method constructor (line 31) | constructor(graphics) {
method start (line 104) | start() {
method end (line 130) | end() {
method adjustOriginPosition (line 162) | adjustOriginPosition(text, editStatus) {
method add (line 193) | add(text, options) {
method change (line 243) | change(activeObj, text) {
method setStyle (line 265) | setStyle(activeObj, styleObj) {
method getText (line 293) | getText(activeObj) {
method setSelectedInfo (line 302) | setSelectedInfo(obj, state) {
method isSelected (line 311) | isSelected() {
method getSelectedObj (line 319) | getSelectedObj() {
method setCanvasRatio (line 326) | setCanvasRatio() {
method getCanvasRatio (line 338) | getCanvasRatio() {
method _getTextDecorationAdaptObject (line 347) | _getTextDecorationAdaptObject(textDecoration) {
method _setInitPos (line 360) | _setInitPos(position) {
method _onInput (line 371) | _onInput() {
method _onKeyDown (line 384) | _onKeyDown() {
method _onBlur (line 401) | _onBlur() {
method _onScroll (line 438) | _onScroll() {
method _onFabricScaling (line 448) | _onFabricScaling(fEvent) {
method _onFabricTextChanged (line 461) | _onFabricTextChanged(props) {
method _onFabricSelectClear (line 470) | _onFabricSelectClear(fEvent) {
method _onFabricSelect (line 490) | _onFabricSelect(fEvent) {
method _onFabricMouseDown (line 501) | _onFabricMouseDown(fEvent) {
method _fireAddText (line 522) | _fireAddText(fEvent) {
method _onFabricMouseUp (line 546) | _onFabricMouseUp(fEvent) {
method _isDoubleClick (line 567) | _isDoubleClick(newClickTime) {
FILE: apps/image-editor/src/js/component/zoom.js
constant MOUSE_MOVE_THRESHOLD (line 6) | const MOUSE_MOVE_THRESHOLD = 10;
constant DEFAULT_SCROLL_OPTION (line 7) | const DEFAULT_SCROLL_OPTION = {
constant DEFAULT_VERTICAL_SCROLL_RATIO (line 20) | const DEFAULT_VERTICAL_SCROLL_RATIO = {
constant DEFAULT_HORIZONTAL_SCROLL_RATIO (line 25) | const DEFAULT_HORIZONTAL_SCROLL_RATIO = {
constant DEFAULT_ZOOM_LEVEL (line 30) | const DEFAULT_ZOOM_LEVEL = 1.0;
class Zoom (line 49) | class Zoom extends Component {
method constructor (line 50) | constructor(graphics) {
method attachKeyboardZoomEvents (line 133) | attachKeyboardZoomEvents() {
method detachKeyboardZoomEvents (line 141) | detachKeyboardZoomEvents() {
method _startTextEditingHandler (line 150) | _startTextEditingHandler() {
method _stopTextEditingHandler (line 158) | _stopTextEditingHandler() {
method _startHandModeWithSpaceBar (line 167) | _startHandModeWithSpaceBar(e) {
method _endHandModeWithSpaceBar (line 183) | _endHandModeWithSpaceBar(e) {
method startZoomInMode (line 193) | startZoomInMode() {
method endZoomInMode (line 225) | endZoomInMode() {
method start (line 248) | start() {
method end (line 257) | end() {
method startHandMode (line 265) | startHandMode() {
method endHandMode (line 285) | endHandMode() {
method _onMouseDownWithZoomMode (line 305) | _onMouseDownWithZoomMode({ target, e }) {
method _onMouseMoveWithZoomMode (line 329) | _onMouseMoveWithZoomMode({ e }) {
method _calcRectDimensionFromPoint (line 351) | _calcRectDimensionFromPoint(x, y) {
method _onMouseUpWithZoomMode (line 370) | _onMouseUpWithZoomMode() {
method _getCenterPoint (line 407) | _getCenterPoint() {
method zoom (line 426) | zoom({ x, y }, zoomLevel = this.zoomLevel) {
method zoomOut (line 458) | zoomOut() {
method resetZoom (line 483) | resetZoom() {
method _isMaxZoomLevel (line 499) | _isMaxZoomLevel() {
method _movePointOfZoom (line 508) | _movePointOfZoom({ x: deltaX, y: deltaY }) {
method _onMouseDownWithHandMode (line 535) | _onMouseDownWithHandMode({ target, e }) {
method _onMouseMoveWithHandMode (line 562) | _onMouseMoveWithHandMode({ e }) {
method _onMouseUpWithHandMode (line 575) | _onMouseUpWithHandMode() {
method _changeScrollState (line 591) | _changeScrollState({ viewport, zoomLevel }) {
method _changeObjectsEventedState (line 654) | _changeObjectsEventedState(evented = true) {
method _addScrollBar (line 666) | _addScrollBar() {
method _isDefaultZoomLevel (line 687) | _isDefaultZoomLevel(zoomLevel) {
method _fireZoomChanged (line 696) | _fireZoomChanged(canvas, zoomLevel) {
method mode (line 703) | get mode() {
FILE: apps/image-editor/src/js/consts.js
constant ZOOM_HELP_MENUS (line 7) | const ZOOM_HELP_MENUS = ['zoomIn', 'zoomOut', 'hand'];
constant COMMAND_HELP_MENUS (line 13) | const COMMAND_HELP_MENUS = ['history', 'undo', 'redo', 'reset'];
constant DELETE_HELP_MENUS (line 19) | const DELETE_HELP_MENUS = ['delete', 'deleteAll'];
constant HELP_MENUS (line 25) | const HELP_MENUS = [...ZOOM_HELP_MENUS, ...COMMAND_HELP_MENUS, ...DELETE...
constant SHAPE_FILL_TYPE (line 31) | const SHAPE_FILL_TYPE = {
constant SHAPE_TYPE (line 40) | const SHAPE_TYPE = ['rect', 'circle', 'triangle'];
constant OBJ_TYPE (line 46) | const OBJ_TYPE = {
constant SHAPE_DEFAULT_OPTIONS (line 87) | const SHAPE_DEFAULT_OPTIONS = {
constant CROPZONE_DEFAULT_OPTIONS (line 98) | const CROPZONE_DEFAULT_OPTIONS = {
FILE: apps/image-editor/src/js/drawingMode/cropper.js
class CropperDrawingMode (line 9) | class CropperDrawingMode extends DrawingMode {
method constructor (line 10) | constructor() {
method start (line 19) | start(graphics) {
method end (line 29) | end(graphics) {
FILE: apps/image-editor/src/js/drawingMode/freeDrawing.js
class FreeDrawingMode (line 9) | class FreeDrawingMode extends DrawingMode {
method constructor (line 10) | constructor() {
method start (line 20) | start(graphics, options) {
method end (line 30) | end(graphics) {
FILE: apps/image-editor/src/js/drawingMode/icon.js
class IconDrawingMode (line 9) | class IconDrawingMode extends DrawingMode {
method constructor (line 10) | constructor() {
method start (line 19) | start(graphics) {
method end (line 29) | end(graphics) {
FILE: apps/image-editor/src/js/drawingMode/lineDrawing.js
class LineDrawingMode (line 9) | class LineDrawingMode extends DrawingMode {
method constructor (line 10) | constructor() {
method start (line 20) | start(graphics, options) {
method end (line 30) | end(graphics) {
FILE: apps/image-editor/src/js/drawingMode/resize.js
class ResizeDrawingMode (line 9) | class ResizeDrawingMode extends DrawingMode {
method constructor (line 10) | constructor() {
method start (line 19) | start(graphics) {
method end (line 29) | end(graphics) {
FILE: apps/image-editor/src/js/drawingMode/shape.js
class ShapeDrawingMode (line 9) | class ShapeDrawingMode extends DrawingMode {
method constructor (line 10) | constructor() {
method start (line 19) | start(graphics) {
method end (line 29) | end(graphics) {
FILE: apps/image-editor/src/js/drawingMode/text.js
class TextDrawingMode (line 9) | class TextDrawingMode extends DrawingMode {
method constructor (line 10) | constructor() {
method start (line 19) | start(graphics) {
method end (line 29) | end(graphics) {
FILE: apps/image-editor/src/js/drawingMode/zoom.js
class ZoomDrawingMode (line 9) | class ZoomDrawingMode extends DrawingMode {
method constructor (line 10) | constructor() {
method start (line 19) | start(graphics) {
method end (line 30) | end(graphics) {
FILE: apps/image-editor/src/js/extension/arrowLine.js
constant ARROW_ANGLE (line 3) | const ARROW_ANGLE = 30;
constant CHEVRON_SIZE_RATIO (line 4) | const CHEVRON_SIZE_RATIO = 2.7;
constant TRIANGLE_SIZE_RATIO (line 5) | const TRIANGLE_SIZE_RATIO = 1.7;
constant RADIAN_CONVERSION_VALUE (line 6) | const RADIAN_CONVERSION_VALUE = 180;
method initialize (line 24) | initialize(points, options = {}) {
method _render (line 35) | _render(ctx) {
method _renderBasicLinePath (line 61) | _renderBasicLinePath({ fromX, fromY, toX, toY }) {
method _drawDecoratorPath (line 76) | _drawDecoratorPath(linePosition) {
method _drawDecoratorPathType (line 91) | _drawDecoratorPathType(type, linePosition) {
method _drawTrianglePath (line 114) | _drawTrianglePath(type, linePosition) {
method _drawChevronPath (line 132) | _drawChevronPath(type, { fromX, fromY, toX, toY }, decorateSize) {
method getRotatePosition (line 163) | getRotatePosition(distance, angle, referencePosition) {
FILE: apps/image-editor/src/js/extension/blur.js
method initialize (line 23) | initialize() {
FILE: apps/image-editor/src/js/extension/colorFilter.js
method initialize (line 27) | initialize(options) {
method applyTo (line 42) | applyTo(canvas) {
method _isOutsideThreshold (line 75) | _isOutsideThreshold(color1, color2, threshold) {
method _getColor (line 88) | _getColor(imageData, x, y) {
FILE: apps/image-editor/src/js/extension/cropzone.js
constant CORNER_TYPE_TOP_LEFT (line 6) | const CORNER_TYPE_TOP_LEFT = 'tl';
constant CORNER_TYPE_TOP_RIGHT (line 7) | const CORNER_TYPE_TOP_RIGHT = 'tr';
constant CORNER_TYPE_MIDDLE_TOP (line 8) | const CORNER_TYPE_MIDDLE_TOP = 'mt';
constant CORNER_TYPE_MIDDLE_LEFT (line 9) | const CORNER_TYPE_MIDDLE_LEFT = 'ml';
constant CORNER_TYPE_MIDDLE_RIGHT (line 10) | const CORNER_TYPE_MIDDLE_RIGHT = 'mr';
constant CORNER_TYPE_MIDDLE_BOTTOM (line 11) | const CORNER_TYPE_MIDDLE_BOTTOM = 'mb';
constant CORNER_TYPE_BOTTOM_LEFT (line 12) | const CORNER_TYPE_BOTTOM_LEFT = 'bl';
constant CORNER_TYPE_BOTTOM_RIGHT (line 13) | const CORNER_TYPE_BOTTOM_RIGHT = 'br';
constant CORNER_TYPE_LIST (line 14) | const CORNER_TYPE_LIST = [
function cornerTypeValid (line 32) | function cornerTypeValid(selectedCorner) {
function getScaleBasis (line 43) | function getScaleBasis(diffX, diffY) {
method initialize (line 65) | initialize(canvas, options, extendsOptions) {
method canvasEventDelegation (line 75) | canvasEventDelegation(eventName) {
method canvasEventRegister (line 86) | canvasEventRegister(eventName, eventTrigger) {
method _addEventHandler (line 89) | _addEventHandler() {
method _renderCropzone (line 101) | _renderCropzone(ctx) {
method _render (line 144) | _render(ctx) {
method _fillOuterRect (line 175) | _fillOuterRect(ctx, fillStyle) {
method _fillInnerRect (line 208) | _fillInnerRect(ctx) {
method _caculateInnerPosition (line 242) | _caculateInnerPosition(outer, size) {
method _getCoordinates (line 257) | _getCoordinates() {
method _strokeBorder (line 289) | _strokeBorder(ctx, strokeStyle, { lineDashWidth, lineDashOffset, lineWid...
method _onMoving (line 321) | _onMoving() {
method _onScaling (line 337) | _onScaling(fEvent) {
method _calcScalingSizeFromPointer (line 356) | _calcScalingSizeFromPointer(pointer, selectedCorner) {
method adjustRatioCropzoneSize (line 372) | adjustRatioCropzoneSize({ width, height, leftMaker, topMaker, maxWidth, ...
method _getCropzoneRectInfo (line 418) | _getCropzoneRectInfo() {
method _resizeCropZone (line 446) | _resizeCropZone({ x, y }, corner) {
method isValid (line 540) | isValid() {
method _onKeyDown (line 549) | _onKeyDown({ keyCode }) {
method _onKeyUp (line 560) | _onKeyUp({ keyCode }) {
FILE: apps/image-editor/src/js/extension/emboss.js
method initialize (line 23) | initialize() {
FILE: apps/image-editor/src/js/extension/mask.js
method applyTo (line 17) | applyTo(pipelineState) {
method _createCanvasOfMask (line 42) | _createCanvasOfMask(width, height) {
method _drawMask (line 56) | _drawMask(maskCtx) {
method _mapData (line 77) | _mapData(maskCtx, imageData, width, height) {
FILE: apps/image-editor/src/js/extension/sharpen.js
method initialize (line 23) | initialize() {
FILE: apps/image-editor/src/js/factory/command.js
function create (line 12) | function create(name, ...args) {
function register (line 29) | function register(command) {
FILE: apps/image-editor/src/js/factory/errorMessage.js
method UN_IMPLEMENTATION (line 10) | UN_IMPLEMENTATION(methodName) {
method NO_COMPONENT_NAME (line 13) | NO_COMPONENT_NAME() {
method create (line 21) | create(type, ...args) {
FILE: apps/image-editor/src/js/graphics.js
constant DEFAULT_CSS_MAX_WIDTH (line 41) | const DEFAULT_CSS_MAX_WIDTH = 1000;
constant DEFAULT_CSS_MAX_HEIGHT (line 42) | const DEFAULT_CSS_MAX_HEIGHT = 800;
constant EXTRA_PX_FOR_PASTE (line 43) | const EXTRA_PX_FOR_PASTE = 10;
class Graphics (line 61) | class Graphics {
method constructor (line 62) | constructor(element, { cssMaxWidth, cssMaxHeight } = {}) {
method destroy (line 165) | destroy() {
method _attachZoomEvents (line 178) | _attachZoomEvents() {
method _detachZoomEvents (line 187) | _detachZoomEvents() {
method deactivateAll (line 197) | deactivateAll() {
method renderAll (line 207) | renderAll() {
method add (line 217) | add(objects) {
method contains (line 233) | contains(target) {
method getObjects (line 241) | getObjects() {
method getObject (line 250) | getObject(id) {
method remove (line 258) | remove(target) {
method removeAll (line 267) | removeAll(includesBackground) {
method removeObjectById (line 284) | removeObjectById(id) {
method getObjectId (line 309) | getObjectId(object) {
method getActiveObject (line 326) | getActiveObject() {
method getActiveObjectIdForRemove (line 334) | getActiveObjectIdForRemove() {
method isReadyRemoveObject (line 355) | isReadyRemoveObject() {
method getActiveObjects (line 365) | getActiveObjects() {
method getActiveSelectionFromObjects (line 376) | getActiveSelectionFromObjects(objects) {
method setActiveObject (line 386) | setActiveObject(target) {
method setCropSelectionStyle (line 394) | setCropSelectionStyle(style) {
method getComponent (line 403) | getComponent(name) {
method getDrawingMode (line 411) | getDrawingMode() {
method startDrawingMode (line 423) | startDrawingMode(mode, option) {
method stopDrawingMode (line 444) | stopDrawingMode() {
method zoom (line 461) | zoom({ x, y }, zoomLevel) {
method getZoomMode (line 471) | getZoomMode() {
method startZoomInMode (line 480) | startZoomInMode() {
method endZoomInMode (line 489) | endZoomInMode() {
method zoomOut (line 498) | zoomOut() {
method startHandMode (line 507) | startHandMode() {
method endHandMode (line 516) | endHandMode() {
method resetZoom (line 525) | resetZoom() {
method toDataURL (line 543) | toDataURL(options) {
method setCanvasImage (line 558) | setCanvasImage(name, canvasImage) {
method setCssMaxDimension (line 570) | setCssMaxDimension(maxDimension) {
method adjustCanvasDimension (line 578) | adjustCanvasDimension() {
method adjustCanvasDimensionBase (line 582) | adjustCanvasDimensionBase(canvasImage = null) {
method setCanvasCssDimension (line 609) | setCanvasCssDimension(dimension) {
method setCanvasBackstoreDimension (line 618) | setCanvasBackstoreDimension(dimension) {
method setImageProperties (line 628) | setImageProperties(setting, withRendering) {
method getCanvasElement (line 645) | getCanvasElement() {
method getCanvas (line 653) | getCanvas() {
method getCanvasImage (line 661) | getCanvasImage() {
method getImageName (line 669) | getImageName() {
method addImageObject (line 678) | addImageObject(imgUrl) {
method getCenter (line 699) | getCenter() {
method getCropzoneRect (line 707) | getCropzoneRect() {
method setCropzoneRect (line 715) | setCropzoneRect(mode) {
method getCroppedImageData (line 728) | getCroppedImageData(cropRect) {
method setBrush (line 738) | setBrush(option) {
method setDrawingShape (line 763) | setDrawingShape(type, options) {
method setIconStyle (line 772) | setIconStyle(type, iconColor) {
method registerPaths (line 782) | registerPaths(pathInfos) {
method changeCursor (line 790) | changeCursor(cursorType) {
method hasFilter (line 801) | hasFilter(type) {
method setSelectionStyle (line 809) | setSelectionStyle(styles) {
method setObjectProperties (line 826) | setObjectProperties(id, props) {
method getObjectProperties (line 845) | getObjectProperties(id, keys) {
method getObjectPosition (line 871) | getObjectPosition(id, originX, originY) {
method setObjectPosition (line 890) | setObjectPosition(id, posInfo) {
method getCanvasSize (line 916) | getCanvasSize() {
method createStaticCanvas (line 929) | createStaticCanvas() {
method _getDrawingModeInstance (line 945) | _getDrawingModeInstance(modeName) {
method _setObjectCachingToFalse (line 954) | _setObjectCachingToFalse() {
method _setCanvasElement (line 963) | _setCanvasElement(element) {
method _createDrawingModeInstances (line 988) | _createDrawingModeInstances() {
method _createComponents (line 1003) | _createComponents() {
method _register (line 1024) | _register(map, module) {
method _isSameDrawingMode (line 1033) | _isSameDrawingMode(mode) {
method _calcMaxDimension (line 1046) | _calcMaxDimension(width, height) {
method _callbackAfterLoadingImageObject (line 1071) | _callbackAfterLoadingImageObject(obj) {
method _attachCanvasEvents (line 1087) | _attachCanvasEvents() {
method _onMouseDown (line 1110) | _onMouseDown(fEvent) {
method _onObjectAdded (line 1131) | _onObjectAdded(fEvent) {
method _onObjectRemoved (line 1145) | _onObjectRemoved(fEvent) {
method _onObjectMoved (line 1156) | _onObjectMoved(fEvent) {
method _onObjectScaled (line 1169) | _onObjectScaled(fEvent) {
method _onObjectModified (line 1182) | _onObjectModified(fEvent) {
method _onObjectRotated (line 1198) | _onObjectRotated(fEvent) {
method _lazyFire (line 1213) | _lazyFire(eventName, paramsMaker, target) {
method _onObjectSelected (line 1233) | _onObjectSelected(fEvent) {
method _onPathCreated (line 1245) | _onPathCreated(obj) {
method _onSelectionCleared (line 1266) | _onSelectionCleared() {
method _onSelectionCreated (line 1275) | _onSelectionCreated(fEvent) {
method discardSelection (line 1286) | discardSelection() {
method changeSelectableAll (line 1295) | changeSelectableAll(selectable) {
method createObjectProperties (line 1307) | createObjectProperties(obj) {
method _createTextProperties (line 1344) | _createTextProperties(obj) {
method _addFabricObject (line 1365) | _addFabricObject(obj) {
method _removeFabricObject (line 1376) | _removeFabricObject(id) {
method resetTargetObjectForCopyPaste (line 1383) | resetTargetObjectForCopyPaste() {
method pasteObject (line 1395) | pasteObject() {
method _cloneObject (line 1424) | _cloneObject(targetObjects) {
method _cloneObjectItem (line 1436) | _cloneObjectItem(targetObject) {
method _copyFabricObjectForPaste (line 1453) | _copyFabricObjectForPaste(targetObject) {
method _copyFabricObject (line 1483) | _copyFabricObject(targetObject) {
method getCurrentDimensions (line 1500) | getCurrentDimensions() {
method getOriginalDimensions (line 1510) | getOriginalDimensions() {
method setOriginalDimensions (line 1520) | setOriginalDimensions(dimensions) {
method resize (line 1530) | resize(dimensions) {
FILE: apps/image-editor/src/js/helper/imagetracer.js
class ImageTracer (line 30) | class ImageTracer {
method tracerDefaultOption (line 31) | static tracerDefaultOption() {
method constructor (line 60) | constructor() {
method imageToSVG (line 292) | imageToSVG(url, callback, options) {
method imagedataToSVG (line 303) | imagedataToSVG(imgd, options) {
method imageToTracedata (line 310) | imageToTracedata(url, callback, options) {
method imagedataToTracedata (line 321) | imagedataToTracedata(imgd, options) {
method checkoptions (line 362) | checkoptions(options) {
method colorquantization (line 382) | colorquantization(imgd, options) {
method samplepalette (line 477) | samplepalette(numberofcolors, imgd) {
method samplepalette2 (line 493) | samplepalette2(numberofcolors, imgd) {
method generatepalette (line 519) | generatepalette(numberofcolors) {
method layering (line 553) | layering(ii) {
method layeringstep (line 607) | layeringstep(ii, cnum) {
method pathscan (line 632) | pathscan(arr, pathomit) {
method boundingboxincludes (line 721) | boundingboxincludes(parentbbox, childbbox) {
method batchpathscan (line 730) | batchpathscan(layers, pathomit) {
method internodes (line 742) | internodes(paths, options) {
method testrightangle (line 806) | testrightangle(path, idx1, idx2, idx3, idx4, idx5) {
method getdirection (line 819) | getdirection(x1, y1, x2, y2) {
method batchinternodes (line 848) | batchinternodes(bpaths, options) {
method tracepath (line 860) | tracepath(path, ltres, qtres) {
method fitseq (line 902) | fitseq(path, ltres, qtres, seqstart, seqend) {
method batchtracepaths (line 1001) | batchtracepaths(internodepaths, ltres, qtres) {
method batchtracelayers (line 1013) | batchtracelayers(binternodes, ltres, qtres) {
method roundtodec (line 1025) | roundtodec(val, places) {
method svgpathstring (line 1029) | svgpathstring(tracedata, lnum, pathnum, options) {
method getsvgstring (line 1194) | getsvgstring(tracedata, options) {
method compareNumbers (line 1216) | compareNumbers(a, b) {
method torgbastr (line 1220) | torgbastr(c) {
method tosvgcolorstr (line 1224) | tosvgcolorstr(c, options) {
method appendSVGString (line 1230) | appendSVGString(svgstr, parentid) {
method blur (line 1246) | blur(imgd, radius, delta) {
method loadImage (line 1336) | loadImage(url, callback, options) {
method getImgdata (line 1352) | getImgdata(canvas) {
method drawLayers (line 1358) | drawLayers(layers, palette, scale, parentid) {
FILE: apps/image-editor/src/js/helper/selectionModifyHelper.js
function setCachedUndoDataForDimension (line 16) | function setCachedUndoDataForDimension(undoData) {
function getCachedUndoDataForDimension (line 25) | function getCachedUndoDataForDimension() {
function makeSelectionUndoData (line 36) | function makeSelectionUndoData(obj, undoDatumMaker) {
function makeSelectionUndoDatum (line 73) | function makeSelectionUndoDatum(id, obj, isSelection) {
FILE: apps/image-editor/src/js/helper/shapeFilterFillHelper.js
constant FILTER_OPTION_MAP (line 7) | const FILTER_OPTION_MAP = {
constant POSITION_DIMENSION_MAP (line 11) | const POSITION_DIMENSION_MAP = {
constant FILTER_NAME_VALUE_MAP (line 16) | const FILTER_NAME_VALUE_MAP = flipObject(FILTER_OPTION_MAP);
function getFillImageFromShape (line 31) | function getFillImageFromShape(shapeObj) {
function rePositionFilterTypeFillImage (line 43) | function rePositionFilterTypeFillImage(shapeObj) {
function makeFilterOptionFromFabricImage (line 91) | function makeFilterOptionFromFabricImage(imageObject) {
function calculateFillImageDimensionOutsideCanvas (line 115) | function calculateFillImageDimensionOutsideCanvas({
function calculateDimensionRightBottomEdge (line 182) | function calculateDimensionRightBottomEdge(
function calculateDimensionLeftTopEdge (line 235) | function calculateDimensionLeftTopEdge(
function makeFillPatternForFilter (line 270) | function makeFillPatternForFilter(canvasImage, filterOption, patternSour...
function resetFillPatternCanvas (line 291) | function resetFillPatternCanvas(patternSourceCanvas) {
function reMakePatternImageSource (line 308) | function reMakePatternImageSource(shapeObj, canvasImage) {
function getCachedCanvasImageElement (line 327) | function getCachedCanvasImageElement(canvasImage, reset = false) {
function calculateDistanceOverflowPart (line 344) | function calculateDistanceOverflowPart({ type, shapeObj, outDistance, le...
function getReversePositionForFlip (line 382) | function getReversePositionForFlip({ outDistance, startPointIndex, flipX...
function calculateLinePointsOutsideCanvas (line 412) | function calculateLinePointsOutsideCanvas(
function calculateLineAngleOfOutsideCanvas (line 449) | function calculateLineAngleOfOutsideCanvas(type, shapePointNavigation, l...
function isReverseLeftPositionForFlip (line 471) | function isReverseLeftPositionForFlip(startPointIndex, flipX, flipY) {
function isReverseTopPositionForFlip (line 489) | function isReverseTopPositionForFlip(startPointIndex, flipX, flipY) {
function getShapeEdgePoint (line 504) | function getShapeEdgePoint(shapeObj) {
function getRotatedDimension (line 518) | function getRotatedDimension(shapeObj) {
function makeFillImage (line 545) | function makeFillImage(copiedCanvasElement, currentCanvasImageAngle, fil...
FILE: apps/image-editor/src/js/helper/shapeResizeHelper.js
constant DIVISOR (line 1) | const DIVISOR = {
constant DIMENSION_KEYS (line 6) | const DIMENSION_KEYS = {
function setStartPoint (line 26) | function setStartPoint(shape) {
function getPositionsOfRotatedOrigin (line 41) | function getPositionsOfRotatedOrigin(origin, pointer, angle) {
function hasCenterOrigin (line 62) | function hasCenterOrigin(shape) {
function adjustOriginByStartPoint (line 72) | function adjustOriginByStartPoint(pointer, shape) {
function adjustOriginByMovingPointer (line 97) | function adjustOriginByMovingPointer(pointer, shape) {
function adjustDimensionOnScaling (line 112) | function adjustDimensionOnScaling(shape) {
function adjustDimensionOnMouseMove (line 144) | function adjustDimensionOnMouseMove(pointer, shape) {
method setOrigins (line 180) | setOrigins(shape) {
method resize (line 200) | resize(shape, pointer, isScaling) {
method adjustOriginToCenter (line 219) | adjustOriginToCenter(shape) {
FILE: apps/image-editor/src/js/imageEditor.js
class ImageEditor (line 162) | class ImageEditor {
method constructor (line 163) | constructor(wrapper, options) {
method _attachColorPickerInputBoxEvents (line 250) | _attachColorPickerInputBoxEvents() {
method _detachColorPickerInputBoxEvents (line 259) | _detachColorPickerInputBoxEvents() {
method _setSelectionStyle (line 272) | _setSelectionStyle(selectionStyle, { applyCropSelectionStyle, applyGro...
method _attachInvokerEvents (line 294) | _attachInvokerEvents() {
method _attachGraphicsEvents (line 342) | _attachGraphicsEvents() {
method _attachDomEvents (line 366) | _attachDomEvents() {
method _detachDomEvents (line 375) | _detachDomEvents() {
method _onKeyDown (line 386) | _onKeyDown(e) {
method removeActiveObject (line 417) | removeActiveObject() {
method _onMouseDown (line 431) | _onMouseDown(event, originPointer) {
method _pushAddObjectCommand (line 460) | _pushAddObjectCommand(obj) {
method _pushModifyObjectCommand (line 470) | _pushModifyObjectCommand(obj) {
method _onObjectActivated (line 486) | _onObjectActivated(props) {
method _onObjectMoved (line 506) | _onObjectMoved(props) {
method _onObjectScaled (line 525) | _onObjectScaled(props) {
method _onObjectRotated (line 544) | _onObjectRotated(props) {
method getDrawingMode (line 574) | getDrawingMode() {
method clearObjects (line 584) | clearObjects() {
method deactivateAll (line 593) | deactivateAll() {
method discardSelection (line 603) | discardSelection() {
method changeSelectableAll (line 613) | changeSelectableAll(selectable) {
method _initHistory (line 620) | _initHistory() {
method _clearHistory (line 629) | _clearHistory() {
method execute (line 642) | execute(commandName, ...args) {
method executeSilent (line 656) | executeSilent(commandName, ...args) {
method undo (line 670) | undo(iterationCount = 1) {
method redo (line 687) | redo(iterationCount = 1) {
method zoom (line 703) | zoom({ x, y, zoomLevel }) {
method resetZoom (line 710) | resetZoom() {
method loadImageFromFile (line 725) | loadImageFromFile(imgFile, imageName) {
method loadImageFromURL (line 751) | loadImageFromURL(url, imageName) {
method addImageObject (line 768) | addImageObject(imgUrl) {
method startDrawingMode (line 800) | startDrawingMode(mode, option) {
method stopDrawingMode (line 809) | stopDrawingMode() {
method crop (line 824) | crop(rect) {
method getCropzoneRect (line 837) | getCropzoneRect() {
method setCropzoneRect (line 845) | setCropzoneRect(mode) {
method _flip (line 856) | _flip(type) {
method flipX (line 872) | flipX() {
method flipY (line 888) | flipY() {
method resetFlip (line 904) | resetFlip() {
method _rotate (line 915) | _rotate(type, angle, isSilent) {
method rotate (line 944) | rotate(angle, isSilent) {
method setAngle (line 965) | setAngle(angle, isSilent) {
method setBrush (line 985) | setBrush(option) {
method setDrawingShape (line 1038) | setDrawingShape(type, options) {
method setDrawingIcon (line 1042) | setDrawingIcon(type, iconColor) {
method addShape (line 1099) | addShape(type, options) {
method changeShape (line 1141) | changeShape(id, options, isSilent) {
method addText (line 1179) | addText(text, options) {
method changeText (line 1194) | changeText(id, text) {
method changeTextStyle (line 1218) | changeTextStyle(id, styleObj, isSilent) {
method _changeActivateMode (line 1229) | _changeActivateMode(type) {
method _onTextChanged (line 1240) | _onTextChanged(target) {
method _onIconCreateResize (line 1251) | _onIconCreateResize(originPointer) {
method _onIconCreateEnd (line 1262) | _onIconCreateEnd(originPointer) {
method _onTextEditing (line 1270) | _onTextEditing() {
method _onAddText (line 1288) | _onAddText(event) {
method _onAddObject (line 1317) | _onAddObject(objectProps) {
method _onObjectAdded (line 1328) | _onObjectAdded(objectProps) {
method _onObjectModified (line 1354) | _onObjectModified(obj) {
method _selectionCleared (line 1365) | _selectionCleared() {
method _selectionCreated (line 1374) | _selectionCreated(eventTarget) {
method registerIcons (line 1387) | registerIcons(infos) {
method changeCursor (line 1397) | changeCursor(cursorType) {
method addIcon (line 1419) | addIcon(type, options) {
method changeIconColor (line 1435) | changeIconColor(id, color) {
method removeObject (line 1446) | removeObject(id) {
method hasFilter (line 1457) | hasFilter(type) {
method removeFilter (line 1473) | removeFilter(type) {
method applyFilter (line 1493) | applyFilter(type, options, isSilent) {
method toDataURL (line 1517) | toDataURL(options) {
method getImageName (line 1527) | getImageName() {
method clearUndoStack (line 1536) | clearUndoStack() {
method clearRedoStack (line 1545) | clearRedoStack() {
method isEmptyUndoStack (line 1554) | isEmptyUndoStack() {
method isEmptyRedoStack (line 1563) | isEmptyRedoStack() {
method resizeCanvasDimension (line 1572) | resizeCanvasDimension(dimension) {
method destroy (line 1583) | destroy() {
method _setPositions (line 1608) | _setPositions(options) {
method setObjectProperties (line 1634) | setObjectProperties(id, keyValue) {
method setObjectPropertiesQuietly (line 1651) | setObjectPropertiesQuietly(id, keyValue) {
method getObjectProperties (line 1676) | getObjectProperties(id, keys) {
method getCanvasSize (line 1693) | getCanvasSize() {
method getObjectPosition (line 1707) | getObjectPosition(id, originX, originY) {
method setObjectPosition (line 1756) | setObjectPosition(id, posInfo) {
method resize (line 1764) | resize(dimensions) {
FILE: apps/image-editor/src/js/interface/command.js
class Command (line 15) | class Command {
method constructor (line 16) | constructor(actions, args) {
method execute (line 65) | execute() {
method undo (line 74) | undo() {
method isRedo (line 82) | get isRedo() {
method setUndoData (line 93) | setUndoData(undoData, cachedUndoDataForSilent, isSilent) {
method setExecuteCallback (line 113) | setExecuteCallback(callback) {
method setUndoCallback (line 124) | setUndoCallback(callback) {
FILE: apps/image-editor/src/js/interface/component.js
class Component (line 8) | class Component {
method constructor (line 9) | constructor(name, graphics) {
method fire (line 27) | fire(...args) {
method setCanvasImage (line 38) | setCanvasImage(name, oImage) {
method getCanvasElement (line 46) | getCanvasElement() {
method getCanvas (line 54) | getCanvas() {
method getCanvasImage (line 62) | getCanvasImage() {
method getImageName (line 70) | getImageName() {
method getEditor (line 78) | getEditor() {
method getName (line 86) | getName() {
method setImageProperties (line 95) | setImageProperties(setting, withRendering) {
method setCanvasCssDimension (line 103) | setCanvasCssDimension(dimension) {
method setCanvasBackstoreDimension (line 111) | setCanvasBackstoreDimension(dimension) {
method adjustCanvasDimension (line 118) | adjustCanvasDimension() {
method adjustCanvasDimensionBase (line 122) | adjustCanvasDimensionBase() {
FILE: apps/image-editor/src/js/interface/drawingMode.js
class DrawingMode (line 12) | class DrawingMode {
method constructor (line 13) | constructor(name) {
method getName (line 25) | getName() {
method start (line 34) | start() {
method end (line 42) | end() {
FILE: apps/image-editor/src/js/invoker.js
class Invoker (line 12) | class Invoker {
method constructor (line 13) | constructor() {
method _invokeExecution (line 45) | _invokeExecution(command, isRedo = false) {
method _invokeUndo (line 81) | _invokeUndo(command) {
method _fireRedoStackChanged (line 112) | _fireRedoStackChanged() {
method _fireUndoStackChanged (line 120) | _fireUndoStackChanged() {
method lock (line 127) | lock() {
method unlock (line 134) | unlock() {
method executeSilent (line 138) | executeSilent(...args) {
method execute (line 154) | execute(...args) {
method undo (line 175) | undo() {
method redo (line 204) | redo() {
method pushUndoStack (line 234) | pushUndoStack(command, isSilent) {
method pushRedoStack (line 246) | pushRedoStack(command, isSilent) {
method isEmptyRedoStack (line 257) | isEmptyRedoStack() {
method isEmptyUndoStack (line 265) | isEmptyUndoStack() {
method clearUndoStack (line 272) | clearUndoStack() {
method clearRedoStack (line 282) | clearRedoStack() {
FILE: apps/image-editor/src/js/polyfill.js
function getOrigin (line 313) | function getOrigin(loc) {
function observeIfDone (line 352) | function observeIfDone() {
function attrUpdateFunc (line 361) | function attrUpdateFunc(spec) {
function onloadFunc (line 371) | function onloadFunc(xhr) {
function onErrorTimeout (line 390) | function onErrorTimeout(xhr) {
FILE: apps/image-editor/src/js/ui.js
constant SUB_UI_COMPONENT (line 29) | const SUB_UI_COMPONENT = {
constant BI_EXPRESSION_MINSIZE_WHEN_TOP_POSITION (line 42) | const BI_EXPRESSION_MINSIZE_WHEN_TOP_POSITION = '1300';
constant HISTORY_MENU (line 43) | const HISTORY_MENU = 'history';
constant HISTORY_PANEL_CLASS_NAME (line 44) | const HISTORY_PANEL_CLASS_NAME = 'tie-panel-history';
constant CLASS_NAME_ON (line 46) | const CLASS_NAME_ON = 'on';
constant ZOOM_BUTTON_TYPE (line 47) | const ZOOM_BUTTON_TYPE = {
class Ui (line 67) | class Ui {
method constructor (line 68) | constructor(element, options, actions) {
method destroy (line 97) | destroy() {
method setUiDefaultSelectionStyle (line 111) | setUiDefaultSelectionStyle(option) {
method resizeEditor (line 151) | resizeEditor({ uiSize, imageSize = this.imageSize } = {}) {
method toggleZoomButtonStatus (line 189) | toggleZoomButtonStatus(type) {
method offZoomInButtonStatus (line 204) | offZoomInButtonStatus() {
method changeHandButtonStatus (line 214) | changeHandButtonStatus(enabled) {
method changeHelpButtonEnabled (line 226) | changeHelpButtonEnabled(buttonType, enableStatus) {
method _initializeOption (line 243) | _initializeOption(options) {
method _setUiSize (line 282) | _setUiSize(uiSize = this.options.uiSize) {
method _makeSubMenu (line 292) | _makeSubMenu() {
method _attachHistoryEvent (line 317) | _attachHistoryEvent() {
method _attachZoomEvent (line 327) | _attachZoomEvent() {
method _makeUiElement (line 340) | _makeUiElement(element) {
method _activateZoomMenus (line 397) | _activateZoomMenus() {
method _makeHelpMenuWithPartition (line 408) | _makeHelpMenuWithPartition() {
method _addHelpMenus (line 416) | _addHelpMenus() {
method _makeMenuPartitionElement (line 436) | _makeMenuPartitionElement() {
method _makeMenuElement (line 453) | _makeMenuElement(menuName, useIconTypes = ['normal', 'active', 'hover'...
method _addHelpActionEvent (line 472) | _addHelpActionEvent() {
method _removeHelpActionEvent (line 483) | _removeHelpActionEvent() {
method _addHistory (line 493) | _addHistory(command) {
method initHistory (line 505) | initHistory() {
method clearHistory (line 512) | clearHistory() {
method _selectPrevHistory (line 519) | _selectPrevHistory() {
method _selectNextHistory (line 526) | _selectNextHistory() {
method toggleHistoryMenu (line 534) | toggleHistoryMenu(event) {
method _addTooltipAttribute (line 553) | _addTooltipAttribute(element, tooltipName) {
method _addDownloadEvent (line 564) | _addDownloadEvent() {
method _removeDownloadEvent (line 571) | _removeDownloadEvent() {
method _addLoadEvent (line 581) | _addLoadEvent() {
method _removeLoadEvent (line 593) | _removeLoadEvent() {
method _addMainMenuEvent (line 604) | _addMainMenuEvent(menuName) {
method _addSubMenuEvent (line 614) | _addSubMenuEvent(menuName) {
method _addMenuEvent (line 628) | _addMenuEvent() {
method _removeMainMenuEvent (line 639) | _removeMainMenuEvent() {
method getEditorArea (line 652) | getEditorArea() {
method activeMenuEvent (line 660) | activeMenuEvent() {
method _removeUiEvent (line 677) | _removeUiEvent() {
method _destroyAllMenu (line 689) | _destroyAllMenu() {
method initCanvas (line 701) | initCanvas() {
method _getLoadImage (line 731) | _getLoadImage() {
method changeMenu (line 742) | changeMenu(menuName, toggle = true, discardSelection = true) {
method _changeMenu (line 757) | _changeMenu(menuName, toggle, discardSelection) {
method _initMenu (line 784) | _initMenu() {
method _getCanvasMaxDimension (line 801) | _getCanvasMaxDimension() {
method _setEditorPosition (line 818) | _setEditorPosition(menuBarPosition) {
FILE: apps/image-editor/src/js/ui/crop.js
class Crop (line 11) | class Crop extends Submenu {
method constructor (line 12) | constructor(subMenuElement, { locale, makeSvgIcon, menuBarPosition, us...
method destroy (line 36) | destroy() {
method addEvent (line 49) | addEvent(actions) {
method _removeEvent (line 70) | _removeEvent() {
method _applyEventHandler (line 76) | _applyEventHandler() {
method _cancelEventHandler (line 81) | _cancelEventHandler() {
method _cropzonePresetEventHandler (line 86) | _cropzonePresetEventHandler(event) {
method changeStartMode (line 99) | changeStartMode() {
method changeStandbyMode (line 106) | changeStandbyMode() {
method changeApplyButtonStatus (line 115) | changeApplyButtonStatus(enableStatus) {
method _setPresetButtonActive (line 128) | _setPresetButtonActive(button = this.defaultPresetButton) {
FILE: apps/image-editor/src/js/ui/draw.js
constant DRAW_OPACITY (line 8) | const DRAW_OPACITY = 0.7;
class Draw (line 15) | class Draw extends Submenu {
method constructor (line 16) | constructor(subMenuElement, { locale, makeSvgIcon, menuBarPosition, us...
method destroy (line 54) | destroy() {
method addEvent (line 67) | addEvent(actions) {
method _removeEvent (line 89) | _removeEvent() {
method setDrawMode (line 107) | setDrawMode() {
method changeStandbyMode (line 117) | changeStandbyMode() {
method changeStartMode (line 128) | changeStartMode() {
method _changeDrawType (line 139) | _changeDrawType(event) {
method _changeDrawColor (line 163) | _changeDrawColor(color) {
method _changeDrawRange (line 177) | _changeDrawRange(value) {
FILE: apps/image-editor/src/js/ui/filter.js
constant PICKER_CONTROL_HEIGHT (line 11) | const PICKER_CONTROL_HEIGHT = '130px';
constant BLEND_OPTIONS (line 12) | const BLEND_OPTIONS = ['add', 'diff', 'subtract', 'multiply', 'screen', ...
constant FILTER_OPTIONS (line 13) | const FILTER_OPTIONS = [
constant RANGE_INSTANCE_NAMES (line 52) | const RANGE_INSTANCE_NAMES = [
constant COLORPICKER_INSTANCE_NAMES (line 60) | const COLORPICKER_INSTANCE_NAMES = ['filterBlendColor', 'filterMultiplyC...
class Filter (line 67) | class Filter extends Submenu {
method constructor (line 68) | constructor(subMenuElement, { locale, menuBarPosition, usageStatistics...
method destroy (line 86) | destroy() {
method _removeEvent (line 96) | _removeEvent() {
method _destroyToolInstance (line 121) | _destroyToolInstance() {
method addEvent (line 132) | addEvent({ applyFilter }) {
method setFilterState (line 186) | setFilterState(changedFilterInfos) {
method initFilterCheckBoxState (line 201) | initFilterCheckBoxState() {
method _setFilterState (line 218) | _setFilterState(filterName, options) {
method _getFilterNameFromOptions (line 246) | _getFilterNameFromOptions(type, options) {
method _changeFilterState (line 268) | _changeFilterState(applyFilter, filterName, isLast = true) {
method _getFilterOption (line 290) | _getFilterOption(type) {
method _makeControlElement (line 339) | _makeControlElement() {
method _pickerWithRange (line 407) | _pickerWithRange(pickerControl) {
method _pickerWithSelectbox (line 428) | _pickerWithSelectbox(pickerControl) {
method _drawSelectOptionList (line 456) | _drawSelectOptionList(selectlist, optionlist) {
method _pickerWithSelectboxForAddEvent (line 472) | _pickerWithSelectboxForAddEvent(selectlist, optionlist) {
method _makeSelectOptionList (line 500) | _makeSelectOptionList(selectlist) {
FILE: apps/image-editor/src/js/ui/flip.js
class Flip (line 11) | class Flip extends Submenu {
method constructor (line 12) | constructor(subMenuElement, { locale, makeSvgIcon, menuBarPosition, us...
method destroy (line 31) | destroy() {
method addEvent (line 42) | addEvent(actions) {
method _removeEvent (line 52) | _removeEvent() {
method _changeFlip (line 61) | _changeFlip(event) {
FILE: apps/image-editor/src/js/ui/history.js
class History (line 14) | class History extends Panel {
method constructor (line 15) | constructor(menuElement, { locale, makeSvgIcon }) {
method add (line 30) | add({ name, detail }) {
method init (line 46) | init() {
method clear (line 55) | clear() {
method prev (line 63) | prev() {
method next (line 71) | next() {
method _hasDisabledItem (line 80) | _hasDisabledItem() {
method _addHistoryEventListener (line 88) | _addHistoryEventListener() {
method _removeHistoryEventListener (line 97) | _removeHistoryEventListener() {
method _clickHistoryItem (line 106) | _clickHistoryItem(event) {
method _selectItem (line 131) | _selectItem(index) {
method destroy (line 145) | destroy() {
method addEvent (line 157) | addEvent(actions) {
method removeEvent (line 166) | removeEvent() {
FILE: apps/image-editor/src/js/ui/icon.js
class Icon (line 13) | class Icon extends Submenu {
method constructor (line 14) | constructor(subMenuElement, { locale, makeSvgIcon, menuBarPosition, us...
method destroy (line 45) | destroy() {
method addEvent (line 59) | addEvent(actions) {
method _removeEvent (line 87) | _removeEvent() {
method clearIconType (line 105) | clearIconType() {
method registerDefaultIcon (line 113) | registerDefaultIcon() {
method setIconPickerColor (line 123) | setIconPickerColor(iconColor) {
method changeStandbyMode (line 130) | changeStandbyMode() {
method _changeColorHandler (line 140) | _changeColorHandler(color) {
method _addIconHandler (line 150) | _addIconHandler(event) {
method _registerIconHandler (line 175) | _registerIconHandler(event) {
FILE: apps/image-editor/src/js/ui/locale/locale.js
class Locale (line 4) | class Locale {
method constructor (line 5) | constructor(locale) {
method localize (line 14) | localize(message) {
FILE: apps/image-editor/src/js/ui/mask.js
class Mask (line 10) | class Mask extends Submenu {
method constructor (line 11) | constructor(subMenuElement, { locale, makeSvgIcon, menuBarPosition, us...
method destroy (line 30) | destroy() {
method addEvent (line 42) | addEvent(actions) {
method _removeEvent (line 60) | _removeEvent() {
method _applyMask (line 69) | _applyMask() {
method _loadMaskFile (line 79) | _loadMaskFile(event) {
FILE: apps/image-editor/src/js/ui/panelMenu.js
class Panel (line 7) | class Panel {
method constructor (line 13) | constructor(menuElement, { name }) {
method _makePanelElement (line 28) | _makePanelElement() {
method _makeListElement (line 41) | _makeListElement() {
method makeListItemElement (line 54) | makeListItemElement(html) {
method pushListItemElement (line 68) | pushListItemElement(item) {
method deleteListItemElement (line 79) | deleteListItemElement(start, end) {
method getListLength (line 92) | getListLength() {
method addClass (line 101) | addClass(index, className) {
method removeClass (line 112) | removeClass(index, className) {
method toggleClass (line 123) | toggleClass(index, className) {
FILE: apps/image-editor/src/js/ui/resize.js
class Resize (line 12) | class Resize extends Submenu {
method constructor (line 13) | constructor(subMenuElement, { locale, makeSvgIcon, menuBarPosition, us...
method changeStartMode (line 58) | changeStartMode() {
method changeStandbyMode (line 77) | changeStandbyMode() {
method setLimit (line 86) | setLimit(limits) {
method calcMaxValue (line 98) | calcMaxValue(maxValue) {
method calcMinValue (line 111) | calcMinValue(minValue) {
method setWidthValue (line 124) | setWidthValue(value, trigger = false) {
method setHeightValue (line 136) | setHeightValue(value, trigger = false) {
method destroy (line 146) | destroy() {
method addEvent (line 163) | addEvent(actions) {
method _changeWidthRangeHandler (line 186) | _changeWidthRangeHandler(value) {
method _changeHeightRangeHandler (line 195) | _changeHeightRangeHandler(value) {
method _changeLockAspectRatio (line 204) | _changeLockAspectRatio(event) {
method _removeEvent (line 213) | _removeEvent() {
method _applyEventHandler (line 218) | _applyEventHandler() {
method _cancelEventHandler (line 223) | _cancelEventHandler() {
method changeApplyButtonStatus (line 232) | changeApplyButtonStatus(enableStatus) {
FILE: apps/image-editor/src/js/ui/rotate.js
constant CLOCKWISE (line 7) | const CLOCKWISE = 30;
constant COUNTERCLOCKWISE (line 8) | const COUNTERCLOCKWISE = -30;
class Rotate (line 15) | class Rotate extends Submenu {
method constructor (line 16) | constructor(subMenuElement, { locale, makeSvgIcon, menuBarPosition, us...
method destroy (line 42) | destroy() {
method setRangeBarAngle (line 49) | setRangeBarAngle(type, angle) {
method _setRangeBarRatio (line 59) | _setRangeBarRatio(angle) {
method addEvent (line 69) | addEvent(actions) {
method _removeEvent (line 82) | _removeEvent() {
method _changeRotateForRange (line 93) | _changeRotateForRange(value, isLast) {
method _changeRotateForButton (line 104) | _changeRotateForButton(event) {
FILE: apps/image-editor/src/js/ui/shape.js
constant SHAPE_DEFAULT_OPTION (line 9) | const SHAPE_DEFAULT_OPTION = {
class Shape (line 20) | class Shape extends Submenu {
method constructor (line 21) | constructor(subMenuElement, { locale, makeSvgIcon, menuBarPosition, us...
method destroy (line 74) | destroy() {
method addEvent (line 89) | addEvent(actions) {
method _removeEvent (line 114) | _removeEvent() {
method setShapeStatus (line 137) | setShapeStatus({ strokeWidth, strokeColor, fillColor }) {
method changeStartMode (line 151) | changeStartMode() {
method changeStandbyMode (line 158) | changeStandbyMode() {
method setMaxStrokeValue (line 170) | setMaxStrokeValue(maxValue) {
method setStrokeValue (line 182) | setStrokeValue(value) {
method getStrokeValue (line 191) | getStrokeValue() {
method _changeShapeHandler (line 200) | _changeShapeHandler(event) {
method _changeStrokeRangeHandler (line 226) | _changeStrokeRangeHandler(value, isLast) {
method _changeFillColorHandler (line 243) | _changeFillColorHandler(color) {
method _changeStrokeColorHandler (line 256) | _changeStrokeColorHandler(color) {
FILE: apps/image-editor/src/js/ui/submenuBase.js
class Submenu (line 9) | class Submenu {
method constructor (line 19) | constructor(
method selector (line 42) | selector(selectName) {
method colorPickerChangeShow (line 50) | colorPickerChangeShow(occurredControl) {
method getButtonType (line 64) | getButtonType(button, buttonNames) {
method changeClass (line 74) | changeClass(target, removeClass, addClass) {
method changeStandbyMode (line 83) | changeStandbyMode() {}
method changeStartMode (line 89) | changeStartMode() {}
method _makeSubMenuElement (line 99) | _makeSubMenuElement({ locale, name, iconStyle, makeSvgIcon, templateHt...
method _onStartEditingInputBox (line 111) | _onStartEditingInputBox() {
method _onStopEditingInputBox (line 115) | _onStopEditingInputBox() {
FILE: apps/image-editor/src/js/ui/text.js
class Text (line 13) | class Text extends Submenu {
method constructor (line 14) | constructor(subMenuElement, { locale, makeSvgIcon, menuBarPosition, us...
method destroy (line 54) | destroy() {
method addEvent (line 67) | addEvent(actions) {
method _removeEvent (line 96) | _removeEvent() {
method changeStandbyMode (line 117) | changeStandbyMode() {
method changeStartMode (line 124) | changeStartMode() {
method textColor (line 132) | get textColor() {
method textColor (line 136) | set textColor(color) {
method fontSize (line 144) | get fontSize() {
method fontSize (line 152) | set fontSize(value) {
method fontStyle (line 160) | get fontStyle() {
method fontWeight (line 168) | get fontWeight() {
method underline (line 176) | get underline() {
method setTextStyleStateOnAction (line 180) | setTextStyleStateOnAction(textStyle = {}) {
method setEffectState (line 191) | setEffectState(effectName, value) {
method setAlignState (line 202) | setAlignState(value) {
method _setTextEffectHandler (line 214) | _setTextEffectHandler(event) {
method _setTextAlignHandler (line 235) | _setTextAlignHandler(event) {
method _changeTextRnageHandler (line 257) | _changeTextRnageHandler(value, isLast) {
method _changeColorHandler (line 271) | _changeColorHandler(color) {
FILE: apps/image-editor/src/js/ui/theme/theme.js
class Theme (line 15) | class Theme {
method constructor (line 16) | constructor(customTheme) {
method getStyle (line 29) | getStyle(type) {
method _styleMaker (line 90) | _styleMaker() {
method _changeToObject (line 126) | _changeToObject(styleOptions) {
method _makeCssText (line 147) | _makeCssText(styleObject) {
method _toUnderScore (line 167) | _toUnderScore(targetString) {
method _loadDefaultSvgIcon (line 175) | _loadDefaultSvgIcon() {
method _makeIconClassName (line 192) | _makeIconClassName(iconType, isSubmenu) {
method _makeSvgIconPrefix (line 206) | _makeSvgIconPrefix(iconType, isSubmenu) {
method _makeSvgItem (line 221) | _makeSvgItem(useIconTypes, menuName, isSubmenu) {
method makeMenSvgIconSet (line 240) | makeMenSvgIconSet(useIconTypes, menuName, isSubmenu = false) {
FILE: apps/image-editor/src/js/ui/tools/colorpicker.js
constant PICKER_COLOR (line 5) | const PICKER_COLOR = [
class Colorpicker (line 29) | class Colorpicker {
method constructor (line 30) | constructor(
method destroy (line 57) | destroy() {
method color (line 70) | get color() {
method color (line 78) | set color(color) {
method _changeColorElement (line 88) | _changeColorElement(color) {
method _makePickerButtonElement (line 103) | _makePickerButtonElement(defaultColor) {
method _makePickerLayerElement (line 121) | _makePickerLayerElement(colorpickerElement, title) {
method _addEvent (line 146) | _addEvent() {
method _removeEvent (line 166) | _removeEvent() {
method _pickerToggleEventHandler (line 177) | _pickerToggleEventHandler(event) {
method _isPaletteButton (line 196) | _isPaletteButton(target) {
method _isElementInColorPickerControl (line 206) | _isElementInColorPickerControl(element) {
method hide (line 224) | hide() {
method _setPickerControlPosition (line 233) | _setPickerControlPosition() {
FILE: apps/image-editor/src/js/ui/tools/range.js
constant INPUT_FILTER_REGEXP (line 6) | const INPUT_FILTER_REGEXP = /(-?)([0-9]*)[^0-9]*([0-9]*)/g;
class Range (line 13) | class Range {
method constructor (line 27) | constructor(rangeElements, options = {}) {
method destroy (line 63) | destroy() {
method max (line 73) | get max() {
method max (line 81) | set max(maxValue) {
method min (line 87) | get min() {
method min (line 95) | set min(minValue) {
method value (line 104) | get value() {
method value (line 112) | set value(value) {
method trigger (line 135) | trigger(type) {
method _getRangeWidth (line 143) | _getRangeWidth() {
method _drawRangeElement (line 153) | _drawRangeElement() {
method _addInputEvent (line 174) | _addInputEvent() {
method _removeInputEvent (line 186) | _removeInputEvent() {
method _changeValueWithInputKeyEvent (line 199) | _changeValueWithInputKeyEvent(event) {
method _valueUpDownForKeyEvent (line 226) | _valueUpDownForKeyEvent(value, keyCode) {
method _changeInput (line 238) | _changeInput(event) {
method _inputSetValue (line 253) | _inputSetValue(stringValue) {
method _changeValueWithInput (line 267) | _changeValueWithInput(isLast, event) {
method _addClickEvent (line 287) | _addClickEvent() {
method _removeClickEvent (line 295) | _removeClickEvent() {
method _addDragEvent (line 303) | _addDragEvent() {
method _removeDragEvent (line 311) | _removeDragEvent() {
method _changeSlide (line 320) | _changeSlide(event) {
method _changeSlideFinally (line 343) | _changeSlideFinally(event) {
method _startChangingSlide (line 358) | _startChangingSlide(event) {
method _stopChangingSlide (line 370) | _stopChangingSlide() {
method _filterForInputText (line 383) | _filterForInputText(inputValue) {
FILE: apps/image-editor/src/js/util.js
constant FLOATING_POINT_DIGIT (line 17) | const FLOATING_POINT_DIGIT = 2;
constant CSS_PREFIX (line 18) | const CSS_PREFIX = 'tui-image-editor-';
function stamp (line 23) | function stamp(obj) {
function hasStamp (line 33) | function hasStamp(obj) {
function isNil (line 37) | function isNil(value) {
function isFunction (line 41) | function isFunction(value) {
function clamp (line 52) | function clamp(value, minValue, maxValue) {
function keyMirror (line 64) | function keyMirror(...args) {
function makeStyleText (line 79) | function makeStyleText(styleObj) {
function getProperties (line 95) | function getProperties(obj, keys) {
function toInteger (line 114) | function toInteger(value) {
function toCamelCase (line 124) | function toCamelCase(targetString) {
function isSupportFileApi (line 133) | function isSupportFileApi() {
function getRgb (line 143) | function getRgb(color, alpha) {
function sendHostName (line 158) | function sendHostName() {
function styleLoad (line 172) | function styleLoad(styleBuffer, tagId) {
function getSelector (line 191) | function getSelector(targetElement) {
function base64ToBlob (line 200) | function base64ToBlob(data) {
function fixFloatingPoint (line 227) | function fixFloatingPoint(value) {
function assignmentForDestroy (line 235) | function assignmentForDestroy(targetObject) {
function cls (line 247) | function cls(str = '', prefix = '') {
function changeOrigin (line 262) | function changeOrigin(fObject, origin) {
function flipObject (line 281) | function flipObject(targetObject) {
function setCustomProperty (line 296) | function setCustomProperty(targetObject, props) {
function getCustomProperty (line 307) | function getCustomProperty(fObject, propNames) {
function capitalizeString (line 324) | function capitalizeString(targetString) {
function includes (line 334) | function includes(targetArray, compareValue) {
function getFillTypeFromOption (line 343) | function getFillTypeFromOption(fillOption = {}) {
function getFillTypeFromObject (line 352) | function getFillTypeFromObject(shapeObj) {
function isShape (line 366) | function isShape(obj) {
function getObjectType (line 375) | function getObjectType(type) {
function getFilterType (line 401) | function getFilterType(type, { useAlpha = true, mode } = {}) {
function isSilentCommand (line 429) | function isSilentCommand(command) {
function getHistoryTitle (line 441) | function getHistoryTitle(command) {
function getHelpMenuBarPosition (line 514) | function getHelpMenuBarPosition(position) {
function toStartOfCapital (line 533) | function toStartOfCapital(str) {
function isEmptyCropzone (line 546) | function isEmptyCropzone(cropRect) {
FILE: apps/image-editor/tests/arrowLine.spec.js
function assertPointsToMatchSnapshots (line 5) | function assertPointsToMatchSnapshots() {
FILE: apps/image-editor/tests/command.spec.js
method execute (line 74) | execute(compMap, obj1, obj2, obj3) {
method execute (line 89) | execute() {
method undo (line 92) | undo(compMap, obj1, obj2, obj3) {
FILE: apps/image-editor/tests/history.spec.js
method undo (line 9) | undo() {}
method redo (line 9) | redo() {}
FILE: apps/react-image-editor/src/index.js
class ImageEditor (line 4) | class ImageEditor extends React.Component {
method componentDidMount (line 9) | componentDidMount() {
method componentWillUnmount (line 17) | componentWillUnmount() {
method shouldComponentUpdate (line 25) | shouldComponentUpdate(nextProps) {
method getInstance (line 31) | getInstance() {
method getRootElement (line 35) | getRootElement() {
method bindEventHandlers (line 39) | bindEventHandlers(props, prevProps) {
method unbindEventHandlers (line 52) | unbindEventHandlers() {
method isEventHandlerKeys (line 61) | isEventHandlerKeys(key) {
method render (line 65) | render() {
FILE: apps/react-image-editor/stories/index.stories.js
class Story (line 27) | class Story extends React.Component {
method componentDidMount (line 32) | componentDidMount() {
method flipImageByAxis (line 36) | flipImageByAxis(isXAxis) {
method render (line 48) | render() {
class Story2 (line 75) | class Story2 extends React.Component {
method componentDidMount (line 80) | componentDidMount() {
method render (line 84) | render() {
FILE: apps/vue-image-editor/stories/index.stories.js
method created (line 29) | created() {
Condensed preview — 223 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (978K chars).
[
{
"path": ".editorconfig",
"chars": 74,
"preview": "[*]\ncharset = utf-8\nindent_style = space\nindent_size = 2\nend_of_line = lf\n"
},
{
"path": ".eslintrc.js",
"chars": 994,
"preview": "module.exports = {\n root: true,\n extends: ['tui/es6', 'plugin:jest/recommended', 'plugin:prettier/recommended'],\n plu"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 830,
"preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: Bug\nassignees: ''\n---\n\n**Describe the b"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 823,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: Enhancement, Need Discussion\nassigne"
},
{
"path": ".github/ISSUE_TEMPLATE/question.md",
"chars": 765,
"preview": "---\nname: Question\nabout: Create a question about imageEditor\ntitle: ''\nlabels: Question\nassignees: ''\n---\n\n<!--\n To ma"
},
{
"path": ".github/auto-comment.yml",
"chars": 321,
"preview": "# Comment to a new issue.\nissuesOpened: >\n Thank you for raising an issue. \n \n We will try and get back to you as soo"
},
{
"path": ".github/composite-actions/build-package/action.yml",
"chars": 1233,
"preview": "name: 'Build'\ndescription: 'Build package'\ninputs:\n ROOT_CACHE_KEY:\n description: 'Key of root dependencies cache'\n "
},
{
"path": ".github/composite-actions/install-dependencies/action.yml",
"chars": 1091,
"preview": "name: 'Install root dependencies using cache'\ndescription: 'Set Node.js version and install node_modules'\noutputs:\n roo"
},
{
"path": ".github/composite-actions/publish-cdn/action.yml",
"chars": 1641,
"preview": "name: 'Publish CDN'\ndescription: 'Publish CDN'\ninputs:\n ROOT_CACHE_KEY:\n description: 'Key of root dependencies cach"
},
{
"path": ".github/composite-actions/publish-docs/action.yml",
"chars": 2368,
"preview": "name: 'Publish docs'\ndescription: 'Publish docs'\ninputs:\n ROOT_CACHE_KEY:\n description: 'Key of root dependencies ca"
},
{
"path": ".github/composite-actions/publish-package/action.yml",
"chars": 1287,
"preview": "name: 'Publish package'\ndescription: 'Publish package'\ninputs:\n ROOT_CACHE_KEY:\n description: 'Key of root dependenc"
},
{
"path": ".github/stale.yml",
"chars": 1100,
"preview": "# Configuration for probot-stale - https://github.com/probot/stale\n\n# Number of days of inactivity before an Issue or Pu"
},
{
"path": ".github/workflows/detectRuntimeError.yml",
"chars": 1165,
"preview": "name: detect runtime error\n\non:\n schedule:\n - cron: '0 22 * * *'\njobs:\n detectError:\n runs-on: ubuntu-latest\n "
},
{
"path": ".github/workflows/publish-docs.yml",
"chars": 1465,
"preview": "name: Publish docs\non: [workflow_dispatch]\n\nenv:\n BUILD_CACHE_KEY: ${{ github.sha }}\n\njobs:\n install-dependencies:\n "
},
{
"path": ".github/workflows/publish-npm.yml",
"chars": 4719,
"preview": "name: Publish NPM\non: [workflow_dispatch]\n\nenv:\n BUILD_CACHE_KEY: ${{ github.sha }}\n\njobs:\n check-version:\n name: C"
},
{
"path": ".github/workflows/publish-wrapper.yml",
"chars": 2440,
"preview": "name: Publish wrapper\non: [workflow_dispatch]\n\nenv:\n WORKING_DIRECTORY: ./apps/image-editor\n REACT_WRAPPER_DIRECTORY: "
},
{
"path": ".gitignore",
"chars": 771,
"preview": "# Logs\nlogs\n*.log\n\n# Runtime data\npids\n*.pid\n*.seed\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nl"
},
{
"path": ".prettierrc",
"chars": 401,
"preview": "{\n \"singleQuote\": true,\n \"printWidth\": 100,\n \"tabWidth\": 2,\n \"useTabs\": false,\n \"semi\": true,\n \"quoteProps\": \"as-n"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 3229,
"preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
},
{
"path": "CONTRIBUTING.md",
"chars": 5199,
"preview": "# Contributing to TOAST UI\n\nFirst off, thanks for taking the time to contribute! 🎉 😘 ✨\n\nThe following is a set of guidel"
},
{
"path": "ISSUE_TEMPLATE.md",
"chars": 685,
"preview": "<!--\nThank you for your contribution.\n\nWhen it comes to write an issue, please, use the template below.\nTo use the templ"
},
{
"path": "LICENSE",
"chars": 1077,
"preview": "\nThe MIT License\n\nCopyright (c) 2019 NHN Cloud Corp.\n\nPermission is hereby granted, free of charge, to any person obtain"
},
{
"path": "README.md",
"chars": 17249,
"preview": "# ;\n\nmodule.exports = {\n process(src, filename) {\n return `module.exports = ${JSON.stringi"
},
{
"path": "apps/image-editor/__mocks__/svgMock.js",
"chars": 139,
"preview": "module.exports = {\n process() {\n return `module.exports = 'PGRlZnMgaWQ9InR1aS1pbWFnZS1lZGl0b3Itc3ZnLWRlZmF1bHQtaWNvb"
},
{
"path": "apps/image-editor/createConfigVariable.js",
"chars": 928,
"preview": "const fs = require('fs');\nconst path = require('path');\nconst config = require(path.resolve(__dirname, 'tuidoc.config.js"
},
{
"path": "apps/image-editor/examples/css/service-basic.css",
"chars": 2177,
"preview": ".border {\n border: 1px solid black;\n}\n.body-container {\n width: 1000px;\n}\n.tui-image-editor-controls {\n min-height: 2"
},
{
"path": "apps/image-editor/examples/css/service-mobile.css",
"chars": 3854,
"preview": "html,\nbody {\n margin: 0;\n padding: 0;\n height: 100%;\n overflow: hidden;\n background-color: #383838;\n font-family: "
},
{
"path": "apps/image-editor/examples/css/tui-example-style.css",
"chars": 288,
"preview": "body {\n margin: 0;\n padding: 0;\n}\n\n.code-description {\n padding: 22px 52px;\n background-color: rgba(81, 92, 230, 0.1"
},
{
"path": "apps/image-editor/examples/example01-includeUi.html",
"chars": 1923,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <title>0. Design</title>\n <link\n type"
},
{
"path": "apps/image-editor/examples/example02-useApiDirect.html",
"chars": 14583,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <title>1. Basic</title>\n <link\n type="
},
{
"path": "apps/image-editor/examples/example03-mobile.html",
"chars": 10365,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-w"
},
{
"path": "apps/image-editor/examples/examples.json",
"chars": 194,
"preview": "{\n \"example01-includeUi\": {\n \"title\": \"1. Include ui\"\n },\n \"example02-useApiDirect\": {\n \"title\": \"2. Use api di"
},
{
"path": "apps/image-editor/examples/js/service-basic.js",
"chars": 24789,
"preview": "/* eslint-disable vars-on-top,no-var,strict,prefer-template,prefer-arrow-callback,prefer-destructuring,object-shorthand,"
},
{
"path": "apps/image-editor/examples/js/service-mobile.js",
"chars": 13966,
"preview": "/* eslint-disable vars-on-top,no-var,strict,prefer-template,prefer-arrow-callback,prefer-destructuring,object-shorthand,"
},
{
"path": "apps/image-editor/examples/js/theme/black-theme.js",
"chars": 2278,
"preview": "var blackTheme = {\n 'common.bi.image': 'https://uicdn.toast.com/toastui/img/tui-image-editor-bi.png',\n 'common.bisize."
},
{
"path": "apps/image-editor/examples/js/theme/white-theme.js",
"chars": 2302,
"preview": "var whiteTheme = {\n 'common.bi.image': 'https://uicdn.toast.com/toastui/img/tui-image-editor-bi.png',\n 'common.bisize."
},
{
"path": "apps/image-editor/index.d.ts",
"chars": 9554,
"preview": "// Type definitions for TOAST UI Image Editor v3.15.2\n// TypeScript Version: 3.2.2\n\ndeclare namespace tuiImageEditor {\n "
},
{
"path": "apps/image-editor/jest-setup.js",
"chars": 27,
"preview": "import 'jest-canvas-mock';\n"
},
{
"path": "apps/image-editor/jest.config.js",
"chars": 642,
"preview": "const path = require('path');\nconst setupFile = path.resolve(__dirname, './jest-setup.js');\n\nmodule.exports = {\n module"
},
{
"path": "apps/image-editor/makesvg.js",
"chars": 770,
"preview": "/* eslint-disable */\nconst fs = require('fs');\nconst mkdirp = require('mkdirp');\nconst svgstore = require('svgstore');\nc"
},
{
"path": "apps/image-editor/package.json",
"chars": 1395,
"preview": "{\n \"name\": \"tui-image-editor\",\n \"version\": \"3.15.3\",\n \"description\": \"TOAST UI ImageEditor\",\n \"keywords\": [\n \"nhn"
},
{
"path": "apps/image-editor/scripts/publishToCDN.js",
"chars": 2526,
"preview": "/* eslint-disable */\nconst path = require('path');\nconst fs = require('fs');\nconst fetch = require('node-fetch');\nconst "
},
{
"path": "apps/image-editor/scripts/updateWrapper.js",
"chars": 898,
"preview": "/* eslint-disable */\nconst path = require('path');\nconst fs = require('fs');\n\nconst CORE_PACKAGE_JSON_PATH = path.join(_"
},
{
"path": "apps/image-editor/src/css/buttons.styl",
"chars": 3135,
"preview": "/* ICON BUTTON */\n.tie-icon-add-button\n &.icon-bubble .{prefix}-button[data-icontype=\"icon-bubble\"] svg > use.active,"
},
{
"path": "apps/image-editor/src/css/checkbox.styl",
"chars": 2999,
"preview": "/* VIRTUAL CHECKBOX */\n.{prefix}-container\n .filter-color-item\n display: inline-block;\n .tui-image-editor-checkbo"
},
{
"path": "apps/image-editor/src/css/colorpicker.styl",
"chars": 4401,
"preview": "/* COLOR PICKER */\n.{prefix}-container\n div.tui-colorpicker-clearfix\n width: 159px;\n height: 28px;\n "
},
{
"path": "apps/image-editor/src/css/gridtable.styl",
"chars": 1505,
"preview": "/* GRID VISUAL OF FLIP AND ROTATE MENU */\n.{prefix}-container\n .{prefix}-grid-visual\n display: none;\n "
},
{
"path": "apps/image-editor/src/css/icon.styl",
"chars": 1145,
"preview": "/* ICON */\n.{prefix}-container\n .tie-icon-add-button .{prefix}-button\n min-width: 42px;\n .svg_ic-menu\n ."
},
{
"path": "apps/image-editor/src/css/index.styl",
"chars": 404,
"preview": "prefix = 'tui-image-editor'\n\n@import 'main.styl'\n@import 'gridtable.styl'\n@import 'submenu.styl'\n@import 'checkbox.styl'"
},
{
"path": "apps/image-editor/src/css/main.styl",
"chars": 4115,
"preview": "body > textarea\n position: fixed !important;\n\n+prefix-classes(prefix)\n .-container\n margin: 0;\n padding: 0;\n "
},
{
"path": "apps/image-editor/src/css/position.styl",
"chars": 9077,
"preview": "/* POSITION LEFT */\n.{prefix}-container\n &.left\n .{prefix}-menu\n > .{prefix}-item[tooltip-content]\n "
},
{
"path": "apps/image-editor/src/css/range.styl",
"chars": 2457,
"preview": "/* VIRTUAL RANGE */\n.{prefix}-container\n\n .{prefix}-virtual-range-bar\n .{prefix}-virtual-range-subbar\n .{prefix"
},
{
"path": "apps/image-editor/src/css/submenu.styl",
"chars": 6103,
"preview": "/* SUBMENU */\n.{prefix}-container\n .{prefix}-submenu\n display: none;\n position: absolute;\n botto"
},
{
"path": "apps/image-editor/src/index.js",
"chars": 835,
"preview": "import '@/polyfill';\nimport ImageEditor from '@/imageEditor';\nimport '@css/index.styl';\n\n// commands\nimport '@/command/a"
},
{
"path": "apps/image-editor/src/js/action.js",
"chars": 19819,
"preview": "import extend from 'tui-code-snippet/object/extend';\nimport Imagetracer from '@/helper/imagetracer';\nimport { isSupportF"
},
{
"path": "apps/image-editor/src/js/command/addIcon.js",
"chars": 1103,
"preview": "import commandFactory from '@/factory/command';\nimport { componentNames, commandNames } from '@/consts';\n\nconst { ICON }"
},
{
"path": "apps/image-editor/src/js/command/addImageObject.js",
"chars": 768,
"preview": "import commandFactory from '@/factory/command';\nimport { commandNames } from '@/consts';\n\nconst command = {\n name: comm"
},
{
"path": "apps/image-editor/src/js/command/addObject.js",
"chars": 1003,
"preview": "import commandFactory from '@/factory/command';\nimport { commandNames, rejectMessages } from '@/consts';\n\nconst command "
},
{
"path": "apps/image-editor/src/js/command/addShape.js",
"chars": 1822,
"preview": "import commandFactory from '@/factory/command';\nimport { componentNames, commandNames } from '@/consts';\n\nconst { SHAPE "
},
{
"path": "apps/image-editor/src/js/command/addText.js",
"chars": 2327,
"preview": "import commandFactory from '@/factory/command';\nimport { componentNames, commandNames, rejectMessages } from '@/consts';"
},
{
"path": "apps/image-editor/src/js/command/applyFilter.js",
"chars": 2440,
"preview": "import extend from 'tui-code-snippet/object/extend';\nimport commandFactory from '@/factory/command';\nimport { componentN"
},
{
"path": "apps/image-editor/src/js/command/changeIconColor.js",
"chars": 1176,
"preview": "import commandFactory from '@/factory/command';\nimport { componentNames, rejectMessages, commandNames } from '@/consts';"
},
{
"path": "apps/image-editor/src/js/command/changeSelection.js",
"chars": 704,
"preview": "import commandFactory from '@/factory/command';\nimport { commandNames } from '@/consts';\nimport { getCachedUndoDataForDi"
},
{
"path": "apps/image-editor/src/js/command/changeShape.js",
"chars": 2684,
"preview": "import forEachOwnProperties from 'tui-code-snippet/collection/forEachOwnProperties';\nimport commandFactory from '@/facto"
},
{
"path": "apps/image-editor/src/js/command/changeText.js",
"chars": 1072,
"preview": "import commandFactory from '@/factory/command';\nimport { componentNames, rejectMessages, commandNames } from '@/consts';"
},
{
"path": "apps/image-editor/src/js/command/changeTextStyle.js",
"chars": 2357,
"preview": "import forEachOwnProperties from 'tui-code-snippet/collection/forEachOwnProperties';\nimport commandFactory from '@/facto"
},
{
"path": "apps/image-editor/src/js/command/clearObjects.js",
"chars": 691,
"preview": "import commandFactory from '@/factory/command';\nimport { commandNames } from '@/consts';\n\nconst command = {\n name: comm"
},
{
"path": "apps/image-editor/src/js/command/flip.js",
"chars": 804,
"preview": "import commandFactory from '@/factory/command';\nimport { componentNames, commandNames } from '@/consts';\n\nconst { FLIP }"
},
{
"path": "apps/image-editor/src/js/command/loadImage.js",
"chars": 1550,
"preview": "import commandFactory from '@/factory/command';\nimport { componentNames, commandNames } from '@/consts';\n\nconst { IMAGE_"
},
{
"path": "apps/image-editor/src/js/command/removeFilter.js",
"chars": 900,
"preview": "import commandFactory from '@/factory/command';\nimport { componentNames, commandNames } from '@/consts';\n\nconst { FILTER"
},
{
"path": "apps/image-editor/src/js/command/removeObject.js",
"chars": 826,
"preview": "import commandFactory from '@/factory/command';\nimport { commandNames, rejectMessages } from '@/consts';\n\nconst command "
},
{
"path": "apps/image-editor/src/js/command/resize.js",
"chars": 996,
"preview": "import commandFactory from '@/factory/command';\nimport { componentNames, commandNames } from '@/consts';\n\nconst { RESIZE"
},
{
"path": "apps/image-editor/src/js/command/resizeCanvasDimension.js",
"chars": 964,
"preview": "import commandFactory from '@/factory/command';\nimport { commandNames } from '@/consts';\n\nconst command = {\n name: comm"
},
{
"path": "apps/image-editor/src/js/command/rotate.js",
"chars": 1500,
"preview": "import commandFactory from '@/factory/command';\nimport { componentNames, commandNames } from '@/consts';\n\nconst { ROTATI"
},
{
"path": "apps/image-editor/src/js/command/setObjectPosition.js",
"chars": 1316,
"preview": "import commandFactory from '@/factory/command';\nimport { commandNames, rejectMessages } from '@/consts';\n\nconst command "
},
{
"path": "apps/image-editor/src/js/command/setObjectProperties.js",
"chars": 1672,
"preview": "import forEachOwnProperties from 'tui-code-snippet/collection/forEachOwnProperties';\nimport commandFactory from '@/facto"
},
{
"path": "apps/image-editor/src/js/component/cropper.js",
"chars": 10376,
"preview": "import { fabric } from 'fabric';\nimport extend from 'tui-code-snippet/object/extend';\nimport Component from '@/interface"
},
{
"path": "apps/image-editor/src/js/component/filter.js",
"chars": 5913,
"preview": "import isUndefined from 'tui-code-snippet/type/isUndefined';\nimport extend from 'tui-code-snippet/object/extend';\nimport"
},
{
"path": "apps/image-editor/src/js/component/flip.js",
"chars": 3293,
"preview": "import extend from 'tui-code-snippet/object/extend';\nimport Component from '@/interface/component';\nimport { componentNa"
},
{
"path": "apps/image-editor/src/js/component/freeDrawing.js",
"chars": 1415,
"preview": "import { fabric } from 'fabric';\nimport Component from '@/interface/component';\nimport { componentNames } from '@/consts"
},
{
"path": "apps/image-editor/src/js/component/icon.js",
"chars": 5773,
"preview": "import { fabric } from 'fabric';\nimport extend from 'tui-code-snippet/object/extend';\nimport forEach from 'tui-code-snip"
},
{
"path": "apps/image-editor/src/js/component/imageLoader.js",
"chars": 1918,
"preview": "import Component from '@/interface/component';\nimport { componentNames, rejectMessages } from '@/consts';\n\nconst imageOp"
},
{
"path": "apps/image-editor/src/js/component/line.js",
"chars": 4489,
"preview": "import { fabric } from 'fabric';\nimport extend from 'tui-code-snippet/object/extend';\nimport Component from '@/interface"
},
{
"path": "apps/image-editor/src/js/component/resize.js",
"chars": 2222,
"preview": "import Component from '@/interface/component';\nimport { componentNames } from '@/consts';\n\n/**\n * Resize components\n * @"
},
{
"path": "apps/image-editor/src/js/component/rotation.js",
"chars": 2570,
"preview": "import { fabric } from 'fabric';\nimport Component from '@/interface/component';\nimport { componentNames } from '@/consts"
},
{
"path": "apps/image-editor/src/js/component/shape.js",
"chars": 16988,
"preview": "import { fabric } from 'fabric';\nimport extend from 'tui-code-snippet/object/extend';\nimport Component from '@/interface"
},
{
"path": "apps/image-editor/src/js/component/text.js",
"chars": 14164,
"preview": "import { fabric } from 'fabric';\nimport extend from 'tui-code-snippet/object/extend';\nimport isExisty from 'tui-code-sni"
},
{
"path": "apps/image-editor/src/js/component/zoom.js",
"chars": 17228,
"preview": "import { fabric } from 'fabric';\nimport Component from '@/interface/component';\nimport { clamp } from '@/util';\nimport {"
},
{
"path": "apps/image-editor/src/js/consts.js",
"chars": 9375,
"preview": "import { keyMirror } from '@/util';\n\n/**\n * Help features for zoom\n * @type {Array.<string>}\n */\nexport const ZOOM_HELP_"
},
{
"path": "apps/image-editor/src/js/drawingMode/cropper.js",
"chars": 749,
"preview": "import DrawingMode from '@/interface/drawingMode';\nimport { drawingModes, componentNames as components } from '@/consts'"
},
{
"path": "apps/image-editor/src/js/drawingMode/freeDrawing.js",
"chars": 866,
"preview": "import DrawingMode from '@/interface/drawingMode';\nimport { drawingModes, componentNames as components } from '@/consts'"
},
{
"path": "apps/image-editor/src/js/drawingMode/icon.js",
"chars": 719,
"preview": "import DrawingMode from '@/interface/drawingMode';\nimport { drawingModes, componentNames as components } from '@/consts'"
},
{
"path": "apps/image-editor/src/js/drawingMode/lineDrawing.js",
"chars": 850,
"preview": "import DrawingMode from '@/interface/drawingMode';\nimport { drawingModes, componentNames as components } from '@/consts'"
},
{
"path": "apps/image-editor/src/js/drawingMode/resize.js",
"chars": 739,
"preview": "import DrawingMode from '@/interface/drawingMode';\nimport { drawingModes, componentNames as components } from '@/consts'"
},
{
"path": "apps/image-editor/src/js/drawingMode/shape.js",
"chars": 729,
"preview": "import DrawingMode from '@/interface/drawingMode';\nimport { drawingModes, componentNames as components } from '@/consts'"
},
{
"path": "apps/image-editor/src/js/drawingMode/text.js",
"chars": 719,
"preview": "import DrawingMode from '@/interface/drawingMode';\nimport { drawingModes, componentNames as components } from '@/consts'"
},
{
"path": "apps/image-editor/src/js/drawingMode/zoom.js",
"chars": 721,
"preview": "import DrawingMode from '@/interface/drawingMode';\nimport { drawingModes, componentNames as components } from '@/consts'"
},
{
"path": "apps/image-editor/src/js/extension/arrowLine.js",
"chars": 5269,
"preview": "import { fabric } from 'fabric';\n\nconst ARROW_ANGLE = 30;\nconst CHEVRON_SIZE_RATIO = 2.7;\nconst TRIANGLE_SIZE_RATIO = 1."
},
{
"path": "apps/image-editor/src/js/extension/blur.js",
"chars": 528,
"preview": "import { fabric } from 'fabric';\n\n/**\n * Blur object\n * @class Blur\n * @extends {fabric.Image.filters.Convolute}\n * @ign"
},
{
"path": "apps/image-editor/src/js/extension/colorFilter.js",
"chars": 2970,
"preview": "import { fabric } from 'fabric';\n\n/**\n * ColorFilter object\n * @class ColorFilter\n * @extends {fabric.Image.filters.Base"
},
{
"path": "apps/image-editor/src/js/extension/cropzone.js",
"chars": 16293,
"preview": "import { fabric } from 'fabric';\nimport extend from 'tui-code-snippet/object/extend';\nimport { clamp } from '@/util';\nim"
},
{
"path": "apps/image-editor/src/js/extension/emboss.js",
"chars": 508,
"preview": "import { fabric } from 'fabric';\n\n/**\n * Emboss object\n * @class Emboss\n * @extends {fabric.Image.filters.Convolute}\n * "
},
{
"path": "apps/image-editor/src/js/extension/mask.js",
"chars": 2600,
"preview": "import { fabric } from 'fabric';\n\n/**\n * Mask object\n * @class Mask\n * @extends {fabric.Image.filters.BlendImage}\n * @ig"
},
{
"path": "apps/image-editor/src/js/extension/sharpen.js",
"chars": 511,
"preview": "import { fabric } from 'fabric';\n\n/**\n * Sharpen object\n * @class Sharpen\n * @extends {fabric.Image.filters.Convolute}\n "
},
{
"path": "apps/image-editor/src/js/factory/command.js",
"chars": 777,
"preview": "import Command from '@/interface/command';\n\nconst commands = {};\n\n/**\n * Create a command\n * @param {string} name - Comm"
},
{
"path": "apps/image-editor/src/js/factory/errorMessage.js",
"chars": 626,
"preview": "import extend from 'tui-code-snippet/object/extend';\nimport { keyMirror } from '@/util';\n\nconst types = keyMirror('UN_IM"
},
{
"path": "apps/image-editor/src/js/graphics.js",
"chars": 40113,
"preview": "import { fabric } from 'fabric';\nimport extend from 'tui-code-snippet/object/extend';\nimport isArray from 'tui-code-snip"
},
{
"path": "apps/image-editor/src/js/helper/imagetracer.js",
"chars": 41755,
"preview": "/*\n imagetracer.js version 1.2.4\n Simple raster image tracer and vectorizer written in JavaScript.\n andras@jankovics."
},
{
"path": "apps/image-editor/src/js/helper/selectionModifyHelper.js",
"chars": 1883,
"preview": "import { fabric } from 'fabric';\nimport extend from 'tui-code-snippet/object/extend';\n\n/**\n * Cached selection's info\n *"
},
{
"path": "apps/image-editor/src/js/helper/shapeFilterFillHelper.js",
"chars": 17490,
"preview": "import { fabric } from 'fabric';\nimport forEach from 'tui-code-snippet/collection/forEach';\nimport extend from 'tui-code"
},
{
"path": "apps/image-editor/src/js/helper/shapeResizeHelper.js",
"chars": 6175,
"preview": "const DIVISOR = {\n rect: 1,\n circle: 2,\n triangle: 1,\n};\nconst DIMENSION_KEYS = {\n rect: {\n w: 'width',\n h: 'h"
},
{
"path": "apps/image-editor/src/js/imageEditor.js",
"chars": 52455,
"preview": "import { fabric } from 'fabric';\nimport extend from 'tui-code-snippet/object/extend';\nimport isUndefined from 'tui-code-"
},
{
"path": "apps/image-editor/src/js/interface/command.js",
"chars": 2844,
"preview": "import extend from 'tui-code-snippet/object/extend';\nimport errorMessage from '@/factory/errorMessage';\n\nconst createMes"
},
{
"path": "apps/image-editor/src/js/interface/component.js",
"chars": 2567,
"preview": "/**\n * Component interface\n * @class\n * @param {string} name - component name\n * @param {Graphics} graphics - Graphics i"
},
{
"path": "apps/image-editor/src/js/interface/drawingMode.js",
"chars": 873,
"preview": "import errorMessage from '@/factory/errorMessage';\n\nconst createMessage = errorMessage.create;\nconst errorTypes = errorM"
},
{
"path": "apps/image-editor/src/js/invoker.js",
"chars": 5861,
"preview": "import isString from 'tui-code-snippet/type/isString';\nimport CustomEvents from 'tui-code-snippet/customEvents/customEve"
},
{
"path": "apps/image-editor/src/js/polyfill.js",
"chars": 16420,
"preview": "/* eslint-disable */\n\n// https://developer.mozilla.org/en-US/docs/Web/API/Element/closest\nif (!Element.prototype.matches"
},
{
"path": "apps/image-editor/src/js/ui/crop.js",
"chars": 3486,
"preview": "import forEach from 'tui-code-snippet/collection/forEach';\nimport Submenu from '@/ui/submenuBase';\nimport templateHtml f"
},
{
"path": "apps/image-editor/src/js/ui/draw.js",
"chars": 4672,
"preview": "import Colorpicker from '@/ui/tools/colorpicker';\nimport Range from '@/ui/tools/range';\nimport Submenu from '@/ui/submen"
},
{
"path": "apps/image-editor/src/js/ui/filter.js",
"chars": 16676,
"preview": "import forEach from 'tui-code-snippet/collection/forEach';\nimport forEachArray from 'tui-code-snippet/collection/forEach"
},
{
"path": "apps/image-editor/src/js/ui/flip.js",
"chars": 2115,
"preview": "import forEach from 'tui-code-snippet/collection/forEach';\nimport Submenu from '@/ui/submenuBase';\nimport templateHtml f"
},
{
"path": "apps/image-editor/src/js/ui/history.js",
"chars": 3921,
"preview": "import Panel from '@/ui/panelMenu';\nimport templateHtml from '@/ui/template/submenu/history';\nimport { assignmentForDest"
},
{
"path": "apps/image-editor/src/js/ui/icon.js",
"chars": 4903,
"preview": "import forEach from 'tui-code-snippet/collection/forEach';\nimport Colorpicker from '@/ui/tools/colorpicker';\nimport Subm"
},
{
"path": "apps/image-editor/src/js/ui/locale/locale.js",
"chars": 316,
"preview": "/**\n * Translate messages\n */\nclass Locale {\n constructor(locale) {\n this._locale = locale;\n }\n\n /**\n * localize"
},
{
"path": "apps/image-editor/src/js/ui/mask.js",
"chars": 2202,
"preview": "import Submenu from '@/ui/submenuBase';\nimport templateHtml from '@/ui/template/submenu/mask';\nimport { assignmentForDes"
},
{
"path": "apps/image-editor/src/js/ui/panelMenu.js",
"chars": 2881,
"preview": "/**\n * Menu Panel Class\n * @class\n * @ignore\n */\n\nclass Panel {\n /**\n * @param {HTMLElement} menuElement - menu dom e"
},
{
"path": "apps/image-editor/src/js/ui/resize.js",
"chars": 6175,
"preview": "import Submenu from '@/ui/submenuBase';\nimport templateHtml from '@/ui/template/submenu/resize';\nimport { assignmentForD"
},
{
"path": "apps/image-editor/src/js/ui/rotate.js",
"chars": 3142,
"preview": "import Range from '@/ui/tools/range';\nimport Submenu from '@/ui/submenuBase';\nimport templateHtml from '@/ui/template/su"
},
{
"path": "apps/image-editor/src/js/ui/shape.js",
"chars": 7505,
"preview": "import forEachArray from 'tui-code-snippet/collection/forEachArray';\nimport Colorpicker from '@/ui/tools/colorpicker';\ni"
},
{
"path": "apps/image-editor/src/js/ui/submenuBase.js",
"chars": 3354,
"preview": "import CustomEvents from 'tui-code-snippet/customEvents/customEvents';\nimport { eventNames } from '@/consts';\n\n/**\n * Su"
},
{
"path": "apps/image-editor/src/js/ui/template/controls.js",
"chars": 860,
"preview": "import { getHelpMenuBarPosition } from '@/util';\n\nexport default ({ locale, biImage, loadButtonStyle, downloadButtonStyl"
},
{
"path": "apps/image-editor/src/js/ui/template/mainContainer.js",
"chars": 1381,
"preview": "export default ({\n locale,\n biImage,\n commonStyle,\n headerStyle,\n loadButtonStyle,\n downloadButtonStyle,\n submenu"
},
{
"path": "apps/image-editor/src/js/ui/template/style.js",
"chars": 6731,
"preview": "export default ({\n subMenuLabelActive,\n subMenuLabelNormal,\n subMenuRangeTitle,\n submenuPartitionVertical,\n submenu"
},
{
"path": "apps/image-editor/src/js/ui/template/submenu/crop.js",
"chars": 2940,
"preview": "/**\n * @param {Object} submenuInfo - submenu info for make template\n * @param {Locale} locale - Translate text\n * @p"
},
{
"path": "apps/image-editor/src/js/ui/template/submenu/draw.js",
"chars": 1541,
"preview": "/**\n * @param {Object} submenuInfo - submenu info for make template\n * @param {Locale} locale - Translate text\n * @p"
},
{
"path": "apps/image-editor/src/js/ui/template/submenu/filter.js",
"chars": 6938,
"preview": "/**\n * @param {Locale} locale - Translate text\n * @returns {string}\n */\nexport default ({ locale }) => `\n <ul class=\""
},
{
"path": "apps/image-editor/src/js/ui/template/submenu/flip.js",
"chars": 1336,
"preview": "/**\n * @param {Object} submenuInfo - submenu info for make template\n * @param {Locale} locale - Translate text\n * @p"
},
{
"path": "apps/image-editor/src/js/ui/template/submenu/history.js",
"chars": 814,
"preview": "/**\n * @param {Object} submenuInfo - submenu info for make template\n * @param {Locale} locale - Translate text\n * @p"
},
{
"path": "apps/image-editor/src/js/ui/template/submenu/icon.js",
"chars": 3958,
"preview": "/**\n * @param {Object} submenuInfo - submenu info for make template\n * @param {Locale} locale - Translate text\n * @p"
},
{
"path": "apps/image-editor/src/js/ui/template/submenu/mask.js",
"chars": 1134,
"preview": "/**\n * @param {Object} submenuInfo - submenu info for make template\n * @param {Locale} locale - Translate text\n * @p"
},
{
"path": "apps/image-editor/src/js/ui/template/submenu/resize.js",
"chars": 2439,
"preview": "/**\n * @param {Object} submenuInfo - submenu info for make template\n * @param {Locale} locale - Translate text\n * @p"
},
{
"path": "apps/image-editor/src/js/ui/template/submenu/rotate.js",
"chars": 1254,
"preview": "/**\n * @param {Object} submenuInfo - submenu info for make template\n * @param {Locale} locale - Translate text\n * @p"
},
{
"path": "apps/image-editor/src/js/ui/template/submenu/shape.js",
"chars": 1861,
"preview": "/**\n * @param {Object} submenuInfo - submenu info for make template\n * @param {Locale} locale - Translate text\n * @p"
},
{
"path": "apps/image-editor/src/js/ui/template/submenu/text.js",
"chars": 2675,
"preview": "/**\n * @param {Object} submenuInfo - submenu info for make template\n * @param {Locale} locale - Translate text\n * @p"
},
{
"path": "apps/image-editor/src/js/ui/template/submenu/zoom.js",
"chars": 1338,
"preview": "/**\n * @param {Object} submenuInfo - submenu info for make template\n * @param {Locale} locale - Translate text\n * @p"
},
{
"path": "apps/image-editor/src/js/ui/text.js",
"chars": 7139,
"preview": "import Range from '@/ui/tools/range';\nimport Colorpicker from '@/ui/tools/colorpicker';\nimport Submenu from '@/ui/submen"
},
{
"path": "apps/image-editor/src/js/ui/theme/standard.js",
"chars": 9371,
"preview": "/**\n * Full configuration for theme.<br>\n * @typedef {object} themeConfig\n * @property {string} common.bi.image - Brand "
},
{
"path": "apps/image-editor/src/js/ui/theme/theme.js",
"chars": 7790,
"preview": "import extend from 'tui-code-snippet/object/extend';\nimport forEach from 'tui-code-snippet/collection/forEach';\nimport s"
},
{
"path": "apps/image-editor/src/js/ui/tools/colorpicker.js",
"chars": 6141,
"preview": "import forEach from 'tui-code-snippet/collection/forEach';\nimport CustomEvents from 'tui-code-snippet/customEvents/custo"
},
{
"path": "apps/image-editor/src/js/ui/tools/range.js",
"chars": 10383,
"preview": "import forEach from 'tui-code-snippet/collection/forEach';\nimport CustomEvents from 'tui-code-snippet/customEvents/custo"
},
{
"path": "apps/image-editor/src/js/ui.js",
"chars": 23888,
"preview": "import CustomEvents from 'tui-code-snippet/customEvents/customEvents';\nimport extend from 'tui-code-snippet/object/exten"
},
{
"path": "apps/image-editor/src/js/util.js",
"chars": 13482,
"preview": "import isUndefined from 'tui-code-snippet/type/isUndefined';\nimport forEach from 'tui-code-snippet/collection/forEach';\n"
},
{
"path": "apps/image-editor/tests/__snapshots__/arrowLine.spec.js.snap",
"chars": 1755,
"preview": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`ArrowLine should be a triangular shape that closes the path with cl"
},
{
"path": "apps/image-editor/tests/__snapshots__/shape.spec.js.snap",
"chars": 2040,
"preview": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Shape Fill - filter type should be the same size as the rectangle t"
},
{
"path": "apps/image-editor/tests/__snapshots__/text.spec.js.snap",
"chars": 1215,
"preview": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Text should maintain consistent left and top positions after enteri"
},
{
"path": "apps/image-editor/tests/__snapshots__/theme.spec.js.snap",
"chars": 1043,
"preview": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Theme _makeCssText() should return the cssText of the expected valu"
},
{
"path": "apps/image-editor/tests/action.spec.js",
"chars": 16571,
"preview": "import { fabric } from 'fabric';\nimport ImageEditor from '@/imageEditor';\n\nimport '@/command/loadImage';\n\ndescribe('UI',"
},
{
"path": "apps/image-editor/tests/arrowLine.spec.js",
"chars": 1603,
"preview": "import ArrowLine from '@/extension/arrowLine';\n\ndescribe('ArrowLine', () => {\n let ctx, arrowLine, linePath;\n function"
},
{
"path": "apps/image-editor/tests/command.spec.js",
"chars": 15722,
"preview": "import { fabric } from 'fabric';\nimport Graphics from '@/graphics';\nimport Invoker from '@/invoker';\nimport commandFacto"
},
{
"path": "apps/image-editor/tests/cropper.spec.js",
"chars": 11390,
"preview": "import { fabric } from 'fabric';\nimport Graphics from '@/graphics';\nimport Cropper from '@/component/cropper';\nimport { "
},
{
"path": "apps/image-editor/tests/cropzone.spec.js",
"chars": 3034,
"preview": "import { fabric } from 'fabric';\nimport Cropzone from '@/extension/cropzone';\n\ndescribe('Cropzone', () => {\n const opti"
},
{
"path": "apps/image-editor/tests/drawingMode.spec.js",
"chars": 1461,
"preview": "import { fabric } from 'fabric';\nimport ImageEditor from '@/imageEditor';\nimport '@/command/loadImage';\n\nimport img from"
},
{
"path": "apps/image-editor/tests/filter.spec.js",
"chars": 820,
"preview": "import { fabric } from 'fabric';\nimport Graphics from '@/graphics';\nimport Filter from '@/component/filter';\n\nimport img"
},
{
"path": "apps/image-editor/tests/flip.spec.js",
"chars": 2394,
"preview": "import { fabric } from 'fabric';\nimport Graphics from '@/graphics';\nimport Flip from '@/component/flip';\n\ndescribe('Flip"
},
{
"path": "apps/image-editor/tests/graphics.spec.js",
"chars": 6367,
"preview": "import { fabric } from 'fabric';\nimport Graphics from '@/graphics';\nimport { stamp } from '@/util';\nimport { drawingMode"
},
{
"path": "apps/image-editor/tests/history.spec.js",
"chars": 2991,
"preview": "import History from '@/ui/history';\n\ndescribe('history', () => {\n let history, options, name, detail;\n\n beforeEach(() "
},
{
"path": "apps/image-editor/tests/icon.spec.js",
"chars": 2911,
"preview": "import { fabric } from 'fabric';\nimport Graphics from '@/graphics';\nimport Icon from '@/component/icon';\n\ndescribe('Icon"
},
{
"path": "apps/image-editor/tests/imageEditor.spec.js",
"chars": 1661,
"preview": "import { fabric } from 'fabric';\nimport ImageEditor from '@/imageEditor';\nimport * as util from '@/util';\nimport { event"
},
{
"path": "apps/image-editor/tests/index.js",
"chars": 81,
"preview": "import { fabric } from 'fabric';\n\nfabric.Object.prototype.objectCaching = false;\n"
},
{
"path": "apps/image-editor/tests/invoker.spec.js",
"chars": 3208,
"preview": "import Invoker from '@/invoker';\nimport Command from '@/interface/command';\n\ndescribe('Invoker', () => {\n let invoker, "
},
{
"path": "apps/image-editor/tests/line.spec.js",
"chars": 1627,
"preview": "import { fabric } from 'fabric';\nimport Graphics from '@/graphics';\nimport Line from '@/component/line';\nimport { eventN"
},
{
"path": "apps/image-editor/tests/promiseApi.spec.js",
"chars": 7882,
"preview": "import { fabric } from 'fabric';\nimport ImageEditor from '@/imageEditor';\nimport { stamp } from '@/util';\nimport { rejec"
},
{
"path": "apps/image-editor/tests/resize.spec.js",
"chars": 2484,
"preview": "import { fabric } from 'fabric';\nimport Graphics from '@/graphics';\nimport Resize from '@/component/resize';\n\ndescribe('"
},
{
"path": "apps/image-editor/tests/rotation.spec.js",
"chars": 1479,
"preview": "import { fabric } from 'fabric';\nimport Graphics from '@/graphics';\nimport Rotation from '@/component/rotation';\n\ndescri"
},
{
"path": "apps/image-editor/tests/selectionModifyHelper.spec.js",
"chars": 1680,
"preview": "import { fabric } from 'fabric';\nimport Graphics from '@/graphics';\nimport {\n setCachedUndoDataForDimension,\n getCache"
},
{
"path": "apps/image-editor/tests/shape.spec.js",
"chars": 12133,
"preview": "import { fabric } from 'fabric';\nimport Graphics from '@/graphics';\nimport Shape from '@/component/shape';\nimport { resi"
},
{
"path": "apps/image-editor/tests/text.spec.js",
"chars": 3377,
"preview": "import { fabric } from 'fabric';\nimport Graphics from '@/graphics';\nimport Text from '@/component/text';\n\ndescribe('Text"
},
{
"path": "apps/image-editor/tests/theme.spec.js",
"chars": 2884,
"preview": "import Theme from '@/ui/theme/theme';\nimport defaultTheme from '@/ui/theme/standard';\n\ndescribe('Theme', () => {\n let t"
},
{
"path": "apps/image-editor/tests/types/tsconfig.json",
"chars": 137,
"preview": "{\n \"compilerOptions\": {\n \"noEmit\": true,\n \"noImplicitAny\": false\n },\n \"include\": [\n \"../../index.d.ts\", \"./t"
},
{
"path": "apps/image-editor/tests/types/type-tests.ts",
"chars": 7744,
"preview": "import ImageEditor = require('tui-image-editor');\n\nconst blackTheme = {\n 'common.bi.image': 'https://uicdn.toast.com/to"
},
{
"path": "apps/image-editor/tests/ui.spec.js",
"chars": 4794,
"preview": "import UI from '@/ui';\nimport { HELP_MENUS } from '@/consts';\n\ndescribe('UI', () => {\n let ui, options;\n\n beforeEach(("
},
{
"path": "apps/image-editor/tests/uiRange.spec.js",
"chars": 1136,
"preview": "import Range from '@/ui/tools/range';\nimport { defaultRotateRangeValues } from '@/consts';\n\ndescribe('Range', () => {\n "
},
{
"path": "apps/image-editor/tests/zoom.spec.js",
"chars": 1028,
"preview": "import { fabric } from 'fabric';\nimport ImageEditor from '@/imageEditor';\n\nimport '@/command/loadImage';\n\nimport img fro"
},
{
"path": "apps/image-editor/tsBannerGenerator.js",
"chars": 825,
"preview": "/*eslint-disable*/\nvar fs = require('fs');\nvar path = require('path');\nvar rootPkg = require('../../package.json');\nvar "
},
{
"path": "apps/image-editor/tuidoc.config.json",
"chars": 850,
"preview": "{\n \"header\": {\n \"logo\": {\n \"src\": \"https://uicdn.toast.com/toastui/img/tui-image-editor-bi-white.png\"\n },\n "
},
{
"path": "apps/image-editor/webpack.common.config.js",
"chars": 1639,
"preview": "/* eslint-disable */\nconst path = require('path');\n\nconst ESLintPlugin = require('eslint-webpack-plugin');\nconst MiniCss"
},
{
"path": "apps/image-editor/webpack.config.js",
"chars": 463,
"preview": "/* eslint-disable */\nconst { merge } = require('webpack-merge');\n\nconst commonWebpackConfig = require('./webpack.common."
},
{
"path": "apps/image-editor/webpack.dev.config.js",
"chars": 247,
"preview": "/* eslint-disable */\nmodule.exports = () => ({\n mode: 'development',\n devServer: {\n compress: true,\n open: true,"
},
{
"path": "apps/image-editor/webpack.prod.config.js",
"chars": 755,
"preview": "/* eslint-disable */\nconst { version, license } = require('./package.json');\n\nconst webpack = require('webpack');\nconst "
},
{
"path": "apps/react-image-editor/.babelrc.json",
"chars": 81,
"preview": "{\n \"extends\": \"../../babel.config.json\",\n \"presets\": [\"@babel/preset-react\"]\n}\n"
},
{
"path": "apps/react-image-editor/.eslintrc.js",
"chars": 507,
"preview": "module.exports = {\n extends: ['tui/es6', 'plugin:react/recommended', 'plugin:prettier/recommended'],\n plugins: ['react"
},
{
"path": "apps/react-image-editor/.storybook/main.js",
"chars": 102,
"preview": "module.exports = {\n core: {\n builder: 'webpack5',\n },\n stories: ['../stories/*.stories.js'],\n};\n"
},
{
"path": "apps/react-image-editor/.storybook/preview.js",
"chars": 106,
"preview": "import 'tui-image-editor/dist/tui-image-editor.css';\nimport 'tui-color-picker/dist/tui-color-picker.css';\n"
},
{
"path": "apps/react-image-editor/README.md",
"chars": 5091,
"preview": "# TOAST UI Image Editor for React\n\n> This is a React component wrapping [TOAST UI Image Editor](https://github.com/nhn/t"
},
{
"path": "apps/react-image-editor/package.json",
"chars": 941,
"preview": "{\n \"name\": \"@toast-ui/react-image-editor\",\n \"version\": \"3.15.3\",\n \"description\": \"TOAST UI Image-Editor for React\",\n "
},
{
"path": "apps/react-image-editor/src/index.js",
"chars": 1544,
"preview": "import React from 'react';\nimport TuiImageEditor from 'tui-image-editor';\n\nexport default class ImageEditor extends Reac"
},
{
"path": "apps/react-image-editor/stories/index.stories.js",
"chars": 2368,
"preview": "import React from 'react';\nimport { storiesOf } from '@storybook/react';\n\nimport ImageEditor from '../src/index';\n\nconst"
},
{
"path": "apps/react-image-editor/webpack.config.js",
"chars": 990,
"preview": "/* eslint-disable */\nconst path = require('path');\nconst { version, author, license } = require('./package.json');\n\ncons"
}
]
// ... and 23 more files (download for full content)
About this extraction
This page contains the full source code of the nhn/tui.image-editor GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 223 files (905.1 KB), approximately 243.9k tokens, and a symbol index with 1077 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.