dragon-editor 2.0.0-beta.1.4 → 2.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -135
- package/README_en.md +14 -62
- package/dist/module.json +1 -1
- package/dist/module.mjs +8 -0
- package/dist/runtime/core/components/SvgIcon.vue +30 -21
- package/dist/runtime/core/components/editor/ImageBlock.vue +174 -0
- package/dist/runtime/core/components/editor/TextBlock.vue +76 -31
- package/dist/runtime/core/components/icon/Accept.vue +5 -0
- package/dist/runtime/core/components/icon/ArrowDown.vue +3 -0
- package/dist/runtime/core/components/icon/ArrowUp.vue +3 -0
- package/dist/runtime/core/components/icon/Cancel.vue +5 -0
- package/dist/runtime/core/components/icon/Delete.vue +3 -0
- package/dist/runtime/core/style/common.css +260 -31
- package/dist/runtime/core/style/viewer.css +191 -0
- package/dist/runtime/core/utils/cursor.d.ts +1 -1
- package/dist/runtime/core/utils/cursor.mjs +16 -4
- package/dist/runtime/core/utils/element.mjs +8 -4
- package/dist/runtime/core/utils/index.d.ts +2 -3
- package/dist/runtime/core/utils/index.mjs +47 -6
- package/dist/runtime/core/utils/keyboard.d.ts +1 -1
- package/dist/runtime/core/utils/keyboard.mjs +264 -40
- package/dist/runtime/core/utils/style.d.ts +6 -2
- package/dist/runtime/core/utils/style.mjs +125 -30
- package/dist/runtime/shared/components/DragonEditor.vue +356 -157
- package/dist/runtime/shared/components/DragonEditorComment.vue +33 -11
- package/dist/runtime/shared/components/DragonEditorViewer.vue +28 -2
- package/package.json +1 -1
- package/dist/runtime/core/style/main.d.ts +0 -1
- package/dist/runtime/core/style/main.mjs +0 -24
package/README.md
CHANGED
|
@@ -3,176 +3,113 @@
|
|
|
3
3
|
[](https://github.com/lovefields/dragonEditor/network/members)
|
|
4
4
|
[](https://github.com/lovefields/dragonEditor/)
|
|
5
5
|
[](https://hits.seeyoufarm.com)
|
|
6
|
+
[![npm version][npm-version-src]][npm-version-href]
|
|
7
|
+
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
|
8
|
+
[![License][license-src]][license-href]
|
|
9
|
+
[![Nuxt][nuxt-src]][nuxt-href]
|
|
6
10
|
|
|
7
11
|
[KO](https://github.com/lovefields/dragonEditor/blob/main/README.md) / [EN](https://github.com/lovefields/dragonEditor/blob/main/README_en.md)
|
|
8
12
|
|
|
9
13
|
# DragonEditor
|
|
10
14
|
|
|
11
|
-
드래곤 에디터는 그냥 블로그에 쓸 이지윅 에디터가 필요해서 만들었습니다.<br
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
- Chrome 55+
|
|
15
|
-
- Safari 13+
|
|
16
|
-
- Firefox 63+
|
|
17
|
-
- Edge 79+
|
|
18
|
-
- IOS 11+
|
|
19
|
-
- Android 7+
|
|
20
|
-
|
|
21
|
-
IE 따위는 지원하지 않습니다.
|
|
15
|
+
드래곤 에디터는 그냥 블로그에 쓸 이지윅 에디터가 필요해서 만들었습니다.<br>
|
|
16
|
+
커스터마이징이 가능하며 AMP 페이지를 지원합니다.<br>
|
|
17
|
+
2.0 기점으로 Nuxt.js만 지원합니다.
|
|
22
18
|
|
|
23
|
-
##
|
|
24
|
-
|
|
25
|
-
코드블럭을 사용하는 경우만 사용합니다.<br>
|
|
26
|
-
~~직접 만들려고 했는데 미친 짓인 것 같네요~~
|
|
19
|
+
## 사용법
|
|
27
20
|
|
|
28
|
-
|
|
21
|
+
### 에디터
|
|
29
22
|
|
|
30
|
-
|
|
23
|
+
```vue
|
|
24
|
+
<tempalte>
|
|
25
|
+
<DragonEditor v-model="contentData" :option="option" ref="editor" />
|
|
26
|
+
</tempalte>
|
|
31
27
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
* 에디터 CSS를 로드합니다.
|
|
37
|
-
-->
|
|
38
|
-
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;700&display=swap">
|
|
39
|
-
<link rel="stylesheet" href="[yourdir]/dragonEditor.css">
|
|
40
|
-
|
|
41
|
-
<!--
|
|
42
|
-
* editor-dragon 클레스를 지정합니다.
|
|
43
|
-
-->
|
|
44
|
-
<div class="editor-dragon"></div>
|
|
45
|
-
|
|
46
|
-
<!--
|
|
47
|
-
* 코드 블럭을 사용할 경우 플러그인을 불러오세요.
|
|
48
|
-
* 에디터 JS를 로드합니다.
|
|
49
|
-
-->
|
|
50
|
-
<script src="[yourdir]/highlight.pack.js"></script>
|
|
51
|
-
<script src="[yourdir]/dragonEditor.js"></script>
|
|
52
|
-
<script>
|
|
53
|
-
const editor = new DragonEditor();
|
|
54
|
-
// 위나 아래처럼 사용 가능합니다
|
|
55
|
-
const editor = new DragonEditor({
|
|
56
|
-
key: "value",
|
|
57
|
-
});
|
|
28
|
+
<script setup lang="ts">
|
|
29
|
+
const editor = ref();
|
|
30
|
+
const contentData = ref([]);
|
|
31
|
+
const option = ref({}); // 선택사항
|
|
58
32
|
</script>
|
|
59
33
|
```
|
|
60
34
|
|
|
61
|
-
|
|
62
|
-
```html
|
|
63
|
-
<!--
|
|
64
|
-
* 코드 블럭을 사용한다면 구글 폰트(Inconsolata)를 불러옵니다.
|
|
65
|
-
* 뷰페이지용 CSS를 로드합니다.
|
|
66
|
-
* [code] 값은 convertor를 사용한 결과값입니다.(view-convertor 폴더 참조)
|
|
67
|
-
-->
|
|
68
|
-
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;700&display=swap">
|
|
69
|
-
<link rel="stylesheet" href="[yourdir]/dragonEditorViewer.css">
|
|
70
|
-
|
|
71
|
-
<div class="editor-dragon-viewer">[code]</div>
|
|
72
|
-
```
|
|
35
|
+
#### 컴포넌트 명령어
|
|
73
36
|
|
|
74
|
-
|
|
75
|
-
[Demo page](https://lovefields.github.io/dragonEditor/examples)
|
|
37
|
+
1. 이미지 삽입
|
|
76
38
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
<!--
|
|
86
|
-
Get your module up and running quickly.
|
|
87
|
-
|
|
88
|
-
Find and replace all on all files (CMD+SHIFT+F):
|
|
89
|
-
- Name: My Module
|
|
90
|
-
- Package name: my-module
|
|
91
|
-
- Description: My new Nuxt module
|
|
92
|
-
-->
|
|
93
|
-
|
|
94
|
-
# My Module
|
|
95
|
-
|
|
96
|
-
[![npm version][npm-version-src]][npm-version-href]
|
|
97
|
-
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
|
98
|
-
[![License][license-src]][license-href]
|
|
99
|
-
[![Nuxt][nuxt-src]][nuxt-href]
|
|
100
|
-
|
|
101
|
-
My new Nuxt module for doing amazing things.
|
|
102
|
-
|
|
103
|
-
- [✨ Release Notes](/CHANGELOG.md)
|
|
104
|
-
<!-- - [🏀 Online playground](https://stackblitz.com/github/your-org/my-module?file=playground%2Fapp.vue) -->
|
|
105
|
-
<!-- - [📖 Documentation](https://example.com) -->
|
|
106
|
-
|
|
107
|
-
## Features
|
|
108
|
-
|
|
109
|
-
<!-- Highlight some of the features your module provide here -->
|
|
110
|
-
- ⛰ Foo
|
|
111
|
-
- 🚠 Bar
|
|
112
|
-
- 🌲 Baz
|
|
39
|
+
```typescript
|
|
40
|
+
editor.value.addImageBlock({
|
|
41
|
+
src: string;
|
|
42
|
+
width: number;
|
|
43
|
+
height: number;
|
|
44
|
+
webp: boolean;
|
|
45
|
+
});
|
|
46
|
+
```
|
|
113
47
|
|
|
114
|
-
|
|
48
|
+
### 코멘트
|
|
115
49
|
|
|
116
|
-
|
|
50
|
+
```vue
|
|
51
|
+
<tempalte>
|
|
52
|
+
<DragonEditorComment v-model="commentData" ref="editor" />
|
|
53
|
+
</tempalte>
|
|
117
54
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
55
|
+
<script setup lang="ts">
|
|
56
|
+
const editor = ref();
|
|
57
|
+
const commentData = ref({
|
|
58
|
+
type: "comment",
|
|
59
|
+
classList: [],
|
|
60
|
+
content: "",
|
|
61
|
+
});
|
|
62
|
+
</script>
|
|
63
|
+
```
|
|
121
64
|
|
|
122
|
-
|
|
123
|
-
yarn add --dev my-module
|
|
65
|
+
#### 컴포넌트 명령어
|
|
124
66
|
|
|
125
|
-
|
|
126
|
-
npm install --save-dev my-module
|
|
127
|
-
```
|
|
67
|
+
1. 스타일 설정
|
|
128
68
|
|
|
129
|
-
|
|
69
|
+
스타일의 경우 컴포넌트에서 다음과 같이 명령어를 사용할 수 있습니다.<br>
|
|
70
|
+
해당되는 스타일이 존재하지 않을 경우 클레스에 값을 부여합니다.
|
|
130
71
|
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
modules: [
|
|
134
|
-
'my-module'
|
|
135
|
-
]
|
|
136
|
-
})
|
|
72
|
+
```typescript
|
|
73
|
+
editor.value.setStyles("decorationBold");
|
|
137
74
|
```
|
|
138
75
|
|
|
139
|
-
|
|
76
|
+
2. 스타일 리스트
|
|
140
77
|
|
|
141
|
-
|
|
78
|
+
- `alignLeft` : 왼쪽 정렬
|
|
79
|
+
- `alignCenter` : 가운데 정렬
|
|
80
|
+
- `alignRight` : 오른쪽 정렬
|
|
81
|
+
- `decorationBold` : 볼드
|
|
82
|
+
- `decorationItalic` : 이텔릭
|
|
83
|
+
- `decorationUnderline` : 밑줄
|
|
84
|
+
- `decorationStrikethrough` : 취소선
|
|
142
85
|
|
|
143
|
-
|
|
144
|
-
# Install dependencies
|
|
145
|
-
npm install
|
|
86
|
+
### 뷰어
|
|
146
87
|
|
|
147
|
-
|
|
148
|
-
|
|
88
|
+
```vue
|
|
89
|
+
<tempalte>
|
|
90
|
+
<DragonEditorViewer :content="contentData"/>
|
|
91
|
+
</tempalte>
|
|
149
92
|
|
|
150
|
-
|
|
151
|
-
|
|
93
|
+
<script setup lang="ts">
|
|
94
|
+
const contentData = ref([]); // 에디터로 저장한 데이터
|
|
95
|
+
</script>
|
|
96
|
+
```
|
|
152
97
|
|
|
153
|
-
|
|
154
|
-
npm run dev:build
|
|
98
|
+
<!-- ## 데모 페이지
|
|
155
99
|
|
|
156
|
-
|
|
157
|
-
npm run lint
|
|
100
|
+
[Demo page](https://lovefields.github.io/dragonEditor/examples)
|
|
158
101
|
|
|
159
|
-
|
|
160
|
-
npm run test
|
|
161
|
-
npm run test:watch
|
|
102
|
+
## 문서
|
|
162
103
|
|
|
163
|
-
|
|
164
|
-
npm run release
|
|
165
|
-
```
|
|
104
|
+
- [DragonEditor Document](https://lovefields.github.io/dragonEditor-doc/) -->
|
|
166
105
|
|
|
167
106
|
<!-- Badges -->
|
|
168
|
-
[npm-version-src]: https://img.shields.io/npm/v/my-module/latest.svg?style=flat&colorA=18181B&colorB=28CF8D
|
|
169
|
-
[npm-version-href]: https://npmjs.com/package/my-module
|
|
170
107
|
|
|
108
|
+
[npm-version-src]: https://img.shields.io/npm/v/my-module/latest.svg?style=flat&colorA=18181B&colorB=28CF8D
|
|
109
|
+
[npm-version-href]: https://www.npmjs.com/package/dragon-edito
|
|
171
110
|
[npm-downloads-src]: https://img.shields.io/npm/dm/my-module.svg?style=flat&colorA=18181B&colorB=28CF8D
|
|
172
|
-
[npm-downloads-href]: https://npmjs.com/package/
|
|
173
|
-
|
|
111
|
+
[npm-downloads-href]: https://www.npmjs.com/package/dragon-edito
|
|
174
112
|
[license-src]: https://img.shields.io/npm/l/my-module.svg?style=flat&colorA=18181B&colorB=28CF8D
|
|
175
|
-
[license-href]: https://npmjs.com/package/
|
|
176
|
-
|
|
113
|
+
[license-href]: https://www.npmjs.com/package/dragon-edito
|
|
177
114
|
[nuxt-src]: https://img.shields.io/badge/Nuxt-18181B?logo=nuxt.js
|
|
178
115
|
[nuxt-href]: https://nuxt.com
|
package/README_en.md
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
[](https://github.com/lovefields/dragonEditor/network/members)
|
|
4
4
|
[](https://github.com/lovefields/dragonEditor/)
|
|
5
5
|
[](https://hits.seeyoufarm.com)
|
|
6
|
+
[![npm version][npm-version-src]][npm-version-href]
|
|
7
|
+
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
|
8
|
+
[![License][license-src]][license-href]
|
|
9
|
+
[![Nuxt][nuxt-src]][nuxt-href]
|
|
6
10
|
|
|
7
11
|
[KO](https://github.com/lovefields/dragonEditor/blob/main/README.md) / [EN](https://github.com/lovefields/dragonEditor/blob/main/README_en.md)
|
|
8
12
|
|
|
@@ -10,69 +14,17 @@
|
|
|
10
14
|
|
|
11
15
|
I made WYSIWYG DragonEditor because just i needed an WYSIWYG editor to use in my blog.<br>Well DragonEditor has any customized option and support AMP page.
|
|
12
16
|
|
|
13
|
-
|
|
14
|
-
- Chrome 55+
|
|
15
|
-
- Safari 13+
|
|
16
|
-
- Firefox 63+
|
|
17
|
-
- Edge 79+
|
|
18
|
-
- IOS 11+
|
|
19
|
-
- Android 7+
|
|
17
|
+
# I will make EN version. wait plz :)
|
|
20
18
|
|
|
21
|
-
|
|
19
|
+
<!-- Badges -->
|
|
20
|
+
[npm-version-src]: https://img.shields.io/npm/v/my-module/latest.svg?style=flat&colorA=18181B&colorB=28CF8D
|
|
21
|
+
[npm-version-href]: https://www.npmjs.com/package/dragon-edito
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
[npm-downloads-src]: https://img.shields.io/npm/dm/my-module.svg?style=flat&colorA=18181B&colorB=28CF8D
|
|
24
|
+
[npm-downloads-href]: https://www.npmjs.com/package/dragon-edito
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
[license-src]: https://img.shields.io/npm/l/my-module.svg?style=flat&colorA=18181B&colorB=28CF8D
|
|
27
|
+
[license-href]: https://www.npmjs.com/package/dragon-edito
|
|
26
28
|
|
|
27
|
-
-
|
|
28
|
-
|
|
29
|
-
## Using
|
|
30
|
-
|
|
31
|
-
# editor
|
|
32
|
-
```html
|
|
33
|
-
<!--
|
|
34
|
-
* Load Google font(Inconsolata) if you using code block.
|
|
35
|
-
* Load DragonEditor CSS
|
|
36
|
-
-->
|
|
37
|
-
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;700&display=swap">
|
|
38
|
-
<link rel="stylesheet" href="[yourdir]/dragonEditor.css">
|
|
39
|
-
|
|
40
|
-
<!--
|
|
41
|
-
* Set editor-dragon class element.
|
|
42
|
-
-->
|
|
43
|
-
<div class="editor-dragon"></div>
|
|
44
|
-
|
|
45
|
-
<!--
|
|
46
|
-
* Load highlight plugin if you using code block.
|
|
47
|
-
* Load dragonEditor js
|
|
48
|
-
-->
|
|
49
|
-
<script src="[yourdir]/highlight.pack.js"></script>
|
|
50
|
-
<script src="[yourdir]/dragonEditor.js"></script>
|
|
51
|
-
<script>
|
|
52
|
-
const editor = new DragonEditor();
|
|
53
|
-
// OR
|
|
54
|
-
const editor = new DragonEditor({
|
|
55
|
-
key: "value",
|
|
56
|
-
});
|
|
57
|
-
</script>
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
# viewer
|
|
61
|
-
```html
|
|
62
|
-
<!--
|
|
63
|
-
* Load Google font(Inconsolata) if you using code block.
|
|
64
|
-
* Load DragonEditorViewer CSS
|
|
65
|
-
* The [code] value is the result with converter (see view-convertor folder).
|
|
66
|
-
-->
|
|
67
|
-
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;700&display=swap">
|
|
68
|
-
<link rel="stylesheet" href="[yourdir]/dragonEditorViewer.css">
|
|
69
|
-
|
|
70
|
-
<div class="editor-dragon-viewer">[code]</div>
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## Demo
|
|
74
|
-
[Demo page](https://lovefields.github.io/dragonEditor/examples)
|
|
75
|
-
|
|
76
|
-
## Document
|
|
77
|
-
|
|
78
|
-
- [DragonEditor Document](https://lovefields.github.io/dragonEditor-doc/)
|
|
29
|
+
[nuxt-src]: https://img.shields.io/badge/Nuxt-18181B?logo=nuxt.js
|
|
30
|
+
[nuxt-href]: https://nuxt.com
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -6,10 +6,18 @@ const module = defineNuxtModule({
|
|
|
6
6
|
},
|
|
7
7
|
setup(options, nuxt) {
|
|
8
8
|
const resolver = createResolver(import.meta.url);
|
|
9
|
+
addComponent({
|
|
10
|
+
name: "DragonEditor",
|
|
11
|
+
filePath: resolver.resolve("./runtime/shared/components/DragonEditor")
|
|
12
|
+
});
|
|
9
13
|
addComponent({
|
|
10
14
|
name: "DragonEditorComment",
|
|
11
15
|
filePath: resolver.resolve("./runtime/shared/components/DragonEditorComment")
|
|
12
16
|
});
|
|
17
|
+
addComponent({
|
|
18
|
+
name: "DragonEditorViewer",
|
|
19
|
+
filePath: resolver.resolve("./runtime/shared/components/DragonEditorViewer")
|
|
20
|
+
});
|
|
13
21
|
}
|
|
14
22
|
});
|
|
15
23
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<svg class="
|
|
2
|
+
<svg class="d-icon" viewBox="0 0 64 64">
|
|
3
3
|
<component :is="iconComponent" />
|
|
4
4
|
</svg>
|
|
5
5
|
</template>
|
|
@@ -20,8 +20,13 @@ import DecorationUnderline from "./icon/DecorationUnderline.vue";
|
|
|
20
20
|
import DecorationStrikethrough from "./icon/DecorationStrikethrough.vue";
|
|
21
21
|
import LinkPath from "./icon/LinkPath.vue";
|
|
22
22
|
import CodeBlock from "./icon/CodeBlock.vue";
|
|
23
|
+
import Cancel from "./icon/Cancel.vue";
|
|
24
|
+
import Accept from "./icon/Accept.vue";
|
|
25
|
+
import ArrowDown from "./icon/ArrowDown.vue";
|
|
26
|
+
import ArrowUp from "./icon/ArrowUp.vue";
|
|
27
|
+
import Delete from "./icon/Delete.vue";
|
|
23
28
|
|
|
24
|
-
const props = defineProps<{ kind:
|
|
29
|
+
const props = defineProps<{ kind: String }>();
|
|
25
30
|
let iconComponent: any;
|
|
26
31
|
|
|
27
32
|
switch (props.kind) {
|
|
@@ -70,13 +75,31 @@ switch (props.kind) {
|
|
|
70
75
|
case "codeBlock":
|
|
71
76
|
iconComponent = CodeBlock;
|
|
72
77
|
break;
|
|
78
|
+
case "cancel":
|
|
79
|
+
iconComponent = Cancel;
|
|
80
|
+
break;
|
|
81
|
+
case "accept":
|
|
82
|
+
iconComponent = Accept;
|
|
83
|
+
break;
|
|
84
|
+
case "arrowDown":
|
|
85
|
+
iconComponent = ArrowDown;
|
|
86
|
+
break;
|
|
87
|
+
case "arrowUp":
|
|
88
|
+
iconComponent = ArrowUp;
|
|
89
|
+
break;
|
|
90
|
+
case "delete":
|
|
91
|
+
iconComponent = Delete;
|
|
92
|
+
break;
|
|
73
93
|
}
|
|
74
94
|
|
|
95
|
+
// <g id="icon-delete-block"> trash
|
|
96
|
+
//
|
|
97
|
+
// </g>
|
|
98
|
+
//
|
|
75
99
|
|
|
76
100
|
// <g id="icon-linkbox-block">
|
|
77
101
|
// <path fill-rule="evenodd" clip-rule="evenodd" d="M19 13H45C48.3137 13 51 15.6863 51 19V45C51 48.3137 48.3137 51 45 51H19C15.6863 51 13 48.3137 13 45V19C13 15.6863 15.6863 13 19 13ZM9 19C9 13.4772 13.4772 9 19 9H45C50.5228 9 55 13.4772 55 19V45C55 50.5228 50.5228 55 45 55H19C13.4772 55 9 50.5228 9 45V19ZM18 20C19.1046 20 20 19.1046 20 18C20 16.8954 19.1046 16 18 16C16.8954 16 16 16.8954 16 18C16 19.1046 16.8954 20 18 20ZM26 18C26 19.1046 25.1046 20 24 20C22.8954 20 22 19.1046 22 18C22 16.8954 22.8954 16 24 16C25.1046 16 26 16.8954 26 18ZM30 20C31.1046 20 32 19.1046 32 18C32 16.8954 31.1046 16 30 16C28.8954 16 28 16.8954 28 18C28 19.1046 28.8954 20 30 20ZM23.161 38.7988C21.9894 39.9704 21.9894 41.8699 23.161 43.0415C24.3326 44.2131 26.2321 44.2131 27.4036 43.0415L32.3534 38.0917C32.7439 37.7012 32.7439 37.068 32.3534 36.6775C31.5723 35.8965 31.5723 34.6301 32.3534 33.8491C33.1344 33.068 34.4008 33.0681 35.1818 33.8491C37.1344 35.8017 37.1344 38.9675 35.1818 40.9202L30.2321 45.8699C27.4984 48.6036 23.0662 48.6036 20.3326 45.8699C17.5989 43.1362 17.5989 38.7041 20.3326 35.9704L24.2699 32.0331C25.0509 31.2521 26.3172 31.2521 27.0983 32.0331C27.8793 32.8142 27.8793 34.0805 27.0983 34.8615L23.161 38.7988ZM36.5964 23.9497C37.7679 22.7782 39.6674 22.7782 40.839 23.9497C42.0106 25.1213 42.0106 27.0208 40.839 28.1924L36.9017 32.1297C36.1207 32.9107 36.1207 34.177 36.9017 34.9581C37.6828 35.7391 38.9491 35.7391 39.7301 34.9581L43.6674 31.0208C46.4011 28.2871 46.4011 23.855 43.6674 21.1213C40.9338 18.3876 36.5016 18.3876 33.7679 21.1213L28.8182 26.071C26.8656 28.0237 26.8656 31.1895 28.8182 33.1421C29.5992 33.9232 30.8656 33.9232 31.6466 33.1421C32.4277 32.3611 32.4277 31.0947 31.6466 30.3137C31.2561 29.9232 31.2561 29.29 31.6466 28.8995L36.5964 23.9497Z"></path>
|
|
78
102
|
// </g>
|
|
79
|
-
//
|
|
80
103
|
// <g id="icon-emoticon-block">
|
|
81
104
|
// <path fill-rule="evenodd" clip-rule="evenodd" d="M51 32C51 42.4934 42.4934 51 32 51C21.5066 51 13 42.4934 13 32C13 21.5066 21.5066 13 32 13C42.4934 13 51 21.5066 51 32ZM55 32C55 44.7025 44.7025 55 32 55C19.2975 55 9 44.7025 9 32C9 19.2975 19.2975 9 32 9C44.7025 9 55 19.2975 55 32ZM26 36C26 34.8954 25.1046 34 24 34C22.8954 34 22 34.8954 22 36C22 41.2131 26.7364 45 32 45C37.2636 45 42 41.2131 42 36C42 34.8954 41.1046 34 40 34C38.8954 34 38 34.8954 38 36C38 38.5189 35.5729 41 32 41C28.4271 41 26 38.5189 26 36ZM26 26C26 27.1046 25.1046 28 24 28C22.8954 28 22 27.1046 22 26C22 24.8954 22.8954 24 24 24C25.1046 24 26 24.8954 26 26ZM40 28C41.1046 28 42 27.1046 42 26C42 24.8954 41.1046 24 40 24C38.8954 24 38 24.8954 38 26C38 27.1046 38.8954 28 40 28Z"></path>
|
|
82
105
|
// </g>
|
|
@@ -92,13 +115,9 @@ switch (props.kind) {
|
|
|
92
115
|
// <path d="M10.7472 18.9708C8.41355 21.415 8.41818 25.2485 10.7577 27.6871L27.093 44.7144C27.1826 44.8216 27.2764 44.9266 27.3743 45.0292C28.6361 46.3507 30.3291 47.0078 32.0197 46.9999C33.6972 46.9975 35.3737 46.3404 36.6257 45.0291C36.7233 44.9269 36.8167 44.8222 36.9062 44.7154L53.2423 27.6872C55.5818 25.2486 55.5864 21.4151 53.2528 18.9709C50.7481 16.3475 46.5437 16.3425 44.0326 18.9599L32 31.5022L19.9674 18.9598C17.4563 16.3424 13.2519 16.3474 10.7472 18.9708Z"></path>
|
|
93
116
|
// </g>
|
|
94
117
|
//
|
|
95
|
-
|
|
96
|
-
// <path d="M13.2497 13.0226C11.032 15.2442 11.032 18.8461 13.2497 21.0677L24.0457 31.8826L13.0153 42.9323C10.7976 45.1539 10.7976 48.7558 13.0153 50.9774C15.2331 53.199 18.8287 53.199 21.0464 50.9774L32.0768 39.9278L42.9532 50.8233C45.1709 53.0449 48.7666 53.0449 50.9843 50.8233C53.202 48.6017 53.202 44.9997 50.9843 42.7781L40.1078 31.8826L50.7499 21.2219C52.9677 19.0003 52.9677 15.3983 50.7499 13.1767C48.5322 10.9551 44.9366 10.9551 42.7189 13.1767L32.0768 23.8375L21.2808 13.0226C19.063 10.801 15.4674 10.801 13.2497 13.0226Z"></path>
|
|
97
|
-
// </g>
|
|
118
|
+
|
|
98
119
|
//
|
|
99
|
-
|
|
100
|
-
// <path d="M51.3456 17.6735C49.1181 15.4422 45.5066 15.4422 43.2792 17.6735L26.0616 34.9213L20.741 29.5914C18.5126 27.3591 14.8997 27.3591 12.6713 29.5914C10.4429 31.8236 10.4429 35.4429 12.6713 37.6752L21.9937 47.0139C24.222 49.2462 27.835 49.2462 30.0633 47.0139C30.1078 46.9693 30.1514 46.9243 30.194 46.8787C30.3822 46.7324 30.5633 46.5728 30.736 46.3997L51.3456 25.7541C53.573 23.5227 53.573 19.9049 51.3456 17.6735Z"></path>
|
|
101
|
-
// </g>
|
|
120
|
+
|
|
102
121
|
// <g id="icon-table-header">
|
|
103
122
|
// <path fill-rule="evenodd" clip-rule="evenodd" d="M13 13H51V23H13V13ZM9 13C9 10.791 10.7909 9 13 9H51C53.2091 9 55 10.791 55 13V23V27H51H13H9V23V13ZM9 30C9 28.8964 9.89392 28.0015 10.9972 28H11.0028C12.1061 28.0015 13 28.8964 13 30V32C13 33.1046 12.1046 34 11 34C9.89543 34 9 33.1046 9 32V30ZM51 30C51 28.8954 51.8954 28 53 28C54.1046 28 55 28.8954 55 30V32C55 33.1046 54.1046 34 53 34C51.8954 34 51 33.1046 51 32V30ZM11 37C12.1046 37 13 37.8954 13 39V41C13 42.1046 12.1046 43 11 43C9.89543 43 9 42.1046 9 41V39C9 37.8954 9.89543 37 11 37ZM53 37C54.1046 37 55 37.8954 55 39V41C55 42.1046 54.1046 43 53 43C51.8954 43 51 42.1046 51 41V39C51 37.8954 51.8954 37 53 37ZM11 46C12.1046 46 13 46.8954 13 48V49C13 49.1208 13.0105 49.2376 13.0302 49.3498C13.2208 50.4379 12.4933 51.4744 11.4053 51.665C10.3173 51.8556 9.28075 51.1281 9.09016 50.0401C9.03074 49.7009 9 49.3532 9 49V48C9 46.8954 9.89543 46 11 46ZM53 46C54.1046 46 55 46.8954 55 48V49C55 49.3532 54.9693 49.7009 54.9098 50.0401C54.7192 51.1281 53.6827 51.8556 52.5947 51.665C51.5067 51.4744 50.7792 50.4379 50.9698 49.3499C50.9895 49.2376 51 49.1208 51 49V48C51 46.8954 51.8954 46 53 46ZM12.335 52.5947C12.5256 51.5067 13.5621 50.7792 14.6501 50.9698C14.7624 50.9895 14.8792 51 15 51H15.9444C17.049 51 17.9444 51.8954 17.9444 53C17.9444 54.1046 17.049 55 15.9444 55H15C14.6468 55 14.2991 54.9693 13.9599 54.9098C12.8719 54.7192 12.1444 53.6827 12.335 52.5947ZM51.665 52.5947C51.8555 53.6827 51.1281 54.7192 50.0401 54.9098C49.7009 54.9693 49.3532 55 49 55H48.0556C46.951 55 46.0556 54.1046 46.0556 53C46.0556 51.8954 46.951 51 48.0556 51H49C49.1208 51 49.2376 50.9895 49.3498 50.9698C50.4379 50.7792 51.4744 51.5067 51.665 52.5947ZM20.5556 53C20.5556 51.8954 21.451 51 22.5556 51H24.4444C25.549 51 26.4444 51.8954 26.4444 53C26.4444 54.1046 25.549 55 24.4444 55H22.5556C21.451 55 20.5556 54.1046 20.5556 53ZM29.0556 53C29.0556 51.8954 29.951 51 31.0556 51H32.9444C34.049 51 34.9444 51.8954 34.9444 53C34.9444 54.1046 34.049 55 32.9444 55H31.0556C29.951 55 29.0556 54.1046 29.0556 53ZM37.5556 53C37.5556 51.8954 38.451 51 39.5556 51H41.4444C42.549 51 43.4444 51.8954 43.4444 53C43.4444 54.1046 42.549 55 41.4444 55H39.5556C38.451 55 37.5556 54.1046 37.5556 53Z"></path>
|
|
104
123
|
// </g>
|
|
@@ -119,18 +138,8 @@ switch (props.kind) {
|
|
|
119
138
|
// <path fill-rule="evenodd" clip-rule="evenodd" d="M19 13H45C48.3137 13 51 15.6863 51 19V45C51 48.3137 48.3137 51 45 51H19C15.6863 51 13 48.3137 13 45V19C13 15.6863 15.6863 13 19 13ZM9 19C9 13.4772 13.4772 9 19 9H45C50.5228 9 55 13.4772 55 19V45C55 50.5228 50.5228 55 45 55H19C13.4772 55 9 50.5228 9 45V19ZM43.8342 28.665C43.0642 27.6159 42.0196 27.0914 40.7005 27.0914C40.0232 27.0914 39.4171 27.2234 38.8824 27.4873C38.3547 27.7513 37.8877 28.181 37.4813 28.7766H37.3316C37.4314 27.7343 37.4813 27 37.4813 26.5736V23H33.2995V38.797H36.5615L37.2246 37.6701H37.4813C37.8449 38.0491 38.1622 38.3198 38.4332 38.4822C38.7112 38.6447 39.025 38.7699 39.3743 38.8579C39.7237 38.9526 40.123 39 40.5722 39C41.9626 39 43.0463 38.4721 43.8235 37.4162C44.6078 36.3536 45 34.8883 45 33.0203C45 31.1658 44.6114 29.714 43.8342 28.665ZM37.8877 30.7868C38.1586 30.401 38.5865 30.2081 39.1711 30.2081C40.2193 30.2081 40.7433 31.132 40.7433 32.9797C40.7433 33.9069 40.6114 34.6108 40.3476 35.0914C40.0838 35.5651 39.7059 35.802 39.2139 35.802C38.6007 35.802 38.1586 35.599 37.8877 35.1929C37.6168 34.78 37.4813 34.1032 37.4813 33.1624V32.6041C37.4813 31.7783 37.6168 31.1726 37.8877 30.7868ZM26.754 37.2741L27.5561 38.797H30.4545V31.2538C30.4545 29.9408 30.0267 28.9188 29.1711 28.1878C28.3226 27.4569 27.1212 27.0914 25.5668 27.0914C23.4135 27.0914 21.631 27.4365 20.2193 28.1269L21.4278 30.7462C22.7897 30.1777 23.9127 29.8934 24.7968 29.8934C25.7807 29.8934 26.2727 30.3672 26.2727 31.3147V31.4772L24.2513 31.5381C22.5472 31.6125 21.246 31.9509 20.3476 32.5533C19.4492 33.1489 19 34.0592 19 35.2843C19 36.4619 19.328 37.3756 19.984 38.0254C20.6399 38.6751 21.5383 39 22.6791 39C23.6061 39 24.3619 38.8782 24.9465 38.6345C25.5312 38.3909 26.1052 37.9374 26.6684 37.2741H26.754ZM25.7487 35.7411C25.3922 36.0457 24.9608 36.198 24.4545 36.198C23.6631 36.198 23.2674 35.846 23.2674 35.1421C23.2674 34.2284 23.9554 33.7479 25.3316 33.7005L26.2941 33.6599V34.5533C26.2941 35.0406 26.1123 35.4365 25.7487 35.7411Z"></path>
|
|
120
139
|
// </g>
|
|
121
140
|
//
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
// </g>
|
|
125
|
-
//
|
|
126
|
-
// <g id="icon-arrow-up">
|
|
127
|
-
// <path d="M45.7366 27.4896C46.5176 28.2706 47.7839 28.2706 48.565 27.4896C49.346 26.7085 49.346 25.4422 48.565 24.6612L33.4896 9.58579C32.7085 8.80473 31.4422 8.80474 30.6612 9.58579L15.5858 24.6612C14.8047 25.4422 14.8047 26.7085 15.5858 27.4896C16.3668 28.2706 17.6332 28.2706 18.4142 27.4896L30 15.9038V53C30 54.1046 30.8954 55 32 55C33.1045 55 34 54.1046 34 53V15.753L45.7366 27.4896Z"></path>
|
|
128
|
-
// </g>
|
|
129
|
-
//
|
|
130
|
-
// <g id="icon-delete-block">
|
|
131
|
-
// <path fill-rule="evenodd" clip-rule="evenodd" d="M32 51C42.4934 51 51 42.4934 51 32C51 21.5066 42.4934 13 32 13C21.5066 13 13 21.5066 13 32C13 42.4934 21.5066 51 32 51ZM32 55C44.7026 55 55 44.7026 55 32C55 19.2974 44.7026 9 32 9C19.2974 9 9 19.2974 9 32C9 44.7026 19.2974 55 32 55ZM21.4142 42.6274C20.6332 41.8462 20.6332 40.5801 21.4142 39.7988L29.1715 32.0415L21.5858 24.4558C20.8047 23.6748 20.8047 22.4084 21.5858 21.6274C22.3668 20.8462 23.6332 20.8462 24.4142 21.6274L31.9999 29.2131L39.799 21.4141C40.58 20.6331 41.8464 20.6331 42.6274 21.4141C43.4084 22.1953 43.4084 23.4614 42.6274 24.2427L34.8284 32.0417L42.799 40.0122C43.58 40.7932 43.58 42.0596 42.799 42.8406C42.0179 43.6216 40.7516 43.6216 39.9706 42.8406L32.0001 34.8701L24.2426 42.6274C23.4616 43.4084 22.1953 43.4084 21.4142 42.6274Z"></path>
|
|
132
|
-
// </g>
|
|
133
|
-
//
|
|
141
|
+
|
|
142
|
+
|
|
134
143
|
// <g id="icon-pc">
|
|
135
144
|
// <path d="M50 16H14C13.4477 16 13 16.4477 13 17V37C13 37.5523 13.4477 38 14 38H32H50C50.5523 38 51 37.5523 51 37V17C51 16.4477 50.5523 16 50 16ZM50 42H34V51H40C41.1046 51 42 51.8954 42 53C42 54.1046 41.1046 55 40 55H32H24C22.8954 55 22 54.1046 22 53C22 51.8954 22.8954 51 24 51H30V42H14C11.2386 42 9 39.7614 9 37V17C9 14.2386 11.2386 12 14 12H50C52.7614 12 55 14.2386 55 17V37C55 39.7614 52.7614 42 50 42Z"></path>
|
|
136
145
|
// </g>
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="d-image-block" :class="data.classList" ref="$block" @mousemove="resizeMouseEvent" @touchmove="resizeTouchEvent" @mouseup="doneResizeStatus" @touchend="doneResizeStatus">
|
|
3
|
+
<div class="d-image-area">
|
|
4
|
+
<button class="d-btn-size-left" @mousedown="startResizeEvent" @touchstart="startResizeEvent"></button>
|
|
5
|
+
<button class="d-btn-size-right" @mousedown="startResizeEvent" @touchstart="startResizeEvent"></button>
|
|
6
|
+
|
|
7
|
+
<template v-if="data.webp">
|
|
8
|
+
<picture>
|
|
9
|
+
<source :srcset="data.src.replace(/\.(jpg|png)/g, '.webp')">
|
|
10
|
+
<img class="d-img" :src="data.src" :width="data.width" :height="data.height" :alt="data.caption" loading="lazy">
|
|
11
|
+
</picture>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<template v-else>
|
|
15
|
+
<img class="d-img" :src="data.src" :width="data.width" :height="data.height" :alt="data.caption" loading="lazy">
|
|
16
|
+
</template>
|
|
17
|
+
</div>
|
|
18
|
+
<p class="d-caption" v-html="data.caption" @keydown="textKeyboardEvent" ref="$caption" contenteditable></p>
|
|
19
|
+
</div>
|
|
20
|
+
</template>
|
|
21
|
+
|
|
22
|
+
<script setup lang="ts">
|
|
23
|
+
import { ref, unref } from "#imports";
|
|
24
|
+
import { keyboardEvent, pasteText, styleSettings } from "../../utils/index";
|
|
25
|
+
import { imageBlock, cursorSelection, styleFunctionArgument } from "../../../../types/index";
|
|
26
|
+
|
|
27
|
+
const $block = ref();
|
|
28
|
+
const $caption = ref();
|
|
29
|
+
const data = ref<imageBlock>({
|
|
30
|
+
type: "",
|
|
31
|
+
id: "",
|
|
32
|
+
classList: [],
|
|
33
|
+
src: "",
|
|
34
|
+
width: 0,
|
|
35
|
+
height: 0,
|
|
36
|
+
webp: false,
|
|
37
|
+
caption: "",
|
|
38
|
+
});
|
|
39
|
+
const props = defineProps<{ modelValue: imageBlock; cursorData: cursorSelection }>();
|
|
40
|
+
const emit = defineEmits<{
|
|
41
|
+
(e: "update:modelValue", modelValue: imageBlock): void;
|
|
42
|
+
(e: "addBlock", name: string): void;
|
|
43
|
+
(e: "deleteBlockLocal", index?: number): void;
|
|
44
|
+
}>();
|
|
45
|
+
|
|
46
|
+
data.value = unref(props.modelValue) as imageBlock;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 내부 상수
|
|
50
|
+
*/
|
|
51
|
+
let activeResize = false;
|
|
52
|
+
let startX = 0;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* 내부 이벤트
|
|
56
|
+
*/
|
|
57
|
+
// 키보드 이벤트 할당
|
|
58
|
+
function textKeyboardEvent(e: KeyboardEvent) {
|
|
59
|
+
keyboardEvent("image", e, emit, updateBlockData);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// 리사이즈 시작
|
|
63
|
+
const startResizeStatus = (value) => {
|
|
64
|
+
activeResize = true;
|
|
65
|
+
startX = value;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
function startResizeEvent() {
|
|
69
|
+
// startResizeStatus(e.clientX);
|
|
70
|
+
activeResize = true;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function activeResizeTouchEvent(e: TouchEvent) {
|
|
74
|
+
// startResizeStatus(Math.floor(e.touches[0].clientX));
|
|
75
|
+
activeResize = true;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// 리사이즈 이벤트
|
|
79
|
+
const resizeEvent = (value) => {
|
|
80
|
+
if (activeResize) {
|
|
81
|
+
const blockRect = $block.value.getBoundingClientRect();
|
|
82
|
+
const bodyRect = document.body.getBoundingClientRect();
|
|
83
|
+
const blockLeft = blockRect.left - bodyRect.left;
|
|
84
|
+
const centerPoint: number = blockRect.width / 2 + blockLeft;
|
|
85
|
+
const blockRight = window.innerWidth - (centerPoint + blockRect.width / 2);
|
|
86
|
+
let percent: number = 0;
|
|
87
|
+
|
|
88
|
+
// console.log(value);
|
|
89
|
+
|
|
90
|
+
if (centerPoint > value) {
|
|
91
|
+
// 왼쪽
|
|
92
|
+
const leftPercent = (100 / (centerPoint - blockLeft)) * (value - blockLeft);
|
|
93
|
+
|
|
94
|
+
percent = Math.floor(100 - leftPercent) + 2;
|
|
95
|
+
} else {
|
|
96
|
+
// 오른쪽
|
|
97
|
+
const right = window.innerWidth - (centerPoint + blockRight);
|
|
98
|
+
const valueData = value - centerPoint;
|
|
99
|
+
const rightPercent = (100 / right) * valueData;
|
|
100
|
+
|
|
101
|
+
percent = Math.floor(rightPercent);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
percent = percent - (percent % 5);
|
|
105
|
+
percent = percent / 5;
|
|
106
|
+
|
|
107
|
+
const classList = data.value.classList.filter((item) => /--\d{1,2}/g.test(item) === false);
|
|
108
|
+
classList.push(`--${percent}`);
|
|
109
|
+
data.value.classList = classList;
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
function resizeMouseEvent(e: MouseEvent) {
|
|
114
|
+
resizeEvent(e.clientX);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function resizeTouchEvent(e: TouchEvent) {
|
|
118
|
+
resizeEvent(Math.floor(e.touches[0].clientX));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// 리사이즈 종료
|
|
122
|
+
function doneResizeStatus() {
|
|
123
|
+
activeResize = false;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* 외부용 함수
|
|
128
|
+
*/
|
|
129
|
+
function focus() {
|
|
130
|
+
$caption.value.focus();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// 블럭 위치 주기
|
|
134
|
+
function getBoundingClientRect() {
|
|
135
|
+
return $block.value.parentNode.getBoundingClientRect();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// 타입 전달
|
|
139
|
+
function getType() {
|
|
140
|
+
return data.value.type;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// 붙여넣기 이벤트
|
|
144
|
+
function pasteEvent(text: string) {
|
|
145
|
+
pasteText("text", text);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// 데이터 정규화 및 검수
|
|
149
|
+
function updateBlockData() {
|
|
150
|
+
emit("update:modelValue", data.value);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// 텍스트 스타일 지정
|
|
154
|
+
function setStyles({ type, url }: styleFunctionArgument) {
|
|
155
|
+
data.value = styleSettings({
|
|
156
|
+
kind: type,
|
|
157
|
+
blockData: data.value,
|
|
158
|
+
$target: $block.value,
|
|
159
|
+
cursorData: props.cursorData,
|
|
160
|
+
});
|
|
161
|
+
setTimeout(() => {
|
|
162
|
+
updateBlockData();
|
|
163
|
+
}, 250);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
defineExpose({
|
|
167
|
+
updateBlockData,
|
|
168
|
+
getType,
|
|
169
|
+
focus,
|
|
170
|
+
pasteEvent,
|
|
171
|
+
setStyles,
|
|
172
|
+
getBoundingClientRect,
|
|
173
|
+
});
|
|
174
|
+
</script>
|