MinsoftK

redownload

Showing 276 changed files with 0 additions and 4886 deletions
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;
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;
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;
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;
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;
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;
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;
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 -
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
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 -
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;
This diff is collapsed. Click to expand it.
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
1 -/**
2 - * @author NHN. FE Development Team <dl_javascript@nhn.com>
3 - * @fileoverview Free drawing module, Set brush
4 - */
5 -import fabric from 'fabric';
6 -import snippet from 'tui-code-snippet';
7 -import Component from '../interface/component';
8 -import ArrowLine from '../extension/arrowLine';
9 -import { eventNames, componentNames, fObjectOptions } from '../consts';
10 -
11 -/**
12 - * Line
13 - * @class Line
14 - * @param {Graphics} graphics - Graphics instance
15 - * @extends {Component}
16 - * @ignore
17 - */
18 -class Line extends Component {
19 - constructor(graphics) {
20 - super(componentNames.LINE, graphics);
21 -
22 - /**
23 - * Brush width
24 - * @type {number}
25 - * @private
26 - */
27 - this._width = 12;
28 -
29 - /**
30 - * fabric.Color instance for brush color
31 - * @type {fabric.Color}
32 - * @private
33 - */
34 - this._oColor = new fabric.Color('rgba(0, 0, 0, 0.5)');
35 -
36 - /**
37 - * Listeners
38 - * @type {object.<string, function>}
39 - * @private
40 - */
41 - this._listeners = {
42 - mousedown: this._onFabricMouseDown.bind(this),
43 - mousemove: this._onFabricMouseMove.bind(this),
44 - mouseup: this._onFabricMouseUp.bind(this),
45 - };
46 - }
47 -
48 - /**
49 - * Start drawing line mode
50 - * @param {{width: ?number, color: ?string}} [setting] - Brush width & color
51 - */
52 - setHeadOption(setting) {
53 - const {
54 - arrowType = {
55 - head: null,
56 - tail: null,
57 - },
58 - } = setting;
59 -
60 - this._arrowType = arrowType;
61 - }
62 -
63 - /**
64 - * Start drawing line mode
65 - * @param {{width: ?number, color: ?string}} [setting] - Brush width & color
66 - */
67 - start(setting = {}) {
68 - const canvas = this.getCanvas();
69 -
70 - canvas.defaultCursor = 'crosshair';
71 - canvas.selection = false;
72 -
73 - this.setHeadOption(setting);
74 - this.setBrush(setting);
75 -
76 - canvas.forEachObject((obj) => {
77 - obj.set({
78 - evented: false,
79 - });
80 - });
81 -
82 - canvas.on({
83 - 'mouse:down': this._listeners.mousedown,
84 - });
85 - }
86 -
87 - /**
88 - * Set brush
89 - * @param {{width: ?number, color: ?string}} [setting] - Brush width & color
90 - */
91 - setBrush(setting) {
92 - const brush = this.getCanvas().freeDrawingBrush;
93 -
94 - setting = setting || {};
95 - this._width = setting.width || this._width;
96 -
97 - if (setting.color) {
98 - this._oColor = new fabric.Color(setting.color);
99 - }
100 - brush.width = this._width;
101 - brush.color = this._oColor.toRgba();
102 - }
103 -
104 - /**
105 - * End drawing line mode
106 - */
107 - end() {
108 - const canvas = this.getCanvas();
109 -
110 - canvas.defaultCursor = 'default';
111 - canvas.selection = true;
112 -
113 - canvas.forEachObject((obj) => {
114 - obj.set({
115 - evented: true,
116 - });
117 - });
118 -
119 - canvas.off('mouse:down', this._listeners.mousedown);
120 - }
121 -
122 - /**
123 - * Mousedown event handler in fabric canvas
124 - * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event object
125 - * @private
126 - */
127 - _onFabricMouseDown(fEvent) {
128 - const canvas = this.getCanvas();
129 - const { x, y } = canvas.getPointer(fEvent.e);
130 - const points = [x, y, x, y];
131 -
132 - this._line = new ArrowLine(points, {
133 - stroke: this._oColor.toRgba(),
134 - strokeWidth: this._width,
135 - arrowType: this._arrowType,
136 - evented: false,
137 - });
138 -
139 - this._line.set(fObjectOptions.SELECTION_STYLE);
140 -
141 - canvas.add(this._line);
142 -
143 - canvas.on({
144 - 'mouse:move': this._listeners.mousemove,
145 - 'mouse:up': this._listeners.mouseup,
146 - });
147 -
148 - this.fire(eventNames.ADD_OBJECT, this._createLineEventObjectProperties());
149 - }
150 -
151 - /**
152 - * Mousemove event handler in fabric canvas
153 - * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event object
154 - * @private
155 - */
156 - _onFabricMouseMove(fEvent) {
157 - const canvas = this.getCanvas();
158 - const pointer = canvas.getPointer(fEvent.e);
159 -
160 - this._line.set({
161 - x2: pointer.x,
162 - y2: pointer.y,
163 - });
164 -
165 - this._line.setCoords();
166 -
167 - canvas.renderAll();
168 - }
169 -
170 - /**
171 - * Mouseup event handler in fabric canvas
172 - * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event object
173 - * @private
174 - */
175 - _onFabricMouseUp() {
176 - const canvas = this.getCanvas();
177 -
178 - this.fire(eventNames.OBJECT_ADDED, this._createLineEventObjectProperties());
179 -
180 - this._line = null;
181 -
182 - canvas.off({
183 - 'mouse:move': this._listeners.mousemove,
184 - 'mouse:up': this._listeners.mouseup,
185 - });
186 - }
187 -
188 - /**
189 - * create line event object properties
190 - * @returns {Object} properties line object
191 - * @private
192 - */
193 - _createLineEventObjectProperties() {
194 - const params = this.graphics.createObjectProperties(this._line);
195 - const { x1, x2, y1, y2 } = this._line;
196 -
197 - return snippet.extend({}, params, {
198 - startPosition: {
199 - x: x1,
200 - y: y1,
201 - },
202 - endPosition: {
203 - x: x2,
204 - y: y2,
205 - },
206 - });
207 - }
208 -}
209 -
210 -export default Line;
1 -/**
2 - * @author NHN Ent. FE Development Team <dl_javascript@nhn.com>
3 - * @fileoverview Image rotation module
4 - */
5 -import fabric from 'fabric';
6 -import { Promise } from '../util';
7 -import Component from '../interface/component';
8 -import { componentNames } from '../consts';
9 -
10 -/**
11 - * Image Rotation component
12 - * @class Rotation
13 - * @extends {Component}
14 - * @param {Graphics} graphics - Graphics instance
15 - * @ignore
16 - */
17 -class Rotation extends Component {
18 - constructor(graphics) {
19 - super(componentNames.ROTATION, graphics);
20 - }
21 -
22 - /**
23 - * Get current angle
24 - * @returns {Number}
25 - */
26 - getCurrentAngle() {
27 - return this.getCanvasImage().angle;
28 - }
29 -
30 - /**
31 - * Set angle of the image
32 - *
33 - * Do not call "this.setImageProperties" for setting angle directly.
34 - * Before setting angle, The originX,Y of image should be set to center.
35 - * See "http://fabricjs.com/docs/fabric.Object.html#setAngle"
36 - *
37 - * @param {number} angle - Angle value
38 - * @returns {Promise}
39 - */
40 - setAngle(angle) {
41 - const oldAngle = this.getCurrentAngle() % 360; // The angle is lower than 2*PI(===360 degrees)
42 -
43 - angle %= 360;
44 -
45 - const canvasImage = this.getCanvasImage();
46 - const oldImageCenter = canvasImage.getCenterPoint();
47 - canvasImage.set({ angle }).setCoords();
48 - this.adjustCanvasDimension();
49 - const newImageCenter = canvasImage.getCenterPoint();
50 - this._rotateForEachObject(oldImageCenter, newImageCenter, angle - oldAngle);
51 -
52 - return Promise.resolve(angle);
53 - }
54 -
55 - /**
56 - * Rotate for each object
57 - * @param {fabric.Point} oldImageCenter - Image center point before rotation
58 - * @param {fabric.Point} newImageCenter - Image center point after rotation
59 - * @param {number} angleDiff - Image angle difference after rotation
60 - * @private
61 - */
62 - _rotateForEachObject(oldImageCenter, newImageCenter, angleDiff) {
63 - const canvas = this.getCanvas();
64 - const centerDiff = {
65 - x: oldImageCenter.x - newImageCenter.x,
66 - y: oldImageCenter.y - newImageCenter.y,
67 - };
68 -
69 - canvas.forEachObject((obj) => {
70 - const objCenter = obj.getCenterPoint();
71 - const radian = fabric.util.degreesToRadians(angleDiff);
72 - const newObjCenter = fabric.util.rotatePoint(objCenter, oldImageCenter, radian);
73 -
74 - obj.set({
75 - left: newObjCenter.x - centerDiff.x,
76 - top: newObjCenter.y - centerDiff.y,
77 - angle: (obj.angle + angleDiff) % 360,
78 - });
79 - obj.setCoords();
80 - });
81 - canvas.renderAll();
82 - }
83 -
84 - /**
85 - * Rotate the image
86 - * @param {number} additionalAngle - Additional angle
87 - * @returns {Promise}
88 - */
89 - rotate(additionalAngle) {
90 - const current = this.getCurrentAngle();
91 -
92 - return this.setAngle(current + additionalAngle);
93 - }
94 -}
95 -
96 -export default Rotation;
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 -/**
2 - * @author NHN Ent. FE Development Team <dl_javascript@nhn.com>
3 - * @fileoverview Constants
4 - */
5 -import { keyMirror } from './util';
6 -
7 -/**
8 - * Editor help features
9 - * @type {Array.<string>}
10 - */
11 -export const HELP_MENUS = ['undo', 'redo', 'reset', 'delete', 'deleteAll'];
12 -
13 -/**
14 - * Filter name value map
15 - * @type {Object.<string, string>}
16 - */
17 -export const FILTER_NAME_VALUE_MAP = {
18 - blur: 'blur',
19 - blocksize: 'pixelate',
20 -};
21 -
22 -/**
23 - * Fill type for shape
24 - * @type {Object.<string, string>}
25 - */
26 -export const SHAPE_FILL_TYPE = {
27 - FILTER: 'filter',
28 - COLOR: 'color',
29 -};
30 -
31 -/**
32 - * Shape type list
33 - * @type {Array.<string>}
34 - */
35 -export const SHAPE_TYPE = ['rect', 'circle', 'triangle'];
36 -
37 -/**
38 - * Component names
39 - * @type {Object.<string, string>}
40 - */
41 -export const componentNames = keyMirror(
42 - 'IMAGE_LOADER',
43 - 'CROPPER',
44 - 'FLIP',
45 - 'ROTATION',
46 - 'FREE_DRAWING',
47 - 'LINE',
48 - 'TEXT',
49 - 'ICON',
50 - 'FILTER',
51 - 'SHAPE'
52 -);
53 -
54 -/**
55 - * Shape default option
56 - * @type {Object}
57 - */
58 -export const SHAPE_DEFAULT_OPTIONS = {
59 - lockSkewingX: true,
60 - lockSkewingY: true,
61 - bringForward: true,
62 - isRegular: false,
63 -};
64 -
65 -/**
66 - * Cropzone default option
67 - * @type {Object}
68 - */
69 -export const CROPZONE_DEFAULT_OPTIONS = {
70 - hasRotatingPoint: false,
71 - hasBorders: false,
72 - lockScalingFlip: true,
73 - lockRotation: true,
74 - lockSkewingX: true,
75 - lockSkewingY: true,
76 -};
77 -
78 -/**
79 - * Command names
80 - * @type {Object.<string, string>}
81 - */
82 -export const commandNames = {
83 - CLEAR_OBJECTS: 'clearObjects',
84 - LOAD_IMAGE: 'loadImage',
85 - FLIP_IMAGE: 'flip',
86 - ROTATE_IMAGE: 'rotate',
87 - ADD_OBJECT: 'addObject',
88 - REMOVE_OBJECT: 'removeObject',
89 - APPLY_FILTER: 'applyFilter',
90 - REMOVE_FILTER: 'removeFilter',
91 - ADD_ICON: 'addIcon',
92 - CHANGE_ICON_COLOR: 'changeIconColor',
93 - ADD_SHAPE: 'addShape',
94 - CHANGE_SHAPE: 'changeShape',
95 - ADD_TEXT: 'addText',
96 - CHANGE_TEXT: 'changeText',
97 - CHANGE_TEXT_STYLE: 'changeTextStyle',
98 - ADD_IMAGE_OBJECT: 'addImageObject',
99 - RESIZE_CANVAS_DIMENSION: 'resizeCanvasDimension',
100 - SET_OBJECT_PROPERTIES: 'setObjectProperties',
101 - SET_OBJECT_POSITION: 'setObjectPosition',
102 - CHANGE_SELECTION: 'changeSelection',
103 -};
104 -
105 -/**
106 - * Event names
107 - * @type {Object.<string, string>}
108 - */
109 -export const eventNames = {
110 - OBJECT_ACTIVATED: 'objectActivated',
111 - OBJECT_MOVED: 'objectMoved',
112 - OBJECT_SCALED: 'objectScaled',
113 - OBJECT_CREATED: 'objectCreated',
114 - OBJECT_ROTATED: 'objectRotated',
115 - OBJECT_ADDED: 'objectAdded',
116 - OBJECT_MODIFIED: 'objectModified',
117 - TEXT_EDITING: 'textEditing',
118 - TEXT_CHANGED: 'textChanged',
119 - ICON_CREATE_RESIZE: 'iconCreateResize',
120 - ICON_CREATE_END: 'iconCreateEnd',
121 - ADD_TEXT: 'addText',
122 - ADD_OBJECT: 'addObject',
123 - ADD_OBJECT_AFTER: 'addObjectAfter',
124 - MOUSE_DOWN: 'mousedown',
125 - MOUSE_UP: 'mouseup',
126 - MOUSE_MOVE: 'mousemove',
127 - // UNDO/REDO Events
128 - REDO_STACK_CHANGED: 'redoStackChanged',
129 - UNDO_STACK_CHANGED: 'undoStackChanged',
130 - SELECTION_CLEARED: 'selectionCleared',
131 - SELECTION_CREATED: 'selectionCreated',
132 -};
133 -
134 -/**
135 - * Editor states
136 - * @type {Object.<string, string>}
137 - */
138 -export const drawingModes = keyMirror(
139 - 'NORMAL',
140 - 'CROPPER',
141 - 'FREE_DRAWING',
142 - 'LINE_DRAWING',
143 - 'TEXT',
144 - 'SHAPE',
145 - 'ICON'
146 -);
147 -
148 -/**
149 - * Shortcut key values
150 - * @type {Object.<string, number>}
151 - */
152 -export const keyCodes = {
153 - Z: 90,
154 - Y: 89,
155 - C: 67,
156 - V: 86,
157 - SHIFT: 16,
158 - BACKSPACE: 8,
159 - DEL: 46,
160 - ARROW_DOWN: 40,
161 - ARROW_UP: 38,
162 -};
163 -
164 -/**
165 - * Fabric object options
166 - * @type {Object.<string, Object>}
167 - */
168 -export const fObjectOptions = {
169 - SELECTION_STYLE: {
170 - borderColor: 'red',
171 - cornerColor: 'green',
172 - cornerSize: 10,
173 - originX: 'center',
174 - originY: 'center',
175 - transparentCorners: false,
176 - },
177 -};
178 -
179 -/**
180 - * Promise reject messages
181 - * @type {Object.<string, string>}
182 - */
183 -export const rejectMessages = {
184 - addedObject: 'The object is already added.',
185 - flip: 'The flipX and flipY setting values are not changed.',
186 - invalidDrawingMode: 'This operation is not supported in the drawing mode.',
187 - invalidParameters: 'Invalid parameters.',
188 - isLock: 'The executing command state is locked.',
189 - loadImage: 'The background image is empty.',
190 - loadingImageFailed: 'Invalid image loaded.',
191 - noActiveObject: 'There is no active object.',
192 - noObject: 'The object is not in canvas.',
193 - redo: 'The promise of redo command is reject.',
194 - rotation: 'The current angle is same the old angle.',
195 - undo: 'The promise of undo command is reject.',
196 - unsupportedOperation: 'Unsupported operation.',
197 - unsupportedType: 'Unsupported object type.',
198 -};
199 -
200 -/**
201 - * Default icon menu svg path
202 - * @type {Object.<string, string>}
203 - */
204 -export const defaultIconPath = {
205 - 'icon-arrow': 'M40 12V0l24 24-24 24V36H0V12h40z',
206 - 'icon-arrow-2': 'M49,32 H3 V22 h46 l-18,-18 h12 l23,23 L43,50 h-12 l18,-18 z ',
207 - 'icon-arrow-3':
208 - 'M43.349998,27 L17.354,53 H1.949999 l25.996,-26 L1.949999,1 h15.404 L43.349998,27 z ',
209 - 'icon-star':
210 - 'M35,54.557999 l-19.912001,10.468 l3.804,-22.172001 l-16.108,-15.7 l22.26,-3.236 L35,3.746 l9.956,20.172001 l22.26,3.236 l-16.108,15.7 l3.804,22.172001 z ',
211 - 'icon-star-2':
212 - 'M17,31.212 l-7.194,4.08 l-4.728,-6.83 l-8.234,0.524 l-1.328,-8.226 l-7.644,-3.14 l2.338,-7.992 l-5.54,-6.18 l5.54,-6.176 l-2.338,-7.994 l7.644,-3.138 l1.328,-8.226 l8.234,0.522 l4.728,-6.83 L17,-24.312 l7.194,-4.08 l4.728,6.83 l8.234,-0.522 l1.328,8.226 l7.644,3.14 l-2.338,7.992 l5.54,6.178 l-5.54,6.178 l2.338,7.992 l-7.644,3.14 l-1.328,8.226 l-8.234,-0.524 l-4.728,6.83 z ',
213 - 'icon-polygon': 'M3,31 L19,3 h32 l16,28 l-16,28 H19 z ',
214 - 'icon-location':
215 - 'M24 62C8 45.503 0 32.837 0 24 0 10.745 10.745 0 24 0s24 10.745 24 24c0 8.837-8 21.503-24 38zm0-28c5.523 0 10-4.477 10-10s-4.477-10-10-10-10 4.477-10 10 4.477 10 10 10z',
216 - 'icon-heart':
217 - 'M49.994999,91.349998 l-6.96,-6.333 C18.324001,62.606995 2.01,47.829002 2.01,29.690998 C2.01,14.912998 13.619999,3.299999 28.401001,3.299999 c8.349,0 16.362,5.859 21.594,12 c5.229,-6.141 13.242001,-12 21.591,-12 c14.778,0 26.390999,11.61 26.390999,26.390999 c0,18.138 -16.314001,32.916 -41.025002,55.374001 l-6.96,6.285 z ',
218 - 'icon-bubble':
219 - 'M44 48L34 58V48H12C5.373 48 0 42.627 0 36V12C0 5.373 5.373 0 12 0h40c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12h-8z',
220 -};
221 -
222 -export const defaultRotateRangeValus = {
223 - realTimeEvent: true,
224 - min: -360,
225 - max: 360,
226 - value: 0,
227 -};
228 -
229 -export const defaultDrawRangeValus = {
230 - min: 5,
231 - max: 30,
232 - value: 12,
233 -};
234 -
235 -export const defaultShapeStrokeValus = {
236 - realTimeEvent: true,
237 - min: 2,
238 - max: 300,
239 - value: 3,
240 -};
241 -
242 -export const defaultTextRangeValus = {
243 - realTimeEvent: true,
244 - min: 10,
245 - max: 100,
246 - value: 50,
247 -};
248 -
249 -export const defaultFilterRangeValus = {
250 - tintOpacityRange: {
251 - realTimeEvent: true,
252 - min: 0,
253 - max: 1,
254 - value: 0.7,
255 - useDecimal: true,
256 - },
257 - removewhiteDistanceRange: {
258 - realTimeEvent: true,
259 - min: 0,
260 - max: 1,
261 - value: 0.2,
262 - useDecimal: true,
263 - },
264 - brightnessRange: {
265 - realTimeEvent: true,
266 - min: -1,
267 - max: 1,
268 - value: 0,
269 - useDecimal: true,
270 - },
271 - noiseRange: {
272 - realTimeEvent: true,
273 - min: 0,
274 - max: 1000,
275 - value: 100,
276 - },
277 - pixelateRange: {
278 - realTimeEvent: true,
279 - min: 2,
280 - max: 20,
281 - value: 4,
282 - },
283 - colorfilterThresholeRange: {
284 - realTimeEvent: true,
285 - min: 0,
286 - max: 1,
287 - value: 0.2,
288 - useDecimal: true,
289 - },
290 - blurFilterRange: {
291 - value: 0.1,
292 - },
293 -};
1 -/**
2 - * @author NHN Ent. FE Development Team <dl_javascript@nhn.com>
3 - * @fileoverview CropperDrawingMode class
4 - */
5 -import DrawingMode from '../interface/drawingMode';
6 -import { drawingModes, componentNames as components } from '../consts';
7 -
8 -/**
9 - * CropperDrawingMode class
10 - * @class
11 - * @ignore
12 - */
13 -class CropperDrawingMode extends DrawingMode {
14 - constructor() {
15 - super(drawingModes.CROPPER);
16 - }
17 -
18 - /**
19 - * start this drawing mode
20 - * @param {Graphics} graphics - Graphics instance
21 - * @override
22 - */
23 - start(graphics) {
24 - const cropper = graphics.getComponent(components.CROPPER);
25 - cropper.start();
26 - }
27 -
28 - /**
29 - * stop this drawing mode
30 - * @param {Graphics} graphics - Graphics instance
31 - * @override
32 - */
33 - end(graphics) {
34 - const cropper = graphics.getComponent(components.CROPPER);
35 - cropper.end();
36 - }
37 -}
38 -
39 -export default CropperDrawingMode;
1 -/**
2 - * @author NHN Ent. FE Development Team <dl_javascript@nhn.com>
3 - * @fileoverview FreeDrawingMode class
4 - */
5 -import DrawingMode from '../interface/drawingMode';
6 -import { drawingModes, componentNames as components } from '../consts';
7 -
8 -/**
9 - * FreeDrawingMode class
10 - * @class
11 - * @ignore
12 - */
13 -class FreeDrawingMode extends DrawingMode {
14 - constructor() {
15 - super(drawingModes.FREE_DRAWING);
16 - }
17 -
18 - /**
19 - * start this drawing mode
20 - * @param {Graphics} graphics - Graphics instance
21 - * @param {{width: ?number, color: ?string}} [options] - Brush width & color
22 - * @override
23 - */
24 - start(graphics, options) {
25 - const freeDrawing = graphics.getComponent(components.FREE_DRAWING);
26 - freeDrawing.start(options);
27 - }
28 -
29 - /**
30 - * stop this drawing mode
31 - * @param {Graphics} graphics - Graphics instance
32 - * @override
33 - */
34 - end(graphics) {
35 - const freeDrawing = graphics.getComponent(components.FREE_DRAWING);
36 - freeDrawing.end();
37 - }
38 -}
39 -
40 -export default FreeDrawingMode;
1 -/**
2 - * @author NHN Ent. FE Development Team <dl_javascript@nhn.com>
3 - * @fileoverview IconDrawingMode class
4 - */
5 -import DrawingMode from '../interface/drawingMode';
6 -import { drawingModes, componentNames as components } from '../consts';
7 -
8 -/**
9 - * IconDrawingMode class
10 - * @class
11 - * @ignore
12 - */
13 -class IconDrawingMode extends DrawingMode {
14 - constructor() {
15 - super(drawingModes.ICON);
16 - }
17 -
18 - /**
19 - * start this drawing mode
20 - * @param {Graphics} graphics - Graphics instance
21 - * @override
22 - */
23 - start(graphics) {
24 - const icon = graphics.getComponent(components.ICON);
25 - icon.start();
26 - }
27 -
28 - /**
29 - * stop this drawing mode
30 - * @param {Graphics} graphics - Graphics instance
31 - * @override
32 - */
33 - end(graphics) {
34 - const icon = graphics.getComponent(components.ICON);
35 - icon.end();
36 - }
37 -}
38 -
39 -export default IconDrawingMode;
1 -/**
2 - * @author NHN Ent. FE Development Team <dl_javascript@nhn.com>
3 - * @fileoverview LineDrawingMode class
4 - */
5 -import DrawingMode from '../interface/drawingMode';
6 -import { drawingModes, componentNames as components } from '../consts';
7 -
8 -/**
9 - * LineDrawingMode class
10 - * @class
11 - * @ignore
12 - */
13 -class LineDrawingMode extends DrawingMode {
14 - constructor() {
15 - super(drawingModes.LINE_DRAWING);
16 - }
17 -
18 - /**
19 - * start this drawing mode
20 - * @param {Graphics} graphics - Graphics instance
21 - * @param {{width: ?number, color: ?string}} [options] - Brush width & color
22 - * @override
23 - */
24 - start(graphics, options) {
25 - const lineDrawing = graphics.getComponent(components.LINE);
26 - lineDrawing.start(options);
27 - }
28 -
29 - /**
30 - * stop this drawing mode
31 - * @param {Graphics} graphics - Graphics instance
32 - * @override
33 - */
34 - end(graphics) {
35 - const lineDrawing = graphics.getComponent(components.LINE);
36 - lineDrawing.end();
37 - }
38 -}
39 -
40 -export default LineDrawingMode;
1 -/**
2 - * @author NHN Ent. FE Development Team <dl_javascript@nhn.com>
3 - * @fileoverview ShapeDrawingMode class
4 - */
5 -import DrawingMode from '../interface/drawingMode';
6 -import { drawingModes, componentNames as components } from '../consts';
7 -
8 -/**
9 - * ShapeDrawingMode class
10 - * @class
11 - * @ignore
12 - */
13 -class ShapeDrawingMode extends DrawingMode {
14 - constructor() {
15 - super(drawingModes.SHAPE);
16 - }
17 -
18 - /**
19 - * start this drawing mode
20 - * @param {Graphics} graphics - Graphics instance
21 - * @override
22 - */
23 - start(graphics) {
24 - const shape = graphics.getComponent(components.SHAPE);
25 - shape.start();
26 - }
27 -
28 - /**
29 - * stop this drawing mode
30 - * @param {Graphics} graphics - Graphics instance
31 - * @override
32 - */
33 - end(graphics) {
34 - const shape = graphics.getComponent(components.SHAPE);
35 - shape.end();
36 - }
37 -}
38 -
39 -export default ShapeDrawingMode;
1 -/**
2 - * @author NHN Ent. FE Development Team <dl_javascript@nhn.com>
3 - * @fileoverview TextDrawingMode class
4 - */
5 -import DrawingMode from '../interface/drawingMode';
6 -import { drawingModes, componentNames as components } from '../consts';
7 -
8 -/**
9 - * TextDrawingMode class
10 - * @class
11 - * @ignore
12 - */
13 -class TextDrawingMode extends DrawingMode {
14 - constructor() {
15 - super(drawingModes.TEXT);
16 - }
17 -
18 - /**
19 - * start this drawing mode
20 - * @param {Graphics} graphics - Graphics instance
21 - * @override
22 - */
23 - start(graphics) {
24 - const text = graphics.getComponent(components.TEXT);
25 - text.start();
26 - }
27 -
28 - /**
29 - * stop this drawing mode
30 - * @param {Graphics} graphics - Graphics instance
31 - * @override
32 - */
33 - end(graphics) {
34 - const text = graphics.getComponent(components.TEXT);
35 - text.end();
36 - }
37 -}
38 -
39 -export default TextDrawingMode;
1 -/**
2 - * @author NHN. FE Development Team <dl_javascript@nhn.com>
3 - * @fileoverview Blur extending fabric.Image.filters.Convolute
4 - */
5 -import fabric from 'fabric';
6 -
7 -const ARROW_ANGLE = 30;
8 -const CHEVRON_SIZE_RATIO = 2.7;
9 -const TRIANGLE_SIZE_RATIO = 1.7;
10 -const RADIAN_CONVERSION_VALUE = 180;
11 -
12 -const ArrowLine = fabric.util.createClass(
13 - fabric.Line,
14 - /** @lends Convolute.prototype */ {
15 - /**
16 - * Line type
17 - * @param {String} type
18 - * @default
19 - */
20 - type: 'line',
21 -
22 - /**
23 - * Constructor
24 - * @param {Array} [points] Array of points
25 - * @param {Object} [options] Options object
26 - * @override
27 - */
28 - initialize(points, options = {}) {
29 - this.callSuper('initialize', points, options);
30 -
31 - this.arrowType = options.arrowType;
32 - },
33 -
34 - /**
35 - * Render ArrowLine
36 - * @private
37 - * @override
38 - */
39 - _render(ctx) {
40 - const { x1: fromX, y1: fromY, x2: toX, y2: toY } = this.calcLinePoints();
41 - const linePosition = {
42 - fromX,
43 - fromY,
44 - toX,
45 - toY,
46 - };
47 - this.ctx = ctx;
48 - ctx.lineWidth = this.strokeWidth;
49 -
50 - this._renderBasicLinePath(linePosition);
51 - this._drawDecoratorPath(linePosition);
52 -
53 - this._renderStroke(ctx);
54 - },
55 -
56 - /**
57 - * Render Basic line path
58 - * @param {Object} linePosition - line position
59 - * @param {number} option.fromX - line start position x
60 - * @param {number} option.fromY - line start position y
61 - * @param {number} option.toX - line end position x
62 - * @param {number} option.toY - line end position y
63 - * @private
64 - */
65 - _renderBasicLinePath({ fromX, fromY, toX, toY }) {
66 - this.ctx.beginPath();
67 - this.ctx.moveTo(fromX, fromY);
68 - this.ctx.lineTo(toX, toY);
69 - },
70 -
71 - /**
72 - * Render Arrow Head
73 - * @param {Object} linePosition - line position
74 - * @param {number} option.fromX - line start position x
75 - * @param {number} option.fromY - line start position y
76 - * @param {number} option.toX - line end position x
77 - * @param {number} option.toY - line end position y
78 - * @private
79 - */
80 - _drawDecoratorPath(linePosition) {
81 - this._drawDecoratorPathType('head', linePosition);
82 - this._drawDecoratorPathType('tail', linePosition);
83 - },
84 -
85 - /**
86 - * Render Arrow Head
87 - * @param {string} type - 'head' or 'tail'
88 - * @param {Object} linePosition - line position
89 - * @param {number} option.fromX - line start position x
90 - * @param {number} option.fromY - line start position y
91 - * @param {number} option.toX - line end position x
92 - * @param {number} option.toY - line end position y
93 - * @private
94 - */
95 - _drawDecoratorPathType(type, linePosition) {
96 - switch (this.arrowType[type]) {
97 - case 'triangle':
98 - this._drawTrianglePath(type, linePosition);
99 - break;
100 - case 'chevron':
101 - this._drawChevronPath(type, linePosition);
102 - break;
103 - default:
104 - break;
105 - }
106 - },
107 -
108 - /**
109 - * Render Triangle Head
110 - * @param {string} type - 'head' or 'tail'
111 - * @param {Object} linePosition - line position
112 - * @param {number} option.fromX - line start position x
113 - * @param {number} option.fromY - line start position y
114 - * @param {number} option.toX - line end position x
115 - * @param {number} option.toY - line end position y
116 - * @private
117 - */
118 - _drawTrianglePath(type, linePosition) {
119 - const decorateSize = this.ctx.lineWidth * TRIANGLE_SIZE_RATIO;
120 -
121 - this._drawChevronPath(type, linePosition, decorateSize);
122 - this.ctx.closePath();
123 - },
124 -
125 - /**
126 - * Render Chevron Head
127 - * @param {string} type - 'head' or 'tail'
128 - * @param {Object} linePosition - line position
129 - * @param {number} option.fromX - line start position x
130 - * @param {number} option.fromY - line start position y
131 - * @param {number} option.toX - line end position x
132 - * @param {number} option.toY - line end position y
133 - * @param {number} decorateSize - decorate size
134 - * @private
135 - */
136 - _drawChevronPath(type, { fromX, fromY, toX, toY }, decorateSize) {
137 - const { ctx } = this;
138 - if (!decorateSize) {
139 - decorateSize = this.ctx.lineWidth * CHEVRON_SIZE_RATIO;
140 - }
141 -
142 - const [standardX, standardY] = type === 'head' ? [fromX, fromY] : [toX, toY];
143 - const [compareX, compareY] = type === 'head' ? [toX, toY] : [fromX, fromY];
144 -
145 - const angle =
146 - (Math.atan2(compareY - standardY, compareX - standardX) * RADIAN_CONVERSION_VALUE) /
147 - Math.PI;
148 - const rotatedPosition = (changeAngle) =>
149 - this.getRotatePosition(decorateSize, changeAngle, {
150 - x: standardX,
151 - y: standardY,
152 - });
153 -
154 - ctx.moveTo(...rotatedPosition(angle + ARROW_ANGLE));
155 - ctx.lineTo(standardX, standardY);
156 - ctx.lineTo(...rotatedPosition(angle - ARROW_ANGLE));
157 - },
158 -
159 - /**
160 - * return position from change angle.
161 - * @param {number} distance - change distance
162 - * @param {number} angle - change angle
163 - * @param {Object} referencePosition - reference position
164 - * @returns {Array}
165 - * @private
166 - */
167 - getRotatePosition(distance, angle, referencePosition) {
168 - const radian = (angle * Math.PI) / RADIAN_CONVERSION_VALUE;
169 - const { x, y } = referencePosition;
170 -
171 - return [distance * Math.cos(radian) + x, distance * Math.sin(radian) + y];
172 - },
173 - }
174 -);
175 -
176 -export default ArrowLine;
1 -/**
2 - * @author NHN Ent. FE Development Team <dl_javascript@nhn.com>
3 - * @fileoverview Blur extending fabric.Image.filters.Convolute
4 - */
5 -import fabric from 'fabric';
6 -
7 -/**
8 - * Blur object
9 - * @class Blur
10 - * @extends {fabric.Image.filters.Convolute}
11 - * @ignore
12 - */
13 -const Blur = fabric.util.createClass(
14 - fabric.Image.filters.Convolute,
15 - /** @lends Convolute.prototype */ {
16 - /**
17 - * Filter type
18 - * @param {String} type
19 - * @default
20 - */
21 - type: 'Blur',
22 -
23 - /**
24 - * constructor
25 - * @override
26 - */
27 - initialize() {
28 - this.matrix = [1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9];
29 - },
30 - }
31 -);
32 -
33 -export default Blur;
1 -/**
2 - * @author NHN Ent. FE Development Team <dl_javascript@nhn.com>
3 - * @fileoverview ColorFilter extending fabric.Image.filters.BaseFilter
4 - */
5 -import fabric from 'fabric';
6 -
7 -/**
8 - * ColorFilter object
9 - * @class ColorFilter
10 - * @extends {fabric.Image.filters.BaseFilter}
11 - * @ignore
12 - */
13 -const ColorFilter = fabric.util.createClass(
14 - fabric.Image.filters.BaseFilter,
15 - /** @lends BaseFilter.prototype */ {
16 - /**
17 - * Filter type
18 - * @param {String} type
19 - * @default
20 - */
21 - type: 'ColorFilter',
22 -
23 - /**
24 - * Constructor
25 - * @member fabric.Image.filters.ColorFilter.prototype
26 - * @param {Object} [options] Options object
27 - * @param {Number} [options.color='#FFFFFF'] Value of color (0...255)
28 - * @param {Number} [options.threshold=45] Value of threshold (0...255)
29 - * @override
30 - */
31 - initialize(options) {
32 - if (!options) {
33 - options = {};
34 - }
35 - this.color = options.color || '#FFFFFF';
36 - this.threshold = options.threshold || 45;
37 - this.x = options.x || null;
38 - this.y = options.y || null;
39 - },
40 -
41 - /**
42 - * Applies filter to canvas element
43 - * @param {Object} canvas Canvas object passed by fabric
44 - */
45 - // eslint-disable-next-line complexity
46 - applyTo(canvas) {
47 - const { canvasEl } = canvas;
48 - const context = canvasEl.getContext('2d');
49 - const imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height);
50 - const { data } = imageData;
51 - const { threshold } = this;
52 - let filterColor = fabric.Color.sourceFromHex(this.color);
53 - let i, len;
54 -
55 - if (this.x && this.y) {
56 - filterColor = this._getColor(imageData, this.x, this.y);
57 - }
58 -
59 - for (i = 0, len = data.length; i < len; i += 4) {
60 - if (
61 - this._isOutsideThreshold(data[i], filterColor[0], threshold) ||
62 - this._isOutsideThreshold(data[i + 1], filterColor[1], threshold) ||
63 - this._isOutsideThreshold(data[i + 2], filterColor[2], threshold)
64 - ) {
65 - continue;
66 - }
67 - data[i] = data[i + 1] = data[i + 2] = data[i + 3] = 0;
68 - }
69 - context.putImageData(imageData, 0, 0);
70 - },
71 -
72 - /**
73 - * Check color if it is within threshold
74 - * @param {Number} color1 source color
75 - * @param {Number} color2 filtering color
76 - * @param {Number} threshold threshold
77 - * @returns {boolean} true if within threshold or false
78 - */
79 - _isOutsideThreshold(color1, color2, threshold) {
80 - const diff = color1 - color2;
81 -
82 - return Math.abs(diff) > threshold;
83 - },
84 -
85 - /**
86 - * Get color at (x, y)
87 - * @param {Object} imageData of canvas
88 - * @param {Number} x left position
89 - * @param {Number} y top position
90 - * @returns {Array} color array
91 - */
92 - _getColor(imageData, x, y) {
93 - const color = [0, 0, 0, 0];
94 - const { data, width } = imageData;
95 - const bytes = 4;
96 - const position = (width * y + x) * bytes;
97 -
98 - color[0] = data[position];
99 - color[1] = data[position + 1];
100 - color[2] = data[position + 2];
101 - color[3] = data[position + 3];
102 -
103 - return color;
104 - },
105 - }
106 -);
107 -
108 -export default ColorFilter;
This diff is collapsed. Click to expand it.
1 -/**
2 - * @author NHN Ent. FE Development Team <dl_javascript@nhn.com>
3 - * @fileoverview Emboss extending fabric.Image.filters.Convolute
4 - */
5 -import fabric from 'fabric';
6 -
7 -/**
8 - * Emboss object
9 - * @class Emboss
10 - * @extends {fabric.Image.filters.Convolute}
11 - * @ignore
12 - */
13 -const Emboss = fabric.util.createClass(
14 - fabric.Image.filters.Convolute,
15 - /** @lends Convolute.prototype */ {
16 - /**
17 - * Filter type
18 - * @param {String} type
19 - * @default
20 - */
21 - type: 'Emboss',
22 -
23 - /**
24 - * constructor
25 - * @override
26 - */
27 - initialize() {
28 - const matrix = [1, 1, 1, 1, 0.7, -1, -1, -1, -1];
29 - this.matrix = matrix;
30 - },
31 - }
32 -);
33 -
34 -export default Emboss;
1 -/**
2 - * @author NHN Ent. FE Development Team <dl_javascript@nhn.com>
3 - * @fileoverview Mask extending fabric.Image.filters.Mask
4 - */
5 -import fabric from 'fabric';
6 -
7 -/**
8 - * Mask object
9 - * @class Mask
10 - * @extends {fabric.Image.filters.BlendImage}
11 - * @ignore
12 - */
13 -const Mask = fabric.util.createClass(
14 - fabric.Image.filters.BlendImage,
15 - /** @lends Mask.prototype */ {
16 - /**
17 - * Apply filter to canvas element
18 - * @param {Object} pipelineState - Canvas element to apply filter
19 - * @override
20 - */
21 - applyTo(pipelineState) {
22 - if (!this.mask) {
23 - return;
24 - }
25 -
26 - const canvas = pipelineState.canvasEl;
27 - const { width, height } = canvas;
28 - const maskCanvasEl = this._createCanvasOfMask(width, height);
29 - const ctx = canvas.getContext('2d');
30 - const maskCtx = maskCanvasEl.getContext('2d');
31 - const imageData = ctx.getImageData(0, 0, width, height);
32 -
33 - this._drawMask(maskCtx, canvas, ctx);
34 - this._mapData(maskCtx, imageData, width, height);
35 -
36 - pipelineState.imageData = imageData;
37 - },
38 -
39 - /**
40 - * Create canvas of mask image
41 - * @param {number} width - Width of main canvas
42 - * @param {number} height - Height of main canvas
43 - * @returns {HTMLElement} Canvas element
44 - * @private
45 - */
46 - _createCanvasOfMask(width, height) {
47 - const maskCanvasEl = fabric.util.createCanvasElement();
48 -
49 - maskCanvasEl.width = width;
50 - maskCanvasEl.height = height;
51 -
52 - return maskCanvasEl;
53 - },
54 -
55 - /**
56 - * Draw mask image on canvas element
57 - * @param {Object} maskCtx - Context of mask canvas
58 - * @private
59 - */
60 - _drawMask(maskCtx) {
61 - const { mask } = this;
62 - const maskImg = mask.getElement();
63 - const { angle, left, scaleX, scaleY, top } = mask;
64 -
65 - maskCtx.save();
66 - maskCtx.translate(left, top);
67 - maskCtx.rotate((angle * Math.PI) / 180);
68 - maskCtx.scale(scaleX, scaleY);
69 - maskCtx.drawImage(maskImg, -maskImg.width / 2, -maskImg.height / 2);
70 - maskCtx.restore();
71 - },
72 -
73 - /**
74 - * Map mask image data to source image data
75 - * @param {Object} maskCtx - Context of mask canvas
76 - * @param {Object} imageData - Data of source image
77 - * @param {number} width - Width of main canvas
78 - * @param {number} height - Height of main canvas
79 - * @private
80 - */
81 - _mapData(maskCtx, imageData, width, height) {
82 - const { data, height: imgHeight, width: imgWidth } = imageData;
83 - const sourceData = data;
84 - const len = imgWidth * imgHeight * 4;
85 - const maskData = maskCtx.getImageData(0, 0, width, height).data;
86 -
87 - for (let i = 0; i < len; i += 4) {
88 - sourceData[i + 3] = maskData[i]; // adjust value of alpha data
89 - }
90 - },
91 - }
92 -);
93 -
94 -export default Mask;
1 -/**
2 - * @author NHN Ent. FE Development Team <dl_javascript@nhn.com>
3 - * @fileoverview Sharpen extending fabric.Image.filters.Convolute
4 - */
5 -import fabric from 'fabric';
6 -
7 -/**
8 - * Sharpen object
9 - * @class Sharpen
10 - * @extends {fabric.Image.filters.Convolute}
11 - * @ignore
12 - */
13 -const Sharpen = fabric.util.createClass(
14 - fabric.Image.filters.Convolute,
15 - /** @lends Convolute.prototype */ {
16 - /**
17 - * Filter type
18 - * @param {String} type
19 - * @default
20 - */
21 - type: 'Sharpen',
22 -
23 - /**
24 - * constructor
25 - * @override
26 - */
27 - initialize() {
28 - const matrix = [0, -1, 0, -1, 5, -1, 0, -1, 0];
29 - this.matrix = matrix;
30 - },
31 - }
32 -);
33 -
34 -export default Sharpen;
1 -/**
2 - * @author NHN Ent. FE Development Team <dl_javascript@nhn.com>
3 - * @fileoverview Command factory
4 - */
5 -import Command from '../interface/command';
6 -
7 -const commands = {};
8 -
9 -/**
10 - * Create a command
11 - * @param {string} name - Command name
12 - * @param {...*} args - Arguments for creating command
13 - * @returns {Command}
14 - * @ignore
15 - */
16 -function create(name, ...args) {
17 - const actions = commands[name];
18 - if (actions) {
19 - return new Command(actions, args);
20 - }
21 -
22 - return null;
23 -}
24 -
25 -/**
26 - * Register a command with name as a key
27 - * @param {Object} command - {name:{string}, execute: {function}, undo: {function}}
28 - * @param {string} command.name - command name
29 - * @param {function} command.execute - executable function
30 - * @param {function} command.undo - undo function
31 - * @ignore
32 - */
33 -function register(command) {
34 - commands[command.name] = command;
35 -}
36 -
37 -export default {
38 - create,
39 - register,
40 -};
1 -/**
2 - * @author NHN Ent. FE Development Team <dl_javascript@nhn.com>
3 - * @fileoverview Error-message factory
4 - */
5 -import snippet from 'tui-code-snippet';
6 -import { keyMirror } from '../util';
7 -
8 -const types = keyMirror('UN_IMPLEMENTATION', 'NO_COMPONENT_NAME');
9 -const messages = {
10 - UN_IMPLEMENTATION: 'Should implement a method: ',
11 - NO_COMPONENT_NAME: 'Should set a component name',
12 -};
13 -const map = {
14 - UN_IMPLEMENTATION(methodName) {
15 - return messages.UN_IMPLEMENTATION + methodName;
16 - },
17 - NO_COMPONENT_NAME() {
18 - return messages.NO_COMPONENT_NAME;
19 - },
20 -};
21 -
22 -export default {
23 - types: snippet.extend({}, types),
24 -
25 - create(type, ...args) {
26 - type = type.toLowerCase();
27 - const func = map[type];
28 -
29 - return func(...args);
30 - },
31 -};
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 -/**
2 - * @author NHN. FE Development Team <dl_javascript@nhn.com>
3 - * @fileoverview Selection modification helper
4 - */
5 -
6 -import { extend } from 'tui-code-snippet/src/js/object';
7 -
8 -/**
9 - * Cached selection's info
10 - * @type {Array}
11 - * @private
12 - */
13 -let cachedUndoDataForChangeDimension = null;
14 -
15 -/**
16 - * Set cached undo data
17 - * @param {Array} undoData - selection object
18 - * @private
19 - */
20 -export function setCachedUndoDataForDimension(undoData) {
21 - cachedUndoDataForChangeDimension = undoData;
22 -}
23 -
24 -/**
25 - * Get cached undo data
26 - * @returns {Object} cached undo data
27 - * @private
28 - */
29 -export function getCachedUndoDataForDimension() {
30 - return cachedUndoDataForChangeDimension;
31 -}
32 -
33 -/**
34 - * Make undo data
35 - * @param {fabric.Object} obj - selection object
36 - * @param {Function} undoDatumMaker - make undo datum
37 - * @returns {Array} undoData
38 - * @private
39 - */
40 -export function makeSelectionUndoData(obj, undoDatumMaker) {
41 - let undoData;
42 -
43 - if (obj.type === 'activeSelection') {
44 - undoData = obj.getObjects().map((item) => {
45 - const { angle, left, top, scaleX, scaleY, width, height } = item;
46 -
47 - obj.realizeTransform(item);
48 - const result = undoDatumMaker(item);
49 -
50 - item.set({
51 - angle,
52 - left,
53 - top,
54 - width,
55 - height,
56 - scaleX,
57 - scaleY,
58 - });
59 -
60 - return result;
61 - });
62 - } else {
63 - undoData = [undoDatumMaker(obj)];
64 - }
65 -
66 - return undoData;
67 -}
68 -
69 -/**
70 - * Make undo datum
71 - * @param {number} id - object id
72 - * @param {fabric.Object} obj - selection object
73 - * @param {boolean} isSelection - whether or not object is selection
74 - * @returns {Object} undo datum
75 - * @private
76 - */
77 -export function makeSelectionUndoDatum(id, obj, isSelection) {
78 - return isSelection
79 - ? {
80 - id,
81 - width: obj.width,
82 - height: obj.height,
83 - top: obj.top,
84 - left: obj.left,
85 - angle: obj.angle,
86 - scaleX: obj.scaleX,
87 - scaleY: obj.scaleY,
88 - }
89 - : extend({ id }, obj);
90 -}
This diff is collapsed. Click to expand it.
1 -/**
2 - * @author NHN Ent. FE Development Team <dl_javascript@nhn.com>
3 - * @fileoverview Shape resize helper
4 - */
5 -const DIVISOR = {
6 - rect: 1,
7 - circle: 2,
8 - triangle: 1,
9 -};
10 -const DIMENSION_KEYS = {
11 - rect: {
12 - w: 'width',
13 - h: 'height',
14 - },
15 - circle: {
16 - w: 'rx',
17 - h: 'ry',
18 - },
19 - triangle: {
20 - w: 'width',
21 - h: 'height',
22 - },
23 -};
24 -
25 -/**
26 - * Set the start point value to the shape object
27 - * @param {fabric.Object} shape - Shape object
28 - * @ignore
29 - */
30 -function setStartPoint(shape) {
31 - const { originX, originY } = shape;
32 - const originKey = originX.substring(0, 1) + originY.substring(0, 1);
33 -
34 - shape.startPoint = shape.origins[originKey];
35 -}
36 -
37 -/**
38 - * Get the positions of ratated origin by the pointer value
39 - * @param {{x: number, y: number}} origin - Origin value
40 - * @param {{x: number, y: number}} pointer - Pointer value
41 - * @param {number} angle - Rotating angle
42 - * @returns {Object} Postions of origin
43 - * @ignore
44 - */
45 -function getPositionsOfRotatedOrigin(origin, pointer, angle) {
46 - const sx = origin.x;
47 - const sy = origin.y;
48 - const px = pointer.x;
49 - const py = pointer.y;
50 - const r = (angle * Math.PI) / 180;
51 - const rx = (px - sx) * Math.cos(r) - (py - sy) * Math.sin(r) + sx;
52 - const ry = (px - sx) * Math.sin(r) + (py - sy) * Math.cos(r) + sy;
53 -
54 - return {
55 - originX: sx > rx ? 'right' : 'left',
56 - originY: sy > ry ? 'bottom' : 'top',
57 - };
58 -}
59 -
60 -/**
61 - * Whether the shape has the center origin or not
62 - * @param {fabric.Object} shape - Shape object
63 - * @returns {boolean} State
64 - * @ignore
65 - */
66 -function hasCenterOrigin(shape) {
67 - return shape.originX === 'center' && shape.originY === 'center';
68 -}
69 -
70 -/**
71 - * Adjust the origin of shape by the start point
72 - * @param {{x: number, y: number}} pointer - Pointer value
73 - * @param {fabric.Object} shape - Shape object
74 - * @ignore
75 - */
76 -function adjustOriginByStartPoint(pointer, shape) {
77 - const centerPoint = shape.getPointByOrigin('center', 'center');
78 - const angle = -shape.angle;
79 - const originPositions = getPositionsOfRotatedOrigin(centerPoint, pointer, angle);
80 - const { originX, originY } = originPositions;
81 - const origin = shape.getPointByOrigin(originX, originY);
82 - const left = shape.left - (centerPoint.x - origin.x);
83 - const top = shape.top - (centerPoint.y - origin.y);
84 -
85 - shape.set({
86 - originX,
87 - originY,
88 - left,
89 - top,
90 - });
91 -
92 - shape.setCoords();
93 -}
94 -
95 -/**
96 - * Adjust the origin of shape by the moving pointer value
97 - * @param {{x: number, y: number}} pointer - Pointer value
98 - * @param {fabric.Object} shape - Shape object
99 - * @ignore
100 - */
101 -function adjustOriginByMovingPointer(pointer, shape) {
102 - const origin = shape.startPoint;
103 - const angle = -shape.angle;
104 - const originPositions = getPositionsOfRotatedOrigin(origin, pointer, angle);
105 - const { originX, originY } = originPositions;
106 -
107 - shape.setPositionByOrigin(origin, originX, originY);
108 - shape.setCoords();
109 -}
110 -
111 -/**
112 - * Adjust the dimension of shape on firing scaling event
113 - * @param {fabric.Object} shape - Shape object
114 - * @ignore
115 - */
116 -function adjustDimensionOnScaling(shape) {
117 - const { type, scaleX, scaleY } = shape;
118 - const dimensionKeys = DIMENSION_KEYS[type];
119 - let width = shape[dimensionKeys.w] * scaleX;
120 - let height = shape[dimensionKeys.h] * scaleY;
121 -
122 - if (shape.isRegular) {
123 - const maxScale = Math.max(scaleX, scaleY);
124 -
125 - width = shape[dimensionKeys.w] * maxScale;
126 - height = shape[dimensionKeys.h] * maxScale;
127 - }
128 -
129 - const options = {
130 - hasControls: false,
131 - hasBorders: false,
132 - scaleX: 1,
133 - scaleY: 1,
134 - };
135 -
136 - options[dimensionKeys.w] = width;
137 - options[dimensionKeys.h] = height;
138 -
139 - shape.set(options);
140 -}
141 -
142 -/**
143 - * Adjust the dimension of shape on firing mouse move event
144 - * @param {{x: number, y: number}} pointer - Pointer value
145 - * @param {fabric.Object} shape - Shape object
146 - * @ignore
147 - */
148 -function adjustDimensionOnMouseMove(pointer, shape) {
149 - const { type, strokeWidth, startPoint: origin } = shape;
150 - const divisor = DIVISOR[type];
151 - const dimensionKeys = DIMENSION_KEYS[type];
152 - const isTriangle = !!(shape.type === 'triangle');
153 - const options = {};
154 - let width = Math.abs(origin.x - pointer.x) / divisor;
155 - let height = Math.abs(origin.y - pointer.y) / divisor;
156 -
157 - if (width > strokeWidth) {
158 - width -= strokeWidth / divisor;
159 - }
160 -
161 - if (height > strokeWidth) {
162 - height -= strokeWidth / divisor;
163 - }
164 -
165 - if (shape.isRegular) {
166 - width = height = Math.max(width, height);
167 -
168 - if (isTriangle) {
169 - height = (Math.sqrt(3) / 2) * width;
170 - }
171 - }
172 -
173 - options[dimensionKeys.w] = width;
174 - options[dimensionKeys.h] = height;
175 -
176 - shape.set(options);
177 -}
178 -
179 -module.exports = {
180 - /**
181 - * Set each origin value to shape
182 - * @param {fabric.Object} shape - Shape object
183 - */
184 - setOrigins(shape) {
185 - const leftTopPoint = shape.getPointByOrigin('left', 'top');
186 - const rightTopPoint = shape.getPointByOrigin('right', 'top');
187 - const rightBottomPoint = shape.getPointByOrigin('right', 'bottom');
188 - const leftBottomPoint = shape.getPointByOrigin('left', 'bottom');
189 -
190 - shape.origins = {
191 - lt: leftTopPoint,
192 - rt: rightTopPoint,
193 - rb: rightBottomPoint,
194 - lb: leftBottomPoint,
195 - };
196 - },
197 -
198 - /**
199 - * Resize the shape
200 - * @param {fabric.Object} shape - Shape object
201 - * @param {{x: number, y: number}} pointer - Mouse pointer values on canvas
202 - * @param {boolean} isScaling - Whether the resizing action is scaling or not
203 - */
204 - resize(shape, pointer, isScaling) {
205 - if (hasCenterOrigin(shape)) {
206 - adjustOriginByStartPoint(pointer, shape);
207 - setStartPoint(shape);
208 - }
209 -
210 - if (isScaling) {
211 - adjustDimensionOnScaling(shape, pointer);
212 - } else {
213 - adjustDimensionOnMouseMove(pointer, shape);
214 - }
215 -
216 - adjustOriginByMovingPointer(pointer, shape);
217 - },
218 -
219 - /**
220 - * Adjust the origin position of shape to center
221 - * @param {fabric.Object} shape - Shape object
222 - */
223 - adjustOriginToCenter(shape) {
224 - const centerPoint = shape.getPointByOrigin('center', 'center');
225 - const { originX, originY } = shape;
226 - const origin = shape.getPointByOrigin(originX, originY);
227 - const left = shape.left + (centerPoint.x - origin.x);
228 - const top = shape.top + (centerPoint.y - origin.y);
229 -
230 - shape.set({
231 - hasControls: true,
232 - hasBorders: true,
233 - originX: 'center',
234 - originY: 'center',
235 - left,
236 - top,
237 - });
238 -
239 - shape.setCoords(); // For left, top properties
240 - },
241 -};
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
This diff is collapsed. Click to expand it.