jellies-draw 0.1.0
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/.eslintrc.js +89 -0
- package/README.md +24 -0
- package/babel.config.js +5 -0
- package/package.json +65 -0
- package/public/favicon.ico +0 -0
- package/public/index.html +17 -0
- package/src/App.vue +93 -0
- package/src/assets/jellies-draw-tool.ttf +0 -0
- package/src/components/DrawingCanvas.vue +66 -0
- package/src/components/PropertyPickers.vue +218 -0
- package/src/components/ToolButton.vue +125 -0
- package/src/components/ToolButtons.vue +113 -0
- package/src/components/functions/canvas.js +136 -0
- package/src/components/functions/clipboard.js +32 -0
- package/src/components/functions/histories.js +53 -0
- package/src/components/functions/properties.js +126 -0
- package/src/components/functions/tools/arrow.js +70 -0
- package/src/components/functions/tools/clear.js +8 -0
- package/src/components/functions/tools/ellipse.js +73 -0
- package/src/components/functions/tools/eraser.js +51 -0
- package/src/components/functions/tools/image.js +74 -0
- package/src/components/functions/tools/index.js +23 -0
- package/src/components/functions/tools/line.js +56 -0
- package/src/components/functions/tools/pen.js +61 -0
- package/src/components/functions/tools/rectangle.js +71 -0
- package/src/components/functions/tools/selector.js +47 -0
- package/src/components/functions/tools/text.js +178 -0
- package/src/components/functions/transformer.js +214 -0
- package/src/index.js +9 -0
- package/src/main.js +8 -0
- package/webpack.config.js +39 -0
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
root: true,
|
|
3
|
+
env: {
|
|
4
|
+
node: true,
|
|
5
|
+
browser: true,
|
|
6
|
+
es6: true
|
|
7
|
+
},
|
|
8
|
+
extends: [
|
|
9
|
+
'plugin:vue/essential',
|
|
10
|
+
'eslint:recommended'
|
|
11
|
+
],
|
|
12
|
+
globals: {
|
|
13
|
+
WeixinJSBridge : false
|
|
14
|
+
},
|
|
15
|
+
parserOptions: {
|
|
16
|
+
ecmaFeatures: {
|
|
17
|
+
legacyDecorators: true
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
rules: {
|
|
21
|
+
"indent": ["error", 2, { "SwitchCase": 1 }],
|
|
22
|
+
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
|
23
|
+
"func-names": 0,
|
|
24
|
+
"one-var": [1, "never"],
|
|
25
|
+
"prefer-const": 1,
|
|
26
|
+
"prefer-arrow-callback": 2,
|
|
27
|
+
"arrow-body-style": 0,
|
|
28
|
+
"prefer-template": ["error"],
|
|
29
|
+
"consistent-return": "off",
|
|
30
|
+
"prefer-rest-params": 2,
|
|
31
|
+
"no-script-url": 0,
|
|
32
|
+
"no-console": [
|
|
33
|
+
2,
|
|
34
|
+
{
|
|
35
|
+
"allow": ["info", "error", "warn", "log"]
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"no-duplicate-imports": 2,
|
|
39
|
+
"eol-last": 2,
|
|
40
|
+
"no-useless-rename": 2,
|
|
41
|
+
"class-methods-use-this": 0,
|
|
42
|
+
"prefer-destructuring": 0,
|
|
43
|
+
"no-unused-vars": [2, {
|
|
44
|
+
// 允许声明未使用变量
|
|
45
|
+
"vars": "local",
|
|
46
|
+
// 参数不检查
|
|
47
|
+
"args": "none"
|
|
48
|
+
}],
|
|
49
|
+
"no-plusplus": 0,
|
|
50
|
+
"import/prefer-default-export": 0,
|
|
51
|
+
"no-use-before-define": [
|
|
52
|
+
"error",
|
|
53
|
+
{
|
|
54
|
+
"functions": false
|
|
55
|
+
}
|
|
56
|
+
],
|
|
57
|
+
"@typescript-eslint/no-use-before-define": 0,
|
|
58
|
+
"object-shorthand": ["error", "always"],
|
|
59
|
+
"@typescript-eslint/explicit-function-return-type": 0,
|
|
60
|
+
"@typescript-eslint/interface-name-prefix": 0,
|
|
61
|
+
"no-invalid-this": 0,
|
|
62
|
+
"no-await-in-loop": "off",
|
|
63
|
+
"array-callback-return": "off",
|
|
64
|
+
"no-restricted-syntax": "off",
|
|
65
|
+
"@typescript-eslint/no-explicit-any": 0,
|
|
66
|
+
"import/no-extraneous-dependencies": 0,
|
|
67
|
+
"import/no-unresolved": 0,
|
|
68
|
+
"@typescript-eslint/explicit-member-accessibility": 0,
|
|
69
|
+
"@typescript-eslint/no-object-literal-type-assertion": 0,
|
|
70
|
+
"generator-star-spacing": "off",
|
|
71
|
+
"eqeqeq": 0,
|
|
72
|
+
"no-else-return": 2,
|
|
73
|
+
"arrow-parens": 0,
|
|
74
|
+
"space-before-function-paren": ["error", "never"],
|
|
75
|
+
"comma-dangle": [2, "never"]
|
|
76
|
+
},
|
|
77
|
+
overrides: [
|
|
78
|
+
{
|
|
79
|
+
files: [
|
|
80
|
+
'**/__tests__/*.{j,t}s?(x)',
|
|
81
|
+
'**/tests/unit/**/*.spec.{j,t}s?(x)'
|
|
82
|
+
],
|
|
83
|
+
env: {
|
|
84
|
+
jest: true
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# jellies-draw
|
|
2
|
+
|
|
3
|
+
## Project setup
|
|
4
|
+
```
|
|
5
|
+
yarn install
|
|
6
|
+
```
|
|
7
|
+
|
|
8
|
+
### Compiles and hot-reloads for development
|
|
9
|
+
```
|
|
10
|
+
yarn serve
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Compiles and minifies for production
|
|
14
|
+
```
|
|
15
|
+
yarn build
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### Lints and fixes files
|
|
19
|
+
```
|
|
20
|
+
yarn lint
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Customize configuration
|
|
24
|
+
See [Configuration Reference](https://cli.vuejs.org/config/).
|
package/babel.config.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "jellies-draw",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A drawer for jellies",
|
|
5
|
+
"private": false,
|
|
6
|
+
"main": "./src/index.js",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"serve": "vue-cli-service serve",
|
|
9
|
+
"build": "webpack --display-error-details --config webpack.config.js",
|
|
10
|
+
"lint": "vue-cli-service lint"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"src/*",
|
|
14
|
+
"package",
|
|
15
|
+
"public/*",
|
|
16
|
+
"*.json",
|
|
17
|
+
"*.js"
|
|
18
|
+
],
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"core-js": "^3.6.5",
|
|
21
|
+
"konva": "^9.0.1",
|
|
22
|
+
"vue": "^2.6.11"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@vue/cli-plugin-babel": "^4.1.1",
|
|
26
|
+
"@vue/cli-plugin-eslint": "^4.1.1",
|
|
27
|
+
"@vue/cli-service": "^4.1.1",
|
|
28
|
+
"babel-eslint": "^10.1.0",
|
|
29
|
+
"eslint": "^6.7.2",
|
|
30
|
+
"eslint-plugin-vue": "^6.2.2",
|
|
31
|
+
"babel-core": "^6.26.3",
|
|
32
|
+
"babel-loader": "^7.1.5",
|
|
33
|
+
"css-loader": "^0.28.7",
|
|
34
|
+
"less": "^2.7.3",
|
|
35
|
+
"less-loader": "^4.0.5",
|
|
36
|
+
"sass": "^1.26.5",
|
|
37
|
+
"sass-loader": "^7.3.1",
|
|
38
|
+
"style-loader": "^0.19.0",
|
|
39
|
+
"url-loader": "^0.6.2",
|
|
40
|
+
"vue": "^2.5.9",
|
|
41
|
+
"vue-loader": "^13.5.0",
|
|
42
|
+
"vue-style-loader": "^3.0.3",
|
|
43
|
+
"vue-template-compiler": "^2.5.9",
|
|
44
|
+
"webpack": "^3.9.1"
|
|
45
|
+
},
|
|
46
|
+
"eslintConfig": {
|
|
47
|
+
"root": true,
|
|
48
|
+
"env": {
|
|
49
|
+
"node": true
|
|
50
|
+
},
|
|
51
|
+
"extends": [
|
|
52
|
+
"plugin:vue/essential",
|
|
53
|
+
"eslint:recommended"
|
|
54
|
+
],
|
|
55
|
+
"parserOptions": {
|
|
56
|
+
"parser": "babel-eslint"
|
|
57
|
+
},
|
|
58
|
+
"rules": {}
|
|
59
|
+
},
|
|
60
|
+
"browserslist": [
|
|
61
|
+
"> 1%",
|
|
62
|
+
"last 2 versions",
|
|
63
|
+
"not dead"
|
|
64
|
+
]
|
|
65
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
6
|
+
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
7
|
+
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
|
8
|
+
<title><%= htmlWebpackPlugin.options.title %></title>
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<noscript>
|
|
12
|
+
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
|
13
|
+
</noscript>
|
|
14
|
+
<div id="app"></div>
|
|
15
|
+
<!-- built files will be auto injected -->
|
|
16
|
+
</body>
|
|
17
|
+
</html>
|
package/src/App.vue
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div id="app">
|
|
3
|
+
<div class="toolbar" v-show="isCanvasEnabled">
|
|
4
|
+
<tool-buttons :has-short-cuts="isCanvasEnabled" />
|
|
5
|
+
<div class="toolbar-divider"/>
|
|
6
|
+
<property-pickers />
|
|
7
|
+
</div>
|
|
8
|
+
<div class="demo-entry">
|
|
9
|
+
<input type="checkbox" v-model="isCanvasEnabled"/> Enable Canvas
|
|
10
|
+
</div>
|
|
11
|
+
<drawing-canvas
|
|
12
|
+
ref="drawingCanvas"
|
|
13
|
+
v-if="isCanvasCreated"
|
|
14
|
+
v-show="isCanvasVisible"
|
|
15
|
+
/>
|
|
16
|
+
</div>
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<script>
|
|
20
|
+
import DrawingCanvas from './components/DrawingCanvas.vue'
|
|
21
|
+
import ToolButtons from './components/ToolButtons.vue'
|
|
22
|
+
import PropertyPickers from './components/PropertyPickers.vue'
|
|
23
|
+
export default {
|
|
24
|
+
name: 'App',
|
|
25
|
+
components: {
|
|
26
|
+
DrawingCanvas,
|
|
27
|
+
ToolButtons,
|
|
28
|
+
PropertyPickers
|
|
29
|
+
},
|
|
30
|
+
data: () => ({
|
|
31
|
+
isCanvasCreated: false,
|
|
32
|
+
isCanvasVisible: false
|
|
33
|
+
}),
|
|
34
|
+
computed: {
|
|
35
|
+
isCanvasEnabled: {
|
|
36
|
+
get() {
|
|
37
|
+
return this.isCanvasCreated && this.isCanvasVisible
|
|
38
|
+
},
|
|
39
|
+
set(isEnabled) {
|
|
40
|
+
if (isEnabled) {
|
|
41
|
+
if (this.isCanvasCreated) {
|
|
42
|
+
this.isCanvasVisible = true
|
|
43
|
+
} else {
|
|
44
|
+
this.isCanvasCreated = true
|
|
45
|
+
this.isCanvasVisible = true
|
|
46
|
+
}
|
|
47
|
+
} else {
|
|
48
|
+
this.isCanvasVisible = false
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
<style>
|
|
57
|
+
body {
|
|
58
|
+
margin: 0;
|
|
59
|
+
padding: 0;
|
|
60
|
+
font-family: 'Avenir', Helvetica, Arial, sans-serif;
|
|
61
|
+
-webkit-font-smoothing: antialiased;
|
|
62
|
+
-moz-osx-font-smoothing: grayscale;
|
|
63
|
+
text-align: center;
|
|
64
|
+
color: #2c3e50;
|
|
65
|
+
height: 100vh;
|
|
66
|
+
width: 100vw;
|
|
67
|
+
overflow: hidden;
|
|
68
|
+
}
|
|
69
|
+
#app {
|
|
70
|
+
height: 100%;
|
|
71
|
+
width: 100%;
|
|
72
|
+
}
|
|
73
|
+
.toolbar {
|
|
74
|
+
height: 40px;
|
|
75
|
+
width: 100%;
|
|
76
|
+
display: flex;
|
|
77
|
+
justify-content: center;
|
|
78
|
+
align-items: center;
|
|
79
|
+
background: #EBEEF3;
|
|
80
|
+
}
|
|
81
|
+
.toolbar-divider {
|
|
82
|
+
height: 30px;
|
|
83
|
+
width: 1px;
|
|
84
|
+
background: rgba(0, 0, 0, 0.1);
|
|
85
|
+
margin: 0 7px 0 9px;
|
|
86
|
+
}
|
|
87
|
+
.demo-entry {
|
|
88
|
+
position: absolute;
|
|
89
|
+
top: 0;
|
|
90
|
+
right: 0;
|
|
91
|
+
z-index: 2;
|
|
92
|
+
}
|
|
93
|
+
</style>
|
|
Binary file
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
ref="container"
|
|
4
|
+
class="container"
|
|
5
|
+
>
|
|
6
|
+
<div
|
|
7
|
+
ref="whiteboard"
|
|
8
|
+
:class="[
|
|
9
|
+
'whiteboard',
|
|
10
|
+
{
|
|
11
|
+
'cursor-crosshair': isCrosshairCursorActive
|
|
12
|
+
}
|
|
13
|
+
]"
|
|
14
|
+
/>
|
|
15
|
+
</div>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<script>
|
|
19
|
+
import Canvas from './functions/canvas';
|
|
20
|
+
import Properties from './functions/properties';
|
|
21
|
+
export default {
|
|
22
|
+
name: 'DrawingCanvas',
|
|
23
|
+
computed: {
|
|
24
|
+
canvas() {
|
|
25
|
+
return this.$refs.whiteboard
|
|
26
|
+
},
|
|
27
|
+
container() {
|
|
28
|
+
return this.$refs.container
|
|
29
|
+
},
|
|
30
|
+
isCrosshairCursorActive() {
|
|
31
|
+
return (Properties.isUsingDrawingTool && !Properties.isUsingText)
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
mounted() {
|
|
35
|
+
this.createStage();
|
|
36
|
+
},
|
|
37
|
+
beforeDestroy() {
|
|
38
|
+
this.destroyStage();
|
|
39
|
+
},
|
|
40
|
+
methods: {
|
|
41
|
+
createStage() {
|
|
42
|
+
Canvas.initialize(this.canvas, this.container)
|
|
43
|
+
},
|
|
44
|
+
destroyStage() {
|
|
45
|
+
Canvas.destroy()
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<style scoped>
|
|
52
|
+
* {
|
|
53
|
+
margin: 0;
|
|
54
|
+
padding: 0;
|
|
55
|
+
}
|
|
56
|
+
.container {
|
|
57
|
+
width: 100%;
|
|
58
|
+
height: 100%;
|
|
59
|
+
}
|
|
60
|
+
.whiteboard {
|
|
61
|
+
background-color: yellow;
|
|
62
|
+
}
|
|
63
|
+
.cursor-crosshair {
|
|
64
|
+
cursor: crosshair;
|
|
65
|
+
}
|
|
66
|
+
</style>
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="property">
|
|
3
|
+
<div class="colors">
|
|
4
|
+
<div
|
|
5
|
+
class="color fill-color"
|
|
6
|
+
:style="fillColorStyle"
|
|
7
|
+
>
|
|
8
|
+
<input
|
|
9
|
+
class="color-picker"
|
|
10
|
+
type="color"
|
|
11
|
+
v-model="fillColorValue"
|
|
12
|
+
@contextmenu="removeFillColor"
|
|
13
|
+
/>
|
|
14
|
+
</div>
|
|
15
|
+
<div
|
|
16
|
+
class="color stroke-color"
|
|
17
|
+
:style="{
|
|
18
|
+
borderColor: strokeColor
|
|
19
|
+
}"
|
|
20
|
+
>
|
|
21
|
+
<input
|
|
22
|
+
class="color-picker"
|
|
23
|
+
type="color"
|
|
24
|
+
v-model="strokeColor"
|
|
25
|
+
/>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
<div class="size">
|
|
29
|
+
<span>{{ size }}</span>
|
|
30
|
+
<select
|
|
31
|
+
v-if="isUsingText"
|
|
32
|
+
v-model="fontSize"
|
|
33
|
+
>
|
|
34
|
+
<option
|
|
35
|
+
v-for="fontSizeOptionName, fontSizeOptionValue in fontSizeOptions"
|
|
36
|
+
:value="`${fontSizeOptionValue}`"
|
|
37
|
+
:key="fontSizeOptionValue"
|
|
38
|
+
>
|
|
39
|
+
{{ fontSizeOptionName }}
|
|
40
|
+
</option>
|
|
41
|
+
</select>
|
|
42
|
+
<select
|
|
43
|
+
v-else
|
|
44
|
+
v-model="strokeWidth"
|
|
45
|
+
>
|
|
46
|
+
<option
|
|
47
|
+
v-for="strokeWidthOptionName, strokeWidthOptionValue in strokeWidthOptions"
|
|
48
|
+
:value="`${strokeWidthOptionValue}`"
|
|
49
|
+
:key="strokeWidthOptionValue"
|
|
50
|
+
>
|
|
51
|
+
{{ strokeWidthOptionName }}
|
|
52
|
+
</option>
|
|
53
|
+
</select>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</template>
|
|
57
|
+
|
|
58
|
+
<script>
|
|
59
|
+
import Properties from './functions/properties';
|
|
60
|
+
export default {
|
|
61
|
+
name: 'PropertiesPicker',
|
|
62
|
+
data() {
|
|
63
|
+
return {
|
|
64
|
+
fontSizeOptions: {
|
|
65
|
+
15: 'S',
|
|
66
|
+
20: 'M',
|
|
67
|
+
35: 'L',
|
|
68
|
+
50: 'XL'
|
|
69
|
+
},
|
|
70
|
+
strokeWidthOptions: {
|
|
71
|
+
3: 'H',
|
|
72
|
+
4: 'HB',
|
|
73
|
+
5: 'B',
|
|
74
|
+
6: '2B'
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
computed: {
|
|
79
|
+
fillColor: {
|
|
80
|
+
get() {
|
|
81
|
+
return Properties.fillColor
|
|
82
|
+
},
|
|
83
|
+
set(newColor) {
|
|
84
|
+
Properties.fillColor = newColor
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
strokeColor: {
|
|
88
|
+
get() {
|
|
89
|
+
return Properties.strokeColor
|
|
90
|
+
},
|
|
91
|
+
set(newColor) {
|
|
92
|
+
Properties.strokeColor = newColor
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
strokeWidth: {
|
|
96
|
+
get() {
|
|
97
|
+
return Properties.strokeWidth
|
|
98
|
+
},
|
|
99
|
+
set(newWidth) {
|
|
100
|
+
Properties.strokeWidth = parseInt(newWidth)
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
fontSize: {
|
|
104
|
+
get() {
|
|
105
|
+
return Properties.fontSize
|
|
106
|
+
},
|
|
107
|
+
set(newSize) {
|
|
108
|
+
Properties.fontSize = parseInt(newSize)
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
fillColorValue: {
|
|
112
|
+
get() {
|
|
113
|
+
if (this.fillColor === 'transparent') {
|
|
114
|
+
return '#ffffff'
|
|
115
|
+
}
|
|
116
|
+
return this.fillColor
|
|
117
|
+
},
|
|
118
|
+
set(newColor) {
|
|
119
|
+
this.fillColor = newColor
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
fillColorStyle() {
|
|
123
|
+
if (this.fillColor !== 'transparent') {
|
|
124
|
+
return {
|
|
125
|
+
background: this.fillColor
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
backgroundImage: 'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAMUlEQVQ4T2NkYGAQYcAP3uCTZhw1gGGYhAGBZIA/nYDCgBDAm9BGDWAAJyRCgLaBCAAgXwixzAS0pgAAAABJRU5ErkJggg==)',
|
|
130
|
+
backgroundColor: 'white'
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
isUsingText() {
|
|
134
|
+
return Properties.isUsingText
|
|
135
|
+
},
|
|
136
|
+
size() {
|
|
137
|
+
if (Properties.isUsingText) {
|
|
138
|
+
return this.fontSizeOptions[this.fontSize]
|
|
139
|
+
}
|
|
140
|
+
return this.strokeWidthOptions[this.strokeWidth]
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
methods: {
|
|
144
|
+
removeFillColor(event) {
|
|
145
|
+
event.preventDefault()
|
|
146
|
+
this.fillColor = 'transparent'
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
</script>
|
|
151
|
+
|
|
152
|
+
<style scoped>
|
|
153
|
+
.property {
|
|
154
|
+
background-color: #fff;
|
|
155
|
+
border-radius: 17px;
|
|
156
|
+
height: 34px;
|
|
157
|
+
margin: 3px;
|
|
158
|
+
padding: 8px;
|
|
159
|
+
box-sizing: border-box;
|
|
160
|
+
display: flex;
|
|
161
|
+
}
|
|
162
|
+
.colors {
|
|
163
|
+
height: 18px;
|
|
164
|
+
position: relative;
|
|
165
|
+
width: 30px;
|
|
166
|
+
}
|
|
167
|
+
.color {
|
|
168
|
+
position: absolute;
|
|
169
|
+
width: 18px;
|
|
170
|
+
height: 18px;
|
|
171
|
+
top: 0;
|
|
172
|
+
border-radius: 10px;
|
|
173
|
+
border: 1px solid #eee;
|
|
174
|
+
box-sizing: border-box;
|
|
175
|
+
-webkit-font-smoothing: antialiased;
|
|
176
|
+
-moz-osx-font-smoothing: grayscale;
|
|
177
|
+
overflow: hidden;
|
|
178
|
+
left: 12px;
|
|
179
|
+
}
|
|
180
|
+
.stroke-color {
|
|
181
|
+
background: #fff;
|
|
182
|
+
left: 0;
|
|
183
|
+
border: 4px solid black;
|
|
184
|
+
}
|
|
185
|
+
.color-picker {
|
|
186
|
+
display: block;
|
|
187
|
+
width: 18px;
|
|
188
|
+
height: 18px;
|
|
189
|
+
opacity: 0;
|
|
190
|
+
margin: -1px 0 0 -1px;
|
|
191
|
+
cursor: pointer;
|
|
192
|
+
}
|
|
193
|
+
.stroke-color > .color-picker {
|
|
194
|
+
margin: -4px 0 0 -4px;
|
|
195
|
+
}
|
|
196
|
+
.size {
|
|
197
|
+
height: 18px;
|
|
198
|
+
width: 40px;
|
|
199
|
+
background: #ebeef3;
|
|
200
|
+
font-size: 12px;
|
|
201
|
+
line-height: 18px;
|
|
202
|
+
border-radius: 9px;
|
|
203
|
+
color: #333;
|
|
204
|
+
position: relative;
|
|
205
|
+
margin-left: 6px;
|
|
206
|
+
}
|
|
207
|
+
.size span {
|
|
208
|
+
display: block;
|
|
209
|
+
text-align: center;
|
|
210
|
+
position: absolute;
|
|
211
|
+
width: 40px;
|
|
212
|
+
}
|
|
213
|
+
.size select {
|
|
214
|
+
display: block;
|
|
215
|
+
position: absolute;
|
|
216
|
+
opacity: 0;
|
|
217
|
+
}
|
|
218
|
+
</style>
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
:class="[
|
|
4
|
+
'wrapper',
|
|
5
|
+
{ active: isActive }
|
|
6
|
+
]">
|
|
7
|
+
<button
|
|
8
|
+
:class="[
|
|
9
|
+
'jellies-draw-tool',
|
|
10
|
+
`tool-${action}`
|
|
11
|
+
]"
|
|
12
|
+
@click="applyAction"
|
|
13
|
+
/>
|
|
14
|
+
<span>{{ shortCut }}</span>
|
|
15
|
+
</div>
|
|
16
|
+
</template>
|
|
17
|
+
<script>
|
|
18
|
+
export default {
|
|
19
|
+
name: 'ToolButton',
|
|
20
|
+
props: {
|
|
21
|
+
action: {
|
|
22
|
+
type: String,
|
|
23
|
+
default: 'selector'
|
|
24
|
+
},
|
|
25
|
+
shortCut: {
|
|
26
|
+
type: Number,
|
|
27
|
+
default: 1
|
|
28
|
+
},
|
|
29
|
+
isActive: {
|
|
30
|
+
type: Boolean,
|
|
31
|
+
default: false
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
methods: {
|
|
35
|
+
applyAction() {
|
|
36
|
+
this.$emit('action-applied', this.action)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
</script>
|
|
41
|
+
<style scoped>
|
|
42
|
+
@font-face {
|
|
43
|
+
font-family: "jellies-draw";
|
|
44
|
+
src: url('../assets/jellies-draw-tool.ttf') format('truetype');
|
|
45
|
+
}
|
|
46
|
+
button {
|
|
47
|
+
border: none;
|
|
48
|
+
cursor: pointer;
|
|
49
|
+
padding: 0;
|
|
50
|
+
width: 100%;
|
|
51
|
+
height: 100%;
|
|
52
|
+
text-align: center;
|
|
53
|
+
color: inherit;
|
|
54
|
+
outline: none;
|
|
55
|
+
background-color: transparent;
|
|
56
|
+
font-family: "jellies-draw", sans-serif !important;
|
|
57
|
+
font-size: 16px;
|
|
58
|
+
font-style: normal;
|
|
59
|
+
-webkit-font-smoothing: antialiased;
|
|
60
|
+
-moz-osx-font-smoothing: grayscale;
|
|
61
|
+
}
|
|
62
|
+
.wrapper {
|
|
63
|
+
position: relative;
|
|
64
|
+
border-radius: 5px;
|
|
65
|
+
width: 34px;
|
|
66
|
+
height: 34px;
|
|
67
|
+
margin: 3px;
|
|
68
|
+
color: #555;
|
|
69
|
+
background-color: #fff;
|
|
70
|
+
}
|
|
71
|
+
.wrapper:hover {
|
|
72
|
+
box-shadow: 0 1px 0 0 rgba(30, 30, 30, 0.2);
|
|
73
|
+
margin-top: 2px;
|
|
74
|
+
}
|
|
75
|
+
.wrapper > span {
|
|
76
|
+
position: absolute;
|
|
77
|
+
bottom: 2px;
|
|
78
|
+
right: 4px;
|
|
79
|
+
font-size: 9px;
|
|
80
|
+
font-weight: bold;
|
|
81
|
+
color: #aaa;
|
|
82
|
+
pointer-events: none;
|
|
83
|
+
}
|
|
84
|
+
.wrapper.active {
|
|
85
|
+
background-color: #c6e2ff;
|
|
86
|
+
color: #399af4;
|
|
87
|
+
}
|
|
88
|
+
.wrapper.active:hover {
|
|
89
|
+
margin-top: 3px;
|
|
90
|
+
box-shadow: none;
|
|
91
|
+
}
|
|
92
|
+
.wrapper.active > span {
|
|
93
|
+
color: #399af4;
|
|
94
|
+
}
|
|
95
|
+
.tool-ellipse:before {
|
|
96
|
+
content: "\e654";
|
|
97
|
+
}
|
|
98
|
+
.tool-eraser:before {
|
|
99
|
+
content: "\e689";
|
|
100
|
+
}
|
|
101
|
+
.tool-text:before {
|
|
102
|
+
content: "\e69f";
|
|
103
|
+
}
|
|
104
|
+
.tool-image:before {
|
|
105
|
+
content: "\e6d8";
|
|
106
|
+
}
|
|
107
|
+
.tool-arrow:before {
|
|
108
|
+
content: "\e6f7";
|
|
109
|
+
}
|
|
110
|
+
.tool-line:before {
|
|
111
|
+
content: "\e70a";
|
|
112
|
+
}
|
|
113
|
+
.tool-selector:before {
|
|
114
|
+
content: "\e713";
|
|
115
|
+
}
|
|
116
|
+
.tool-pen:before {
|
|
117
|
+
content: "\e727";
|
|
118
|
+
}
|
|
119
|
+
.tool-rectangle:before {
|
|
120
|
+
content: "\e777";
|
|
121
|
+
}
|
|
122
|
+
.tool-clear:before {
|
|
123
|
+
content: "\e7a9";
|
|
124
|
+
}
|
|
125
|
+
</style>
|