Showing
361 changed files
with
4856 additions
and
0 deletions
minsung/.babelrc
0 → 100644
minsung/.editorconfig
0 → 100644
minsung/.eslintignore
0 → 100644
minsung/.eslintrc.js
0 → 100644
1 | +module.exports = { | ||
2 | + extends: ['tui/es6', 'plugin:prettier/recommended'], | ||
3 | + plugins: ['prettier'], | ||
4 | + env: { | ||
5 | + browser: true, | ||
6 | + amd: true, | ||
7 | + node: true, | ||
8 | + jasmine: true, | ||
9 | + jquery: true, | ||
10 | + es6: true, | ||
11 | + }, | ||
12 | + globals: { | ||
13 | + fabric: true, | ||
14 | + tui: true, | ||
15 | + loadFixtures: true, | ||
16 | + }, | ||
17 | + parserOptions: { | ||
18 | + sourceType: 'module', | ||
19 | + }, | ||
20 | + rules: { | ||
21 | + 'prefer-destructuring': [ | ||
22 | + 'error', | ||
23 | + { | ||
24 | + VariableDeclarator: { array: true, object: true }, | ||
25 | + AssignmentExpression: { array: false, object: false }, | ||
26 | + }, | ||
27 | + ], | ||
28 | + 'prettier/prettier': 'error', | ||
29 | + }, | ||
30 | +}; |
minsung/.github/ISSUE_TEMPLATE/bug_report.md
0 → 100644
1 | +--- | ||
2 | +name: Bug report | ||
3 | +about: Create a report to help us improve | ||
4 | +title: '' | ||
5 | +labels: Bug | ||
6 | +assignees: '' | ||
7 | +--- | ||
8 | + | ||
9 | +**Describe the bug** | ||
10 | +A clear and concise description of what the bug is. | ||
11 | + | ||
12 | +**To Reproduce** | ||
13 | +Steps to reproduce the behavior: | ||
14 | + | ||
15 | +1. Go to '...' | ||
16 | +2. Click on '....' | ||
17 | +3. Scroll down to '....' | ||
18 | +4. See error | ||
19 | + | ||
20 | +**Expected behavior** | ||
21 | +A clear and concise description of what you expected to happen. | ||
22 | + | ||
23 | +**Screenshots** | ||
24 | +If applicable, add screenshots to help explain your problem. | ||
25 | + | ||
26 | +**Desktop (please complete the following information):** | ||
27 | + | ||
28 | +- OS: [e.g. iOS] | ||
29 | +- Browser [e.g. chrome, safari] | ||
30 | +- Version [e.g. 22] | ||
31 | + | ||
32 | +**Smartphone (please complete the following information):** | ||
33 | + | ||
34 | +- Device: [e.g. iPhone6] | ||
35 | +- OS: [e.g. iOS8.1] | ||
36 | +- Browser [e.g. stock browser, safari] | ||
37 | +- Version [e.g. 22] | ||
38 | + | ||
39 | +**Additional context** | ||
40 | +Add any other context about the problem here. |
1 | +--- | ||
2 | +name: Feature request | ||
3 | +about: Suggest an idea for this project | ||
4 | +title: '' | ||
5 | +labels: Enhancement, Need Discussion | ||
6 | +assignees: '' | ||
7 | +--- | ||
8 | + | ||
9 | +<!-- | ||
10 | +Thank you for your contribution. | ||
11 | + | ||
12 | +When it comes to write an issue, please, use the template below. | ||
13 | +To use the template is mandatory for submit new issue and we won't reply the issue that without the template. | ||
14 | + | ||
15 | +And you can write template's contents in Korean also. | ||
16 | +--> | ||
17 | + | ||
18 | +<!-- TEMPLATE --> | ||
19 | + | ||
20 | +## Version | ||
21 | + | ||
22 | +<!-- Write the version of the imageEditor you are currently using. --> | ||
23 | + | ||
24 | +## Development Environment | ||
25 | + | ||
26 | +<!-- Write the browser type, OS and so on --> | ||
27 | + | ||
28 | +## Current Behavior | ||
29 | + | ||
30 | +<!-- Write a description of the current operation. You can add sample code, 'CodePen' or 'jsfiddle' links. --> | ||
31 | + | ||
32 | +```js | ||
33 | +// Write example code | ||
34 | +``` | ||
35 | + | ||
36 | +## Expected Behavior | ||
37 | + | ||
38 | +<!-- Write a description of the future action. --> |
minsung/.github/ISSUE_TEMPLATE/question.md
0 → 100644
1 | +--- | ||
2 | +name: Question | ||
3 | +about: Create a question about imageEditor | ||
4 | +title: '' | ||
5 | +labels: Question | ||
6 | +assignees: '' | ||
7 | +--- | ||
8 | + | ||
9 | +<!-- | ||
10 | + To make it easier for us to help you, please include as much useful information as possible. | ||
11 | + | ||
12 | + Useful Links: | ||
13 | + - tutorial: https://github.com/nhn/tui.image-editor/tree/master/docs | ||
14 | + - API/Example: https://nhn.github.io/tui.image-editor/latest | ||
15 | + | ||
16 | + Before opening a new issue, please search existing issues https://github.com/nhn/tui.image-editor/issues | ||
17 | +--> | ||
18 | + | ||
19 | +**Summary** | ||
20 | +A clear and concise description of what the question is. | ||
21 | + | ||
22 | +**Screenshots** | ||
23 | +If applicable, add screenshots to help explain your question. | ||
24 | + | ||
25 | +**Version** | ||
26 | +Write the version of the imageEditor you are currently using. | ||
27 | + | ||
28 | +**Additional context** | ||
29 | +Add any other context about the problem here. |
minsung/.github/auto-comment.yml
0 → 100644
1 | +# Comment to a new issue. | ||
2 | +issuesOpened: > | ||
3 | + Thank you for raising an issue. | ||
4 | + | ||
5 | + We will try and get back to you as soon as possible. | ||
6 | + | ||
7 | + | ||
8 | + Please make sure you have filled out issue respecting our form **in English** and given us as much context as possible. | ||
9 | + **If not, the issue will be closed or not replied.** | ||
10 | + |
minsung/.github/stale.yml
0 → 100644
1 | +# Configuration for probot-stale - https://github.com/probot/stale | ||
2 | + | ||
3 | +# Number of days of inactivity before an Issue or Pull Request becomes stale | ||
4 | +daysUntilStale: 30 | ||
5 | + | ||
6 | +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. | ||
7 | +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. | ||
8 | +daysUntilClose: 7 | ||
9 | + | ||
10 | +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable | ||
11 | +exemptLabels: | ||
12 | + - Feature | ||
13 | + - Enhancement | ||
14 | + - Bug | ||
15 | + - NHN | ||
16 | + | ||
17 | +# Label to use when marking as stale | ||
18 | +staleLabel: inactive | ||
19 | + | ||
20 | +# Comment to post when marking as stale. Set to `false` to disable | ||
21 | +markComment: > | ||
22 | + This issue has been automatically marked as inactive because there hasn’t been much going on it lately. | ||
23 | + It is going to be closed after 7 days. Thanks! | ||
24 | +# Comment to post when removing the stale label. | ||
25 | +# unmarkComment: > | ||
26 | +# Your comment here. | ||
27 | + | ||
28 | +# Comment to post when closing a stale Issue or Pull Request. | ||
29 | +closeComment: > | ||
30 | + This issue will be closed due to inactivity. Thanks for your contribution! |
1 | +name: detect runtime error | ||
2 | + | ||
3 | +on: | ||
4 | + schedule: | ||
5 | + - cron: "0 22 * * *" | ||
6 | +jobs: | ||
7 | + detectError: | ||
8 | + runs-on: ubuntu-latest | ||
9 | + steps: | ||
10 | + - name: checkout repository | ||
11 | + uses: actions/checkout@v2 | ||
12 | + - name: create config variable | ||
13 | + run: | | ||
14 | + node createConfigVariable.js | ||
15 | + - name: set global error variable | ||
16 | + run: | | ||
17 | + errorVariable=`cat ./errorVariable.txt` | ||
18 | + echo "ERROR_VARIABLE=$errorVariable" >> $GITHUB_ENV | ||
19 | + - name: set url | ||
20 | + shell: bash | ||
21 | + run: | | ||
22 | + url=`cat ./url.txt` | ||
23 | + echo "URLS=$url" >> $GITHUB_ENV | ||
24 | + - name: detect runtime error | ||
25 | + uses: nhn/toast-ui.detect-runtime-error-actions@v1.0.1 | ||
26 | + with: | ||
27 | + global-error-log-variable: ${{ env.ERROR_VARIABLE }} | ||
28 | + urls: ${{ env.URLS }} | ||
29 | + env: | ||
30 | + BROWSERSTACK_USERNAME: ${{secrets.BROWSERSTACK_USERNAME}} | ||
31 | + BROWSERSTACK_ACCESS_KEY: ${{secrets.BROWSERSTACK_ACCESS_KEY}} |
minsung/.prettierrc
0 → 100644
minsung/CODE_OF_CONDUCT.md
0 → 100644
1 | +# Contributor Covenant Code of Conduct | ||
2 | + | ||
3 | +## Our Pledge | ||
4 | + | ||
5 | +In the interest of fostering an open and welcoming environment, we as | ||
6 | +contributors and maintainers pledge to making participation in our project and | ||
7 | +our community a harassment-free experience for everyone, regardless of age, body | ||
8 | +size, disability, ethnicity, gender identity and expression, level of experience, | ||
9 | +education, socio-economic status, nationality, personal appearance, race, | ||
10 | +religion, or sexual identity and orientation. | ||
11 | + | ||
12 | +## Our Standards | ||
13 | + | ||
14 | +Examples of behavior that contributes to creating a positive environment | ||
15 | +include: | ||
16 | + | ||
17 | +- Using welcoming and inclusive language | ||
18 | +- Being respectful of differing viewpoints and experiences | ||
19 | +- Gracefully accepting constructive criticism | ||
20 | +- Focusing on what is best for the community | ||
21 | +- Showing empathy towards other community members | ||
22 | + | ||
23 | +Examples of unacceptable behavior by participants include: | ||
24 | + | ||
25 | +- The use of sexualized language or imagery and unwelcome sexual attention or | ||
26 | + advances | ||
27 | +- Trolling, insulting/derogatory comments, and personal or political attacks | ||
28 | +- Public or private harassment | ||
29 | +- Publishing others' private information, such as a physical or electronic | ||
30 | + address, without explicit permission | ||
31 | +- Other conduct which could reasonably be considered inappropriate in a | ||
32 | + professional setting | ||
33 | + | ||
34 | +## Our Responsibilities | ||
35 | + | ||
36 | +Project maintainers are responsible for clarifying the standards of acceptable | ||
37 | +behavior and are expected to take appropriate and fair corrective action in | ||
38 | +response to any instances of unacceptable behavior. | ||
39 | + | ||
40 | +Project maintainers have the right and responsibility to remove, edit, or | ||
41 | +reject comments, commits, code, wiki edits, issues, and other contributions | ||
42 | +that are not aligned to this Code of Conduct, or to ban temporarily or | ||
43 | +permanently any contributor for other behaviors that they deem inappropriate, | ||
44 | +threatening, offensive, or harmful. | ||
45 | + | ||
46 | +## Scope | ||
47 | + | ||
48 | +This Code of Conduct applies both within project spaces and in public spaces | ||
49 | +when an individual is representing the project or its community. Examples of | ||
50 | +representing a project or community include using an official project e-mail | ||
51 | +address, posting via an official social media account, or acting as an appointed | ||
52 | +representative at an online or offline event. Representation of a project may be | ||
53 | +further defined and clarified by project maintainers. | ||
54 | + | ||
55 | +## Enforcement | ||
56 | + | ||
57 | +Instances of abusive, harassing, or otherwise unacceptable behavior may be | ||
58 | +reported by contacting the project team at dl_javascript@nhn.com. All | ||
59 | +complaints will be reviewed and investigated and will result in a response that | ||
60 | +is deemed necessary and appropriate to the circumstances. The project team is | ||
61 | +obligated to maintain confidentiality with regard to the reporter of an incident. | ||
62 | +Further details of specific enforcement policies may be posted separately. | ||
63 | + | ||
64 | +Project maintainers who do not follow or enforce the Code of Conduct in good | ||
65 | +faith may face temporary or permanent repercussions as determined by other | ||
66 | +members of the project's leadership. | ||
67 | + | ||
68 | +## Attribution | ||
69 | + | ||
70 | +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, | ||
71 | +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html | ||
72 | + | ||
73 | +[homepage]: https://www.contributor-covenant.org |
minsung/CONTRIBUTING.md
0 → 100644
1 | +# Contributing to TOAST UI | ||
2 | + | ||
3 | +First off, thanks for taking the time to contribute! 🎉 😘 ✨ | ||
4 | + | ||
5 | +The following is a set of guidelines for contributing to TOAST UI. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request. | ||
6 | + | ||
7 | +## Reporting Bugs | ||
8 | + | ||
9 | +Bugs are tracked as GitHub issues. Search the list and try reproduce on [demo][demo] before you create an issue. When you create an issue, please provide the following information by filling in the template. | ||
10 | + | ||
11 | +Explain the problem and include additional details to help maintainers reproduce the problem: | ||
12 | + | ||
13 | +- **Use a clear and descriptive title** for the issue to identify the problem. | ||
14 | +- **Describe the exact steps which reproduce the problem** in as many details as possible. Don't just say what you did, but explain how you did it. For example, if you moved the cursor to the end of a line, explain if you used a mouse or a keyboard. | ||
15 | +- **Provide specific examples to demonstrate the steps.** Include links to files or GitHub projects, or copy/pasteable snippets, which you use in those examples. If you're providing snippets on the issue, use Markdown code blocks. | ||
16 | +- **Describe the behavior you observed after following the steps** and point out what exactly is the problem with that behavior. | ||
17 | +- **Explain which behavior you expected to see instead and why.** | ||
18 | +- **Include screenshots and animated GIFs** which show you following the described steps and clearly demonstrate the problem. | ||
19 | + | ||
20 | +## Suggesting Enhancements | ||
21 | + | ||
22 | +In case you want to suggest for TOAST UI ImageEditor, please follow this guideline to help maintainers and the community understand your suggestion. | ||
23 | +Before creating suggestions, please check [issue list](../../labels/enhancement) if there's already a request. | ||
24 | + | ||
25 | +Create an issue and provide the following information: | ||
26 | + | ||
27 | +- **Use a clear and descriptive title** for the issue to identify the suggestion. | ||
28 | +- **Provide a step-by-step description of the suggested enhancement** in as many details as possible. | ||
29 | +- **Provide specific examples to demonstrate the steps.** Include copy/pasteable snippets which you use in those examples, as Markdown code blocks. | ||
30 | +- **Include screenshots and animated GIFs** which helps demonstrate the steps or point out the part of TOAST UI ImageEditor which the suggestion is related to. | ||
31 | +- **Explain why this enhancement would be useful** to most TOAST UI users. | ||
32 | +- **List some other image editors or applications where this enhancement exists.** | ||
33 | + | ||
34 | +## First Code Contribution | ||
35 | + | ||
36 | +Unsure where to begin contributing to TOAST UI? You can start by looking through these `document`, `good first issue` and `help wanted` issues: | ||
37 | + | ||
38 | +- **document issues**: issues which should be reviewed or improved. | ||
39 | +- **good first issues**: issues which should only require a few lines of code, and a test or two. | ||
40 | +- **help wanted issues**: issues which should be a bit more involved than beginner issues. | ||
41 | + | ||
42 | +## Pull Requests | ||
43 | + | ||
44 | +### Development WorkFlow | ||
45 | + | ||
46 | +- Set up your development environment | ||
47 | +- Make change from a right branch | ||
48 | +- Be sure the code passes `npm run lint`, `npm run test` | ||
49 | +- Make a pull request | ||
50 | + | ||
51 | +### Development environment | ||
52 | + | ||
53 | +- Prepare your machine node and it's packages installed. | ||
54 | +- Checkout our repository | ||
55 | +- Install dependencies by `npm install && bower install` | ||
56 | +- Start webpack-dev-server by `npm run serve` | ||
57 | + | ||
58 | +### Make changes | ||
59 | + | ||
60 | +#### Checkout a branch | ||
61 | + | ||
62 | +- **develop**: PR base branch. merge features, updates for next minor or major release | ||
63 | +- **master**: bug fix or document update for next patch release. develop branch will rebase every time master branch update. so keep code change to a minimum. | ||
64 | +- **production**: lastest release branch with distribution files. never make a PR on this | ||
65 | +- **gh-pages**: API docs, examples and demo | ||
66 | + | ||
67 | +#### Check Code Style | ||
68 | + | ||
69 | +Run `npm run eslint` and make sure all the tests pass. | ||
70 | + | ||
71 | +#### Test | ||
72 | + | ||
73 | +Run `npm run test` and verify all the tests pass. | ||
74 | +If you are adding new commands or features, they must include tests. | ||
75 | +If you are changing functionality, update the tests if you need to. | ||
76 | + | ||
77 | +#### Commit | ||
78 | + | ||
79 | +Follow our [commit message conventions](./docs/COMMIT_MESSAGE_CONVENTION.md). | ||
80 | + | ||
81 | +### Yes! Pull request | ||
82 | + | ||
83 | +Make your pull request, then describe your changes. | ||
84 | + | ||
85 | +#### Title | ||
86 | + | ||
87 | +Follow other PR title format on below. | ||
88 | + | ||
89 | +``` | ||
90 | + <Type>: Short Description (fix #111) | ||
91 | + <Type>: Short Description (fix #123, #111, #122) | ||
92 | + <Type>: Short Description (ref #111) | ||
93 | +``` | ||
94 | + | ||
95 | +- capitalize first letter of Type | ||
96 | +- use present tense: 'change' not 'changed' or 'changes' | ||
97 | + | ||
98 | +#### Description | ||
99 | + | ||
100 | +If it has related to issues, add links to the issues(like `#123`) in the description. | ||
101 | +Fill in the [Pull Request Template](./docs/PULL_REQUEST_TEMPLATE.md) by check your case. | ||
102 | + | ||
103 | +## Code of Conduct | ||
104 | + | ||
105 | +This project and everyone participating in it is governed by the [Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to dl_javascript@nhn.com. | ||
106 | + | ||
107 | +> This Guide is base on [atom contributing guide](https://github.com/atom/atom/blob/master/CONTRIBUTING.md), [CocoaPods](http://guides.cocoapods.org/contributing/contribute-to-cocoapods.html) and [ESLint](http://eslint.org/docs/developer-guide/contributing/pull-requests) |
minsung/ISSUE_TEMPLATE.md
0 → 100644
1 | +<!-- | ||
2 | +Thank you for your contribution. | ||
3 | + | ||
4 | +When it comes to write an issue, please, use the template below. | ||
5 | +To use the template is mandatory for submit new issue and we won't reply the issue that without the template. | ||
6 | + | ||
7 | +And you can write template's contents in Korean also. | ||
8 | +--> | ||
9 | + | ||
10 | +<!-- TEMPLATE --> | ||
11 | + | ||
12 | +## Version | ||
13 | + | ||
14 | +<!-- Write the version of the grid you are currently using. --> | ||
15 | + | ||
16 | +## Development Environment | ||
17 | + | ||
18 | +<!-- Write the browser type, OS and so on --> | ||
19 | + | ||
20 | +## Current Behavior | ||
21 | + | ||
22 | +<!-- Write a description of the current operation. You can add example code, 'CodePen' or 'jsfiddle' links. --> | ||
23 | + | ||
24 | +```js | ||
25 | +// Write example code | ||
26 | +``` | ||
27 | + | ||
28 | +## Expected Behavior | ||
29 | + | ||
30 | +<!-- Write a description of the future action. --> |
minsung/LICENSE
0 → 100644
1 | + | ||
2 | +The MIT License | ||
3 | + | ||
4 | +Copyright (c) 2019 NHN Corp. | ||
5 | + | ||
6 | +Permission is hereby granted, free of charge, to any person obtaining a copy | ||
7 | +of this software and associated documentation files (the "Software"), to deal | ||
8 | +in the Software without restriction, including without limitation the rights | ||
9 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
10 | +copies of the Software, and to permit persons to whom the Software is | ||
11 | +furnished to do so, subject to the following conditions: | ||
12 | + | ||
13 | +The above copyright notice and this permission notice shall be included in | ||
14 | +all copies or substantial portions of the Software. | ||
15 | + | ||
16 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
17 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
18 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
19 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
20 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
21 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
22 | +THE SOFTWARE. |
minsung/README.md
0 → 100644
This diff is collapsed. Click to expand it.
minsung/bower.json
0 → 100644
1 | +{ | ||
2 | + "name": "tui-image-editor", | ||
3 | + "authors": ["NHN FE Dev Lab <dl_javascript@nhn.com>"], | ||
4 | + "license": "MIT", | ||
5 | + "main": ["dist/tui-image-editor.js"], | ||
6 | + "ignore": [ | ||
7 | + "**/.*", | ||
8 | + "node_modules", | ||
9 | + "bower_components", | ||
10 | + "test", | ||
11 | + "tests", | ||
12 | + "src", | ||
13 | + "server", | ||
14 | + "data.js", | ||
15 | + "Gruntfile.js", | ||
16 | + "gulpfile.js", | ||
17 | + "karma.*.js", | ||
18 | + "conf.json", | ||
19 | + "package.json", | ||
20 | + ".gitignore", | ||
21 | + "samples", | ||
22 | + "index.js", | ||
23 | + "jsdoc.conf.json", | ||
24 | + "webpack.*.js" | ||
25 | + ], | ||
26 | + "dependencies": { | ||
27 | + "fabric": "4.2.0", | ||
28 | + "tui-code-snippet": "^1.5.0", | ||
29 | + "tui-color-picker": "^2.2.0" | ||
30 | + }, | ||
31 | + "devDependencies": { | ||
32 | + "tui-component-colorpicker": "~1.0.1", | ||
33 | + "filesaver": "*" | ||
34 | + }, | ||
35 | + "resolutions": { | ||
36 | + "tui-code-snippet": "^1.5.0", | ||
37 | + "tui-color-picker": "^2.2.0" | ||
38 | + } | ||
39 | +} |
minsung/createConfigVariable.js
0 → 100644
1 | +const fs = require('fs'); | ||
2 | +const path = require('path'); | ||
3 | +const config = require(path.resolve(process.cwd(), 'tuidoc.config.json')); | ||
4 | +const examples = config.examples || {}; | ||
5 | +const { filePath, globalErrorLogVariable } = examples; | ||
6 | + | ||
7 | +/** | ||
8 | + * Get Examples Url | ||
9 | + */ | ||
10 | +function getTestUrls() { | ||
11 | + if (!filePath) { | ||
12 | + throw Error('not exist examples path at tuidoc.config.json'); | ||
13 | + } | ||
14 | + | ||
15 | + const urlPrefix = 'http://nhn.github.io/tui.image-editor/latest'; | ||
16 | + | ||
17 | + const testUrls = fs.readdirSync(filePath).reduce((urls, fileName) => { | ||
18 | + if (/html$/.test(fileName)) { | ||
19 | + urls.push(`${urlPrefix}/${filePath}/${fileName}`); | ||
20 | + } | ||
21 | + | ||
22 | + return urls; | ||
23 | + }, []); | ||
24 | + | ||
25 | + fs.writeFileSync('url.txt', testUrls.join(', ')); | ||
26 | +} | ||
27 | + | ||
28 | +function getGlobalVariable() { | ||
29 | + if (!globalErrorLogVariable) { | ||
30 | + throw Error('not exist examples path at tuidoc.config.json'); | ||
31 | + } | ||
32 | + | ||
33 | + fs.writeFileSync('errorVariable.txt', globalErrorLogVariable); | ||
34 | +} | ||
35 | + | ||
36 | +getTestUrls(); | ||
37 | +getGlobalVariable(); |
minsung/examples/css/service-basic.css
0 → 100644
1 | +.border { | ||
2 | + border: 1px solid black; | ||
3 | +} | ||
4 | +.body-container { | ||
5 | + width: 1000px; | ||
6 | +} | ||
7 | +.tui-image-editor-controls { | ||
8 | + min-height: 250px; | ||
9 | +} | ||
10 | +.menu { | ||
11 | + padding: 0; | ||
12 | + margin-bottom: 5px; | ||
13 | + text-align: center; | ||
14 | + color: #544b61; | ||
15 | + font-weight: 400; | ||
16 | + list-style-type: none; | ||
17 | + user-select: none; | ||
18 | + -moz-user-select: none; | ||
19 | + -ms-user-select: none; | ||
20 | + -webkit-user-select: none; | ||
21 | +} | ||
22 | +.logo { | ||
23 | + margin: 0 auto; | ||
24 | + width: 300px; | ||
25 | + vertical-align: middle; | ||
26 | +} | ||
27 | +.header .name { | ||
28 | + padding: 10px; | ||
29 | + line-height: 50px; | ||
30 | + font-size: 30px; | ||
31 | + font-weight: 100; | ||
32 | + vertical-align: middle; | ||
33 | +} | ||
34 | +.header .menu { | ||
35 | + display: inline-block; | ||
36 | +} | ||
37 | +.menu-item { | ||
38 | + padding: 10px; | ||
39 | + display: inline-block; | ||
40 | + cursor: pointer; | ||
41 | + vertical-align: middle; | ||
42 | +} | ||
43 | +.menu-item a { | ||
44 | + text-decoration: none; | ||
45 | +} | ||
46 | +.menu-item.no-pointer { | ||
47 | + cursor: default; | ||
48 | +} | ||
49 | +.menu-item.active, | ||
50 | +.menu-item:hover { | ||
51 | + background-color: #f3f3f3; | ||
52 | +} | ||
53 | +.menu-item.disabled { | ||
54 | + cursor: default; | ||
55 | + color: #bfbebe; | ||
56 | +} | ||
57 | +.align-left-top { | ||
58 | + text-align: left; | ||
59 | + vertical-align: top; | ||
60 | +} | ||
61 | +.range-narrow { | ||
62 | + width: 80px; | ||
63 | +} | ||
64 | +.sub-menu-container { | ||
65 | + font-size: 14px; | ||
66 | + margin-bottom: 1em; | ||
67 | + display: none; | ||
68 | +} | ||
69 | +.tui-image-editor { | ||
70 | + height: 500px; | ||
71 | +} | ||
72 | +.tui-image-editor-canvas-container { | ||
73 | + margin: 0 auto; | ||
74 | + top: 50%; | ||
75 | + transform: translateY(-50%); | ||
76 | + -ms-transform: translateY(-50%); | ||
77 | + -moz-transform: translateY(-50%); | ||
78 | + -webkit-transform: translateY(-50%); | ||
79 | + border: 1px dashed black; | ||
80 | + overflow: hidden; | ||
81 | +} | ||
82 | +.tui-colorpicker-container { | ||
83 | + margin: 5px auto 0; | ||
84 | +} | ||
85 | +.tui-colorpicker-palette-toggle-slider { | ||
86 | + display: none; | ||
87 | +} | ||
88 | +.input-wrapper { | ||
89 | + position: relative; | ||
90 | +} | ||
91 | +.input-wrapper input { | ||
92 | + cursor: pointer; | ||
93 | + position: absolute; | ||
94 | + font-size: 999px; | ||
95 | + left: 0; | ||
96 | + top: 0; | ||
97 | + opacity: 0; | ||
98 | + width: 100%; | ||
99 | + height: 100%; | ||
100 | + overflow: hidden; | ||
101 | +} | ||
102 | +.btn-text-style { | ||
103 | + padding: 5px; | ||
104 | + margin: 3px 1px; | ||
105 | + border: 1px dashed #bfbebe; | ||
106 | + outline: 0; | ||
107 | + background-color: #eee; | ||
108 | + cursor: pointer; | ||
109 | +} | ||
110 | +.icon-text { | ||
111 | + font-size: 20px; | ||
112 | +} | ||
113 | +.select-line-type { | ||
114 | + outline: 0; | ||
115 | + vertical-align: middle; | ||
116 | +} | ||
117 | +#tui-color-picker { | ||
118 | + display: inline-block; | ||
119 | + vertical-align: middle; | ||
120 | +} | ||
121 | +#tui-text-palette { | ||
122 | + display: none; | ||
123 | + position: absolute; | ||
124 | + padding: 10px; | ||
125 | + border: 1px solid #bfbebe; | ||
126 | + background-color: #fff; | ||
127 | + z-index: 9999; | ||
128 | +} |
minsung/examples/css/service-mobile.css
0 → 100644
1 | +html, | ||
2 | +body { | ||
3 | + margin: 0; | ||
4 | + padding: 0; | ||
5 | + height: 100%; | ||
6 | + overflow: hidden; | ||
7 | + background-color: #383838; | ||
8 | + font-family: Sans-Serif; | ||
9 | +} | ||
10 | +ul, | ||
11 | +li { | ||
12 | + list-style: none; | ||
13 | + margin: 0; | ||
14 | + padding: 0; | ||
15 | +} | ||
16 | +input[type='button'], | ||
17 | +button { | ||
18 | + -webkit-appearance: none; | ||
19 | + -moz-appearance: none; | ||
20 | + background-color: #fff; | ||
21 | +} | ||
22 | +input[type='file'] { | ||
23 | + position: absolute; | ||
24 | + margin: 0; | ||
25 | + padding: 0; | ||
26 | + top: 0; | ||
27 | + left: 0; | ||
28 | + width: 100%; | ||
29 | + height: 100%; | ||
30 | + cursor: pointer; | ||
31 | + opacity: 0; | ||
32 | + filter: alpha(opacity=0); | ||
33 | +} | ||
34 | +.header { | ||
35 | + position: fixed; | ||
36 | + left: 0; | ||
37 | + top: 0; | ||
38 | + width: 100%; | ||
39 | + background-color: #fff; | ||
40 | + text-align: center; | ||
41 | + z-index: 9999; | ||
42 | +} | ||
43 | +.header .logo { | ||
44 | + margin: 10px 5px; | ||
45 | + width: 180px; | ||
46 | + vertical-align: middle; | ||
47 | +} | ||
48 | +.header .name { | ||
49 | + font-size: 16px; | ||
50 | + font-weight: bold; | ||
51 | +} | ||
52 | +.header .menu { | ||
53 | + padding: 10px; | ||
54 | + background-color: #000; | ||
55 | +} | ||
56 | +.header .menu input { | ||
57 | + opacity: 0; | ||
58 | +} | ||
59 | +.header .menu img { | ||
60 | + width: 20px; | ||
61 | + height: 20px; | ||
62 | + vertical-align: middle; | ||
63 | +} | ||
64 | +.header .button { | ||
65 | + position: relative; | ||
66 | + display: inline-block; | ||
67 | + margin: 0 5px; | ||
68 | + padding: 0; | ||
69 | + border-radius: 5px 5px; | ||
70 | + width: 30px; | ||
71 | + height: 30px; | ||
72 | + border: 0; | ||
73 | + background-color: #fff; | ||
74 | + vertical-align: middle; | ||
75 | +} | ||
76 | +.header .button.disabled img { | ||
77 | + opacity: 0.5; | ||
78 | +} | ||
79 | +.tui-image-editor { | ||
80 | + height: 100%; | ||
81 | +} | ||
82 | +.tui-image-editor-canvas-container { | ||
83 | + margin: 0 auto; | ||
84 | + top: 50%; | ||
85 | + transform: translateY(-50%); | ||
86 | + -ms-transform: translateY(-50%); | ||
87 | + -moz-transform: translateY(-50%); | ||
88 | + -webkit-transform: translateY(-50%); | ||
89 | + overflow: hidden; | ||
90 | +} | ||
91 | +.tui-image-editor-controls { | ||
92 | + position: fixed; | ||
93 | + width: 100%; | ||
94 | + left: 0; | ||
95 | + bottom: 0; | ||
96 | + background-color: #fff; | ||
97 | +} | ||
98 | +.tui-image-editor-controls .scrollable { | ||
99 | + display: inline-block; | ||
100 | + overflow-x: auto; | ||
101 | + width: 100%; | ||
102 | + height: 100%; | ||
103 | + white-space: nowrap; | ||
104 | + font-size: 0; | ||
105 | + background-color: #000; | ||
106 | + vertical-align: middle; | ||
107 | +} | ||
108 | +.tui-image-editor-controls .no-scrollable { | ||
109 | + overflow-x: hidden; | ||
110 | +} | ||
111 | +.tui-image-editor-controls .menu-item { | ||
112 | + display: inline-block; | ||
113 | + height: 80px; | ||
114 | + border-right: 1px solid #383838; | ||
115 | + background-color: #ddd; | ||
116 | + vertical-align: middle; | ||
117 | +} | ||
118 | +.tui-image-editor-controls .menu-button { | ||
119 | + width: 80px; | ||
120 | + height: 80px; | ||
121 | + border: none; | ||
122 | + vertical-align: middle; | ||
123 | + background-color: #000; | ||
124 | + color: #fff; | ||
125 | + font-size: 12px; | ||
126 | + font-weight: bold; | ||
127 | + outline: 0; | ||
128 | +} | ||
129 | +.tui-image-editor-controls .submenu-button { | ||
130 | + width: 80px; | ||
131 | + height: 80px; | ||
132 | + border: none; | ||
133 | + background-color: #ddd; | ||
134 | + vertical-align: middle; | ||
135 | +} | ||
136 | +.tui-image-editor-controls .hiddenmenu-button { | ||
137 | + margin: 0 10px; | ||
138 | + padding: 5px; | ||
139 | + border: none; | ||
140 | + color: #fff; | ||
141 | + background-color: rgba(255, 255, 255, 0); | ||
142 | +} | ||
143 | +.tui-image-editor-controls .submenu { | ||
144 | + display: none; | ||
145 | + position: absolute; | ||
146 | + top: 0; | ||
147 | + left: 0; | ||
148 | + width: 100%; | ||
149 | + font-size: 0; | ||
150 | +} | ||
151 | +.tui-image-editor-controls .submenu.show { | ||
152 | + display: block; | ||
153 | +} | ||
154 | +.tui-image-editor-controls .submenu .menu-item:last-child { | ||
155 | + margin-right: 50px; | ||
156 | +} | ||
157 | +.tui-image-editor-controls .hiddenmenu { | ||
158 | + position: absolute; | ||
159 | + display: none; | ||
160 | + padding: 40px; | ||
161 | + width: 100%; | ||
162 | + left: 0; | ||
163 | + bottom: 80px; | ||
164 | + background-color: rgba(0, 0, 0, 0.7); | ||
165 | + text-align: center; | ||
166 | + -webkit-box-sizing: border-box; | ||
167 | + -moz-box-sizing: border-box; | ||
168 | + box-sizing: border-box; | ||
169 | + z-index: 9999; | ||
170 | +} | ||
171 | +.tui-image-editor-controls .hiddenmenu.show { | ||
172 | + display: block; | ||
173 | +} | ||
174 | +.tui-image-editor-controls .hiddenmenu .top { | ||
175 | + font-size: 12px; | ||
176 | + color: #fff; | ||
177 | + margin-bottom: 20px; | ||
178 | +} | ||
179 | +.tui-image-editor-controls .btn-prev { | ||
180 | + display: inline-block; | ||
181 | + width: 30px; | ||
182 | + height: 80px; | ||
183 | + background-color: #000; | ||
184 | + color: #fff; | ||
185 | + border: none; | ||
186 | + vertical-align: middle; | ||
187 | +} | ||
188 | +.tui-image-editor-controls .tui-colorpicker-container { | ||
189 | + display: inline-block; | ||
190 | +} | ||
191 | +.tui-image-editor-controls .msg { | ||
192 | + position: absolute; | ||
193 | + margin-left: 50%; | ||
194 | + padding: 5px 10px; | ||
195 | + left: -86px; | ||
196 | + top: -50px; | ||
197 | + border-radius: 5px 5px; | ||
198 | + background-color: rgba(255, 255, 255, 0.5); | ||
199 | + font-size: 12px; | ||
200 | +} | ||
201 | +.tui-image-editor-controls .msg.hide { | ||
202 | + display: none; | ||
203 | +} |
minsung/examples/css/tui-example-style.css
0 → 100644
1 | +body { | ||
2 | + margin: 0; | ||
3 | + padding: 0; | ||
4 | +} | ||
5 | + | ||
6 | +.code-description { | ||
7 | + padding: 22px 52px; | ||
8 | + background-color: rgba(81, 92, 230, 0.1); | ||
9 | + line-height: 1.4em; | ||
10 | +} | ||
11 | + | ||
12 | +.code-description, | ||
13 | +.code-description a { | ||
14 | + font-family: Arial; | ||
15 | + font-size: 14px; | ||
16 | + color: #515ce6; | ||
17 | +} | ||
18 | + | ||
19 | +.code-html { | ||
20 | + padding: 20px 52px; | ||
21 | +} |
minsung/examples/example01-includeUi.html
0 → 100644
1 | +<!DOCTYPE html> | ||
2 | +<html> | ||
3 | + <head> | ||
4 | + <meta charset="UTF-8" /> | ||
5 | + <title>0. Design</title> | ||
6 | + <link | ||
7 | + type="text/css" | ||
8 | + href="https://uicdn.toast.com/tui-color-picker/v2.2.6/tui-color-picker.css" | ||
9 | + rel="stylesheet" | ||
10 | + /> | ||
11 | + <link type="text/css" href="../dist/tui-image-editor.css" rel="stylesheet" /> | ||
12 | + <style> | ||
13 | + @import url(http://fonts.googleapis.com/css?family=Noto+Sans); | ||
14 | + html, | ||
15 | + body { | ||
16 | + height: 100%; | ||
17 | + margin: 0; | ||
18 | + } | ||
19 | + </style> | ||
20 | + </head> | ||
21 | + <body> | ||
22 | + <div id="tui-image-editor-container"></div> | ||
23 | + <script | ||
24 | + type="text/javascript" | ||
25 | + src="https://api-storage.cloud.toast.com/v1/AUTH_e18353c4ea5746c097143946d0644e61/toast-ui-cdn/tui-image-editor/v3.11.0/example/fabric-v4.2.0.js" | ||
26 | + ></script> | ||
27 | + <script | ||
28 | + type="text/javascript" | ||
29 | + src="https://uicdn.toast.com/tui.code-snippet/v1.5.0/tui-code-snippet.min.js" | ||
30 | + ></script> | ||
31 | + <script | ||
32 | + type="text/javascript" | ||
33 | + src="https://uicdn.toast.com/tui-color-picker/v2.2.6/tui-color-picker.js" | ||
34 | + ></script> | ||
35 | + <script | ||
36 | + type="text/javascript" | ||
37 | + src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js" | ||
38 | + ></script> | ||
39 | + <script type="text/javascript" src="../dist/tui-image-editor.js"></script> | ||
40 | + <script type="text/javascript" src="./js/theme/white-theme.js"></script> | ||
41 | + <script type="text/javascript" src="./js/theme/black-theme.js"></script> | ||
42 | + <script> | ||
43 | + // Image editor | ||
44 | + var imageEditor = new tui.ImageEditor('#tui-image-editor-container', { | ||
45 | + includeUI: { | ||
46 | + loadImage: { | ||
47 | + path: 'img/sampleImage2.png', | ||
48 | + name: 'SampleImage', | ||
49 | + }, | ||
50 | + theme: blackTheme, // or whiteTheme | ||
51 | + initMenu: 'filter', | ||
52 | + menuBarPosition: 'bottom', | ||
53 | + }, | ||
54 | + cssMaxWidth: 700, | ||
55 | + cssMaxHeight: 500, | ||
56 | + usageStatistics: false, | ||
57 | + }); | ||
58 | + window.onresize = function () { | ||
59 | + imageEditor.ui.resizeEditor(); | ||
60 | + }; | ||
61 | + </script> | ||
62 | + </body> | ||
63 | +</html> |
minsung/examples/example02-useApiDirect.html
0 → 100644
This diff is collapsed. Click to expand it.
minsung/examples/example03-mobile.html
0 → 100644
This diff is collapsed. Click to expand it.
minsung/examples/examples.json
0 → 100644
minsung/examples/img/TOAST UI Component.png
0 → 100644
27.8 KB
minsung/examples/img/bg.jpg
0 → 100644
20.1 KB
minsung/examples/img/bg.png
0 → 100644
929 Bytes
minsung/examples/img/download.png
0 → 100644
786 Bytes
minsung/examples/img/mask.png
0 → 100644
24.4 KB
minsung/examples/img/openImage.png
0 → 100644
813 Bytes
minsung/examples/img/redo.png
0 → 100644
682 Bytes
minsung/examples/img/remove.png
0 → 100644
1.23 KB
minsung/examples/img/sampleImage.jpg
0 → 100644
584 KB
minsung/examples/img/sampleImage2.png
0 → 100644
1.32 MB
minsung/examples/img/undo.png
0 → 100644
672 Bytes
minsung/examples/js/service-basic.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/examples/js/service-mobile.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/examples/js/theme/black-theme.js
0 → 100644
1 | +var blackTheme = { | ||
2 | + 'common.bi.image': 'https://uicdn.toast.com/toastui/img/tui-image-editor-bi.png', | ||
3 | + 'common.bisize.width': '251px', | ||
4 | + 'common.bisize.height': '21px', | ||
5 | + 'common.backgroundImage': 'none', | ||
6 | + 'common.backgroundColor': '#1e1e1e', | ||
7 | + 'common.border': '0px', | ||
8 | + | ||
9 | + // header | ||
10 | + 'header.backgroundImage': 'none', | ||
11 | + 'header.backgroundColor': 'transparent', | ||
12 | + 'header.border': '0px', | ||
13 | + | ||
14 | + // load button | ||
15 | + 'loadButton.backgroundColor': '#fff', | ||
16 | + 'loadButton.border': '1px solid #ddd', | ||
17 | + 'loadButton.color': '#222', | ||
18 | + 'loadButton.fontFamily': "'Noto Sans', sans-serif", | ||
19 | + 'loadButton.fontSize': '12px', | ||
20 | + | ||
21 | + // download button | ||
22 | + 'downloadButton.backgroundColor': '#fdba3b', | ||
23 | + 'downloadButton.border': '1px solid #fdba3b', | ||
24 | + 'downloadButton.color': '#fff', | ||
25 | + 'downloadButton.fontFamily': "'Noto Sans', sans-serif", | ||
26 | + 'downloadButton.fontSize': '12px', | ||
27 | + | ||
28 | + // main icons | ||
29 | + 'menu.normalIcon.color': '#8a8a8a', | ||
30 | + 'menu.activeIcon.color': '#555555', | ||
31 | + 'menu.disabledIcon.color': '#434343', | ||
32 | + 'menu.hoverIcon.color': '#e9e9e9', | ||
33 | + 'menu.iconSize.width': '24px', | ||
34 | + 'menu.iconSize.height': '24px', | ||
35 | + | ||
36 | + // submenu icons | ||
37 | + 'submenu.normalIcon.color': '#8a8a8a', | ||
38 | + 'submenu.activeIcon.color': '#e9e9e9', | ||
39 | + 'submenu.iconSize.width': '32px', | ||
40 | + 'submenu.iconSize.height': '32px', | ||
41 | + | ||
42 | + // submenu primary color | ||
43 | + 'submenu.backgroundColor': '#1e1e1e', | ||
44 | + 'submenu.partition.color': '#3c3c3c', | ||
45 | + | ||
46 | + // submenu labels | ||
47 | + 'submenu.normalLabel.color': '#8a8a8a', | ||
48 | + 'submenu.normalLabel.fontWeight': 'lighter', | ||
49 | + 'submenu.activeLabel.color': '#fff', | ||
50 | + 'submenu.activeLabel.fontWeight': 'lighter', | ||
51 | + | ||
52 | + // checkbox style | ||
53 | + 'checkbox.border': '0px', | ||
54 | + 'checkbox.backgroundColor': '#fff', | ||
55 | + | ||
56 | + // range style | ||
57 | + 'range.pointer.color': '#fff', | ||
58 | + 'range.bar.color': '#666', | ||
59 | + 'range.subbar.color': '#d1d1d1', | ||
60 | + | ||
61 | + 'range.disabledPointer.color': '#414141', | ||
62 | + 'range.disabledBar.color': '#282828', | ||
63 | + 'range.disabledSubbar.color': '#414141', | ||
64 | + | ||
65 | + 'range.value.color': '#fff', | ||
66 | + 'range.value.fontWeight': 'lighter', | ||
67 | + 'range.value.fontSize': '11px', | ||
68 | + 'range.value.border': '1px solid #353535', | ||
69 | + 'range.value.backgroundColor': '#151515', | ||
70 | + 'range.title.color': '#fff', | ||
71 | + 'range.title.fontWeight': 'lighter', | ||
72 | + | ||
73 | + // colorpicker style | ||
74 | + 'colorpicker.button.border': '1px solid #1e1e1e', | ||
75 | + 'colorpicker.title.color': '#fff', | ||
76 | +}; |
minsung/examples/js/theme/white-theme.js
0 → 100644
1 | +var whiteTheme = { | ||
2 | + 'common.bi.image': 'https://uicdn.toast.com/toastui/img/tui-image-editor-bi.png', | ||
3 | + 'common.bisize.width': '251px', | ||
4 | + 'common.bisize.height': '21px', | ||
5 | + 'common.backgroundImage': './img/bg.png', | ||
6 | + 'common.backgroundColor': '#fff', | ||
7 | + 'common.border': '1px solid #c1c1c1', | ||
8 | + | ||
9 | + // header | ||
10 | + 'header.backgroundImage': 'none', | ||
11 | + 'header.backgroundColor': 'transparent', | ||
12 | + 'header.border': '0px', | ||
13 | + | ||
14 | + // load button | ||
15 | + 'loadButton.backgroundColor': '#fff', | ||
16 | + 'loadButton.border': '1px solid #ddd', | ||
17 | + 'loadButton.color': '#222', | ||
18 | + 'loadButton.fontFamily': "'Noto Sans', sans-serif", | ||
19 | + 'loadButton.fontSize': '12px', | ||
20 | + | ||
21 | + // download button | ||
22 | + 'downloadButton.backgroundColor': '#fdba3b', | ||
23 | + 'downloadButton.border': '1px solid #fdba3b', | ||
24 | + 'downloadButton.color': '#fff', | ||
25 | + 'downloadButton.fontFamily': "'Noto Sans', sans-serif", | ||
26 | + 'downloadButton.fontSize': '12px', | ||
27 | + | ||
28 | + // main icons | ||
29 | + 'menu.normalIcon.color': '#8a8a8a', | ||
30 | + 'menu.activeIcon.color': '#555555', | ||
31 | + 'menu.disabledIcon.color': '#434343', | ||
32 | + 'menu.hoverIcon.color': '#e9e9e9', | ||
33 | + 'menu.iconSize.width': '24px', | ||
34 | + 'menu.iconSize.height': '24px', | ||
35 | + | ||
36 | + // submenu icons | ||
37 | + 'submenu.normalIcon.color': '#8a8a8a', | ||
38 | + 'submenu.activeIcon.color': '#555555', | ||
39 | + 'submenu.iconSize.width': '32px', | ||
40 | + 'submenu.iconSize.height': '32px', | ||
41 | + | ||
42 | + // submenu primary color | ||
43 | + 'submenu.backgroundColor': 'transparent', | ||
44 | + 'submenu.partition.color': '#e5e5e5', | ||
45 | + | ||
46 | + // submenu labels | ||
47 | + 'submenu.normalLabel.color': '#858585', | ||
48 | + 'submenu.normalLabel.fontWeight': 'normal', | ||
49 | + 'submenu.activeLabel.color': '#000', | ||
50 | + 'submenu.activeLabel.fontWeight': 'normal', | ||
51 | + | ||
52 | + // checkbox style | ||
53 | + 'checkbox.border': '1px solid #ccc', | ||
54 | + 'checkbox.backgroundColor': '#fff', | ||
55 | + | ||
56 | + // rango style | ||
57 | + 'range.pointer.color': '#333', | ||
58 | + 'range.bar.color': '#ccc', | ||
59 | + 'range.subbar.color': '#606060', | ||
60 | + | ||
61 | + 'range.disabledPointer.color': '#d3d3d3', | ||
62 | + 'range.disabledBar.color': 'rgba(85,85,85,0.06)', | ||
63 | + 'range.disabledSubbar.color': 'rgba(51,51,51,0.2)', | ||
64 | + | ||
65 | + 'range.value.color': '#000', | ||
66 | + 'range.value.fontWeight': 'normal', | ||
67 | + 'range.value.fontSize': '11px', | ||
68 | + 'range.value.border': '0', | ||
69 | + 'range.value.backgroundColor': '#f5f5f5', | ||
70 | + 'range.title.color': '#000', | ||
71 | + 'range.title.fontWeight': 'lighter', | ||
72 | + | ||
73 | + // colorpicker style | ||
74 | + 'colorpicker.button.border': '0px', | ||
75 | + 'colorpicker.title.color': '#000', | ||
76 | +}; |
minsung/index.d.ts
0 → 100644
1 | +// Type definitions for TOAST UI Image Editor v3.9.0 | ||
2 | +// TypeScript Version: 3.2.2 | ||
3 | + | ||
4 | +declare namespace tuiImageEditor { | ||
5 | + type AngleType = number; | ||
6 | + | ||
7 | + interface IThemeConfig { | ||
8 | + 'common.bi.image'?: string; | ||
9 | + 'common.bisize.width'?: string; | ||
10 | + 'common.bisize.height'?: string; | ||
11 | + 'common.backgroundImage'?: string; | ||
12 | + 'common.backgroundColor'?: string; | ||
13 | + 'common.border'?: string; | ||
14 | + 'header.backgroundImage'?: string; | ||
15 | + 'header.backgroundColor'?: string; | ||
16 | + 'header.border'?: string; | ||
17 | + 'loadButton.backgroundColor'?: string; | ||
18 | + 'loadButton.border'?: string; | ||
19 | + 'loadButton.color'?: string; | ||
20 | + 'loadButton.fontFamily'?: string; | ||
21 | + 'loadButton.fontSize'?: string; | ||
22 | + 'downloadButton.backgroundColor'?: string; | ||
23 | + 'downloadButton.border'?: string; | ||
24 | + 'downloadButton.color'?: string; | ||
25 | + 'downloadButton.fontFamily'?: string; | ||
26 | + 'downloadButton.fontSize'?: string; | ||
27 | + 'menu.normalIcon.path'?: string; | ||
28 | + 'menu.normalIcon.name'?: string; | ||
29 | + 'menu.activeIcon.path'?: string; | ||
30 | + 'menu.activeIcon.name'?: string; | ||
31 | + 'menu.iconSize.width'?: string; | ||
32 | + 'menu.iconSize.height'?: string; | ||
33 | + 'submenu.backgroundColor'?: string; | ||
34 | + 'submenu.partition.color'?: string; | ||
35 | + 'submenu.normalIcon.path'?: string; | ||
36 | + 'submenu.normalIcon.name'?: string; | ||
37 | + 'submenu.activeIcon.path'?: string; | ||
38 | + 'submenu.activeIcon.name'?: string; | ||
39 | + 'submenu.iconSize.width'?: string; | ||
40 | + 'submenu.iconSize.height'?: string; | ||
41 | + 'submenu.normalLabel.color'?: string; | ||
42 | + 'submenu.normalLabel.fontWeight'?: string; | ||
43 | + 'submenu.activeLabel.color'?: string; | ||
44 | + 'submenu.activeLabel.fontWeight'?: string; | ||
45 | + 'checkbox.border'?: string; | ||
46 | + 'checkbox.backgroundColor'?: string; | ||
47 | + 'range.pointer.color'?: string; | ||
48 | + 'range.bar.color'?: string; | ||
49 | + 'range.subbar.color'?: string; | ||
50 | + 'range.value.color'?: string; | ||
51 | + 'range.value.fontWeight'?: string; | ||
52 | + 'range.value.fontSize'?: string; | ||
53 | + 'range.value.border'?: string; | ||
54 | + 'range.value.backgroundColor'?: string; | ||
55 | + 'range.title.color'?: string; | ||
56 | + 'range.title.fontWeight'?: string; | ||
57 | + 'colorpicker.button.border'?: string; | ||
58 | + 'colorpicker.title.color'?: string; | ||
59 | + } | ||
60 | + | ||
61 | + interface IIconInfo { | ||
62 | + [propName: string]: string; | ||
63 | + } | ||
64 | + | ||
65 | + interface IIconOptions { | ||
66 | + fill?: string; | ||
67 | + left?: number; | ||
68 | + top?: number; | ||
69 | + } | ||
70 | + | ||
71 | + interface IShapeOptions { | ||
72 | + fill?: string; | ||
73 | + stroke?: string; | ||
74 | + strokeWidth?: number; | ||
75 | + width?: number; | ||
76 | + height?: number; | ||
77 | + rx?: number; | ||
78 | + ry?: number; | ||
79 | + left?: number; | ||
80 | + top?: number; | ||
81 | + isRegular?: boolean; | ||
82 | + } | ||
83 | + | ||
84 | + interface IGenerateTextOptions { | ||
85 | + styles?: ITextStyleConfig; | ||
86 | + position?: { | ||
87 | + x: number; | ||
88 | + y: number; | ||
89 | + }; | ||
90 | + } | ||
91 | + | ||
92 | + interface ITextStyleConfig { | ||
93 | + fill?: string; | ||
94 | + fontFamily?: string; | ||
95 | + fontSize?: number; | ||
96 | + fontStyle?: string; | ||
97 | + fontWeight?: string; | ||
98 | + textAlign?: string; | ||
99 | + textDecoration?: string; | ||
100 | + } | ||
101 | + | ||
102 | + interface IRectConfig { | ||
103 | + left: number; | ||
104 | + top: number; | ||
105 | + width: number; | ||
106 | + height: number; | ||
107 | + } | ||
108 | + | ||
109 | + interface ICanvasSize { | ||
110 | + width: number; | ||
111 | + height: number; | ||
112 | + } | ||
113 | + | ||
114 | + interface IBrushOptions { | ||
115 | + width: number; | ||
116 | + color: string; | ||
117 | + } | ||
118 | + | ||
119 | + interface IPositionConfig { | ||
120 | + x: number; | ||
121 | + y: number; | ||
122 | + originX: string; | ||
123 | + originY: string; | ||
124 | + } | ||
125 | + | ||
126 | + interface IToDataURLOptions { | ||
127 | + format?: string; | ||
128 | + quality?: number; | ||
129 | + multiplier?: number; | ||
130 | + left?: number; | ||
131 | + top?: number; | ||
132 | + width?: number; | ||
133 | + height?: number; | ||
134 | + } | ||
135 | + | ||
136 | + interface IGraphicObjectProps { | ||
137 | + id?: number; | ||
138 | + type?: string; | ||
139 | + text?: string; | ||
140 | + left?: string | number; | ||
141 | + top?: string | number; | ||
142 | + width?: string | number; | ||
143 | + height?: string | number; | ||
144 | + fill?: string; | ||
145 | + stroke?: string; | ||
146 | + strokeWidth?: string | number; | ||
147 | + fontFamily?: string; | ||
148 | + fontSize?: number; | ||
149 | + fontStyle?: string; | ||
150 | + fontWeight?: string; | ||
151 | + textAlign?: string; | ||
152 | + textDecoration?: string; | ||
153 | + opacity?: number; | ||
154 | + [propName: string]: number | string | boolean | undefined; | ||
155 | + } | ||
156 | + | ||
157 | + interface IIncludeUIOptions { | ||
158 | + loadImage?: { | ||
159 | + path: string; | ||
160 | + name: string; | ||
161 | + }; | ||
162 | + theme?: IThemeConfig; | ||
163 | + menu?: string[]; | ||
164 | + initMenu?: string; | ||
165 | + uiSize?: { | ||
166 | + width: string; | ||
167 | + height: string; | ||
168 | + }; | ||
169 | + menuBarPosition?: string; | ||
170 | + usageStatistics?: boolean; | ||
171 | + } | ||
172 | + | ||
173 | + interface ISelectionStyleConfig { | ||
174 | + cornerStyle?: string; | ||
175 | + cornerSize?: number; | ||
176 | + cornerColor?: string; | ||
177 | + cornerStrokeColor?: string; | ||
178 | + transparentCorners?: boolean; | ||
179 | + lineWidth?: number; | ||
180 | + borderColor?: string; | ||
181 | + rotatingPointOffset?: number; | ||
182 | + } | ||
183 | + | ||
184 | + interface IObjectProps { | ||
185 | + // icon, shape | ||
186 | + fill: string; | ||
187 | + height: number; | ||
188 | + id: number; | ||
189 | + left: number; | ||
190 | + opacity: number; | ||
191 | + stroke: string | null; | ||
192 | + strokeWidth: number | null; | ||
193 | + top: number; | ||
194 | + type: string; | ||
195 | + width: number; | ||
196 | + } | ||
197 | + | ||
198 | + interface ITextObjectProps extends IObjectProps { | ||
199 | + fontFamily: string; | ||
200 | + fontSize: string; | ||
201 | + fontStyle: string; | ||
202 | + text: string; | ||
203 | + textAlign: string; | ||
204 | + textDecoration: string; | ||
205 | + } | ||
206 | + | ||
207 | + interface IFilterResolveObject { | ||
208 | + type: string; | ||
209 | + action: string; | ||
210 | + } | ||
211 | + | ||
212 | + interface ICropResolveObject { | ||
213 | + oldWidth: number; | ||
214 | + oldHeight: number; | ||
215 | + newWidth: number; | ||
216 | + newHeight: number; | ||
217 | + } | ||
218 | + | ||
219 | + interface IFlipXYResolveObject { | ||
220 | + flipX: boolean; | ||
221 | + flipY: boolean; | ||
222 | + angle: AngleType; | ||
223 | + } | ||
224 | + | ||
225 | + interface IOptions { | ||
226 | + includeUI?: IIncludeUIOptions; | ||
227 | + cssMaxWidth?: number; | ||
228 | + cssMaxHeight?: number; | ||
229 | + usageStatistics?: boolean; | ||
230 | + selectionStyle?: ISelectionStyleConfig; | ||
231 | + } | ||
232 | + | ||
233 | + interface IUIDimension { | ||
234 | + height?: string; | ||
235 | + width?: string; | ||
236 | + } | ||
237 | + | ||
238 | + interface IImageDimension { | ||
239 | + oldHeight?: number; | ||
240 | + oldWidth?: number; | ||
241 | + newHeight?: number; | ||
242 | + newWidth?: number; | ||
243 | + } | ||
244 | + | ||
245 | + interface IEditorSize { | ||
246 | + uiSize?: IUIDimension; | ||
247 | + imageSize?: IImageDimension; | ||
248 | + } | ||
249 | + | ||
250 | + interface UI { | ||
251 | + resizeEditor(dimension: IEditorSize): Promise<void>; | ||
252 | + } | ||
253 | + | ||
254 | + class ImageEditor { | ||
255 | + constructor(wrapper: string | Element, options: IOptions); | ||
256 | + public ui: UI; | ||
257 | + | ||
258 | + public addIcon(type: string, options?: IIconOptions): Promise<IObjectProps>; | ||
259 | + public addImageObject(imgUrl: string): Promise<void>; | ||
260 | + public addShape(type: string, options?: IShapeOptions): Promise<IObjectProps>; | ||
261 | + public addText(text: string, options?: IGenerateTextOptions): Promise<ITextObjectProps>; | ||
262 | + public applyFilter( | ||
263 | + type: string, | ||
264 | + options?: { | ||
265 | + maskObjId: number; | ||
266 | + }, | ||
267 | + isSilent?: boolean | ||
268 | + ): Promise<IFilterResolveObject>; | ||
269 | + public changeCursor(cursorType: string): void; | ||
270 | + public changeIconColor(id: number, color: string): Promise<void>; | ||
271 | + public changeSelectableAll(selectable: boolean): void; | ||
272 | + public changeShape(id: number, options?: IShapeOptions, isSilent?: boolean): Promise<void>; | ||
273 | + public changeText(id: number, text?: string): Promise<void>; | ||
274 | + public changeTextStyle( | ||
275 | + id: number, | ||
276 | + styleObj: ITextStyleConfig, | ||
277 | + isSilent?: boolean | ||
278 | + ): Promise<void>; | ||
279 | + public clearObjects(): Promise<void>; | ||
280 | + public clearRedoStack(): void; | ||
281 | + public clearUndoStack(): void; | ||
282 | + public crop(rect: IRectConfig): Promise<ICropResolveObject>; | ||
283 | + public deactivateAll(): void; | ||
284 | + public destroy(): void; | ||
285 | + public discardSelection(): void; | ||
286 | + public flipX(): Promise<IFlipXYResolveObject>; | ||
287 | + public flipY(): Promise<IFlipXYResolveObject>; | ||
288 | + public getCanvasSize(): ICanvasSize; | ||
289 | + public getCropzoneRect(): IRectConfig; | ||
290 | + public getDrawingMode(): string; | ||
291 | + public getImageName(): string; | ||
292 | + public getObjectPosition(id: number, originX: string, originY: string): ICanvasSize; | ||
293 | + public getObjectProperties( | ||
294 | + id: number, | ||
295 | + keys: string | string[] | IGraphicObjectProps | ||
296 | + ): IGraphicObjectProps; | ||
297 | + public hasFilter(type: string): boolean; | ||
298 | + public isEmptyRedoStack(): boolean; | ||
299 | + public isEmptyUndoStack(): boolean; | ||
300 | + public loadImageFromFile(imgFile: File, imageName?: string): Promise<ICropResolveObject>; | ||
301 | + public loadImageFromURL(url: string, imageName?: string): Promise<ICropResolveObject>; | ||
302 | + public redo(): Promise<any>; | ||
303 | + public registerIcons(infos: IIconInfo): void; | ||
304 | + public removeActiveObject(): void; | ||
305 | + public removeFilter(type?: string): Promise<IFilterResolveObject>; | ||
306 | + public removeObject(id: number): Promise<void>; | ||
307 | + public resetFlip(): Promise<IFlipXYResolveObject>; | ||
308 | + public resizeCanvasDimension(dimension: ICanvasSize): Promise<void>; | ||
309 | + public rotate(angle: AngleType, isSilent?: boolean): Promise<AngleType>; | ||
310 | + public setAngle(angle: AngleType, isSilent?: boolean): Promise<AngleType>; | ||
311 | + public setBrush(option: IBrushOptions): void; | ||
312 | + public setCropzoneRect(mode?: number): void; | ||
313 | + public setDrawingShape(type: string, options?: IShapeOptions): void; | ||
314 | + public setObjectPosition(id: number, posInfo?: IPositionConfig): Promise<void>; | ||
315 | + public setObjectProperties(id: number, keyValue?: IGraphicObjectProps): Promise<void>; | ||
316 | + public setObjectPropertiesQuietly(id: number, keyValue?: IGraphicObjectProps): Promise<void>; | ||
317 | + public startDrawingMode(mode: string, option?: { width?: number; color?: string }): boolean; | ||
318 | + public stopDrawingMode(): void; | ||
319 | + public toDataURL(options?: IToDataURLOptions): string; | ||
320 | + public undo(): Promise<any>; | ||
321 | + public on(eventName: string, handler: (...args: any[]) => void): void; | ||
322 | + } | ||
323 | +} | ||
324 | + | ||
325 | +declare module 'tui-image-editor' { | ||
326 | + export = tuiImageEditor.ImageEditor; | ||
327 | +} |
minsung/jsdoc.conf.json
0 → 100644
1 | +{ | ||
2 | + "source": { | ||
3 | + "include": ["src", "README.md"], | ||
4 | + "exclude": [], | ||
5 | + "includePattern": ".+\\.js(doc)?$", | ||
6 | + "excludePattern": "(^|\\/|\\\\)_" | ||
7 | + }, | ||
8 | + "plugins": ["plugins/markdown"], | ||
9 | + "templates": { | ||
10 | + "name": "ImageEditor", | ||
11 | + "logo": { | ||
12 | + "url": "https://user-images.githubusercontent.com/35218826/40895380-0b9f4cd6-67ea-11e8-982f-18121daa3a04.png", | ||
13 | + "width": "150px", | ||
14 | + "height": "13px", | ||
15 | + "link": "https://github.com/nhn/tui.jsdoc-template" | ||
16 | + } | ||
17 | + }, | ||
18 | + "opts": { | ||
19 | + "private": false, | ||
20 | + "recurse": true, | ||
21 | + "destination": "doc", | ||
22 | + "tutorials": "examples", | ||
23 | + "template": "./node_modules/tui-jsdoc-template", | ||
24 | + "package": "package.json" | ||
25 | + } | ||
26 | +} |
minsung/karma.conf.js
0 → 100644
1 | +/* eslint-disable consts-on-top, no-process-env, require-jsdoc */ | ||
2 | +/* eslint-disable no-process-env, require-jsdoc */ | ||
3 | +const webdriverConfig = { | ||
4 | + hostname: 'fe.nhnent.com', | ||
5 | + port: 4444, | ||
6 | + remoteHost: true, | ||
7 | +}; | ||
8 | + | ||
9 | +function setConfig(defaultConfig, server) { | ||
10 | + if (server === 'ne') { | ||
11 | + defaultConfig.customLaunchers = { | ||
12 | + IE9: { | ||
13 | + base: 'WebDriver', | ||
14 | + config: webdriverConfig, | ||
15 | + browserName: 'internet explorer', | ||
16 | + version: '9', | ||
17 | + }, | ||
18 | + IE10: { | ||
19 | + base: 'WebDriver', | ||
20 | + config: webdriverConfig, | ||
21 | + browserName: 'internet explorer', | ||
22 | + version: '10', | ||
23 | + }, | ||
24 | + IE11: { | ||
25 | + base: 'WebDriver', | ||
26 | + config: webdriverConfig, | ||
27 | + browserName: 'internet explorer', | ||
28 | + version: '11', | ||
29 | + }, | ||
30 | + Edge: { | ||
31 | + base: 'WebDriver', | ||
32 | + config: webdriverConfig, | ||
33 | + browserName: 'MicrosoftEdge', | ||
34 | + }, | ||
35 | + 'Chrome-WebDriver': { | ||
36 | + base: 'WebDriver', | ||
37 | + config: webdriverConfig, | ||
38 | + browserName: 'chrome', | ||
39 | + }, | ||
40 | + 'Firefox-WebDriver': { | ||
41 | + base: 'WebDriver', | ||
42 | + config: webdriverConfig, | ||
43 | + browserName: 'firefox', | ||
44 | + }, | ||
45 | + 'Safari-WebDriver': { | ||
46 | + base: 'WebDriver', | ||
47 | + config: webdriverConfig, | ||
48 | + browserName: 'safari', | ||
49 | + }, | ||
50 | + }; | ||
51 | + defaultConfig.browsers = [ | ||
52 | + 'IE9', | ||
53 | + 'IE10', | ||
54 | + // 'IE11', | ||
55 | + // 'Edge', | ||
56 | + 'Chrome-WebDriver', | ||
57 | + 'Firefox-WebDriver', | ||
58 | + // 'Safari-WebDriver' | ||
59 | + ]; | ||
60 | + defaultConfig.reporters.push('coverage'); | ||
61 | + defaultConfig.reporters.push('junit'); | ||
62 | + defaultConfig.coverageReporter = { | ||
63 | + dir: 'report/coverage/', | ||
64 | + reporters: [ | ||
65 | + { | ||
66 | + type: 'html', | ||
67 | + subdir(browser) { | ||
68 | + return `report-html/${browser}`; | ||
69 | + }, | ||
70 | + }, | ||
71 | + { | ||
72 | + type: 'cobertura', | ||
73 | + subdir(browser) { | ||
74 | + return `report-cobertura/${browser}`; | ||
75 | + }, | ||
76 | + file: 'cobertura.txt', | ||
77 | + }, | ||
78 | + ], | ||
79 | + }; | ||
80 | + defaultConfig.junitReporter = { | ||
81 | + outputDir: 'report/junit', | ||
82 | + suite: '', | ||
83 | + }; | ||
84 | + } else { | ||
85 | + defaultConfig.browsers = ['ChromeHeadless']; | ||
86 | + } | ||
87 | +} | ||
88 | + | ||
89 | +module.exports = function (config) { | ||
90 | + const defaultConfig = { | ||
91 | + basePath: './', | ||
92 | + frameworks: ['jasmine', 'jquery-3.2.1', 'es5-shim'], | ||
93 | + files: [ | ||
94 | + // reason for not using karma-jasmine-jquery framework is that including older jasmine-karma file | ||
95 | + // included jasmine-karma version is 2.0.5 and this version don't support ie8 | ||
96 | + 'node_modules/jasmine-jquery/lib/jasmine-jquery.js', | ||
97 | + 'node_modules/fabric/dist/fabric.js', | ||
98 | + 'test/index.js', | ||
99 | + { | ||
100 | + pattern: 'test/fixtures/*.jpg', | ||
101 | + watched: false, | ||
102 | + included: false, | ||
103 | + served: true, | ||
104 | + }, | ||
105 | + { | ||
106 | + pattern: 'test/fixtures/*.png', | ||
107 | + watched: false, | ||
108 | + included: false, | ||
109 | + served: true, | ||
110 | + }, | ||
111 | + { | ||
112 | + pattern: 'test/fixtures/*.svg', | ||
113 | + watched: false, | ||
114 | + included: false, | ||
115 | + served: true, | ||
116 | + }, | ||
117 | + ], | ||
118 | + preprocessors: { | ||
119 | + 'test/index.js': ['webpack', 'sourcemap'], | ||
120 | + }, | ||
121 | + reporters: ['dots'], | ||
122 | + webpack: { | ||
123 | + mode: 'development', | ||
124 | + devtool: 'inline-source-map', | ||
125 | + externals: { | ||
126 | + fabric: 'fabric', | ||
127 | + }, | ||
128 | + module: { | ||
129 | + rules: [ | ||
130 | + { | ||
131 | + test: /\.js$/, | ||
132 | + include: /src/, | ||
133 | + exclude: /node_modules/, | ||
134 | + loader: 'eslint-loader', | ||
135 | + enforce: 'pre', | ||
136 | + }, | ||
137 | + { | ||
138 | + test: /\.js$/, | ||
139 | + exclude: /(test|node_modules)/, | ||
140 | + loader: 'istanbul-instrumenter-loader', | ||
141 | + query: { | ||
142 | + esModules: true, | ||
143 | + }, | ||
144 | + }, | ||
145 | + { | ||
146 | + test: /\.js$/, | ||
147 | + exclude: /node_modules/, | ||
148 | + loader: 'babel-loader?cacheDirectory', | ||
149 | + options: { | ||
150 | + babelrc: true, | ||
151 | + }, | ||
152 | + }, | ||
153 | + { | ||
154 | + test: /\.styl$/, | ||
155 | + use: ['css-loader', 'stylus-loader'], | ||
156 | + }, | ||
157 | + { | ||
158 | + test: /\.svg$/, | ||
159 | + loader: 'svg-inline-loader', | ||
160 | + }, | ||
161 | + ], | ||
162 | + }, | ||
163 | + }, | ||
164 | + port: 9876, | ||
165 | + colors: true, | ||
166 | + logLevel: config.LOG_INFO, | ||
167 | + autoWatch: true, | ||
168 | + singleRun: true, | ||
169 | + }; | ||
170 | + | ||
171 | + /* eslint-disable */ | ||
172 | + setConfig(defaultConfig, process.env.KARMA_SERVER); | ||
173 | + config.set(defaultConfig); | ||
174 | +}; |
minsung/makesvg.js
0 → 100644
1 | +const fs = require('fs'); | ||
2 | +const mkdirp = require('mkdirp'); | ||
3 | +const svgstore = require('svgstore'); | ||
4 | +const svgDir = './src/svg'; | ||
5 | + | ||
6 | +function getFileList(dir) { | ||
7 | + const targetDir = `${svgDir}/${dir}`; | ||
8 | + const sprites = svgstore(); | ||
9 | + fs.readdir(targetDir, (err, files) => { | ||
10 | + if (!files) return; | ||
11 | + files.forEach((file) => { | ||
12 | + if (file.match(/^\./)) return; | ||
13 | + const id = `${dir}-${file.replace(/\.svg$/, '')}`; | ||
14 | + const svg = fs.readFileSync(`${targetDir}/${file}`); | ||
15 | + sprites.add(id, svg); | ||
16 | + }); | ||
17 | + fs.writeFileSync(`./dist/svg/${dir}.svg`, sprites); | ||
18 | + }); | ||
19 | +} | ||
20 | + | ||
21 | +mkdirp('./dist/svg', (mkdirpErr) => { | ||
22 | + if (mkdirpErr) { | ||
23 | + console.error(mkdirpErr); | ||
24 | + } else { | ||
25 | + fs.readdir(svgDir, (err, dirs) => { | ||
26 | + dirs.forEach((dir) => { | ||
27 | + getFileList(dir); | ||
28 | + }); | ||
29 | + }); | ||
30 | + } | ||
31 | +}); |
This diff is collapsed. Click to expand it.
... | @@ -6,7 +6,9 @@ | ... | @@ -6,7 +6,9 @@ |
6 | "@testing-library/jest-dom": "^5.11.6", | 6 | "@testing-library/jest-dom": "^5.11.6", |
7 | "@testing-library/react": "^11.2.2", | 7 | "@testing-library/react": "^11.2.2", |
8 | "@testing-library/user-event": "^12.5.0", | 8 | "@testing-library/user-event": "^12.5.0", |
9 | + "@toast-ui/react-image-editor": "^1.3.0", | ||
9 | "antd": "^4.9.2", | 10 | "antd": "^4.9.2", |
11 | + "eslint-plugin-prettier": "^3.2.0", | ||
10 | "react": "^17.0.1", | 12 | "react": "^17.0.1", |
11 | "react-dom": "^17.0.1", | 13 | "react-dom": "^17.0.1", |
12 | "react-scripts": "4.0.1", | 14 | "react-scripts": "4.0.1", |
... | @@ -35,5 +37,9 @@ | ... | @@ -35,5 +37,9 @@ |
35 | "last 1 firefox version", | 37 | "last 1 firefox version", |
36 | "last 1 safari version" | 38 | "last 1 safari version" |
37 | ] | 39 | ] |
40 | + }, | ||
41 | + "devDependencies": { | ||
42 | + "eslint": "^7.15.0", | ||
43 | + "eslint-config-tui": "^3.1.0" | ||
38 | } | 44 | } |
39 | } | 45 | } | ... | ... |
minsung/src/css/buttons.styl
0 → 100644
1 | +/* ICON BUTTON */ | ||
2 | +.tie-icon-add-button | ||
3 | + &.icon-bubble .{prefix}-button[data-icontype="icon-bubble"] svg > use.active, | ||
4 | + &.icon-heart .{prefix}-button[data-icontype="icon-heart"] svg > use.active, | ||
5 | + &.icon-location .{prefix}-button[data-icontype="icon-location"] svg > use.active, | ||
6 | + &.icon-polygon .{prefix}-button[data-icontype="icon-polygon"] svg > use.active, | ||
7 | + &.icon-star .{prefix}-button[data-icontype="icon-star"] svg > use.active, | ||
8 | + &.icon-star-2 .{prefix}-button[data-icontype="icon-star-2"] svg > use.active, | ||
9 | + &.icon-arrow-3 .{prefix}-button[data-icontype="icon-arrow-3"] svg > use.active, | ||
10 | + &.icon-arrow-2 .{prefix}-button[data-icontype="icon-arrow-2"] svg > use.active, | ||
11 | + &.icon-arrow .{prefix}-button[data-icontype="icon-arrow"] svg > use.active, | ||
12 | + &.icon-bubble .{prefix}-button[data-icontype="icon-bubble"] svg > use.active | ||
13 | + display: block; | ||
14 | + | ||
15 | +/* DRAW BUTTON */ | ||
16 | +.tie-draw-line-select-button | ||
17 | + &.line .{prefix}-button.line svg > use.normal, | ||
18 | + &.free .{prefix}-button.free svg > use.normal | ||
19 | + display: none; | ||
20 | + | ||
21 | + &.line .{prefix}-button.line svg > use.active, | ||
22 | + &.free .{prefix}-button.free svg > use.active | ||
23 | + display: block; | ||
24 | + | ||
25 | +/* FLIP BUTTON */ | ||
26 | +.tie-flip-button | ||
27 | + &.resetFlip .{prefix}-button.resetFlip, | ||
28 | + &.flipX .{prefix}-button.flipX, | ||
29 | + &.flipY .{prefix}-button.flipY | ||
30 | + svg > use.normal | ||
31 | + display: none; | ||
32 | + svg > use.active | ||
33 | + display: block; | ||
34 | + | ||
35 | +/* MASK BUTTON */ | ||
36 | +.tie-mask-apply.apply.active .{prefix}-button.apply | ||
37 | + label | ||
38 | + color: #fff; | ||
39 | + svg > use.active | ||
40 | + display: block; | ||
41 | + | ||
42 | +/* CROP BUTTON */ | ||
43 | +.tie-crop-button, | ||
44 | +.tie-crop-preset-button | ||
45 | + .{prefix}-button.apply | ||
46 | + margin-right: 24px; | ||
47 | + .{prefix}-button.preset.active svg > use.active | ||
48 | + display: block; | ||
49 | + .{prefix}-button.apply.active svg > use.active | ||
50 | + display: block; | ||
51 | + | ||
52 | + | ||
53 | +/* SHAPE BUTTON */ | ||
54 | +.tie-shape-button | ||
55 | + &.rect .{prefix}-button.rect, | ||
56 | + &.circle .{prefix}-button.circle, | ||
57 | + &.triangle .{prefix}-button.triangle | ||
58 | + svg > use.normal | ||
59 | + display: none; | ||
60 | + svg > use.active | ||
61 | + display: block; | ||
62 | + | ||
63 | +/* TEXT BUTTON */ | ||
64 | +.tie-text-effect-button | ||
65 | + .{prefix}-button.active svg > use.active | ||
66 | + display: block; | ||
67 | +.tie-text-align-button | ||
68 | + &.left .{prefix}-button.left svg > use.active, | ||
69 | + &.center .{prefix}-button.center svg > use.active, | ||
70 | + &.right .{prefix}-button.right svg > use.active | ||
71 | + display: block; | ||
72 | +.tie-mask-image-file, | ||
73 | +.tie-icon-image-file | ||
74 | + opacity: 0; | ||
75 | + position: absolute; | ||
76 | + width: 100%; | ||
77 | + height: 100%; | ||
78 | + border: 1px solid green; | ||
79 | + cursor: inherit; | ||
80 | + left: 0; | ||
81 | + top: 0; |
minsung/src/css/checkbox.styl
0 → 100644
1 | +/* VIRTUAL CHECKBOX */ | ||
2 | +.{prefix}-container | ||
3 | + .filter-color-item | ||
4 | + display: inline-block; | ||
5 | + .tui-image-editor-checkbox | ||
6 | + display: block; | ||
7 | + .{prefix}-checkbox-wrap | ||
8 | + display: inline-block !important; | ||
9 | + text-align: left; | ||
10 | + .{prefix}-checkbox-wrap.fixed-width | ||
11 | + width: 187px; | ||
12 | + white-space: normal; | ||
13 | + .{prefix}-checkbox | ||
14 | + display: inline-block; | ||
15 | + margin: 1px 0 1px 0; | ||
16 | + input | ||
17 | + width: 14px; | ||
18 | + height: 14px; | ||
19 | + opacity: 0; | ||
20 | + > label > span | ||
21 | + color: #fff; | ||
22 | + height: 14px; | ||
23 | + position: relative; | ||
24 | + input + label:before, | ||
25 | + > label > span:before | ||
26 | + content: ''; | ||
27 | + position: absolute; | ||
28 | + width: 14px; | ||
29 | + height: 14px; | ||
30 | + background-color: #fff; | ||
31 | + top: 6px; | ||
32 | + left: -19px; | ||
33 | + display: inline-block; | ||
34 | + margin: 0; | ||
35 | + text-align: center; | ||
36 | + font-size: 11px; | ||
37 | + border: 0; | ||
38 | + border-radius: 2px; | ||
39 | + padding-top: 1px; | ||
40 | + box-sizing: border-box; | ||
41 | + input[type='checkbox']:checked + span:before | ||
42 | + background-size: cover; | ||
43 | + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IArs4c6QAAAMBJREFUKBWVkjEOwjAMRe2WgZW7IIHEDdhghhuwcQ42rlJugAQS54Cxa5cq1QM5TUpByZfS2j9+dlJVt/tX5ZxbS4ZU9VLkQvSHKTIGRaVJYFmKrBbTCJxE2UgCdDzMZDkHrOV6b95V0US6UmgKodujEZbJg0B0ZgEModO5lrY1TMQf1TpyJGBEjD+E2NPN7ukIUDiF/BfEXgRiGEw8NgkffYGYwCi808fpn/6OvfUfsDr/Vc1IfRf8sKnFVqeiVQfDu0tf/nWH9gAAAABJRU5ErkJggg=='); | ||
44 | + | ||
45 | + .{prefix}-selectlist-wrap | ||
46 | + position: relative; | ||
47 | + select | ||
48 | + width: 100%; | ||
49 | + height: 28px; | ||
50 | + margin-top: 4px; | ||
51 | + border: 0; | ||
52 | + outline: 0; | ||
53 | + border-radius: 0; | ||
54 | + border: 1px solid #cbdbdb; | ||
55 | + background-color: #fff; | ||
56 | + -webkit-appearance: none; | ||
57 | + -moz-appearance: none; | ||
58 | + appearance: none; | ||
59 | + padding: 0 7px 0 10px; | ||
60 | + .{prefix}-selectlist | ||
61 | + display: none; | ||
62 | + position: relative; | ||
63 | + top: -1px; | ||
64 | + border: 1px solid #ccc; | ||
65 | + background-color: #fff; | ||
66 | + border-top: 0px; | ||
67 | + padding: 4px 0; | ||
68 | + li | ||
69 | + display: block; | ||
70 | + text-align: left; | ||
71 | + padding: 7px 10px; | ||
72 | + font-family: 'Noto Sans', sans-serif; | ||
73 | + li:hover | ||
74 | + background-color: rgba(81, 92, 230, 0.05); | ||
75 | + .{prefix}-selectlist-wrap:before | ||
76 | + content: ''; | ||
77 | + position: absolute; | ||
78 | + display: inline-block; | ||
79 | + width: 14px; | ||
80 | + height: 14px; | ||
81 | + right: 5px; | ||
82 | + top: 10px; | ||
83 | + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IArs4c6QAAAHlJREFUKBVjYBgFOEOAEVkmPDxc89+/f6eAYjzI4kD2FyYmJrOVK1deh4kzwRggGiQBVJCELAZig8SQNYHEmEEEMrh69eo1HR0dfqCYJUickZGxf9WqVf3IakBsFBthklpaWmVA9mEQhrJhUoTp0NBQCRAmrHL4qgAAuu4cWZOZIGsAAAAASUVORK5CYII='); | ||
84 | + background-size: cover; | ||
85 | + .{prefix}-selectlist-wrap select::-ms-expand | ||
86 | + display:none; |
minsung/src/css/colorpicker.styl
0 → 100644
1 | +/* COLOR PICKER */ | ||
2 | +.{prefix}-container | ||
3 | + div.tui-colorpicker-clearfix | ||
4 | + width: 159px; | ||
5 | + height: 28px; | ||
6 | + border: 1px solid #d5d5d5; | ||
7 | + border-radius: 2px; | ||
8 | + background-color: #f5f5f5; | ||
9 | + margin-top: 6px; | ||
10 | + padding: 4px 7px 4px 7px; | ||
11 | + .tui-colorpicker-palette-hex | ||
12 | + width: 114px; | ||
13 | + background-color: #f5f5f5; | ||
14 | + border: 0; | ||
15 | + font-size: 11px; | ||
16 | + margin-top: 2px; | ||
17 | + font-family: 'Noto Sans', sans-serif; | ||
18 | + .tui-colorpicker-palette-hex[value='#ffffff'] + .tui-colorpicker-palette-preview, | ||
19 | + .tui-colorpicker-palette-hex[value=''] + .tui-colorpicker-palette-preview | ||
20 | + border: 1px solid #ccc; | ||
21 | + .tui-colorpicker-palette-hex[value=''] + .tui-colorpicker-palette-preview | ||
22 | + background-size: cover; | ||
23 | + 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'); | ||
24 | + .tui-colorpicker-palette-preview | ||
25 | + border-radius: 100%; | ||
26 | + float: left; | ||
27 | + width: 17px; | ||
28 | + height: 17px; | ||
29 | + border: 0; | ||
30 | + .color-picker-control | ||
31 | + position: absolute; | ||
32 | + display: none; | ||
33 | + z-index: 99; | ||
34 | + width: 192px; | ||
35 | + background-color: #fff; | ||
36 | + box-shadow: 0 3px 22px 6px rgba(0, 0, 0, .15); | ||
37 | + padding: 16px; | ||
38 | + border-radius: 2px; | ||
39 | + .tui-colorpicker-palette-toggle-slider | ||
40 | + display: none; | ||
41 | + .tui-colorpicker-palette-button | ||
42 | + border: 0; | ||
43 | + border-radius: 100%; | ||
44 | + margin: 2px; | ||
45 | + background-size: cover; | ||
46 | + font-size: 1px; | ||
47 | + &[title='#ffffff'] | ||
48 | + border: 1px solid #ccc; | ||
49 | + &[title=''] | ||
50 | + border: 1px solid #ccc; | ||
51 | + .triangle | ||
52 | + width: 0; | ||
53 | + height: 0; | ||
54 | + border-right: 7px solid transparent; | ||
55 | + border-top: 8px solid #fff; | ||
56 | + border-left: 7px solid transparent; | ||
57 | + position: absolute; | ||
58 | + bottom: -8px; | ||
59 | + left: 84px; | ||
60 | + .tui-colorpicker-container, | ||
61 | + .tui-colorpicker-palette-container ul, | ||
62 | + .tui-colorpicker-palette-container | ||
63 | + width: 100%; | ||
64 | + height: auto; | ||
65 | + | ||
66 | + | ||
67 | + .filter-color-item | ||
68 | + .color-picker-control label | ||
69 | + font-color: #333; | ||
70 | + font-weight: normal; | ||
71 | + margin-right: 7pxleft | ||
72 | + .tui-image-editor-checkbox | ||
73 | + margin-top: 0; | ||
74 | + input + label:before, | ||
75 | + > label:before | ||
76 | + left: -16px; | ||
77 | + .color-picker | ||
78 | + width: 100%; | ||
79 | + height: auto; | ||
80 | + .color-picker-value | ||
81 | + width: 32px; | ||
82 | + height: 32px; | ||
83 | + border: 0px; | ||
84 | + border-radius: 100%; | ||
85 | + margin: auto; | ||
86 | + margin-bottom: 1px; | ||
87 | + &.transparent | ||
88 | + border: 1px solid #cbcbcb; | ||
89 | + background-size: cover; | ||
90 | + 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'); | ||
91 | + | ||
92 | + .color-picker-value + label | ||
93 | + color: #fff; | ||
94 | + | ||
95 | + .{prefix}-submenu svg > use | ||
96 | + display: none; | ||
97 | + .{prefix}-submenu svg > use.normal | ||
98 | + display: block; |
minsung/src/css/gridtable.styl
0 → 100644
1 | +/* GRID VISUAL OF FLIP AND ROTATE MENU */ | ||
2 | +.{prefix}-container | ||
3 | + .{prefix}-grid-visual | ||
4 | + display: none; | ||
5 | + position: absolute; | ||
6 | + width: 100%; | ||
7 | + height: 100%; | ||
8 | + border: 1px solid rgba(255,255,255,0.7); | ||
9 | + .{prefix}-main.{prefix}-menu-flip, | ||
10 | + .{prefix}-main.{prefix}-menu-rotate | ||
11 | + .tui-image-editor | ||
12 | + transition: none; | ||
13 | + .{prefix}-main.{prefix}-menu-flip .{prefix}-grid-visual, | ||
14 | + .{prefix}-main.{prefix}-menu-rotate .{prefix}-grid-visual | ||
15 | + display: block; | ||
16 | + .{prefix}-grid-visual | ||
17 | + table | ||
18 | + width: 100%; | ||
19 | + height: 100%; | ||
20 | + border-collapse: collapse; | ||
21 | + td | ||
22 | + border: 1px solid rgba(255,255,255,0.3); | ||
23 | + td.dot:before | ||
24 | + content: ''; | ||
25 | + position: absolute; | ||
26 | + box-sizing: border-box; | ||
27 | + width: 10px; | ||
28 | + height: 10px; | ||
29 | + border: 0; | ||
30 | + box-shadow: 0 0 1px 0 rgba(0,0,0,0.3); | ||
31 | + border-radius: 100%; | ||
32 | + background-color: #fff; | ||
33 | + td.dot.left-top:before | ||
34 | + top: -5px; | ||
35 | + left: -5px; | ||
36 | + td.dot.right-top:before | ||
37 | + top: -5px; | ||
38 | + right: -5px; | ||
39 | + td.dot.left-bottom:before | ||
40 | + bottom: -5px; | ||
41 | + left: -5px; | ||
42 | + td.dot.right-bottom:before | ||
43 | + bottom: -5px; | ||
44 | + right: -5px; |
minsung/src/css/icon.styl
0 → 100644
1 | +/* ICON */ | ||
2 | +.{prefix}-container | ||
3 | + .tie-icon-add-button .{prefix}-button | ||
4 | + min-width: 42px; | ||
5 | + .svg_ic-menu | ||
6 | + .svg_ic-helpmenu | ||
7 | + width: 24px; | ||
8 | + height: 24px; | ||
9 | + .svg_ic-submenu | ||
10 | + width: 32px; | ||
11 | + height: 32px; | ||
12 | + .svg_img-bi | ||
13 | + width: 257px; | ||
14 | + height: 26px; | ||
15 | + | ||
16 | + .{prefix}-controls | ||
17 | + svg > use | ||
18 | + display: none; | ||
19 | + .enabled svg:hover > use.hover | ||
20 | + .normal svg:hover > use.hover | ||
21 | + display: block; | ||
22 | + .active svg:hover > use.hover | ||
23 | + display: none; | ||
24 | + svg > use.normal | ||
25 | + display: block; | ||
26 | + .active svg > use.active | ||
27 | + display: block; | ||
28 | + .enabled svg > use.enabled | ||
29 | + display: block; | ||
30 | + .active svg > use.normal, | ||
31 | + .enabled svg > use.normal | ||
32 | + display: none; | ||
33 | + .help svg > use.disabled, | ||
34 | + .help.enabled svg > use.normal | ||
35 | + display: block; | ||
36 | + .help.enabled svg > use.disabled | ||
37 | + display: none; | ||
38 | + | ||
39 | + .{prefix}-controls:hover | ||
40 | + z-index: 3; |
minsung/src/css/index.styl
0 → 100644
1 | +prefix = 'tui-image-editor' | ||
2 | + | ||
3 | +@import 'main.styl' | ||
4 | +@import 'gridtable.styl' | ||
5 | +@import 'submenu.styl' | ||
6 | +@import 'checkbox.styl' | ||
7 | +@import 'range.styl' | ||
8 | +@import 'position.styl' | ||
9 | +@import 'icon.styl' | ||
10 | +@import 'colorpicker.styl' | ||
11 | +@import 'buttons.styl' | ||
12 | +.{prefix}-container.top | ||
13 | + &.{prefix}-top-optimization | ||
14 | + .{prefix}-controls ul | ||
15 | + text-align: right; | ||
16 | + .{prefix}-controls-logo | ||
17 | + display: none; |
minsung/src/css/main.styl
0 → 100644
1 | +body > textarea | ||
2 | + position: fixed !important; | ||
3 | + | ||
4 | ++prefix-classes(prefix) | ||
5 | + .-container | ||
6 | + margin: 0; | ||
7 | + padding: 0; | ||
8 | + box-sizing: border-box; | ||
9 | + min-height: 300px; | ||
10 | + height: 100%; | ||
11 | + position: relative; | ||
12 | + background-color: #282828; | ||
13 | + overflow: hidden; | ||
14 | + letter-spacing: 0.3px; | ||
15 | + | ||
16 | + div, ul, label, input, li | ||
17 | + box-sizing: border-box; | ||
18 | + margin: 0; | ||
19 | + padding: 0; | ||
20 | + -ms-user-select: none; | ||
21 | + -moz-user-select: -moz-none; | ||
22 | + -khtml-user-select: none; | ||
23 | + -webkit-user-select: none; | ||
24 | + user-select: none; | ||
25 | + | ||
26 | + .-header | ||
27 | + /* BUTTON AND LOGO */ | ||
28 | + min-width: 533px; | ||
29 | + position: absolute; | ||
30 | + background-color: #151515; | ||
31 | + top: 0; | ||
32 | + width: 100%; | ||
33 | + .-header-buttons, | ||
34 | + .-controls-buttons | ||
35 | + float: right; | ||
36 | + margin: 8px; | ||
37 | + | ||
38 | + .-header-logo, | ||
39 | + .-controls-logo | ||
40 | + float: left; | ||
41 | + width: 30%; | ||
42 | + padding: 17px; | ||
43 | + | ||
44 | + .-controls-logo, | ||
45 | + .-controls-buttons | ||
46 | + width: 270px; | ||
47 | + height: 100%; | ||
48 | + display: none; | ||
49 | + | ||
50 | + .-header-buttons button, | ||
51 | + .-header-buttons div, | ||
52 | + .-controls-buttons button, | ||
53 | + .-controls-buttons div | ||
54 | + display: inline-block; | ||
55 | + position: relative; | ||
56 | + width: 120px; | ||
57 | + height: 40px; | ||
58 | + padding: 0; | ||
59 | + line-height: 40px; | ||
60 | + outline: none; | ||
61 | + border-radius: 20px; | ||
62 | + border: 1px solid #ddd; | ||
63 | + font-family: 'Noto Sans', sans-serif; | ||
64 | + font-size: 12px; | ||
65 | + font-weight: bold; | ||
66 | + cursor: pointer; | ||
67 | + vertical-align: middle; | ||
68 | + letter-spacing: 0.3px; | ||
69 | + text-align: center; | ||
70 | + | ||
71 | + .-download-btn | ||
72 | + background-color: #fdba3b; | ||
73 | + border-color: #fdba3b; | ||
74 | + color: #fff; | ||
75 | + .-load-btn | ||
76 | + position: absolute; | ||
77 | + left: 0; | ||
78 | + right: 0; | ||
79 | + display: inline-block; | ||
80 | + top: 0; | ||
81 | + bottom: 0; | ||
82 | + width: 100%; | ||
83 | + cursor: pointer; | ||
84 | + opacity: 0; | ||
85 | + .-main-container | ||
86 | + position: absolute; | ||
87 | + width: 100%; | ||
88 | + top: 0; | ||
89 | + bottom: 64px; | ||
90 | + .-main | ||
91 | + position: absolute; | ||
92 | + text-align: center; | ||
93 | + top: 64px; | ||
94 | + bottom: 0; | ||
95 | + right: 0; | ||
96 | + left: 0; | ||
97 | + .-wrap | ||
98 | + position: absolute; | ||
99 | + bottom: 0; | ||
100 | + width: 100%; | ||
101 | + overflow: auto; | ||
102 | + .-size-wrap | ||
103 | + display: table; | ||
104 | + width: 100%; | ||
105 | + height: 100% | ||
106 | + .-align-wrap | ||
107 | + display: table-cell; | ||
108 | + vertical-align: middle; | ||
109 | + . | ||
110 | + position: relative; | ||
111 | + display: inline-block; | ||
112 | + | ||
113 | + | ||
114 | +/* BIG MENU */ | ||
115 | +.{prefix}-container | ||
116 | + .{prefix}-menu | ||
117 | + width: auto; | ||
118 | + list-style: none; | ||
119 | + padding: 0; | ||
120 | + margin: 0 auto; | ||
121 | + display: table-cell; | ||
122 | + text-align: center; | ||
123 | + vertical-align: middle; | ||
124 | + white-space: nowrap; | ||
125 | + > .{prefix}-item | ||
126 | + position: relative; | ||
127 | + display: inline-block; | ||
128 | + border-radius: 2px; | ||
129 | + padding: 7px 8px 3px 8px; | ||
130 | + cursor: pointer; | ||
131 | + margin: 0 4px; | ||
132 | + > .{prefix}-item[tooltip-content]:hover | ||
133 | + &:before | ||
134 | + content: ''; | ||
135 | + position: absolute; | ||
136 | + display: inline-block; | ||
137 | + margin: 0 auto 0; | ||
138 | + width: 0; | ||
139 | + height: 0; | ||
140 | + border-right: 7px solid transparent; | ||
141 | + border-top: 7px solid #2f2f2f; | ||
142 | + border-left: 7px solid transparent; | ||
143 | + left: 13px; | ||
144 | + top: -2px; | ||
145 | + &:after | ||
146 | + content: attr(tooltip-content); | ||
147 | + position: absolute; | ||
148 | + display: inline-block; | ||
149 | + background-color: #2f2f2f; | ||
150 | + color: #fff; | ||
151 | + padding: 5px 8px; | ||
152 | + font-size: 11px; | ||
153 | + font-weight: lighter; | ||
154 | + border-radius: 3px; | ||
155 | + max-height: 23px; | ||
156 | + top: -25px; | ||
157 | + left: 0; | ||
158 | + min-width: 24px; | ||
159 | + > .{prefix}-item.active | ||
160 | + background-color: #fff; | ||
161 | + transition: all .3s ease; | ||
162 | + .{prefix}-wrap | ||
163 | + position: absolute; |
minsung/src/css/position.styl
0 → 100644
1 | +/* POSITION LEFT */ | ||
2 | +.{prefix}-container | ||
3 | + &.left | ||
4 | + .{prefix}-menu | ||
5 | + > .{prefix}-item[tooltip-content] | ||
6 | + &:before | ||
7 | + left: 28px; | ||
8 | + top: 11px; | ||
9 | + border-right: 7px solid #2f2f2f; | ||
10 | + border-top: 7px solid transparent; | ||
11 | + border-bottom: 7px solid transparent; | ||
12 | + &:after | ||
13 | + top: 7px; | ||
14 | + left: 42px; | ||
15 | + white-space: nowrap; | ||
16 | + .{prefix}-submenu | ||
17 | + left: 0; | ||
18 | + height: 100%; | ||
19 | + width: 248px; | ||
20 | + .{prefix}-main-container | ||
21 | + left: 64px; | ||
22 | + width: calc(100% - 64px); | ||
23 | + height: 100%; | ||
24 | + .{prefix}-controls | ||
25 | + width: 64px; | ||
26 | + height: 100%; | ||
27 | + display: table; | ||
28 | + | ||
29 | +/* POSITION LEFT & RIGHT */ | ||
30 | +.{prefix}-container | ||
31 | + &.left, &.right | ||
32 | + .{prefix}-menu | ||
33 | + white-space: inherit; | ||
34 | + .{prefix}-submenu | ||
35 | + white-space: normal; | ||
36 | + > div | ||
37 | + vertical-align: middle; | ||
38 | + .{prefix}-controls li | ||
39 | + display: inline-block; | ||
40 | + margin: 4px auto; | ||
41 | + .{prefix}-icpartition | ||
42 | + position: relative; | ||
43 | + top: -7px; | ||
44 | + width: 24px; | ||
45 | + height: 1px; | ||
46 | + .{prefix}-submenu | ||
47 | + .{prefix}-partition | ||
48 | + display: block; | ||
49 | + width: 75%; | ||
50 | + margin: auto; | ||
51 | + > div | ||
52 | + border-left: 0; | ||
53 | + height:10px; | ||
54 | + border-bottom: 1px solid #3c3c3c; | ||
55 | + width: 100%; | ||
56 | + margin: 0; | ||
57 | + .{prefix}-submenu-align | ||
58 | + margin-right: 0; | ||
59 | + .{prefix}-submenu-item | ||
60 | + li | ||
61 | + margin-top: 15px; | ||
62 | + .tui-colorpicker-clearfix li | ||
63 | + margin-top: 0; | ||
64 | + | ||
65 | + .{prefix}-checkbox-wrap.fixed-width | ||
66 | + width: 182px; | ||
67 | + white-space: normal; | ||
68 | + .{prefix}-range-wrap.{prefix}-newline label.range | ||
69 | + display: block; | ||
70 | + text-align: left; | ||
71 | + width: 75%; | ||
72 | + margin: auto; | ||
73 | + .{prefix}-range | ||
74 | + width: 136px; | ||
75 | + | ||
76 | + | ||
77 | +/* POSITION RIGIHT */ | ||
78 | +.{prefix}-container | ||
79 | + &.right | ||
80 | + .{prefix}-menu | ||
81 | + > .{prefix}-item[tooltip-content] | ||
82 | + &:before | ||
83 | + left: -3px; | ||
84 | + top: 11px; | ||
85 | + border-left: 7px solid #2f2f2f; | ||
86 | + border-top: 7px solid transparent; | ||
87 | + border-bottom: 7px solid transparent; | ||
88 | + &:after | ||
89 | + top: 7px; | ||
90 | + left: unset; | ||
91 | + right: 43px; | ||
92 | + white-space: nowrap; | ||
93 | + .{prefix}-submenu | ||
94 | + right: 0; | ||
95 | + height: 100%; | ||
96 | + width: 248px; | ||
97 | + .{prefix}-main-container | ||
98 | + right: 64px; | ||
99 | + width: calc(100% - 64px); | ||
100 | + height: 100%; | ||
101 | + .{prefix}-controls | ||
102 | + right: 0; | ||
103 | + width: 64px; | ||
104 | + height: 100%; | ||
105 | + display: table; | ||
106 | + | ||
107 | + | ||
108 | +/* POSITION TOP & BOTTOM */ | ||
109 | +.{prefix}-container | ||
110 | + &.top, &.bottom | ||
111 | + .{prefix}-submenu | ||
112 | + .{prefix}-partition.only-left-right | ||
113 | + display: none; | ||
114 | + | ||
115 | + | ||
116 | +/* POSITION BOTTOM */ | ||
117 | +.{prefix}-container | ||
118 | + &.bottom .tui-image-editor-submenu > div | ||
119 | + padding-bottom: 24px; | ||
120 | + | ||
121 | +/* POSITION TOP */ | ||
122 | +.{prefix}-container | ||
123 | + &.top | ||
124 | + .color-picker-control .triangle | ||
125 | + top: -8px; | ||
126 | + border-right: 7px solid transparent; | ||
127 | + border-top: 0px; | ||
128 | + border-left: 7px solid transparent; | ||
129 | + border-bottom: 8px solid #fff; | ||
130 | + .{prefix}-size-wrap | ||
131 | + height: 100%; | ||
132 | + .{prefix}-main-container | ||
133 | + bottom: 0; | ||
134 | + .{prefix}-menu | ||
135 | + > .{prefix}-item[tooltip-content] | ||
136 | + &:before | ||
137 | + left: 13px; | ||
138 | + border-top: 0; | ||
139 | + border-bottom: 7px solid #2f2f2f; | ||
140 | + top: 33px; | ||
141 | + &:after | ||
142 | + top: 38px; | ||
143 | + .{prefix}-submenu | ||
144 | + top: 0; | ||
145 | + bottom: auto; | ||
146 | + > div | ||
147 | + padding-top: 24px; | ||
148 | + vertical-align: top; | ||
149 | + .{prefix}-controls-logo | ||
150 | + display: table-cell; | ||
151 | + .{prefix}-controls-buttons | ||
152 | + display: table-cell; | ||
153 | + .{prefix}-main | ||
154 | + top: 64px; | ||
155 | + height: calc(100% - 64px); | ||
156 | + .{prefix}-controls | ||
157 | + top: 0; | ||
158 | + bottom: inherit; | ||
159 | + |
minsung/src/css/range.styl
0 → 100644
1 | +/* VIRTUAL RANGE */ | ||
2 | +.{prefix}-container | ||
3 | + | ||
4 | + .{prefix}-virtual-range-bar | ||
5 | + .{prefix}-virtual-range-subbar | ||
6 | + .{prefix}-virtual-range-pointer | ||
7 | + .{prefix}-disabled | ||
8 | + backbround-color: red; | ||
9 | + | ||
10 | + .{prefix}-range | ||
11 | + position: relative; | ||
12 | + top: 5px; | ||
13 | + width: 166px; | ||
14 | + height: 17px; | ||
15 | + display: inline-block; | ||
16 | + .{prefix}-virtual-range-bar | ||
17 | + top: 7px; | ||
18 | + position: absolute; | ||
19 | + width: 100%; | ||
20 | + height: 2px; | ||
21 | + background-color: #666666; | ||
22 | + .{prefix}-virtual-range-subbar | ||
23 | + position: absolute; | ||
24 | + height: 100%; | ||
25 | + left: 0; | ||
26 | + right: 0; | ||
27 | + background-color: #d1d1d1; | ||
28 | + .{prefix}-virtual-range-pointer | ||
29 | + position: absolute; | ||
30 | + cursor: pointer; | ||
31 | + top: -5px; | ||
32 | + left: 0; | ||
33 | + width: 12px; | ||
34 | + height: 12px; | ||
35 | + background-color: #fff; | ||
36 | + border-radius: 100%; | ||
37 | + .{prefix}-range-wrap | ||
38 | + display: inline-block; | ||
39 | + margin-left: 4px; | ||
40 | + &.short .tui-image-editor-range | ||
41 | + width: 100px; | ||
42 | + .color-picker-control | ||
43 | + .{prefix}-range | ||
44 | + width: 108px; | ||
45 | + margin-left: 10px; | ||
46 | + .{prefix}-virtual-range-pointer | ||
47 | + background-color: #333; | ||
48 | + .{prefix}-virtual-range-bar | ||
49 | + background-color: #ccc; | ||
50 | + .{prefix}-virtual-range-subbar | ||
51 | + background-color: #606060; | ||
52 | + .{prefix}-range-wrap.{prefix}-newline.short | ||
53 | + margin-top: -2px; | ||
54 | + margin-left: 19px; | ||
55 | + label | ||
56 | + color: #8e8e8e; | ||
57 | + font-weight: normal; | ||
58 | + .{prefix}-range-wrap label | ||
59 | + vertical-align: baseline; | ||
60 | + font-size: 11px; | ||
61 | + margin-right: 7px; | ||
62 | + color: #fff; | ||
63 | + .{prefix}-range-value | ||
64 | + cursor: default; | ||
65 | + width: 40px; | ||
66 | + height: 24px; | ||
67 | + outline: none; | ||
68 | + border-radius: 2px; | ||
69 | + box-shadow: none; | ||
70 | + border: 1px solid #d5d5d5; | ||
71 | + text-align: center; | ||
72 | + background-color: #1c1c1c; | ||
73 | + color: #fff; | ||
74 | + font-weight: lighter; | ||
75 | + vertical-align: baseline; | ||
76 | + font-family: 'Noto Sans', sans-serif; | ||
77 | + margin-top: 21px; | ||
78 | + margin-left: 4px; | ||
79 | + .{prefix}-controls | ||
80 | + position: absolute; | ||
81 | + background-color: #151515; | ||
82 | + width: 100%; | ||
83 | + height: 64px; | ||
84 | + display: table; | ||
85 | + bottom: 0; | ||
86 | + z-index: 2; | ||
87 | + .{prefix}-icpartition | ||
88 | + display: inline-block; | ||
89 | + background-color: #282828; | ||
90 | + width: 1px; | ||
91 | + height: 24px; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
minsung/src/css/submenu.styl
0 → 100644
1 | +/* SUBMENU */ | ||
2 | +.{prefix}-container | ||
3 | + .{prefix}-submenu | ||
4 | + display: none; | ||
5 | + position: absolute; | ||
6 | + bottom: 0; | ||
7 | + width:100%; | ||
8 | + height: 150px; | ||
9 | + white-space: nowrap; | ||
10 | + z-index: 2; | ||
11 | + .{prefix}-button:hover svg > use.active | ||
12 | + display: block; | ||
13 | + .{prefix}-submenu-item | ||
14 | + li | ||
15 | + display: inline-block; | ||
16 | + vertical-align: top; | ||
17 | + .{prefix}-newline | ||
18 | + display: block; | ||
19 | + margin-top: 0; | ||
20 | + .{prefix}-button | ||
21 | + position: relative; | ||
22 | + cursor: pointer; | ||
23 | + display: inline-block; | ||
24 | + font-weight: normal; | ||
25 | + font-size: 11px; | ||
26 | + margin: 0 9px 0 9px; | ||
27 | + .{prefix}-button.preset | ||
28 | + margin: 0 9px 20px 5px; | ||
29 | + label > span | ||
30 | + display: inline-block; | ||
31 | + cursor: pointer; | ||
32 | + padding-top: 5px; | ||
33 | + font-family: "Noto Sans", sans-serif; | ||
34 | + font-size: 11px; | ||
35 | + .{prefix}-button.apply label, | ||
36 | + .{prefix}-button.cancel label | ||
37 | + vertical-align: 7px; | ||
38 | + > div | ||
39 | + display: none; | ||
40 | + vertical-align: bottom; | ||
41 | + .{prefix}-submenu-style | ||
42 | + opacity: 0.95; | ||
43 | + z-index: -1; | ||
44 | + position: absolute; | ||
45 | + top: 0; | ||
46 | + bottom: 0; | ||
47 | + left: 0; | ||
48 | + right: 0; | ||
49 | + display: block; | ||
50 | + | ||
51 | + .{prefix}-partition > div | ||
52 | + width: 1px; | ||
53 | + height: 52px; | ||
54 | + border-left: 1px solid #3c3c3c; | ||
55 | + margin: 0 8px 0 8px; | ||
56 | + .{prefix}-main.{prefix}-menu-filter .{prefix}-partition > div | ||
57 | + height: 108px; | ||
58 | + margin: 0 29px 0 0px; | ||
59 | + .{prefix}-submenu-align | ||
60 | + text-align: left; | ||
61 | + margin-right: 30px; | ||
62 | + label > span | ||
63 | + width: 55px; | ||
64 | + white-space: nowrap; | ||
65 | + .{prefix}-submenu-align:first-child | ||
66 | + margin-right: 0; | ||
67 | + label > span | ||
68 | + width: 70px; | ||
69 | + .{prefix}-main.{prefix}-menu-crop .{prefix}-submenu > div.{prefix}-menu-crop, | ||
70 | + .{prefix}-main.{prefix}-menu-flip .{prefix}-submenu > div.{prefix}-menu-flip, | ||
71 | + .{prefix}-main.{prefix}-menu-rotate .{prefix}-submenu > div.{prefix}-menu-rotate, | ||
72 | + .{prefix}-main.{prefix}-menu-shape .{prefix}-submenu > div.{prefix}-menu-shape, | ||
73 | + .{prefix}-main.{prefix}-menu-text .{prefix}-submenu > div.{prefix}-menu-text, | ||
74 | + .{prefix}-main.{prefix}-menu-mask .{prefix}-submenu > div.{prefix}-menu-mask, | ||
75 | + .{prefix}-main.{prefix}-menu-icon .{prefix}-submenu > div.{prefix}-menu-icon, | ||
76 | + .{prefix}-main.{prefix}-menu-draw .{prefix}-submenu > div.{prefix}-menu-draw, | ||
77 | + .{prefix}-main.{prefix}-menu-filter .{prefix}-submenu > div.{prefix}-menu-filter | ||
78 | + display: table-cell; | ||
79 | + .{prefix}-main.{prefix}-menu-crop, | ||
80 | + .{prefix}-main.{prefix}-menu-flip, | ||
81 | + .{prefix}-main.{prefix}-menu-rotate, | ||
82 | + .{prefix}-main.{prefix}-menu-shape, | ||
83 | + .{prefix}-main.{prefix}-menu-text, | ||
84 | + .{prefix}-main.{prefix}-menu-mask, | ||
85 | + .{prefix}-main.{prefix}-menu-icon, | ||
86 | + .{prefix}-main.{prefix}-menu-draw, | ||
87 | + .{prefix}-main.{prefix}-menu-filter | ||
88 | + .{prefix}-submenu | ||
89 | + display: table; | ||
90 | + |
minsung/src/index.js
0 → 100644
1 | +import './js/polyfill'; | ||
2 | +import ImageEditor from './js/imageEditor'; | ||
3 | +import './css/index.styl'; | ||
4 | + | ||
5 | +// commands | ||
6 | +import './js/command/addIcon'; | ||
7 | +import './js/command/addImageObject'; | ||
8 | +import './js/command/addObject'; | ||
9 | +import './js/command/addShape'; | ||
10 | +import './js/command/addText'; | ||
11 | +import './js/command/applyFilter'; | ||
12 | +import './js/command/changeIconColor'; | ||
13 | +import './js/command/changeShape'; | ||
14 | +import './js/command/changeText'; | ||
15 | +import './js/command/changeTextStyle'; | ||
16 | +import './js/command/clearObjects'; | ||
17 | +import './js/command/flip'; | ||
18 | +import './js/command/loadImage'; | ||
19 | +import './js/command/removeFilter'; | ||
20 | +import './js/command/removeObject'; | ||
21 | +import './js/command/resizeCanvasDimension'; | ||
22 | +import './js/command/rotate'; | ||
23 | +import './js/command/setObjectProperties'; | ||
24 | +import './js/command/setObjectPosition'; | ||
25 | +import './js/command/changeSelection'; | ||
26 | + | ||
27 | +module.exports = ImageEditor; |
minsung/src/js/action.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/command/addIcon.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Add an icon | ||
4 | + */ | ||
5 | +import commandFactory from '../factory/command'; | ||
6 | +import { Promise } from '../util'; | ||
7 | +import { componentNames, commandNames } from '../consts'; | ||
8 | + | ||
9 | +const { ICON } = componentNames; | ||
10 | + | ||
11 | +const command = { | ||
12 | + name: commandNames.ADD_ICON, | ||
13 | + | ||
14 | + /** | ||
15 | + * Add an icon | ||
16 | + * @param {Graphics} graphics - Graphics instance | ||
17 | + * @param {string} type - Icon type ('arrow', 'cancel', custom icon name) | ||
18 | + * @param {Object} options - Icon options | ||
19 | + * @param {string} [options.fill] - Icon foreground color | ||
20 | + * @param {string} [options.left] - Icon x position | ||
21 | + * @param {string} [options.top] - Icon y position | ||
22 | + * @returns {Promise} | ||
23 | + */ | ||
24 | + execute(graphics, type, options) { | ||
25 | + const iconComp = graphics.getComponent(ICON); | ||
26 | + | ||
27 | + return iconComp.add(type, options).then((objectProps) => { | ||
28 | + this.undoData.object = graphics.getObject(objectProps.id); | ||
29 | + | ||
30 | + return objectProps; | ||
31 | + }); | ||
32 | + }, | ||
33 | + /** | ||
34 | + * @param {Graphics} graphics - Graphics instance | ||
35 | + * @returns {Promise} | ||
36 | + */ | ||
37 | + undo(graphics) { | ||
38 | + graphics.remove(this.undoData.object); | ||
39 | + | ||
40 | + return Promise.resolve(); | ||
41 | + }, | ||
42 | +}; | ||
43 | + | ||
44 | +commandFactory.register(command); | ||
45 | + | ||
46 | +export default command; |
minsung/src/js/command/addImageObject.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Add an image object | ||
4 | + */ | ||
5 | +import commandFactory from '../factory/command'; | ||
6 | +import { Promise } from '../util'; | ||
7 | +import { commandNames } from '../consts'; | ||
8 | + | ||
9 | +const command = { | ||
10 | + name: commandNames.ADD_IMAGE_OBJECT, | ||
11 | + | ||
12 | + /** | ||
13 | + * Add an image object | ||
14 | + * @param {Graphics} graphics - Graphics instance | ||
15 | + * @param {string} imgUrl - Image url to make object | ||
16 | + * @returns {Promise} | ||
17 | + */ | ||
18 | + execute(graphics, imgUrl) { | ||
19 | + return graphics.addImageObject(imgUrl).then((objectProps) => { | ||
20 | + this.undoData.object = graphics.getObject(objectProps.id); | ||
21 | + | ||
22 | + return objectProps; | ||
23 | + }); | ||
24 | + }, | ||
25 | + /** | ||
26 | + * @param {Graphics} graphics - Graphics instance | ||
27 | + * @returns {Promise} | ||
28 | + */ | ||
29 | + undo(graphics) { | ||
30 | + graphics.remove(this.undoData.object); | ||
31 | + | ||
32 | + return Promise.resolve(); | ||
33 | + }, | ||
34 | +}; | ||
35 | + | ||
36 | +commandFactory.register(command); | ||
37 | + | ||
38 | +export default command; |
minsung/src/js/command/addObject.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Add an object | ||
4 | + */ | ||
5 | +import commandFactory from '../factory/command'; | ||
6 | +import { Promise } from '../util'; | ||
7 | +import { commandNames, rejectMessages } from '../consts'; | ||
8 | + | ||
9 | +const command = { | ||
10 | + name: commandNames.ADD_OBJECT, | ||
11 | + | ||
12 | + /** | ||
13 | + * Add an object | ||
14 | + * @param {Graphics} graphics - Graphics instance | ||
15 | + * @param {Object} object - Fabric object | ||
16 | + * @returns {Promise} | ||
17 | + */ | ||
18 | + execute(graphics, object) { | ||
19 | + return new Promise((resolve, reject) => { | ||
20 | + if (!graphics.contains(object)) { | ||
21 | + graphics.add(object); | ||
22 | + resolve(object); | ||
23 | + } else { | ||
24 | + reject(rejectMessages.addedObject); | ||
25 | + } | ||
26 | + }); | ||
27 | + }, | ||
28 | + /** | ||
29 | + * @param {Graphics} graphics - Graphics instance | ||
30 | + * @param {Object} object - Fabric object | ||
31 | + * @returns {Promise} | ||
32 | + */ | ||
33 | + undo(graphics, object) { | ||
34 | + return new Promise((resolve, reject) => { | ||
35 | + if (graphics.contains(object)) { | ||
36 | + graphics.remove(object); | ||
37 | + resolve(object); | ||
38 | + } else { | ||
39 | + reject(rejectMessages.noObject); | ||
40 | + } | ||
41 | + }); | ||
42 | + }, | ||
43 | +}; | ||
44 | + | ||
45 | +commandFactory.register(command); | ||
46 | + | ||
47 | +export default command; |
minsung/src/js/command/addShape.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Add a shape | ||
4 | + */ | ||
5 | +import commandFactory from '../factory/command'; | ||
6 | +import { Promise } from '../util'; | ||
7 | +import { componentNames, commandNames } from '../consts'; | ||
8 | + | ||
9 | +const { SHAPE } = componentNames; | ||
10 | + | ||
11 | +const command = { | ||
12 | + name: commandNames.ADD_SHAPE, | ||
13 | + | ||
14 | + /** | ||
15 | + * Add a shape | ||
16 | + * @param {Graphics} graphics - Graphics instance | ||
17 | + * @param {string} type - Shape type (ex: 'rect', 'circle', 'triangle') | ||
18 | + * @param {Object} options - Shape options | ||
19 | + * @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent') | ||
20 | + * @param {string} [options.stroke] - Shape outline color | ||
21 | + * @param {number} [options.strokeWidth] - Shape outline width | ||
22 | + * @param {number} [options.width] - Width value (When type option is 'rect', this options can use) | ||
23 | + * @param {number} [options.height] - Height value (When type option is 'rect', this options can use) | ||
24 | + * @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use) | ||
25 | + * @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use) | ||
26 | + * @param {number} [options.left] - Shape x position | ||
27 | + * @param {number} [options.top] - Shape y position | ||
28 | + * @param {number} [options.isRegular] - Whether resizing shape has 1:1 ratio or not | ||
29 | + * @returns {Promise} | ||
30 | + */ | ||
31 | + execute(graphics, type, options) { | ||
32 | + const shapeComp = graphics.getComponent(SHAPE); | ||
33 | + | ||
34 | + return shapeComp.add(type, options).then((objectProps) => { | ||
35 | + this.undoData.object = graphics.getObject(objectProps.id); | ||
36 | + | ||
37 | + return objectProps; | ||
38 | + }); | ||
39 | + }, | ||
40 | + /** | ||
41 | + * @param {Graphics} graphics - Graphics instance | ||
42 | + * @returns {Promise} | ||
43 | + */ | ||
44 | + undo(graphics) { | ||
45 | + graphics.remove(this.undoData.object); | ||
46 | + | ||
47 | + return Promise.resolve(); | ||
48 | + }, | ||
49 | +}; | ||
50 | + | ||
51 | +commandFactory.register(command); | ||
52 | + | ||
53 | +export default command; |
minsung/src/js/command/addText.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Add a text object | ||
4 | + */ | ||
5 | +import commandFactory from '../factory/command'; | ||
6 | +import { Promise } from '../util'; | ||
7 | +import { componentNames, commandNames, rejectMessages } from '../consts'; | ||
8 | +const { TEXT } = componentNames; | ||
9 | + | ||
10 | +const command = { | ||
11 | + name: commandNames.ADD_TEXT, | ||
12 | + | ||
13 | + /** | ||
14 | + * Add a text object | ||
15 | + * @param {Graphics} graphics - Graphics instance | ||
16 | + * @param {string} text - Initial input text | ||
17 | + * @param {Object} [options] Options for text styles | ||
18 | + * @param {Object} [options.styles] Initial styles | ||
19 | + * @param {string} [options.styles.fill] Color | ||
20 | + * @param {string} [options.styles.fontFamily] Font type for text | ||
21 | + * @param {number} [options.styles.fontSize] Size | ||
22 | + * @param {string} [options.styles.fontStyle] Type of inclination (normal / italic) | ||
23 | + * @param {string} [options.styles.fontWeight] Type of thicker or thinner looking (normal / bold) | ||
24 | + * @param {string} [options.styles.textAlign] Type of text align (left / center / right) | ||
25 | + * @param {string} [options.styles.textDecoration] Type of line (underline / line-through / overline) | ||
26 | + * @param {{x: number, y: number}} [options.position] - Initial position | ||
27 | + * @returns {Promise} | ||
28 | + */ | ||
29 | + execute(graphics, text, options) { | ||
30 | + const textComp = graphics.getComponent(TEXT); | ||
31 | + | ||
32 | + if (this.undoData.object) { | ||
33 | + const undoObject = this.undoData.object; | ||
34 | + | ||
35 | + return new Promise((resolve, reject) => { | ||
36 | + if (!graphics.contains(undoObject)) { | ||
37 | + graphics.add(undoObject); | ||
38 | + resolve(undoObject); | ||
39 | + } else { | ||
40 | + reject(rejectMessages.redo); | ||
41 | + } | ||
42 | + }); | ||
43 | + } | ||
44 | + | ||
45 | + return textComp.add(text, options).then((objectProps) => { | ||
46 | + const { id } = objectProps; | ||
47 | + const textObject = graphics.getObject(id); | ||
48 | + | ||
49 | + this.undoData.object = textObject; | ||
50 | + | ||
51 | + return objectProps; | ||
52 | + }); | ||
53 | + }, | ||
54 | + /** | ||
55 | + * @param {Graphics} graphics - Graphics instance | ||
56 | + * @returns {Promise} | ||
57 | + */ | ||
58 | + undo(graphics) { | ||
59 | + graphics.remove(this.undoData.object); | ||
60 | + | ||
61 | + return Promise.resolve(); | ||
62 | + }, | ||
63 | +}; | ||
64 | + | ||
65 | +commandFactory.register(command); | ||
66 | + | ||
67 | +export default command; |
minsung/src/js/command/applyFilter.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Apply a filter into an image | ||
4 | + */ | ||
5 | +import snippet from 'tui-code-snippet'; | ||
6 | +import commandFactory from '../factory/command'; | ||
7 | +import { componentNames, rejectMessages, commandNames } from '../consts'; | ||
8 | + | ||
9 | +const { FILTER } = componentNames; | ||
10 | + | ||
11 | +/** | ||
12 | + * Chched data for undo | ||
13 | + * @type {Object} | ||
14 | + */ | ||
15 | +let chchedUndoDataForSilent = null; | ||
16 | + | ||
17 | +/** | ||
18 | + * Make undoData | ||
19 | + * @param {string} type - Filter type | ||
20 | + * @param {Object} prevfilterOption - prev Filter options | ||
21 | + * @param {Object} options - Filter options | ||
22 | + * @returns {object} - undo data | ||
23 | + */ | ||
24 | +function makeUndoData(type, prevfilterOption, options) { | ||
25 | + const undoData = {}; | ||
26 | + | ||
27 | + if (type === 'mask') { | ||
28 | + undoData.object = options.mask; | ||
29 | + } | ||
30 | + | ||
31 | + undoData.options = prevfilterOption; | ||
32 | + | ||
33 | + return undoData; | ||
34 | +} | ||
35 | + | ||
36 | +const command = { | ||
37 | + name: commandNames.APPLY_FILTER, | ||
38 | + | ||
39 | + /** | ||
40 | + * Apply a filter into an image | ||
41 | + * @param {Graphics} graphics - Graphics instance | ||
42 | + * @param {string} type - Filter type | ||
43 | + * @param {Object} options - Filter options | ||
44 | + * @param {number} options.maskObjId - masking image object id | ||
45 | + * @param {boolean} isSilent - is silent execution or not | ||
46 | + * @returns {Promise} | ||
47 | + */ | ||
48 | + execute(graphics, type, options, isSilent) { | ||
49 | + const filterComp = graphics.getComponent(FILTER); | ||
50 | + | ||
51 | + if (type === 'mask') { | ||
52 | + const maskObj = graphics.getObject(options.maskObjId); | ||
53 | + | ||
54 | + if (!(maskObj && maskObj.isType('image'))) { | ||
55 | + return Promise.reject(rejectMessages.invalidParameters); | ||
56 | + } | ||
57 | + | ||
58 | + snippet.extend(options, { mask: maskObj }); | ||
59 | + graphics.remove(options.mask); | ||
60 | + } | ||
61 | + if (!this.isRedo) { | ||
62 | + const prevfilterOption = filterComp.getOptions(type); | ||
63 | + const undoData = makeUndoData(type, prevfilterOption, options); | ||
64 | + | ||
65 | + chchedUndoDataForSilent = this.setUndoData(undoData, chchedUndoDataForSilent, isSilent); | ||
66 | + } | ||
67 | + | ||
68 | + return filterComp.add(type, options); | ||
69 | + }, | ||
70 | + /** | ||
71 | + * @param {Graphics} graphics - Graphics instance | ||
72 | + * @param {string} type - Filter type | ||
73 | + * @returns {Promise} | ||
74 | + */ | ||
75 | + undo(graphics, type) { | ||
76 | + const filterComp = graphics.getComponent(FILTER); | ||
77 | + | ||
78 | + if (type === 'mask') { | ||
79 | + const mask = this.undoData.object; | ||
80 | + graphics.add(mask); | ||
81 | + graphics.setActiveObject(mask); | ||
82 | + | ||
83 | + return filterComp.remove(type); | ||
84 | + } | ||
85 | + | ||
86 | + // options changed case | ||
87 | + if (this.undoData.options) { | ||
88 | + return filterComp.add(type, this.undoData.options); | ||
89 | + } | ||
90 | + | ||
91 | + // filter added case | ||
92 | + return filterComp.remove(type); | ||
93 | + }, | ||
94 | +}; | ||
95 | + | ||
96 | +commandFactory.register(command); | ||
97 | + | ||
98 | +export default command; |
minsung/src/js/command/changeIconColor.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Change icon color | ||
4 | + */ | ||
5 | +import commandFactory from '../factory/command'; | ||
6 | +import { Promise } from '../util'; | ||
7 | +import { componentNames, rejectMessages, commandNames } from '../consts'; | ||
8 | + | ||
9 | +const { ICON } = componentNames; | ||
10 | + | ||
11 | +const command = { | ||
12 | + name: commandNames.CHANGE_ICON_COLOR, | ||
13 | + | ||
14 | + /** | ||
15 | + * Change icon color | ||
16 | + * @param {Graphics} graphics - Graphics instance | ||
17 | + * @param {number} id - object id | ||
18 | + * @param {string} color - Color for icon | ||
19 | + * @returns {Promise} | ||
20 | + */ | ||
21 | + execute(graphics, id, color) { | ||
22 | + return new Promise((resolve, reject) => { | ||
23 | + const iconComp = graphics.getComponent(ICON); | ||
24 | + const targetObj = graphics.getObject(id); | ||
25 | + | ||
26 | + if (!targetObj) { | ||
27 | + reject(rejectMessages.noObject); | ||
28 | + } | ||
29 | + | ||
30 | + this.undoData.object = targetObj; | ||
31 | + this.undoData.color = iconComp.getColor(targetObj); | ||
32 | + iconComp.setColor(color, targetObj); | ||
33 | + resolve(); | ||
34 | + }); | ||
35 | + }, | ||
36 | + /** | ||
37 | + * @param {Graphics} graphics - Graphics instance | ||
38 | + * @returns {Promise} | ||
39 | + */ | ||
40 | + undo(graphics) { | ||
41 | + const iconComp = graphics.getComponent(ICON); | ||
42 | + const { object: icon, color } = this.undoData; | ||
43 | + | ||
44 | + iconComp.setColor(color, icon); | ||
45 | + | ||
46 | + return Promise.resolve(); | ||
47 | + }, | ||
48 | +}; | ||
49 | + | ||
50 | +commandFactory.register(command); | ||
51 | + | ||
52 | +export default command; |
minsung/src/js/command/changeSelection.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview change selection | ||
4 | + */ | ||
5 | +import commandFactory from '../factory/command'; | ||
6 | +import { Promise } from '../util'; | ||
7 | +import { commandNames } from '../consts'; | ||
8 | +import { getCachedUndoDataForDimension } from '../helper/selectionModifyHelper'; | ||
9 | + | ||
10 | +const command = { | ||
11 | + name: commandNames.CHANGE_SELECTION, | ||
12 | + | ||
13 | + execute(graphics, props) { | ||
14 | + if (this.isRedo) { | ||
15 | + props.forEach((prop) => { | ||
16 | + graphics.setObjectProperties(prop.id, prop); | ||
17 | + }); | ||
18 | + } else { | ||
19 | + this.undoData = getCachedUndoDataForDimension(); | ||
20 | + } | ||
21 | + | ||
22 | + return Promise.resolve(); | ||
23 | + }, | ||
24 | + undo(graphics) { | ||
25 | + this.undoData.forEach((datum) => { | ||
26 | + graphics.setObjectProperties(datum.id, datum); | ||
27 | + }); | ||
28 | + | ||
29 | + return Promise.resolve(); | ||
30 | + }, | ||
31 | +}; | ||
32 | + | ||
33 | +commandFactory.register(command); | ||
34 | + | ||
35 | +export default command; |
minsung/src/js/command/changeShape.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview change a shape | ||
4 | + */ | ||
5 | +import snippet from 'tui-code-snippet'; | ||
6 | +import { Promise } from '../util'; | ||
7 | +import commandFactory from '../factory/command'; | ||
8 | +import { componentNames, rejectMessages, commandNames } from '../consts'; | ||
9 | + | ||
10 | +const { SHAPE } = componentNames; | ||
11 | + | ||
12 | +/** | ||
13 | + * Chched data for undo | ||
14 | + * @type {Object} | ||
15 | + */ | ||
16 | +let chchedUndoDataForSilent = null; | ||
17 | + | ||
18 | +/** | ||
19 | + * Make undoData | ||
20 | + * @param {object} options - shape options | ||
21 | + * @param {Component} targetObj - shape component | ||
22 | + * @returns {object} - undo data | ||
23 | + */ | ||
24 | +function makeUndoData(options, targetObj) { | ||
25 | + const undoData = { | ||
26 | + object: targetObj, | ||
27 | + options: {}, | ||
28 | + }; | ||
29 | + | ||
30 | + snippet.forEachOwnProperties(options, (value, key) => { | ||
31 | + undoData.options[key] = targetObj[key]; | ||
32 | + }); | ||
33 | + | ||
34 | + return undoData; | ||
35 | +} | ||
36 | + | ||
37 | +const command = { | ||
38 | + name: commandNames.CHANGE_SHAPE, | ||
39 | + | ||
40 | + /** | ||
41 | + * Change a shape | ||
42 | + * @param {Graphics} graphics - Graphics instance | ||
43 | + * @param {number} id - object id | ||
44 | + * @param {Object} options - Shape options | ||
45 | + * @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent') | ||
46 | + * @param {string} [options.stroke] - Shape outline color | ||
47 | + * @param {number} [options.strokeWidth] - Shape outline width | ||
48 | + * @param {number} [options.width] - Width value (When type option is 'rect', this options can use) | ||
49 | + * @param {number} [options.height] - Height value (When type option is 'rect', this options can use) | ||
50 | + * @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use) | ||
51 | + * @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use) | ||
52 | + * @param {number} [options.left] - Shape x position | ||
53 | + * @param {number} [options.top] - Shape y position | ||
54 | + * @param {number} [options.isRegular] - Whether resizing shape has 1:1 ratio or not | ||
55 | + * @param {boolean} isSilent - is silent execution or not | ||
56 | + * @returns {Promise} | ||
57 | + */ | ||
58 | + execute(graphics, id, options, isSilent) { | ||
59 | + const shapeComp = graphics.getComponent(SHAPE); | ||
60 | + const targetObj = graphics.getObject(id); | ||
61 | + | ||
62 | + if (!targetObj) { | ||
63 | + return Promise.reject(rejectMessages.noObject); | ||
64 | + } | ||
65 | + | ||
66 | + if (!this.isRedo) { | ||
67 | + const undoData = makeUndoData(options, targetObj); | ||
68 | + | ||
69 | + chchedUndoDataForSilent = this.setUndoData(undoData, chchedUndoDataForSilent, isSilent); | ||
70 | + } | ||
71 | + | ||
72 | + return shapeComp.change(targetObj, options); | ||
73 | + }, | ||
74 | + /** | ||
75 | + * @param {Graphics} graphics - Graphics instance | ||
76 | + * @returns {Promise} | ||
77 | + */ | ||
78 | + undo(graphics) { | ||
79 | + const shapeComp = graphics.getComponent(SHAPE); | ||
80 | + const { object: shape, options } = this.undoData; | ||
81 | + | ||
82 | + return shapeComp.change(shape, options); | ||
83 | + }, | ||
84 | +}; | ||
85 | + | ||
86 | +commandFactory.register(command); | ||
87 | + | ||
88 | +export default command; |
minsung/src/js/command/changeText.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Change a text | ||
4 | + */ | ||
5 | +import commandFactory from '../factory/command'; | ||
6 | +import { Promise } from '../util'; | ||
7 | +import { componentNames, rejectMessages, commandNames } from '../consts'; | ||
8 | + | ||
9 | +const { TEXT } = componentNames; | ||
10 | + | ||
11 | +const command = { | ||
12 | + name: commandNames.CHANGE_TEXT, | ||
13 | + | ||
14 | + /** | ||
15 | + * Change a text | ||
16 | + * @param {Graphics} graphics - Graphics instance | ||
17 | + * @param {number} id - object id | ||
18 | + * @param {string} text - Changing text | ||
19 | + * @returns {Promise} | ||
20 | + */ | ||
21 | + execute(graphics, id, text) { | ||
22 | + const textComp = graphics.getComponent(TEXT); | ||
23 | + const targetObj = graphics.getObject(id); | ||
24 | + | ||
25 | + if (!targetObj) { | ||
26 | + return Promise.reject(rejectMessages.noObject); | ||
27 | + } | ||
28 | + | ||
29 | + this.undoData.object = targetObj; | ||
30 | + this.undoData.text = textComp.getText(targetObj); | ||
31 | + | ||
32 | + return textComp.change(targetObj, text); | ||
33 | + }, | ||
34 | + /** | ||
35 | + * @param {Graphics} graphics - Graphics instance | ||
36 | + * @returns {Promise} | ||
37 | + */ | ||
38 | + undo(graphics) { | ||
39 | + const textComp = graphics.getComponent(TEXT); | ||
40 | + const { object: textObj, text } = this.undoData; | ||
41 | + | ||
42 | + return textComp.change(textObj, text); | ||
43 | + }, | ||
44 | +}; | ||
45 | + | ||
46 | +commandFactory.register(command); | ||
47 | + | ||
48 | +export default command; |
minsung/src/js/command/changeTextStyle.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Change text styles | ||
4 | + */ | ||
5 | +import snippet from 'tui-code-snippet'; | ||
6 | +import commandFactory from '../factory/command'; | ||
7 | +import { Promise } from '../util'; | ||
8 | +import { componentNames, rejectMessages, commandNames } from '../consts'; | ||
9 | + | ||
10 | +const { TEXT } = componentNames; | ||
11 | + | ||
12 | +/** | ||
13 | + * Chched data for undo | ||
14 | + * @type {Object} | ||
15 | + */ | ||
16 | +let chchedUndoDataForSilent = null; | ||
17 | + | ||
18 | +/** | ||
19 | + * Make undoData | ||
20 | + * @param {object} styles - text styles | ||
21 | + * @param {Component} targetObj - text component | ||
22 | + * @returns {object} - undo data | ||
23 | + */ | ||
24 | +function makeUndoData(styles, targetObj) { | ||
25 | + const undoData = { | ||
26 | + object: targetObj, | ||
27 | + styles: {}, | ||
28 | + }; | ||
29 | + snippet.forEachOwnProperties(styles, (value, key) => { | ||
30 | + const undoValue = targetObj[key]; | ||
31 | + undoData.styles[key] = undoValue; | ||
32 | + }); | ||
33 | + | ||
34 | + return undoData; | ||
35 | +} | ||
36 | + | ||
37 | +const command = { | ||
38 | + name: commandNames.CHANGE_TEXT_STYLE, | ||
39 | + | ||
40 | + /** | ||
41 | + * Change text styles | ||
42 | + * @param {Graphics} graphics - Graphics instance | ||
43 | + * @param {number} id - object id | ||
44 | + * @param {Object} styles - text styles | ||
45 | + * @param {string} [styles.fill] Color | ||
46 | + * @param {string} [styles.fontFamily] Font type for text | ||
47 | + * @param {number} [styles.fontSize] Size | ||
48 | + * @param {string} [styles.fontStyle] Type of inclination (normal / italic) | ||
49 | + * @param {string} [styles.fontWeight] Type of thicker or thinner looking (normal / bold) | ||
50 | + * @param {string} [styles.textAlign] Type of text align (left / center / right) | ||
51 | + * @param {string} [styles.textDecoration] Type of line (underline / line-through / overline) | ||
52 | + * @param {boolean} isSilent - is silent execution or not | ||
53 | + * @returns {Promise} | ||
54 | + */ | ||
55 | + execute(graphics, id, styles, isSilent) { | ||
56 | + const textComp = graphics.getComponent(TEXT); | ||
57 | + const targetObj = graphics.getObject(id); | ||
58 | + | ||
59 | + if (!targetObj) { | ||
60 | + return Promise.reject(rejectMessages.noObject); | ||
61 | + } | ||
62 | + if (!this.isRedo) { | ||
63 | + const undoData = makeUndoData(styles, targetObj); | ||
64 | + | ||
65 | + chchedUndoDataForSilent = this.setUndoData(undoData, chchedUndoDataForSilent, isSilent); | ||
66 | + } | ||
67 | + | ||
68 | + return textComp.setStyle(targetObj, styles); | ||
69 | + }, | ||
70 | + /** | ||
71 | + * @param {Graphics} graphics - Graphics instance | ||
72 | + * @returns {Promise} | ||
73 | + */ | ||
74 | + undo(graphics) { | ||
75 | + const textComp = graphics.getComponent(TEXT); | ||
76 | + const { object: textObj, styles } = this.undoData; | ||
77 | + | ||
78 | + return textComp.setStyle(textObj, styles); | ||
79 | + }, | ||
80 | +}; | ||
81 | + | ||
82 | +commandFactory.register(command); | ||
83 | + | ||
84 | +export default command; |
minsung/src/js/command/clearObjects.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Clear all objects | ||
4 | + */ | ||
5 | +import commandFactory from '../factory/command'; | ||
6 | +import { Promise } from '../util'; | ||
7 | +import { commandNames } from '../consts'; | ||
8 | + | ||
9 | +const command = { | ||
10 | + name: commandNames.CLEAR_OBJECTS, | ||
11 | + | ||
12 | + /** | ||
13 | + * Clear all objects without background (main) image | ||
14 | + * @param {Graphics} graphics - Graphics instance | ||
15 | + * @returns {Promise} | ||
16 | + */ | ||
17 | + execute(graphics) { | ||
18 | + return new Promise((resolve) => { | ||
19 | + this.undoData.objects = graphics.removeAll(); | ||
20 | + resolve(); | ||
21 | + }); | ||
22 | + }, | ||
23 | + /** | ||
24 | + * @param {Graphics} graphics - Graphics instance | ||
25 | + * @returns {Promise} | ||
26 | + * @ignore | ||
27 | + */ | ||
28 | + undo(graphics) { | ||
29 | + graphics.add(this.undoData.objects); | ||
30 | + | ||
31 | + return Promise.resolve(); | ||
32 | + }, | ||
33 | +}; | ||
34 | + | ||
35 | +commandFactory.register(command); | ||
36 | + | ||
37 | +export default command; |
minsung/src/js/command/flip.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Flip an image | ||
4 | + */ | ||
5 | +import commandFactory from '../factory/command'; | ||
6 | +import { componentNames, commandNames } from '../consts'; | ||
7 | + | ||
8 | +const { FLIP } = componentNames; | ||
9 | + | ||
10 | +const command = { | ||
11 | + name: commandNames.FLIP_IMAGE, | ||
12 | + | ||
13 | + /** | ||
14 | + * flip an image | ||
15 | + * @param {Graphics} graphics - Graphics instance | ||
16 | + * @param {string} type - 'flipX' or 'flipY' or 'reset' | ||
17 | + * @returns {Promise} | ||
18 | + */ | ||
19 | + execute(graphics, type) { | ||
20 | + const flipComp = graphics.getComponent(FLIP); | ||
21 | + | ||
22 | + this.undoData.setting = flipComp.getCurrentSetting(); | ||
23 | + | ||
24 | + return flipComp[type](); | ||
25 | + }, | ||
26 | + /** | ||
27 | + * @param {Graphics} graphics - Graphics instance | ||
28 | + * @returns {Promise} | ||
29 | + */ | ||
30 | + undo(graphics) { | ||
31 | + const flipComp = graphics.getComponent(FLIP); | ||
32 | + | ||
33 | + return flipComp.set(this.undoData.setting); | ||
34 | + }, | ||
35 | +}; | ||
36 | + | ||
37 | +commandFactory.register(command); | ||
38 | + | ||
39 | +export default command; |
minsung/src/js/command/loadImage.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Load a background (main) image | ||
4 | + */ | ||
5 | +import commandFactory from '../factory/command'; | ||
6 | +import { componentNames, commandNames } from '../consts'; | ||
7 | + | ||
8 | +const { IMAGE_LOADER } = componentNames; | ||
9 | + | ||
10 | +const command = { | ||
11 | + name: commandNames.LOAD_IMAGE, | ||
12 | + | ||
13 | + /** | ||
14 | + * Load a background (main) image | ||
15 | + * @param {Graphics} graphics - Graphics instance | ||
16 | + * @param {string} imageName - Image name | ||
17 | + * @param {string} imgUrl - Image Url | ||
18 | + * @returns {Promise} | ||
19 | + */ | ||
20 | + execute(graphics, imageName, imgUrl) { | ||
21 | + const loader = graphics.getComponent(IMAGE_LOADER); | ||
22 | + const prevImage = loader.getCanvasImage(); | ||
23 | + const prevImageWidth = prevImage ? prevImage.width : 0; | ||
24 | + const prevImageHeight = prevImage ? prevImage.height : 0; | ||
25 | + const objects = graphics.removeAll(true).filter((objectItem) => objectItem.type !== 'cropzone'); | ||
26 | + | ||
27 | + objects.forEach((objectItem) => { | ||
28 | + objectItem.evented = true; | ||
29 | + }); | ||
30 | + | ||
31 | + this.undoData = { | ||
32 | + name: loader.getImageName(), | ||
33 | + image: prevImage, | ||
34 | + objects, | ||
35 | + }; | ||
36 | + | ||
37 | + return loader.load(imageName, imgUrl).then((newImage) => ({ | ||
38 | + oldWidth: prevImageWidth, | ||
39 | + oldHeight: prevImageHeight, | ||
40 | + newWidth: newImage.width, | ||
41 | + newHeight: newImage.height, | ||
42 | + })); | ||
43 | + }, | ||
44 | + | ||
45 | + /** | ||
46 | + * @param {Graphics} graphics - Graphics instance | ||
47 | + * @returns {Promise} | ||
48 | + */ | ||
49 | + undo(graphics) { | ||
50 | + const loader = graphics.getComponent(IMAGE_LOADER); | ||
51 | + const { objects, name, image } = this.undoData; | ||
52 | + | ||
53 | + graphics.removeAll(true); | ||
54 | + graphics.add(objects); | ||
55 | + | ||
56 | + return loader.load(name, image); | ||
57 | + }, | ||
58 | +}; | ||
59 | + | ||
60 | +commandFactory.register(command); | ||
61 | + | ||
62 | +export default command; |
minsung/src/js/command/removeFilter.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Remove a filter from an image | ||
4 | + */ | ||
5 | +import commandFactory from '../factory/command'; | ||
6 | +import { componentNames, commandNames } from '../consts'; | ||
7 | + | ||
8 | +const { FILTER } = componentNames; | ||
9 | + | ||
10 | +const command = { | ||
11 | + name: commandNames.REMOVE_FILTER, | ||
12 | + | ||
13 | + /** | ||
14 | + * Remove a filter from an image | ||
15 | + * @param {Graphics} graphics - Graphics instance | ||
16 | + * @param {string} type - Filter type | ||
17 | + * @returns {Promise} | ||
18 | + */ | ||
19 | + execute(graphics, type) { | ||
20 | + const filterComp = graphics.getComponent(FILTER); | ||
21 | + | ||
22 | + this.undoData.options = filterComp.getOptions(type); | ||
23 | + | ||
24 | + return filterComp.remove(type); | ||
25 | + }, | ||
26 | + /** | ||
27 | + * @param {Graphics} graphics - Graphics instance | ||
28 | + * @param {string} type - Filter type | ||
29 | + * @returns {Promise} | ||
30 | + */ | ||
31 | + undo(graphics, type) { | ||
32 | + const filterComp = graphics.getComponent(FILTER); | ||
33 | + const { options } = this.undoData; | ||
34 | + | ||
35 | + return filterComp.add(type, options); | ||
36 | + }, | ||
37 | +}; | ||
38 | + | ||
39 | +commandFactory.register(command); | ||
40 | + | ||
41 | +export default command; |
minsung/src/js/command/removeObject.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Remove an object | ||
4 | + */ | ||
5 | +import commandFactory from '../factory/command'; | ||
6 | +import { Promise } from '../util'; | ||
7 | +import { commandNames, rejectMessages } from '../consts'; | ||
8 | + | ||
9 | +const command = { | ||
10 | + name: commandNames.REMOVE_OBJECT, | ||
11 | + | ||
12 | + /** | ||
13 | + * Remove an object | ||
14 | + * @param {Graphics} graphics - Graphics instance | ||
15 | + * @param {number} id - object id | ||
16 | + * @returns {Promise} | ||
17 | + */ | ||
18 | + execute(graphics, id) { | ||
19 | + return new Promise((resolve, reject) => { | ||
20 | + this.undoData.objects = graphics.removeObjectById(id); | ||
21 | + if (this.undoData.objects.length) { | ||
22 | + resolve(); | ||
23 | + } else { | ||
24 | + reject(rejectMessages.noObject); | ||
25 | + } | ||
26 | + }); | ||
27 | + }, | ||
28 | + /** | ||
29 | + * @param {Graphics} graphics - Graphics instance | ||
30 | + * @returns {Promise} | ||
31 | + */ | ||
32 | + undo(graphics) { | ||
33 | + graphics.add(this.undoData.objects); | ||
34 | + | ||
35 | + return Promise.resolve(); | ||
36 | + }, | ||
37 | +}; | ||
38 | + | ||
39 | +commandFactory.register(command); | ||
40 | + | ||
41 | +export default command; |
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Resize a canvas | ||
4 | + */ | ||
5 | +import commandFactory from '../factory/command'; | ||
6 | +import { Promise } from '../util'; | ||
7 | +import { commandNames } from '../consts'; | ||
8 | + | ||
9 | +const command = { | ||
10 | + name: commandNames.RESIZE_CANVAS_DIMENSION, | ||
11 | + | ||
12 | + /** | ||
13 | + * resize the canvas with given dimension | ||
14 | + * @param {Graphics} graphics - Graphics instance | ||
15 | + * @param {{width: number, height: number}} dimension - Max width & height | ||
16 | + * @returns {Promise} | ||
17 | + */ | ||
18 | + execute(graphics, dimension) { | ||
19 | + return new Promise((resolve) => { | ||
20 | + this.undoData.size = { | ||
21 | + width: graphics.cssMaxWidth, | ||
22 | + height: graphics.cssMaxHeight, | ||
23 | + }; | ||
24 | + | ||
25 | + graphics.setCssMaxDimension(dimension); | ||
26 | + graphics.adjustCanvasDimension(); | ||
27 | + resolve(); | ||
28 | + }); | ||
29 | + }, | ||
30 | + /** | ||
31 | + * @param {Graphics} graphics - Graphics instance | ||
32 | + * @returns {Promise} | ||
33 | + */ | ||
34 | + undo(graphics) { | ||
35 | + graphics.setCssMaxDimension(this.undoData.size); | ||
36 | + graphics.adjustCanvasDimension(); | ||
37 | + | ||
38 | + return Promise.resolve(); | ||
39 | + }, | ||
40 | +}; | ||
41 | + | ||
42 | +commandFactory.register(command); | ||
43 | + | ||
44 | +export default command; |
minsung/src/js/command/rotate.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Rotate an image | ||
4 | + */ | ||
5 | +import commandFactory from '../factory/command'; | ||
6 | +import { componentNames, commandNames } from '../consts'; | ||
7 | + | ||
8 | +const { ROTATION } = componentNames; | ||
9 | + | ||
10 | +/** | ||
11 | + * Chched data for undo | ||
12 | + * @type {Object} | ||
13 | + */ | ||
14 | +let chchedUndoDataForSilent = null; | ||
15 | + | ||
16 | +/** | ||
17 | + * Make undo data | ||
18 | + * @param {Component} rotationComp - rotation component | ||
19 | + * @returns {object} - undodata | ||
20 | + */ | ||
21 | +function makeUndoData(rotationComp) { | ||
22 | + return { | ||
23 | + angle: rotationComp.getCurrentAngle(), | ||
24 | + }; | ||
25 | +} | ||
26 | + | ||
27 | +const command = { | ||
28 | + name: commandNames.ROTATE_IMAGE, | ||
29 | + | ||
30 | + /** | ||
31 | + * Rotate an image | ||
32 | + * @param {Graphics} graphics - Graphics instance | ||
33 | + * @param {string} type - 'rotate' or 'setAngle' | ||
34 | + * @param {number} angle - angle value (degree) | ||
35 | + * @param {boolean} isSilent - is silent execution or not | ||
36 | + * @returns {Promise} | ||
37 | + */ | ||
38 | + execute(graphics, type, angle, isSilent) { | ||
39 | + const rotationComp = graphics.getComponent(ROTATION); | ||
40 | + | ||
41 | + if (!this.isRedo) { | ||
42 | + const undoData = makeUndoData(rotationComp); | ||
43 | + | ||
44 | + chchedUndoDataForSilent = this.setUndoData(undoData, chchedUndoDataForSilent, isSilent); | ||
45 | + } | ||
46 | + | ||
47 | + return rotationComp[type](angle); | ||
48 | + }, | ||
49 | + /** | ||
50 | + * @param {Graphics} graphics - Graphics instance | ||
51 | + * @returns {Promise} | ||
52 | + */ | ||
53 | + undo(graphics) { | ||
54 | + const rotationComp = graphics.getComponent(ROTATION); | ||
55 | + const [, type, angle] = this.args; | ||
56 | + | ||
57 | + if (type === 'setAngle') { | ||
58 | + return rotationComp[type](this.undoData.angle); | ||
59 | + } | ||
60 | + | ||
61 | + return rotationComp.rotate(-angle); | ||
62 | + }, | ||
63 | +}; | ||
64 | + | ||
65 | +commandFactory.register(command); | ||
66 | + | ||
67 | +export default command; |
minsung/src/js/command/setObjectPosition.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Set object properties | ||
4 | + */ | ||
5 | +import commandFactory from '../factory/command'; | ||
6 | +import { Promise } from '../util'; | ||
7 | +import { commandNames, rejectMessages } from '../consts'; | ||
8 | + | ||
9 | +const command = { | ||
10 | + name: commandNames.SET_OBJECT_POSITION, | ||
11 | + | ||
12 | + /** | ||
13 | + * Set object properties | ||
14 | + * @param {Graphics} graphics - Graphics instance | ||
15 | + * @param {number} id - object id | ||
16 | + * @param {Object} posInfo - position object | ||
17 | + * @param {number} posInfo.x - x position | ||
18 | + * @param {number} posInfo.y - y position | ||
19 | + * @param {string} posInfo.originX - can be 'left', 'center', 'right' | ||
20 | + * @param {string} posInfo.originY - can be 'top', 'center', 'bottom' | ||
21 | + * @returns {Promise} | ||
22 | + */ | ||
23 | + execute(graphics, id, posInfo) { | ||
24 | + const targetObj = graphics.getObject(id); | ||
25 | + | ||
26 | + if (!targetObj) { | ||
27 | + return Promise.reject(rejectMessages.noObject); | ||
28 | + } | ||
29 | + | ||
30 | + this.undoData.objectId = id; | ||
31 | + this.undoData.props = graphics.getObjectProperties(id, ['left', 'top']); | ||
32 | + | ||
33 | + graphics.setObjectPosition(id, posInfo); | ||
34 | + graphics.renderAll(); | ||
35 | + | ||
36 | + return Promise.resolve(); | ||
37 | + }, | ||
38 | + /** | ||
39 | + * @param {Graphics} graphics - Graphics instance | ||
40 | + * @returns {Promise} | ||
41 | + */ | ||
42 | + undo(graphics) { | ||
43 | + const { objectId, props } = this.undoData; | ||
44 | + | ||
45 | + graphics.setObjectProperties(objectId, props); | ||
46 | + graphics.renderAll(); | ||
47 | + | ||
48 | + return Promise.resolve(); | ||
49 | + }, | ||
50 | +}; | ||
51 | + | ||
52 | +commandFactory.register(command); | ||
53 | + | ||
54 | +export default command; |
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Set object properties | ||
4 | + */ | ||
5 | +import snippet from 'tui-code-snippet'; | ||
6 | +import commandFactory from '../factory/command'; | ||
7 | +import { Promise } from '../util'; | ||
8 | +import { commandNames, rejectMessages } from '../consts'; | ||
9 | + | ||
10 | +const command = { | ||
11 | + name: commandNames.SET_OBJECT_PROPERTIES, | ||
12 | + | ||
13 | + /** | ||
14 | + * Set object properties | ||
15 | + * @param {Graphics} graphics - Graphics instance | ||
16 | + * @param {number} id - object id | ||
17 | + * @param {Object} props - properties | ||
18 | + * @param {string} [props.fill] Color | ||
19 | + * @param {string} [props.fontFamily] Font type for text | ||
20 | + * @param {number} [props.fontSize] Size | ||
21 | + * @param {string} [props.fontStyle] Type of inclination (normal / italic) | ||
22 | + * @param {string} [props.fontWeight] Type of thicker or thinner looking (normal / bold) | ||
23 | + * @param {string} [props.textAlign] Type of text align (left / center / right) | ||
24 | + * @param {string} [props.textDecoration] Type of line (underline / line-through / overline) | ||
25 | + * @returns {Promise} | ||
26 | + */ | ||
27 | + execute(graphics, id, props) { | ||
28 | + const targetObj = graphics.getObject(id); | ||
29 | + | ||
30 | + if (!targetObj) { | ||
31 | + return Promise.reject(rejectMessages.noObject); | ||
32 | + } | ||
33 | + | ||
34 | + this.undoData.props = {}; | ||
35 | + snippet.forEachOwnProperties(props, (value, key) => { | ||
36 | + this.undoData.props[key] = targetObj[key]; | ||
37 | + }); | ||
38 | + | ||
39 | + graphics.setObjectProperties(id, props); | ||
40 | + | ||
41 | + return Promise.resolve(); | ||
42 | + }, | ||
43 | + /** | ||
44 | + * @param {Graphics} graphics - Graphics instance | ||
45 | + * @param {number} id - object id | ||
46 | + * @returns {Promise} | ||
47 | + */ | ||
48 | + undo(graphics, id) { | ||
49 | + const { props } = this.undoData; | ||
50 | + | ||
51 | + graphics.setObjectProperties(id, props); | ||
52 | + | ||
53 | + return Promise.resolve(); | ||
54 | + }, | ||
55 | +}; | ||
56 | + | ||
57 | +commandFactory.register(command); | ||
58 | + | ||
59 | +export default command; |
minsung/src/js/component/cropper.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Image crop module (start cropping, end cropping) | ||
4 | + */ | ||
5 | +import snippet from 'tui-code-snippet'; | ||
6 | +import fabric from 'fabric'; | ||
7 | +import Component from '../interface/component'; | ||
8 | +import Cropzone from '../extension/cropzone'; | ||
9 | +import { keyCodes, componentNames, CROPZONE_DEFAULT_OPTIONS } from '../consts'; | ||
10 | +import { clamp, fixFloatingPoint } from '../util'; | ||
11 | + | ||
12 | +const MOUSE_MOVE_THRESHOLD = 10; | ||
13 | +const DEFAULT_OPTION = { | ||
14 | + presetRatio: null, | ||
15 | + top: -10, | ||
16 | + left: -10, | ||
17 | + height: 1, | ||
18 | + width: 1, | ||
19 | +}; | ||
20 | + | ||
21 | +/** | ||
22 | + * Cropper components | ||
23 | + * @param {Graphics} graphics - Graphics instance | ||
24 | + * @extends {Component} | ||
25 | + * @class Cropper | ||
26 | + * @ignore | ||
27 | + */ | ||
28 | +class Cropper extends Component { | ||
29 | + constructor(graphics) { | ||
30 | + super(componentNames.CROPPER, graphics); | ||
31 | + | ||
32 | + /** | ||
33 | + * Cropzone | ||
34 | + * @type {Cropzone} | ||
35 | + * @private | ||
36 | + */ | ||
37 | + this._cropzone = null; | ||
38 | + | ||
39 | + /** | ||
40 | + * StartX of Cropzone | ||
41 | + * @type {number} | ||
42 | + * @private | ||
43 | + */ | ||
44 | + this._startX = null; | ||
45 | + | ||
46 | + /** | ||
47 | + * StartY of Cropzone | ||
48 | + * @type {number} | ||
49 | + * @private | ||
50 | + */ | ||
51 | + this._startY = null; | ||
52 | + | ||
53 | + /** | ||
54 | + * State whether shortcut key is pressed or not | ||
55 | + * @type {boolean} | ||
56 | + * @private | ||
57 | + */ | ||
58 | + this._withShiftKey = false; | ||
59 | + | ||
60 | + /** | ||
61 | + * Listeners | ||
62 | + * @type {object.<string, function>} | ||
63 | + * @private | ||
64 | + */ | ||
65 | + this._listeners = { | ||
66 | + keydown: this._onKeyDown.bind(this), | ||
67 | + keyup: this._onKeyUp.bind(this), | ||
68 | + mousedown: this._onFabricMouseDown.bind(this), | ||
69 | + mousemove: this._onFabricMouseMove.bind(this), | ||
70 | + mouseup: this._onFabricMouseUp.bind(this), | ||
71 | + }; | ||
72 | + } | ||
73 | + | ||
74 | + /** | ||
75 | + * Start cropping | ||
76 | + */ | ||
77 | + start() { | ||
78 | + if (this._cropzone) { | ||
79 | + return; | ||
80 | + } | ||
81 | + const canvas = this.getCanvas(); | ||
82 | + | ||
83 | + canvas.forEachObject((obj) => { | ||
84 | + // {@link http://fabricjs.com/docs/fabric.Object.html#evented} | ||
85 | + obj.evented = false; | ||
86 | + }); | ||
87 | + | ||
88 | + this._cropzone = new Cropzone( | ||
89 | + canvas, | ||
90 | + snippet.extend( | ||
91 | + { | ||
92 | + left: 0, | ||
93 | + top: 0, | ||
94 | + width: 0.5, | ||
95 | + height: 0.5, | ||
96 | + strokeWidth: 0, // {@link https://github.com/kangax/fabric.js/issues/2860} | ||
97 | + cornerSize: 10, | ||
98 | + cornerColor: 'black', | ||
99 | + fill: 'transparent', | ||
100 | + }, | ||
101 | + CROPZONE_DEFAULT_OPTIONS, | ||
102 | + this.graphics.cropSelectionStyle | ||
103 | + ) | ||
104 | + ); | ||
105 | + | ||
106 | + canvas.discardActiveObject(); | ||
107 | + canvas.add(this._cropzone); | ||
108 | + canvas.on('mouse:down', this._listeners.mousedown); | ||
109 | + canvas.selection = false; | ||
110 | + canvas.defaultCursor = 'crosshair'; | ||
111 | + | ||
112 | + fabric.util.addListener(document, 'keydown', this._listeners.keydown); | ||
113 | + fabric.util.addListener(document, 'keyup', this._listeners.keyup); | ||
114 | + } | ||
115 | + | ||
116 | + /** | ||
117 | + * End cropping | ||
118 | + */ | ||
119 | + end() { | ||
120 | + const canvas = this.getCanvas(); | ||
121 | + const cropzone = this._cropzone; | ||
122 | + | ||
123 | + if (!cropzone) { | ||
124 | + return; | ||
125 | + } | ||
126 | + canvas.remove(cropzone); | ||
127 | + canvas.selection = true; | ||
128 | + canvas.defaultCursor = 'default'; | ||
129 | + canvas.off('mouse:down', this._listeners.mousedown); | ||
130 | + canvas.forEachObject((obj) => { | ||
131 | + obj.evented = true; | ||
132 | + }); | ||
133 | + | ||
134 | + this._cropzone = null; | ||
135 | + | ||
136 | + fabric.util.removeListener(document, 'keydown', this._listeners.keydown); | ||
137 | + fabric.util.removeListener(document, 'keyup', this._listeners.keyup); | ||
138 | + } | ||
139 | + | ||
140 | + /** | ||
141 | + * Change cropzone visible | ||
142 | + * @param {boolean} visible - cropzone visible state | ||
143 | + */ | ||
144 | + changeVisibility(visible) { | ||
145 | + if (this._cropzone) { | ||
146 | + this._cropzone.set({ visible }); | ||
147 | + } | ||
148 | + } | ||
149 | + | ||
150 | + /** | ||
151 | + * onMousedown handler in fabric canvas | ||
152 | + * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event | ||
153 | + * @private | ||
154 | + */ | ||
155 | + _onFabricMouseDown(fEvent) { | ||
156 | + const canvas = this.getCanvas(); | ||
157 | + | ||
158 | + if (fEvent.target) { | ||
159 | + return; | ||
160 | + } | ||
161 | + | ||
162 | + canvas.selection = false; | ||
163 | + const coord = canvas.getPointer(fEvent.e); | ||
164 | + | ||
165 | + this._startX = coord.x; | ||
166 | + this._startY = coord.y; | ||
167 | + | ||
168 | + canvas.on({ | ||
169 | + 'mouse:move': this._listeners.mousemove, | ||
170 | + 'mouse:up': this._listeners.mouseup, | ||
171 | + }); | ||
172 | + } | ||
173 | + | ||
174 | + /** | ||
175 | + * onMousemove handler in fabric canvas | ||
176 | + * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event | ||
177 | + * @private | ||
178 | + */ | ||
179 | + _onFabricMouseMove(fEvent) { | ||
180 | + const canvas = this.getCanvas(); | ||
181 | + const pointer = canvas.getPointer(fEvent.e); | ||
182 | + const { x, y } = pointer; | ||
183 | + const cropzone = this._cropzone; | ||
184 | + | ||
185 | + if (Math.abs(x - this._startX) + Math.abs(y - this._startY) > MOUSE_MOVE_THRESHOLD) { | ||
186 | + canvas.remove(cropzone); | ||
187 | + cropzone.set(this._calcRectDimensionFromPoint(x, y)); | ||
188 | + | ||
189 | + canvas.add(cropzone); | ||
190 | + canvas.setActiveObject(cropzone); | ||
191 | + } | ||
192 | + } | ||
193 | + | ||
194 | + /** | ||
195 | + * Get rect dimension setting from Canvas-Mouse-Position(x, y) | ||
196 | + * @param {number} x - Canvas-Mouse-Position x | ||
197 | + * @param {number} y - Canvas-Mouse-Position Y | ||
198 | + * @returns {{left: number, top: number, width: number, height: number}} | ||
199 | + * @private | ||
200 | + */ | ||
201 | + _calcRectDimensionFromPoint(x, y) { | ||
202 | + const canvas = this.getCanvas(); | ||
203 | + const canvasWidth = canvas.getWidth(); | ||
204 | + const canvasHeight = canvas.getHeight(); | ||
205 | + const startX = this._startX; | ||
206 | + const startY = this._startY; | ||
207 | + let left = clamp(x, 0, startX); | ||
208 | + let top = clamp(y, 0, startY); | ||
209 | + let width = clamp(x, startX, canvasWidth) - left; // (startX <= x(mouse) <= canvasWidth) - left | ||
210 | + let height = clamp(y, startY, canvasHeight) - top; // (startY <= y(mouse) <= canvasHeight) - top | ||
211 | + | ||
212 | + if (this._withShiftKey) { | ||
213 | + // make fixed ratio cropzone | ||
214 | + if (width > height) { | ||
215 | + height = width; | ||
216 | + } else if (height > width) { | ||
217 | + width = height; | ||
218 | + } | ||
219 | + | ||
220 | + if (startX >= x) { | ||
221 | + left = startX - width; | ||
222 | + } | ||
223 | + | ||
224 | + if (startY >= y) { | ||
225 | + top = startY - height; | ||
226 | + } | ||
227 | + } | ||
228 | + | ||
229 | + return { | ||
230 | + left, | ||
231 | + top, | ||
232 | + width, | ||
233 | + height, | ||
234 | + }; | ||
235 | + } | ||
236 | + | ||
237 | + /** | ||
238 | + * onMouseup handler in fabric canvas | ||
239 | + * @private | ||
240 | + */ | ||
241 | + _onFabricMouseUp() { | ||
242 | + const cropzone = this._cropzone; | ||
243 | + const listeners = this._listeners; | ||
244 | + const canvas = this.getCanvas(); | ||
245 | + | ||
246 | + canvas.setActiveObject(cropzone); | ||
247 | + canvas.off({ | ||
248 | + 'mouse:move': listeners.mousemove, | ||
249 | + 'mouse:up': listeners.mouseup, | ||
250 | + }); | ||
251 | + } | ||
252 | + | ||
253 | + /** | ||
254 | + * Get cropped image data | ||
255 | + * @param {Object} cropRect cropzone rect | ||
256 | + * @param {Number} cropRect.left left position | ||
257 | + * @param {Number} cropRect.top top position | ||
258 | + * @param {Number} cropRect.width width | ||
259 | + * @param {Number} cropRect.height height | ||
260 | + * @returns {?{imageName: string, url: string}} cropped Image data | ||
261 | + */ | ||
262 | + getCroppedImageData(cropRect) { | ||
263 | + const canvas = this.getCanvas(); | ||
264 | + const containsCropzone = canvas.contains(this._cropzone); | ||
265 | + if (!cropRect) { | ||
266 | + return null; | ||
267 | + } | ||
268 | + | ||
269 | + if (containsCropzone) { | ||
270 | + canvas.remove(this._cropzone); | ||
271 | + } | ||
272 | + | ||
273 | + const imageData = { | ||
274 | + imageName: this.getImageName(), | ||
275 | + url: canvas.toDataURL(cropRect), | ||
276 | + }; | ||
277 | + | ||
278 | + if (containsCropzone) { | ||
279 | + canvas.add(this._cropzone); | ||
280 | + } | ||
281 | + | ||
282 | + return imageData; | ||
283 | + } | ||
284 | + | ||
285 | + /** | ||
286 | + * Get cropped rect | ||
287 | + * @returns {Object} rect | ||
288 | + */ | ||
289 | + getCropzoneRect() { | ||
290 | + const cropzone = this._cropzone; | ||
291 | + | ||
292 | + if (!cropzone.isValid()) { | ||
293 | + return null; | ||
294 | + } | ||
295 | + | ||
296 | + return { | ||
297 | + left: cropzone.left, | ||
298 | + top: cropzone.top, | ||
299 | + width: cropzone.width, | ||
300 | + height: cropzone.height, | ||
301 | + }; | ||
302 | + } | ||
303 | + | ||
304 | + /** | ||
305 | + * Set a cropzone square | ||
306 | + * @param {number} [presetRatio] - preset ratio | ||
307 | + */ | ||
308 | + setCropzoneRect(presetRatio) { | ||
309 | + const canvas = this.getCanvas(); | ||
310 | + const cropzone = this._cropzone; | ||
311 | + | ||
312 | + canvas.discardActiveObject(); | ||
313 | + canvas.selection = false; | ||
314 | + canvas.remove(cropzone); | ||
315 | + | ||
316 | + cropzone.set(presetRatio ? this._getPresetPropertiesForCropSize(presetRatio) : DEFAULT_OPTION); | ||
317 | + | ||
318 | + canvas.add(cropzone); | ||
319 | + canvas.selection = true; | ||
320 | + | ||
321 | + if (presetRatio) { | ||
322 | + canvas.setActiveObject(cropzone); | ||
323 | + } | ||
324 | + } | ||
325 | + | ||
326 | + /** | ||
327 | + * get a cropzone square info | ||
328 | + * @param {number} presetRatio - preset ratio | ||
329 | + * @returns {{presetRatio: number, left: number, top: number, width: number, height: number}} | ||
330 | + * @private | ||
331 | + */ | ||
332 | + _getPresetPropertiesForCropSize(presetRatio) { | ||
333 | + const canvas = this.getCanvas(); | ||
334 | + const originalWidth = canvas.getWidth(); | ||
335 | + const originalHeight = canvas.getHeight(); | ||
336 | + | ||
337 | + const standardSize = originalWidth >= originalHeight ? originalWidth : originalHeight; | ||
338 | + const getScale = (value, orignalValue) => (value > orignalValue ? orignalValue / value : 1); | ||
339 | + | ||
340 | + let width = standardSize * presetRatio; | ||
341 | + let height = standardSize; | ||
342 | + | ||
343 | + const scaleWidth = getScale(width, originalWidth); | ||
344 | + [width, height] = snippet.map([width, height], (sizeValue) => sizeValue * scaleWidth); | ||
345 | + | ||
346 | + const scaleHeight = getScale(height, originalHeight); | ||
347 | + [width, height] = snippet.map([width, height], (sizeValue) => | ||
348 | + fixFloatingPoint(sizeValue * scaleHeight) | ||
349 | + ); | ||
350 | + | ||
351 | + return { | ||
352 | + presetRatio, | ||
353 | + top: (originalHeight - height) / 2, | ||
354 | + left: (originalWidth - width) / 2, | ||
355 | + width, | ||
356 | + height, | ||
357 | + }; | ||
358 | + } | ||
359 | + | ||
360 | + /** | ||
361 | + * Keydown event handler | ||
362 | + * @param {KeyboardEvent} e - Event object | ||
363 | + * @private | ||
364 | + */ | ||
365 | + _onKeyDown(e) { | ||
366 | + if (e.keyCode === keyCodes.SHIFT) { | ||
367 | + this._withShiftKey = true; | ||
368 | + } | ||
369 | + } | ||
370 | + | ||
371 | + /** | ||
372 | + * Keyup event handler | ||
373 | + * @param {KeyboardEvent} e - Event object | ||
374 | + * @private | ||
375 | + */ | ||
376 | + _onKeyUp(e) { | ||
377 | + if (e.keyCode === keyCodes.SHIFT) { | ||
378 | + this._withShiftKey = false; | ||
379 | + } | ||
380 | + } | ||
381 | +} | ||
382 | + | ||
383 | +export default Cropper; |
minsung/src/js/component/filter.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Add filter module | ||
4 | + */ | ||
5 | +import { isUndefined, extend, forEach, filter } from 'tui-code-snippet'; | ||
6 | +import { Promise } from '../util'; | ||
7 | +import fabric from 'fabric'; | ||
8 | +import Component from '../interface/component'; | ||
9 | +import Mask from '../extension/mask'; | ||
10 | +import { rejectMessages, componentNames } from '../consts'; | ||
11 | +import Sharpen from '../extension/sharpen'; | ||
12 | +import Emboss from '../extension/emboss'; | ||
13 | +import ColorFilter from '../extension/colorFilter'; | ||
14 | + | ||
15 | +const { filters } = fabric.Image; | ||
16 | +filters.Mask = Mask; | ||
17 | +filters.Sharpen = Sharpen; | ||
18 | +filters.Emboss = Emboss; | ||
19 | +filters.ColorFilter = ColorFilter; | ||
20 | + | ||
21 | +/** | ||
22 | + * Filter | ||
23 | + * @class Filter | ||
24 | + * @param {Graphics} graphics - Graphics instance | ||
25 | + * @extends {Component} | ||
26 | + * @ignore | ||
27 | + */ | ||
28 | +class Filter extends Component { | ||
29 | + constructor(graphics) { | ||
30 | + super(componentNames.FILTER, graphics); | ||
31 | + } | ||
32 | + | ||
33 | + /** | ||
34 | + * Add filter to source image (a specific filter is added on fabric.js) | ||
35 | + * @param {string} type - Filter type | ||
36 | + * @param {Object} [options] - Options of filter | ||
37 | + * @returns {Promise} | ||
38 | + */ | ||
39 | + add(type, options) { | ||
40 | + return new Promise((resolve, reject) => { | ||
41 | + const sourceImg = this._getSourceImage(); | ||
42 | + const canvas = this.getCanvas(); | ||
43 | + let imgFilter = this._getFilter(sourceImg, type); | ||
44 | + if (!imgFilter) { | ||
45 | + imgFilter = this._createFilter(sourceImg, type, options); | ||
46 | + } | ||
47 | + | ||
48 | + if (!imgFilter) { | ||
49 | + reject(rejectMessages.invalidParameters); | ||
50 | + } | ||
51 | + | ||
52 | + this._changeFilterValues(imgFilter, options); | ||
53 | + | ||
54 | + this._apply(sourceImg, () => { | ||
55 | + canvas.renderAll(); | ||
56 | + resolve({ | ||
57 | + type, | ||
58 | + action: 'add', | ||
59 | + options, | ||
60 | + }); | ||
61 | + }); | ||
62 | + }); | ||
63 | + } | ||
64 | + | ||
65 | + /** | ||
66 | + * Remove filter to source image | ||
67 | + * @param {string} type - Filter type | ||
68 | + * @returns {Promise} | ||
69 | + */ | ||
70 | + remove(type) { | ||
71 | + return new Promise((resolve, reject) => { | ||
72 | + const sourceImg = this._getSourceImage(); | ||
73 | + const canvas = this.getCanvas(); | ||
74 | + const options = this.getOptions(type); | ||
75 | + | ||
76 | + if (!sourceImg.filters.length) { | ||
77 | + reject(rejectMessages.unsupportedOperation); | ||
78 | + } | ||
79 | + | ||
80 | + this._removeFilter(sourceImg, type); | ||
81 | + | ||
82 | + this._apply(sourceImg, () => { | ||
83 | + canvas.renderAll(); | ||
84 | + resolve({ | ||
85 | + type, | ||
86 | + action: 'remove', | ||
87 | + options, | ||
88 | + }); | ||
89 | + }); | ||
90 | + }); | ||
91 | + } | ||
92 | + | ||
93 | + /** | ||
94 | + * Whether this has the filter or not | ||
95 | + * @param {string} type - Filter type | ||
96 | + * @returns {boolean} true if it has the filter | ||
97 | + */ | ||
98 | + hasFilter(type) { | ||
99 | + return !!this._getFilter(this._getSourceImage(), type); | ||
100 | + } | ||
101 | + | ||
102 | + /** | ||
103 | + * Get a filter options | ||
104 | + * @param {string} type - Filter type | ||
105 | + * @returns {Object} filter options or null if there is no that filter | ||
106 | + */ | ||
107 | + getOptions(type) { | ||
108 | + const sourceImg = this._getSourceImage(); | ||
109 | + const imgFilter = this._getFilter(sourceImg, type); | ||
110 | + if (!imgFilter) { | ||
111 | + return null; | ||
112 | + } | ||
113 | + | ||
114 | + return extend({}, imgFilter.options); | ||
115 | + } | ||
116 | + | ||
117 | + /** | ||
118 | + * Change filter values | ||
119 | + * @param {Object} imgFilter object of filter | ||
120 | + * @param {Object} options object | ||
121 | + * @private | ||
122 | + */ | ||
123 | + _changeFilterValues(imgFilter, options) { | ||
124 | + forEach(options, (value, key) => { | ||
125 | + if (!isUndefined(imgFilter[key])) { | ||
126 | + imgFilter[key] = value; | ||
127 | + } | ||
128 | + }); | ||
129 | + forEach(imgFilter.options, (value, key) => { | ||
130 | + if (!isUndefined(options[key])) { | ||
131 | + imgFilter.options[key] = options[key]; | ||
132 | + } | ||
133 | + }); | ||
134 | + } | ||
135 | + | ||
136 | + /** | ||
137 | + * Apply filter | ||
138 | + * @param {fabric.Image} sourceImg - Source image to apply filter | ||
139 | + * @param {function} callback - Executed function after applying filter | ||
140 | + * @private | ||
141 | + */ | ||
142 | + _apply(sourceImg, callback) { | ||
143 | + sourceImg.filters.push(); | ||
144 | + const result = sourceImg.applyFilters(); | ||
145 | + if (result) { | ||
146 | + callback(); | ||
147 | + } | ||
148 | + } | ||
149 | + | ||
150 | + /** | ||
151 | + * Get source image on canvas | ||
152 | + * @returns {fabric.Image} Current source image on canvas | ||
153 | + * @private | ||
154 | + */ | ||
155 | + _getSourceImage() { | ||
156 | + return this.getCanvasImage(); | ||
157 | + } | ||
158 | + | ||
159 | + /** | ||
160 | + * Create filter instance | ||
161 | + * @param {fabric.Image} sourceImg - Source image to apply filter | ||
162 | + * @param {string} type - Filter type | ||
163 | + * @param {Object} [options] - Options of filter | ||
164 | + * @returns {Object} Fabric object of filter | ||
165 | + * @private | ||
166 | + */ | ||
167 | + _createFilter(sourceImg, type, options) { | ||
168 | + let filterObj; | ||
169 | + // capitalize first letter for matching with fabric image filter name | ||
170 | + const fabricType = this._getFabricFilterType(type); | ||
171 | + const ImageFilter = fabric.Image.filters[fabricType]; | ||
172 | + if (ImageFilter) { | ||
173 | + filterObj = new ImageFilter(options); | ||
174 | + filterObj.options = options; | ||
175 | + sourceImg.filters.push(filterObj); | ||
176 | + } | ||
177 | + | ||
178 | + return filterObj; | ||
179 | + } | ||
180 | + | ||
181 | + /** | ||
182 | + * Get applied filter instance | ||
183 | + * @param {fabric.Image} sourceImg - Source image to apply filter | ||
184 | + * @param {string} type - Filter type | ||
185 | + * @returns {Object} Fabric object of filter | ||
186 | + * @private | ||
187 | + */ | ||
188 | + _getFilter(sourceImg, type) { | ||
189 | + let imgFilter = null; | ||
190 | + | ||
191 | + if (sourceImg) { | ||
192 | + const fabricType = this._getFabricFilterType(type); | ||
193 | + const { length } = sourceImg.filters; | ||
194 | + let item, i; | ||
195 | + | ||
196 | + for (i = 0; i < length; i += 1) { | ||
197 | + item = sourceImg.filters[i]; | ||
198 | + if (item.type === fabricType) { | ||
199 | + imgFilter = item; | ||
200 | + break; | ||
201 | + } | ||
202 | + } | ||
203 | + } | ||
204 | + | ||
205 | + return imgFilter; | ||
206 | + } | ||
207 | + | ||
208 | + /** | ||
209 | + * Remove applied filter instance | ||
210 | + * @param {fabric.Image} sourceImg - Source image to apply filter | ||
211 | + * @param {string} type - Filter type | ||
212 | + * @private | ||
213 | + */ | ||
214 | + _removeFilter(sourceImg, type) { | ||
215 | + const fabricType = this._getFabricFilterType(type); | ||
216 | + sourceImg.filters = filter(sourceImg.filters, (value) => value.type !== fabricType); | ||
217 | + } | ||
218 | + | ||
219 | + /** | ||
220 | + * Change filter class name to fabric's, especially capitalizing first letter | ||
221 | + * @param {string} type - Filter type | ||
222 | + * @example | ||
223 | + * 'grayscale' -> 'Grayscale' | ||
224 | + * @returns {string} Fabric filter class name | ||
225 | + */ | ||
226 | + _getFabricFilterType(type) { | ||
227 | + return type.charAt(0).toUpperCase() + type.slice(1); | ||
228 | + } | ||
229 | +} | ||
230 | + | ||
231 | +export default Filter; |
minsung/src/js/component/flip.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Image flip module | ||
4 | + */ | ||
5 | +import snippet from 'tui-code-snippet'; | ||
6 | +import { Promise } from '../util'; | ||
7 | +import Component from '../interface/component'; | ||
8 | +import { componentNames, rejectMessages } from '../consts'; | ||
9 | + | ||
10 | +/** | ||
11 | + * Flip | ||
12 | + * @class Flip | ||
13 | + * @param {Graphics} graphics - Graphics instance | ||
14 | + * @extends {Component} | ||
15 | + * @ignore | ||
16 | + */ | ||
17 | +class Flip extends Component { | ||
18 | + constructor(graphics) { | ||
19 | + super(componentNames.FLIP, graphics); | ||
20 | + } | ||
21 | + | ||
22 | + /** | ||
23 | + * Get current flip settings | ||
24 | + * @returns {{flipX: Boolean, flipY: Boolean}} | ||
25 | + */ | ||
26 | + getCurrentSetting() { | ||
27 | + const canvasImage = this.getCanvasImage(); | ||
28 | + | ||
29 | + return { | ||
30 | + flipX: canvasImage.flipX, | ||
31 | + flipY: canvasImage.flipY, | ||
32 | + }; | ||
33 | + } | ||
34 | + | ||
35 | + /** | ||
36 | + * Set flipX, flipY | ||
37 | + * @param {{flipX: Boolean, flipY: Boolean}} newSetting - Flip setting | ||
38 | + * @returns {Promise} | ||
39 | + */ | ||
40 | + set(newSetting) { | ||
41 | + const setting = this.getCurrentSetting(); | ||
42 | + const isChangingFlipX = setting.flipX !== newSetting.flipX; | ||
43 | + const isChangingFlipY = setting.flipY !== newSetting.flipY; | ||
44 | + | ||
45 | + if (!isChangingFlipX && !isChangingFlipY) { | ||
46 | + return Promise.reject(rejectMessages.flip); | ||
47 | + } | ||
48 | + | ||
49 | + snippet.extend(setting, newSetting); | ||
50 | + this.setImageProperties(setting, true); | ||
51 | + this._invertAngle(isChangingFlipX, isChangingFlipY); | ||
52 | + this._flipObjects(isChangingFlipX, isChangingFlipY); | ||
53 | + | ||
54 | + return Promise.resolve({ | ||
55 | + flipX: setting.flipX, | ||
56 | + flipY: setting.flipY, | ||
57 | + angle: this.getCanvasImage().angle, | ||
58 | + }); | ||
59 | + } | ||
60 | + | ||
61 | + /** | ||
62 | + * Invert image angle for flip | ||
63 | + * @param {boolean} isChangingFlipX - Change flipX | ||
64 | + * @param {boolean} isChangingFlipY - Change flipY | ||
65 | + */ | ||
66 | + _invertAngle(isChangingFlipX, isChangingFlipY) { | ||
67 | + const canvasImage = this.getCanvasImage(); | ||
68 | + let { angle } = canvasImage; | ||
69 | + | ||
70 | + if (isChangingFlipX) { | ||
71 | + angle *= -1; | ||
72 | + } | ||
73 | + if (isChangingFlipY) { | ||
74 | + angle *= -1; | ||
75 | + } | ||
76 | + canvasImage.rotate(parseFloat(angle)).setCoords(); // parseFloat for -0 to 0 | ||
77 | + } | ||
78 | + | ||
79 | + /** | ||
80 | + * Flip objects | ||
81 | + * @param {boolean} isChangingFlipX - Change flipX | ||
82 | + * @param {boolean} isChangingFlipY - Change flipY | ||
83 | + * @private | ||
84 | + */ | ||
85 | + _flipObjects(isChangingFlipX, isChangingFlipY) { | ||
86 | + const canvas = this.getCanvas(); | ||
87 | + | ||
88 | + if (isChangingFlipX) { | ||
89 | + canvas.forEachObject((obj) => { | ||
90 | + obj | ||
91 | + .set({ | ||
92 | + angle: parseFloat(obj.angle * -1), // parseFloat for -0 to 0 | ||
93 | + flipX: !obj.flipX, | ||
94 | + left: canvas.width - obj.left, | ||
95 | + }) | ||
96 | + .setCoords(); | ||
97 | + }); | ||
98 | + } | ||
99 | + if (isChangingFlipY) { | ||
100 | + canvas.forEachObject((obj) => { | ||
101 | + obj | ||
102 | + .set({ | ||
103 | + angle: parseFloat(obj.angle * -1), // parseFloat for -0 to 0 | ||
104 | + flipY: !obj.flipY, | ||
105 | + top: canvas.height - obj.top, | ||
106 | + }) | ||
107 | + .setCoords(); | ||
108 | + }); | ||
109 | + } | ||
110 | + canvas.renderAll(); | ||
111 | + } | ||
112 | + | ||
113 | + /** | ||
114 | + * Reset flip settings | ||
115 | + * @returns {Promise} | ||
116 | + */ | ||
117 | + reset() { | ||
118 | + return this.set({ | ||
119 | + flipX: false, | ||
120 | + flipY: false, | ||
121 | + }); | ||
122 | + } | ||
123 | + | ||
124 | + /** | ||
125 | + * Flip x | ||
126 | + * @returns {Promise} | ||
127 | + */ | ||
128 | + flipX() { | ||
129 | + const current = this.getCurrentSetting(); | ||
130 | + | ||
131 | + return this.set({ | ||
132 | + flipX: !current.flipX, | ||
133 | + flipY: current.flipY, | ||
134 | + }); | ||
135 | + } | ||
136 | + | ||
137 | + /** | ||
138 | + * Flip y | ||
139 | + * @returns {Promise} | ||
140 | + */ | ||
141 | + flipY() { | ||
142 | + const current = this.getCurrentSetting(); | ||
143 | + | ||
144 | + return this.set({ | ||
145 | + flipX: current.flipX, | ||
146 | + flipY: !current.flipY, | ||
147 | + }); | ||
148 | + } | ||
149 | +} | ||
150 | + | ||
151 | +export default Flip; |
minsung/src/js/component/freeDrawing.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Free drawing module, Set brush | ||
4 | + */ | ||
5 | +import fabric from 'fabric'; | ||
6 | +import Component from '../interface/component'; | ||
7 | +import { componentNames } from '../consts'; | ||
8 | + | ||
9 | +/** | ||
10 | + * FreeDrawing | ||
11 | + * @class FreeDrawing | ||
12 | + * @param {Graphics} graphics - Graphics instance | ||
13 | + * @extends {Component} | ||
14 | + * @ignore | ||
15 | + */ | ||
16 | +class FreeDrawing extends Component { | ||
17 | + constructor(graphics) { | ||
18 | + super(componentNames.FREE_DRAWING, graphics); | ||
19 | + | ||
20 | + /** | ||
21 | + * Brush width | ||
22 | + * @type {number} | ||
23 | + */ | ||
24 | + this.width = 12; | ||
25 | + | ||
26 | + /** | ||
27 | + * fabric.Color instance for brush color | ||
28 | + * @type {fabric.Color} | ||
29 | + */ | ||
30 | + this.oColor = new fabric.Color('rgba(0, 0, 0, 0.5)'); | ||
31 | + } | ||
32 | + | ||
33 | + /** | ||
34 | + * Start free drawing mode | ||
35 | + * @param {{width: ?number, color: ?string}} [setting] - Brush width & color | ||
36 | + */ | ||
37 | + start(setting) { | ||
38 | + const canvas = this.getCanvas(); | ||
39 | + | ||
40 | + canvas.isDrawingMode = true; | ||
41 | + this.setBrush(setting); | ||
42 | + } | ||
43 | + | ||
44 | + /** | ||
45 | + * Set brush | ||
46 | + * @param {{width: ?number, color: ?string}} [setting] - Brush width & color | ||
47 | + */ | ||
48 | + setBrush(setting) { | ||
49 | + const brush = this.getCanvas().freeDrawingBrush; | ||
50 | + | ||
51 | + setting = setting || {}; | ||
52 | + this.width = setting.width || this.width; | ||
53 | + if (setting.color) { | ||
54 | + this.oColor = new fabric.Color(setting.color); | ||
55 | + } | ||
56 | + brush.width = this.width; | ||
57 | + brush.color = this.oColor.toRgba(); | ||
58 | + } | ||
59 | + | ||
60 | + /** | ||
61 | + * End free drawing mode | ||
62 | + */ | ||
63 | + end() { | ||
64 | + const canvas = this.getCanvas(); | ||
65 | + | ||
66 | + canvas.isDrawingMode = false; | ||
67 | + } | ||
68 | +} | ||
69 | + | ||
70 | +export default FreeDrawing; |
minsung/src/js/component/icon.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Add icon module | ||
4 | + */ | ||
5 | +import fabric from 'fabric'; | ||
6 | +import snippet from 'tui-code-snippet'; | ||
7 | +import { Promise } from '../util'; | ||
8 | +import Component from '../interface/component'; | ||
9 | +import { eventNames as events, rejectMessages, componentNames, fObjectOptions } from '../consts'; | ||
10 | + | ||
11 | +const pathMap = { | ||
12 | + arrow: 'M 0 90 H 105 V 120 L 160 60 L 105 0 V 30 H 0 Z', | ||
13 | + cancel: | ||
14 | + 'M 0 30 L 30 60 L 0 90 L 30 120 L 60 90 L 90 120 L 120 90 ' + | ||
15 | + 'L 90 60 L 120 30 L 90 0 L 60 30 L 30 0 Z', | ||
16 | +}; | ||
17 | + | ||
18 | +/** | ||
19 | + * Icon | ||
20 | + * @class Icon | ||
21 | + * @param {Graphics} graphics - Graphics instance | ||
22 | + * @extends {Component} | ||
23 | + * @ignore | ||
24 | + */ | ||
25 | +class Icon extends Component { | ||
26 | + constructor(graphics) { | ||
27 | + super(componentNames.ICON, graphics); | ||
28 | + | ||
29 | + /** | ||
30 | + * Default icon color | ||
31 | + * @type {string} | ||
32 | + */ | ||
33 | + this._oColor = '#000000'; | ||
34 | + | ||
35 | + /** | ||
36 | + * Path value of each icon type | ||
37 | + * @type {Object} | ||
38 | + */ | ||
39 | + this._pathMap = pathMap; | ||
40 | + | ||
41 | + /** | ||
42 | + * Type of the drawing icon | ||
43 | + * @type {string} | ||
44 | + * @private | ||
45 | + */ | ||
46 | + this._type = null; | ||
47 | + | ||
48 | + /** | ||
49 | + * Color of the drawing icon | ||
50 | + * @type {string} | ||
51 | + * @private | ||
52 | + */ | ||
53 | + this._iconColor = null; | ||
54 | + | ||
55 | + /** | ||
56 | + * Event handler list | ||
57 | + * @type {Object} | ||
58 | + * @private | ||
59 | + */ | ||
60 | + this._handlers = { | ||
61 | + mousedown: this._onFabricMouseDown.bind(this), | ||
62 | + mousemove: this._onFabricMouseMove.bind(this), | ||
63 | + mouseup: this._onFabricMouseUp.bind(this), | ||
64 | + }; | ||
65 | + } | ||
66 | + | ||
67 | + /** | ||
68 | + * Set states of the current drawing shape | ||
69 | + * @ignore | ||
70 | + * @param {string} type - Icon type ('arrow', 'cancel', custom icon name) | ||
71 | + * @param {string} iconColor - Icon foreground color | ||
72 | + */ | ||
73 | + setStates(type, iconColor) { | ||
74 | + this._type = type; | ||
75 | + this._iconColor = iconColor; | ||
76 | + } | ||
77 | + | ||
78 | + /** | ||
79 | + * Start to draw the icon on canvas | ||
80 | + * @ignore | ||
81 | + */ | ||
82 | + start() { | ||
83 | + const canvas = this.getCanvas(); | ||
84 | + canvas.selection = false; | ||
85 | + canvas.on('mouse:down', this._handlers.mousedown); | ||
86 | + } | ||
87 | + | ||
88 | + /** | ||
89 | + * End to draw the icon on canvas | ||
90 | + * @ignore | ||
91 | + */ | ||
92 | + end() { | ||
93 | + const canvas = this.getCanvas(); | ||
94 | + | ||
95 | + canvas.selection = true; | ||
96 | + canvas.off({ | ||
97 | + 'mouse:down': this._handlers.mousedown, | ||
98 | + }); | ||
99 | + } | ||
100 | + | ||
101 | + /** | ||
102 | + * Add icon | ||
103 | + * @param {string} type - Icon type | ||
104 | + * @param {Object} options - Icon options | ||
105 | + * @param {string} [options.fill] - Icon foreground color | ||
106 | + * @param {string} [options.left] - Icon x position | ||
107 | + * @param {string} [options.top] - Icon y position | ||
108 | + * @returns {Promise} | ||
109 | + */ | ||
110 | + add(type, options) { | ||
111 | + return new Promise((resolve, reject) => { | ||
112 | + const canvas = this.getCanvas(); | ||
113 | + const path = this._pathMap[type]; | ||
114 | + const selectionStyle = fObjectOptions.SELECTION_STYLE; | ||
115 | + const icon = path ? this._createIcon(path) : null; | ||
116 | + this._icon = icon; | ||
117 | + | ||
118 | + if (!icon) { | ||
119 | + reject(rejectMessages.invalidParameters); | ||
120 | + } | ||
121 | + | ||
122 | + icon.set( | ||
123 | + snippet.extend( | ||
124 | + { | ||
125 | + type: 'icon', | ||
126 | + fill: this._oColor, | ||
127 | + }, | ||
128 | + selectionStyle, | ||
129 | + options, | ||
130 | + this.graphics.controlStyle | ||
131 | + ) | ||
132 | + ); | ||
133 | + | ||
134 | + canvas.add(icon).setActiveObject(icon); | ||
135 | + | ||
136 | + resolve(this.graphics.createObjectProperties(icon)); | ||
137 | + }); | ||
138 | + } | ||
139 | + | ||
140 | + /** | ||
141 | + * Register icon paths | ||
142 | + * @param {{key: string, value: string}} pathInfos - Path infos | ||
143 | + */ | ||
144 | + registerPaths(pathInfos) { | ||
145 | + snippet.forEach( | ||
146 | + pathInfos, | ||
147 | + (path, type) => { | ||
148 | + this._pathMap[type] = path; | ||
149 | + }, | ||
150 | + this | ||
151 | + ); | ||
152 | + } | ||
153 | + | ||
154 | + /** | ||
155 | + * Set icon object color | ||
156 | + * @param {string} color - Color to set | ||
157 | + * @param {fabric.Path}[obj] - Current activated path object | ||
158 | + */ | ||
159 | + setColor(color, obj) { | ||
160 | + this._oColor = color; | ||
161 | + | ||
162 | + if (obj && obj.get('type') === 'icon') { | ||
163 | + obj.set({ fill: this._oColor }); | ||
164 | + this.getCanvas().renderAll(); | ||
165 | + } | ||
166 | + } | ||
167 | + | ||
168 | + /** | ||
169 | + * Get icon color | ||
170 | + * @param {fabric.Path}[obj] - Current activated path object | ||
171 | + * @returns {string} color | ||
172 | + */ | ||
173 | + getColor(obj) { | ||
174 | + return obj.fill; | ||
175 | + } | ||
176 | + | ||
177 | + /** | ||
178 | + * Create icon object | ||
179 | + * @param {string} path - Path value to create icon | ||
180 | + * @returns {fabric.Path} Path object | ||
181 | + */ | ||
182 | + _createIcon(path) { | ||
183 | + return new fabric.Path(path); | ||
184 | + } | ||
185 | + | ||
186 | + /** | ||
187 | + * MouseDown event handler on canvas | ||
188 | + * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event object | ||
189 | + * @private | ||
190 | + */ | ||
191 | + _onFabricMouseDown(fEvent) { | ||
192 | + const canvas = this.getCanvas(); | ||
193 | + | ||
194 | + this._startPoint = canvas.getPointer(fEvent.e); | ||
195 | + const { x: left, y: top } = this._startPoint; | ||
196 | + | ||
197 | + this.add(this._type, { | ||
198 | + left, | ||
199 | + top, | ||
200 | + fill: this._iconColor, | ||
201 | + }).then(() => { | ||
202 | + this.fire(events.ADD_OBJECT, this.graphics.createObjectProperties(this._icon)); | ||
203 | + canvas.on('mouse:move', this._handlers.mousemove); | ||
204 | + canvas.on('mouse:up', this._handlers.mouseup); | ||
205 | + }); | ||
206 | + } | ||
207 | + | ||
208 | + /** | ||
209 | + * MouseMove event handler on canvas | ||
210 | + * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event object | ||
211 | + * @private | ||
212 | + */ | ||
213 | + _onFabricMouseMove(fEvent) { | ||
214 | + const canvas = this.getCanvas(); | ||
215 | + | ||
216 | + if (!this._icon) { | ||
217 | + return; | ||
218 | + } | ||
219 | + const moveOriginPointer = canvas.getPointer(fEvent.e); | ||
220 | + | ||
221 | + const scaleX = (moveOriginPointer.x - this._startPoint.x) / this._icon.width; | ||
222 | + const scaleY = (moveOriginPointer.y - this._startPoint.y) / this._icon.height; | ||
223 | + | ||
224 | + this._icon.set({ | ||
225 | + scaleX: Math.abs(scaleX * 2), | ||
226 | + scaleY: Math.abs(scaleY * 2), | ||
227 | + }); | ||
228 | + | ||
229 | + this._icon.setCoords(); | ||
230 | + canvas.renderAll(); | ||
231 | + } | ||
232 | + | ||
233 | + /** | ||
234 | + * MouseUp event handler on canvas | ||
235 | + * @private | ||
236 | + */ | ||
237 | + _onFabricMouseUp() { | ||
238 | + const canvas = this.getCanvas(); | ||
239 | + | ||
240 | + this.fire(events.OBJECT_ADDED, this.graphics.createObjectProperties(this._icon)); | ||
241 | + | ||
242 | + this._icon = null; | ||
243 | + | ||
244 | + canvas.off('mouse:down', this._handlers.mousedown); | ||
245 | + canvas.off('mouse:move', this._handlers.mousemove); | ||
246 | + canvas.off('mouse:up', this._handlers.mouseup); | ||
247 | + } | ||
248 | +} | ||
249 | + | ||
250 | +export default Icon; |
minsung/src/js/component/imageLoader.js
0 → 100644
1 | +/** | ||
2 | + * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> | ||
3 | + * @fileoverview Image loader | ||
4 | + */ | ||
5 | +import Component from '../interface/component'; | ||
6 | +import { componentNames, rejectMessages } from '../consts'; | ||
7 | +import { Promise } from '../util'; | ||
8 | + | ||
9 | +const imageOption = { | ||
10 | + padding: 0, | ||
11 | + crossOrigin: 'Anonymous', | ||
12 | +}; | ||
13 | + | ||
14 | +/** | ||
15 | + * ImageLoader components | ||
16 | + * @extends {Component} | ||
17 | + * @class ImageLoader | ||
18 | + * @param {Graphics} graphics - Graphics instance | ||
19 | + * @ignore | ||
20 | + */ | ||
21 | +class ImageLoader extends Component { | ||
22 | + constructor(graphics) { | ||
23 | + super(componentNames.IMAGE_LOADER, graphics); | ||
24 | + } | ||
25 | + | ||
26 | + /** | ||
27 | + * Load image from url | ||
28 | + * @param {?string} imageName - File name | ||
29 | + * @param {?(fabric.Image|string)} img - fabric.Image instance or URL of an image | ||
30 | + * @returns {Promise} | ||
31 | + */ | ||
32 | + load(imageName, img) { | ||
33 | + let promise; | ||
34 | + | ||
35 | + if (!imageName && !img) { | ||
36 | + // Back to the initial state, not error. | ||
37 | + const canvas = this.getCanvas(); | ||
38 | + | ||
39 | + canvas.backgroundImage = null; | ||
40 | + canvas.renderAll(); | ||
41 | + | ||
42 | + promise = new Promise((resolve) => { | ||
43 | + this.setCanvasImage('', null); | ||
44 | + resolve(); | ||
45 | + }); | ||
46 | + } else { | ||
47 | + promise = this._setBackgroundImage(img).then((oImage) => { | ||
48 | + this.setCanvasImage(imageName, oImage); | ||
49 | + this.adjustCanvasDimension(); | ||
50 | + | ||
51 | + return oImage; | ||
52 | + }); | ||
53 | + } | ||
54 | + | ||
55 | + return promise; | ||
56 | + } | ||
57 | + | ||
58 | + /** | ||
59 | + * Set background image | ||
60 | + * @param {?(fabric.Image|String)} img fabric.Image instance or URL of an image to set background to | ||
61 | + * @returns {Promise} | ||
62 | + * @private | ||
63 | + */ | ||
64 | + _setBackgroundImage(img) { | ||
65 | + if (!img) { | ||
66 | + return Promise.reject(rejectMessages.loadImage); | ||
67 | + } | ||
68 | + | ||
69 | + return new Promise((resolve, reject) => { | ||
70 | + const canvas = this.getCanvas(); | ||
71 | + | ||
72 | + canvas.setBackgroundImage( | ||
73 | + img, | ||
74 | + () => { | ||
75 | + const oImage = canvas.backgroundImage; | ||
76 | + | ||
77 | + if (oImage && oImage.getElement()) { | ||
78 | + resolve(oImage); | ||
79 | + } else { | ||
80 | + reject(rejectMessages.loadingImageFailed); | ||
81 | + } | ||
82 | + }, | ||
83 | + imageOption | ||
84 | + ); | ||
85 | + }); | ||
86 | + } | ||
87 | +} | ||
88 | + | ||
89 | +export default ImageLoader; |
minsung/src/js/component/line.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/component/rotation.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/component/shape.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/component/text.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/consts.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/drawingMode/cropper.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/drawingMode/freeDrawing.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/drawingMode/icon.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/drawingMode/lineDrawing.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/drawingMode/shape.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/drawingMode/text.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/extension/arrowLine.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/extension/blur.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/extension/colorFilter.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/extension/cropzone.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/extension/emboss.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/extension/mask.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/extension/sharpen.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/factory/command.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/factory/errorMessage.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/graphics.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/helper/imagetracer.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
minsung/src/js/helper/shapeResizeHelper.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/imageEditor.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/interface/command.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/interface/component.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/interface/drawingMode.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/invoker.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/polyfill.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/crop.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/draw.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/filter.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/flip.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/icon.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/locale/locale.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/mask.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/rotate.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/shape.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/submenuBase.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/template/controls.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/template/mainContainer.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/template/style.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/template/submenu/crop.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/template/submenu/draw.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/template/submenu/filter.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/template/submenu/flip.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/template/submenu/icon.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/template/submenu/mask.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/template/submenu/rotate.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/template/submenu/shape.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/template/submenu/text.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/text.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/theme/standard.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/theme/theme.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/tools/colorpicker.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/ui/tools/range.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/js/util.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/default.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-apply.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-cancel.svg
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-crop.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-delete-all.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-delete.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-draw-free.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-draw-line.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-draw.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-filter.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-flip-reset.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-flip-x.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-flip-y.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-flip.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-icon-arrow-2.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-icon-arrow-3.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-icon-arrow.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-icon-bubble.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-icon-heart.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-icon-load.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-icon-location.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-icon-polygon.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-icon-star-2.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-icon-star.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-icon.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-mask-load.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-mask.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-redo.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-reset.svg
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-rotate.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-shape-circle.svg
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-shape-triangle.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-shape.svg
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-text-bold.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-text-italic.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-text-underline.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-text.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/ic-undo.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-a/img-bi.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-apply.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-cancel.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-crop.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-delete-all.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-delete.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-draw-free.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-draw-line.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-draw.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-filter.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-flip-reset.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-flip-x.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-flip-y.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-flip.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-icon-arrow-2.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-icon-arrow-3.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-icon-arrow.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-icon-bubble.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-icon-heart.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-icon-load.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-icon-location.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-icon-polygon.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-icon-star-2.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-icon-star.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-icon.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-mask-load.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-mask.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-redo.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-reset.svg
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-rotate.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-shape-circle.svg
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-shape-triangle.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-shape.svg
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-text-bold.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-text-italic.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-text-underline.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-text.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/ic-undo.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-b/img-bi.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-apply.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-cancel.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-crop.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-delete-all.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-delete.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-draw-free.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-draw-line.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-draw.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-filter.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-flip-reset.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-flip-x.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-flip-y.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-flip.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-icon-arrow-2.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-icon-arrow-3.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-icon-arrow.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-icon-bubble.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-icon-heart.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-icon-load.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-icon-location.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-icon-polygon.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-icon-star-2.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-icon-star.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-icon.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-mask-load.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-mask.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-redo.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-reset.svg
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-rotate.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-shape-circle.svg
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-shape-triangle.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-shape.svg
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-text-bold.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-text-italic.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-text-underline.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-text.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/ic-undo.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-c/img-bi.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-apply.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-cancel.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-crop.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-delete-all.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-delete.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-draw-free.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-draw-line.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-draw.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-filter.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-flip-reset.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-flip-x.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-flip-y.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-flip.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-icon-arrow-2.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-icon-arrow-3.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-icon-arrow.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-icon-bubble.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-icon-heart.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-icon-load.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-icon-location.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-icon-polygon.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-icon-star-2.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-icon-star.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-icon.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-mask-load.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-mask.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-redo.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-reset.svg
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-rotate.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-shape-circle.svg
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-shape-triangle.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-shape.svg
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-text-bold.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-text-italic.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-text-underline.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-text.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/ic-undo.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/src/svg/icon-d/img-bi.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/.eslintrc.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/action.spec.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/arrowLine.spec.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/command.spec.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/cropper.spec.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/cropzone.spec.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/drawingMode.spec.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/filter.spec.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/fixtures/TOAST UI Component.png
0 → 100644
27.8 KB
minsung/test/fixtures/icon-a.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/fixtures/icon-b.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/fixtures/icon-c.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/fixtures/icon-d.svg
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/fixtures/mask.png
0 → 100644
24.4 KB
minsung/test/fixtures/sampleImage.jpg
0 → 100644
584 KB
minsung/test/flip.spec.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/graphics.spec.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/icon.spec.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/imageEditor.spec.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/index.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/invoker.spec.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/line.spec.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/promiseApi.spec.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/rotation.spec.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/selectionModifyHelper.spec.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/shape.spec.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/text.spec.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/theme.spec.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/types/tsconfig.json
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/types/type-tests.ts
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/ui.spec.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/test/uiRange.spec.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/tsBannerGenerator.js
0 → 100644
This diff is collapsed. Click to expand it.
minsung/tslint.json
0 → 100644
This diff is collapsed. Click to expand it.
minsung/tui.image-editor/.gitignore
0 → 100644
This diff is collapsed. Click to expand it.
minsung/tui.image-editor/package-lock.json
0 → 100644
This diff could not be displayed because it is too large.
minsung/tui.image-editor/package.json
0 → 100644
This diff is collapsed. Click to expand it.
minsung/tuidoc.config.json
0 → 100644
This diff is collapsed. Click to expand it.
minsung/webpack.config.js
0 → 100644
This diff is collapsed. Click to expand it.
-
Please register or login to post a comment