@operato/scene-basic 1.2.5
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/CHANGELOG.md +11 -0
- package/README.md +0 -0
- package/demo/index.html +158 -0
- package/demo/things-scene-basic.html +6 -0
- package/dist/anchors/ellipse-anchors.d.ts +7 -0
- package/dist/anchors/ellipse-anchors.js +43 -0
- package/dist/anchors/ellipse-anchors.js.map +1 -0
- package/dist/audio.d.ts +25 -0
- package/dist/audio.js +141 -0
- package/dist/audio.js.map +1 -0
- package/dist/cloud.d.ts +13 -0
- package/dist/cloud.js +30 -0
- package/dist/cloud.js.map +1 -0
- package/dist/donut.d.ts +15 -0
- package/dist/donut.js +74 -0
- package/dist/donut.js.map +1 -0
- package/dist/ellipse.d.ts +24 -0
- package/dist/ellipse.js +72 -0
- package/dist/ellipse.js.map +1 -0
- package/dist/gif-view.d.ts +18 -0
- package/dist/gif-view.js +116 -0
- package/dist/gif-view.js.map +1 -0
- package/dist/image-view.d.ts +19 -0
- package/dist/image-view.js +180 -0
- package/dist/image-view.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/outline/ellipse-outline.d.ts +2 -0
- package/dist/outline/ellipse-outline.js +11 -0
- package/dist/outline/ellipse-outline.js.map +1 -0
- package/dist/polygon.d.ts +19 -0
- package/dist/polygon.js +84 -0
- package/dist/polygon.js.map +1 -0
- package/dist/polyline.d.ts +18 -0
- package/dist/polyline.js +102 -0
- package/dist/polyline.js.map +1 -0
- package/dist/rect.d.ts +19 -0
- package/dist/rect.js +60 -0
- package/dist/rect.js.map +1 -0
- package/dist/star.d.ts +13 -0
- package/dist/star.js +80 -0
- package/dist/star.js.map +1 -0
- package/dist/templates/audio.d.ts +14 -0
- package/dist/templates/audio.js +15 -0
- package/dist/templates/audio.js.map +1 -0
- package/dist/templates/color-image.d.ts +22 -0
- package/dist/templates/color-image.js +23 -0
- package/dist/templates/color-image.js.map +1 -0
- package/dist/templates/donut.d.ts +22 -0
- package/dist/templates/donut.js +23 -0
- package/dist/templates/donut.js.map +1 -0
- package/dist/templates/ellipse.d.ts +21 -0
- package/dist/templates/ellipse.js +22 -0
- package/dist/templates/ellipse.js.map +1 -0
- package/dist/templates/gif-image.d.ts +14 -0
- package/dist/templates/gif-image.js +15 -0
- package/dist/templates/gif-image.js.map +1 -0
- package/dist/templates/gray-image.d.ts +22 -0
- package/dist/templates/gray-image.js +23 -0
- package/dist/templates/gray-image.js.map +1 -0
- package/dist/templates/index.d.ts +74 -0
- package/dist/templates/index.js +15 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/templates/polygon.d.ts +22 -0
- package/dist/templates/polygon.js +25 -0
- package/dist/templates/polygon.js.map +1 -0
- package/dist/templates/polyline.d.ts +22 -0
- package/dist/templates/polyline.js +25 -0
- package/dist/templates/polyline.js.map +1 -0
- package/dist/templates/rect.d.ts +21 -0
- package/dist/templates/rect.js +22 -0
- package/dist/templates/rect.js.map +1 -0
- package/dist/templates/star.d.ts +23 -0
- package/dist/templates/star.js +24 -0
- package/dist/templates/star.js.map +1 -0
- package/dist/templates/text.d.ts +27 -0
- package/dist/templates/text.js +28 -0
- package/dist/templates/text.js.map +1 -0
- package/dist/templates/triangle.d.ts +23 -0
- package/dist/templates/triangle.js +24 -0
- package/dist/templates/triangle.js.map +1 -0
- package/dist/text.d.ts +6 -0
- package/dist/text.js +11 -0
- package/dist/text.js.map +1 -0
- package/dist/triangle.d.ts +14 -0
- package/dist/triangle.js +75 -0
- package/dist/triangle.js.map +1 -0
- package/icons/audio.png +0 -0
- package/icons/both-arrow.png +0 -0
- package/icons/color-image.png +0 -0
- package/icons/container.png +0 -0
- package/icons/dash.png +0 -0
- package/icons/donut.png +0 -0
- package/icons/ellipse.png +0 -0
- package/icons/gif-image.png +0 -0
- package/icons/global-reference.png +0 -0
- package/icons/gray-image.png +0 -0
- package/icons/humidity-sensor.png +0 -0
- package/icons/info-window.png +0 -0
- package/icons/line.png +0 -0
- package/icons/local-reference.png +0 -0
- package/icons/no-image.png +0 -0
- package/icons/ortholine.png +0 -0
- package/icons/person.png +0 -0
- package/icons/polygon.png +0 -0
- package/icons/polyline.png +0 -0
- package/icons/popup.png +0 -0
- package/icons/rect.png +0 -0
- package/icons/single-arrow.png +0 -0
- package/icons/star.png +0 -0
- package/icons/text.png +0 -0
- package/icons/triangle.png +0 -0
- package/package.json +61 -0
- package/src/anchors/ellipse-anchors.ts +46 -0
- package/src/audio.ts +173 -0
- package/src/cloud.ts +40 -0
- package/src/donut.ts +92 -0
- package/src/ellipse.ts +90 -0
- package/src/gif-view.ts +146 -0
- package/src/image-view.ts +215 -0
- package/src/index.ts +16 -0
- package/src/outline/ellipse-outline.ts +15 -0
- package/src/polygon.ts +103 -0
- package/src/polyline.ts +122 -0
- package/src/rect.ts +71 -0
- package/src/star.ts +104 -0
- package/src/templates/audio.ts +15 -0
- package/src/templates/color-image.ts +23 -0
- package/src/templates/donut.ts +23 -0
- package/src/templates/ellipse.ts +22 -0
- package/src/templates/gif-image.ts +15 -0
- package/src/templates/gray-image.ts +23 -0
- package/src/templates/index.ts +16 -0
- package/src/templates/polygon.ts +25 -0
- package/src/templates/polyline.ts +25 -0
- package/src/templates/rect.ts +22 -0
- package/src/templates/star.ts +24 -0
- package/src/templates/text.ts +28 -0
- package/src/templates/triangle.ts +24 -0
- package/src/text.ts +12 -0
- package/src/triangle.ts +87 -0
- package/test/basic-test.html +63 -0
- package/test/index.html +22 -0
- package/things-scene.config.js +5 -0
- package/tsconfig.json +23 -0
- package/tsconfig.tsbuildinfo +1 -0
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@operato/scene-basic",
|
|
3
|
+
"description": "basic component for things-scene",
|
|
4
|
+
"author": "heartyoh",
|
|
5
|
+
"version": "1.2.5",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"things-scene": true,
|
|
9
|
+
"publishConfig": {
|
|
10
|
+
"access": "public",
|
|
11
|
+
"@oprato:registry": "https://registry.npmjs.org"
|
|
12
|
+
},
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/things-scene/operato-scene.git",
|
|
16
|
+
"directory": "packages/basic"
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"serve": "tsc && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"things-factory-dev\"",
|
|
20
|
+
"serve:dev": "npm run serve",
|
|
21
|
+
"start": "tsc && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"wds\"",
|
|
22
|
+
"build": "tsc",
|
|
23
|
+
"prepublish": "tsc",
|
|
24
|
+
"lint": "eslint --ext .ts,.html . --ignore-path .gitignore && prettier \"**/*.ts\" --check --ignore-path .gitignore",
|
|
25
|
+
"format": "eslint --ext .ts,.html . --fix --ignore-path .gitignore && prettier \"**/*.ts\" --write --ignore-path .gitignore",
|
|
26
|
+
"migration": "things-factory-migration"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@hatiolab/things-scene": "^3.2.0",
|
|
30
|
+
"@wizpanda/super-gif": "^0.0.6"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@hatiolab/prettier-config": "^1.0.0",
|
|
34
|
+
"@things-factory/builder": "^6.0.0",
|
|
35
|
+
"@things-factory/operato-board": "^6.0.0",
|
|
36
|
+
"@typescript-eslint/eslint-plugin": "^4.33.0",
|
|
37
|
+
"@typescript-eslint/parser": "^4.33.0",
|
|
38
|
+
"@web/dev-server": "^0.1.28",
|
|
39
|
+
"concurrently": "^5.3.0",
|
|
40
|
+
"eslint": "^7.32.0",
|
|
41
|
+
"eslint-config-prettier": "^8.3.0",
|
|
42
|
+
"husky": "^4.3.8",
|
|
43
|
+
"lint-staged": "^10.5.4",
|
|
44
|
+
"prettier": "^2.4.1",
|
|
45
|
+
"tslib": "^2.3.1",
|
|
46
|
+
"typescript": "^4.9.4"
|
|
47
|
+
},
|
|
48
|
+
"prettier": "@hatiolab/prettier-config",
|
|
49
|
+
"husky": {
|
|
50
|
+
"hooks": {
|
|
51
|
+
"pre-commit": "lint-staged"
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"lint-staged": {
|
|
55
|
+
"*.ts": [
|
|
56
|
+
"eslint --fix",
|
|
57
|
+
"prettier --write"
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
"gitHead": "31ccfb354b68b2516f48ca0d033b07974326a6eb"
|
|
61
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Anchor, Component } from '@hatiolab/things-scene'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @function ellipseAnchors
|
|
5
|
+
* @param {Component} component
|
|
6
|
+
* @return {Anchor[]}
|
|
7
|
+
*/
|
|
8
|
+
export default function ellipseAnchors(component: Component): Anchor[] {
|
|
9
|
+
var { left, top, width, height } = component.bounds
|
|
10
|
+
|
|
11
|
+
var centerx = left + width / 2
|
|
12
|
+
var centery = top + height / 2
|
|
13
|
+
var right = left + width
|
|
14
|
+
var bottom = top + height
|
|
15
|
+
|
|
16
|
+
return [
|
|
17
|
+
{
|
|
18
|
+
name: 'TOP',
|
|
19
|
+
position: {
|
|
20
|
+
x: centerx,
|
|
21
|
+
y: top
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: 'RIGHT',
|
|
26
|
+
position: {
|
|
27
|
+
x: right,
|
|
28
|
+
y: centery
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'BOTTOM',
|
|
33
|
+
position: {
|
|
34
|
+
x: centerx,
|
|
35
|
+
y: bottom
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'LEFT',
|
|
40
|
+
position: {
|
|
41
|
+
x: left,
|
|
42
|
+
y: centery
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
package/src/audio.ts
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Component, ComponentNature, Properties, RectPath, Shape } from '@hatiolab/things-scene'
|
|
6
|
+
|
|
7
|
+
const NATURE: ComponentNature = {
|
|
8
|
+
mutable: false,
|
|
9
|
+
resizable: true,
|
|
10
|
+
rotatable: true,
|
|
11
|
+
properties: [
|
|
12
|
+
{
|
|
13
|
+
type: 'string',
|
|
14
|
+
label: 'src',
|
|
15
|
+
name: 'src'
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
type: 'checkbox',
|
|
19
|
+
label: 'started',
|
|
20
|
+
name: 'started'
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
type: 'checkbox',
|
|
24
|
+
label: 'loop',
|
|
25
|
+
name: 'loop'
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
'value-property': 'src',
|
|
29
|
+
help: 'scene/component/audio'
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const AUDIO_IMAGE =
|
|
33
|
+
'data:image/png;base64,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'
|
|
34
|
+
|
|
35
|
+
export default class AudioPlayer extends RectPath(Shape) {
|
|
36
|
+
static IMAGE: HTMLImageElement
|
|
37
|
+
|
|
38
|
+
static get image() {
|
|
39
|
+
if (!AudioPlayer.IMAGE) {
|
|
40
|
+
AudioPlayer.IMAGE = new Image()
|
|
41
|
+
AudioPlayer.IMAGE.src = AUDIO_IMAGE
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return AudioPlayer.IMAGE
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
_audio: any
|
|
48
|
+
|
|
49
|
+
dispose() {
|
|
50
|
+
super.dispose()
|
|
51
|
+
|
|
52
|
+
this.started = false
|
|
53
|
+
delete this._audio
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
ready() {
|
|
57
|
+
super.ready()
|
|
58
|
+
|
|
59
|
+
this._audio = new Audio()
|
|
60
|
+
|
|
61
|
+
this._audio.addEventListener('canplay', () => {
|
|
62
|
+
this.started && this._audio.play()
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
var { src = '', loop = false, started = false } = this.state
|
|
66
|
+
|
|
67
|
+
this.onchangeSrc(src)
|
|
68
|
+
this.onchangeLoop(loop)
|
|
69
|
+
this.onchangeStarted(started)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
render(ctx: CanvasRenderingContext2D) {
|
|
73
|
+
var { left, top, width, height, src } = this.state
|
|
74
|
+
|
|
75
|
+
ctx.beginPath()
|
|
76
|
+
|
|
77
|
+
this.drawImage(ctx, AudioPlayer.image, left, top, width, height)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
get nature() {
|
|
81
|
+
return NATURE
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
get hasTextProperty() {
|
|
85
|
+
return false
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
get src() {
|
|
89
|
+
return this.get('src')
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
set src(src) {
|
|
93
|
+
this.set('src', src)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
get started() {
|
|
97
|
+
return !!this.get('started')
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
set started(started) {
|
|
101
|
+
this.set('started', started)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
start() {
|
|
105
|
+
if (!this._audio) return
|
|
106
|
+
|
|
107
|
+
this._audio.classList.add('active')
|
|
108
|
+
this._audio.play()
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
pause() {
|
|
112
|
+
if (!this._audio) return
|
|
113
|
+
|
|
114
|
+
this._audio.classList.remove('active')
|
|
115
|
+
this._audio.pause()
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
onchangeSrc(src: string) {
|
|
119
|
+
try {
|
|
120
|
+
// this._audio.crossOrigin = "anonymous";
|
|
121
|
+
if (String(src).substring(0, 4) !== 'data') this._audio.crossOrigin = 'use-credentials'
|
|
122
|
+
else this._audio.crossOrigin = null
|
|
123
|
+
|
|
124
|
+
this._audio.src = typeof src === 'string' ? this.app.url(src) : src
|
|
125
|
+
} catch (e) {
|
|
126
|
+
console.error(e)
|
|
127
|
+
return
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
onchangeStarted(started: boolean) {
|
|
132
|
+
const audio = this._audio
|
|
133
|
+
|
|
134
|
+
if (started) {
|
|
135
|
+
/*
|
|
136
|
+
[ audio/video.readyState ]
|
|
137
|
+
0 = HAVE_NOTHING - no information whether or not the audio/video is ready
|
|
138
|
+
1 = HAVE_METADATA - metadata for the audio/video is ready
|
|
139
|
+
2 = HAVE_CURRENT_DATA - data for the current playback position is available, but not enough data to play next frame/millisecond
|
|
140
|
+
3 = HAVE_FUTURE_DATA - data for the current and at least the next frame is available
|
|
141
|
+
4 = HAVE_ENOUGH_DATA - enough data available to start playing
|
|
142
|
+
*/
|
|
143
|
+
audio.readyState == 4 && audio.play()
|
|
144
|
+
} else {
|
|
145
|
+
audio.pause()
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
onchangeLoop(loop: boolean) {
|
|
150
|
+
this._audio.loop = loop
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
onchange(after: Properties, before: Properties) {
|
|
154
|
+
'src' in after && this.onchangeSrc(after.src)
|
|
155
|
+
'started' in after && this.onchangeStarted(after.started)
|
|
156
|
+
'loop' in after && this.onchangeLoop(after.loop)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
ondblclick(e: MouseEvent) {
|
|
160
|
+
this.started = !this.started
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
ondropfile(transfered: DataTransferItemList, files: FileList) {
|
|
164
|
+
for (let i = 0; i < transfered.length; i++) {
|
|
165
|
+
if (transfered[i].type.startsWith('audio/')) {
|
|
166
|
+
this.src = files[i]
|
|
167
|
+
return
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
Component.register('audio', AudioPlayer)
|
package/src/cloud.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Component } from '@hatiolab/things-scene'
|
|
6
|
+
|
|
7
|
+
export default class Cloud extends Component {
|
|
8
|
+
prerender(ctx: CanvasRenderingContext2D) {
|
|
9
|
+
//TODO center()를 구현할 때까지, 아무 구현없이 오버라이드한다.
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
render(ctx: CanvasRenderingContext2D) {
|
|
13
|
+
var { x, y } = this.state
|
|
14
|
+
|
|
15
|
+
ctx.beginPath()
|
|
16
|
+
|
|
17
|
+
ctx.moveTo(x, y)
|
|
18
|
+
|
|
19
|
+
ctx.bezierCurveTo(x - 40, y + 20, x - 40, y + 70, x + 50, y + 70)
|
|
20
|
+
ctx.bezierCurveTo(x + 80, y + 100, x + 150, y + 100, x + 170, y + 70)
|
|
21
|
+
ctx.bezierCurveTo(x + 250, y + 70, x + 250, y + 40, x + 220, y + 30)
|
|
22
|
+
ctx.bezierCurveTo(x + 260, y - 40, x + 200, y - 50, x + 170, y - 30)
|
|
23
|
+
ctx.bezierCurveTo(x + 150, y - 75, x + 80, y - 60, x + 80, y - 30)
|
|
24
|
+
ctx.bezierCurveTo(x + 30, y - 75, x - 20, y - 60, x, y)
|
|
25
|
+
|
|
26
|
+
ctx.closePath()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
get path() {
|
|
30
|
+
var { x, y } = this.state
|
|
31
|
+
|
|
32
|
+
return [{ x, y }]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
set path(path) {
|
|
36
|
+
/* do nothing */
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
Component.register('cloud', Cloud)
|
package/src/donut.ts
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Component, ComponentNature, POSITION } from '@hatiolab/things-scene'
|
|
6
|
+
import Ellipse from './ellipse'
|
|
7
|
+
|
|
8
|
+
const NATURE: ComponentNature = {
|
|
9
|
+
mutable: false,
|
|
10
|
+
resizable: true,
|
|
11
|
+
rotatable: true,
|
|
12
|
+
properties: [
|
|
13
|
+
{
|
|
14
|
+
type: 'number',
|
|
15
|
+
label: 'ratio',
|
|
16
|
+
name: 'ratio',
|
|
17
|
+
property: 'ratio'
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
help: 'scene/component/donut'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
var controlHandler = {
|
|
24
|
+
ondragmove: function (point: POSITION, index: number, component: Component) {
|
|
25
|
+
var { cx, rx } = component.model
|
|
26
|
+
rx = Math.abs(rx)
|
|
27
|
+
|
|
28
|
+
var transcoorded = component.transcoordP2S(point.x, point.y)
|
|
29
|
+
|
|
30
|
+
var ratio = ((transcoorded.x - cx) / rx) * 100
|
|
31
|
+
|
|
32
|
+
ratio = ratio >= 100 || ratio <= -100 ? 100 : Math.abs(ratio)
|
|
33
|
+
|
|
34
|
+
component.set({ ratio })
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default class Donut extends Ellipse {
|
|
39
|
+
is3dish() {
|
|
40
|
+
return false
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
render(ctx: CanvasRenderingContext2D) {
|
|
44
|
+
var { ratio = 50, cx, cy, rx, ry, startAngle, endAngle, anticlockwise } = this.state
|
|
45
|
+
rx = Math.abs(rx)
|
|
46
|
+
ry = Math.abs(ry)
|
|
47
|
+
|
|
48
|
+
ctx.beginPath()
|
|
49
|
+
ctx.ellipse(cx, cy, rx, ry, 0, startAngle || 0, endAngle || 2 * Math.PI, anticlockwise)
|
|
50
|
+
|
|
51
|
+
ctx.moveTo(cx + (rx / 100) * ratio, cy)
|
|
52
|
+
// 맨 마지막 속성이 true면 원의 범위만큼 공백이 됨
|
|
53
|
+
ctx.ellipse(cx, cy, (rx / 100) * ratio, (ry / 100) * ratio, 0, startAngle || 0, endAngle || 2 * Math.PI, true)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
contains(x: number, y: number) {
|
|
57
|
+
var { cx, cy, rx, ry, ratio } = this.state
|
|
58
|
+
rx = Math.abs(rx)
|
|
59
|
+
ry = Math.abs(ry)
|
|
60
|
+
|
|
61
|
+
var normx = (x - cx) / (rx * 2 - 0.5)
|
|
62
|
+
var normy = (y - cy) / (ry * 2 - 0.5)
|
|
63
|
+
var ratiox = (x - cx) / ((rx / 100) * ratio * 2 - 0.5)
|
|
64
|
+
var ratioy = (y - cy) / ((ry / 100) * ratio * 2 - 0.5)
|
|
65
|
+
var result = false
|
|
66
|
+
|
|
67
|
+
if (normx * normx + normy * normy < 0.25 && ratiox * ratiox + ratioy * ratioy > 0.25) result = !result
|
|
68
|
+
|
|
69
|
+
return result
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
get controls() {
|
|
73
|
+
var { cx, cy, rx, ratio } = this.state
|
|
74
|
+
rx = Math.abs(rx)
|
|
75
|
+
|
|
76
|
+
return [
|
|
77
|
+
{
|
|
78
|
+
x: cx + (rx / 100) * ratio,
|
|
79
|
+
y: cy,
|
|
80
|
+
handler: controlHandler
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
get nature() {
|
|
86
|
+
return NATURE
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
Component.memoize(Donut.prototype, 'controls', false)
|
|
91
|
+
|
|
92
|
+
Component.register('donut', Donut)
|
package/src/ellipse.ts
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Anchor, Component, ComponentNature, Connectable, Shape } from '@hatiolab/things-scene'
|
|
6
|
+
|
|
7
|
+
import ellipseAnchors from './anchors/ellipse-anchors'
|
|
8
|
+
import ellipseOutline from './outline/ellipse-outline'
|
|
9
|
+
|
|
10
|
+
const NATURE: ComponentNature = {
|
|
11
|
+
mutable: false,
|
|
12
|
+
resizable: true,
|
|
13
|
+
rotatable: true,
|
|
14
|
+
properties: [],
|
|
15
|
+
'value-property': 'text'
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default class Ellipse extends Connectable(Shape) {
|
|
19
|
+
is3dish() {
|
|
20
|
+
return true
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
render(context: CanvasRenderingContext2D) {
|
|
24
|
+
var { cx, cy, rx, ry, startAngle, endAngle, anticlockwise } = this.state
|
|
25
|
+
|
|
26
|
+
context.beginPath()
|
|
27
|
+
|
|
28
|
+
context.ellipse(cx, cy, Math.abs(rx), Math.abs(ry), 0, startAngle || 0, endAngle || 2 * Math.PI, anticlockwise)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
get path() {
|
|
32
|
+
var { cx, cy, rx, ry } = this.state
|
|
33
|
+
|
|
34
|
+
return [
|
|
35
|
+
{
|
|
36
|
+
x: cx - rx,
|
|
37
|
+
y: cy - ry
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
x: cx + rx,
|
|
41
|
+
y: cy - ry
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
x: cx + rx,
|
|
45
|
+
y: cy + ry
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
x: cx - rx,
|
|
49
|
+
y: cy + ry
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
set path(path) {
|
|
55
|
+
var left_top = path[0]
|
|
56
|
+
var right_bottom = path[2]
|
|
57
|
+
|
|
58
|
+
this.set({
|
|
59
|
+
cx: left_top.x + (right_bottom.x - left_top.x) / 2,
|
|
60
|
+
cy: left_top.y + (right_bottom.y - left_top.y) / 2,
|
|
61
|
+
rx: (right_bottom.x - left_top.x) / 2,
|
|
62
|
+
ry: (right_bottom.y - left_top.y) / 2
|
|
63
|
+
})
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
contains(x: number, y: number) {
|
|
67
|
+
var { cx, cy, rx, ry } = this.state
|
|
68
|
+
|
|
69
|
+
var normx = (x - cx) / (rx * 2 - 0.5)
|
|
70
|
+
var normy = (y - cy) / (ry * 2 - 0.5)
|
|
71
|
+
|
|
72
|
+
return normx * normx + normy * normy < 0.25
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
outline(progress: number) {
|
|
76
|
+
return ellipseOutline(this, progress)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
get anchors(): Array<Anchor> {
|
|
80
|
+
return ellipseAnchors(this)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
get nature() {
|
|
84
|
+
return NATURE
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
Component.memoize(Ellipse.prototype, 'path', false)
|
|
89
|
+
|
|
90
|
+
Component.register('ellipse', Ellipse)
|
package/src/gif-view.ts
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
import { Component, ComponentNature, HTMLOverlayElement, Properties, RectPath, Shape } from '@hatiolab/things-scene'
|
|
5
|
+
import { SuperGif } from '@wizpanda/super-gif'
|
|
6
|
+
|
|
7
|
+
const NATURE: ComponentNature = {
|
|
8
|
+
mutable: false,
|
|
9
|
+
resizable: true,
|
|
10
|
+
rotatable: true,
|
|
11
|
+
properties: [
|
|
12
|
+
{
|
|
13
|
+
type: 'string',
|
|
14
|
+
label: 'src',
|
|
15
|
+
name: 'src'
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
type: 'checkbox',
|
|
19
|
+
label: 'play',
|
|
20
|
+
name: 'play'
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
'value-property': 'src',
|
|
24
|
+
help: 'scene/component/gif-view'
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const NOIMAGE_DATA_URI =
|
|
28
|
+
'data:image/gif;base64,R0lGODlhYABIAPcAAAAAAAEBAQICAgMDAwQEBAUFBQYGBgcHBwgICAkJCQoKCgsLCwwMDA0NDQ4ODg8PDxAQEBERERISEhMTExQUFBUVFRYWFhcXFxgYGBkZGRoaGhsbGxwcHB0dHR4eHh8fHyAgICEhISIiIiMjIyQkJCUlJSYmJicnJygoKCkpKSoqKisrKywsLC0tLS4uLi8vLzAwMDExMTIyMjMzMzQ0NDU1NTY2Njc3Nzg4ODk5OTo6Ojs7Ozw8PD09PT4+Pj8/P0BAQEFBQUJCQkNDQ0REREVFRUZGRkdHR0hISElJSUpKSktLS0xMTE1NTU5OTk9PT1BQUFFRUVJSUlNTU1RUVFVVVVZWVldXV1hYWFlZWVpaWltbW1xcXF1dXV5eXl9fX2BgYGFhYWJiYmNjY2RkZGVlZWZmZmdnZ2hoaGlpaWpqamtra2xsbG1tbW5ubm9vb3BwcHFxcXJycnNzc3R0dHV1dXZ2dnd3d3h4eHl5eXp6ent7e3x8fH19fX5+fn9/f4CAgIGBgYKCgoODg4SEhIWFhYaGhoeHh4iIiImJiYqKio+Pj5iYmKCgoKampqurq66urrCwsLGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrOzs7S0tLa2tre3t7m5ubu7u7+/v8DAwMHBwcPDw8XFxcfHx8vLy8/Pz9LS0tXV1dfX193d3eTk5Onp6fj4+Pz8/P7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v///////////////////////////////////////////////////////////////////////////////yH5BAkAAPUAIf47R2VuZXJhdGVkIGJ5IGpzZ2lmIChodHRwczovL2dpdGh1Yi5jb20vYW50aW1hdHRlcjE1L2pzZ2lmLykALAAAAABgAEgAAAj+AGcJHEiwoMGDCBMqXMiwocOHECNKnEixosWLGDNq3Mixo8ePIEOKHEmypMmR9VKqXMmypcuXMGPKnJkSIs2bOHPqZGlzp8+fQOv1DEq0KMyhRpMmRaq0KVCmTqPmhCq1qkyqLrFRSyYwGTVsVo1iZXmNa8Fk18ISHasSm1mDycCq/ck2JTWF1ObSfTjz7cFken3WFbow8M7BDA3rHOwXruKpfGXeTZg3qDVrUge7RRg3KLZjx+Q2HVyvLNy0QaMJjBaVdD2tZr2K/mmNIObRkR+n9AsYt0Pddg1WXppb8bWDx1CLLW74GcJnSl3TtDY8Zu2Et4tKl7n52eyWnxXvhl7+26jqrspbnlfIWjtz2gWPZV95neH8veU9NxZYfbfD3kFt99J6Bnmn0mQO9XfYezrVxxlmx0GUXIAM4hSeffsxBN1TFd5E4Ef3QZbfTg6CNJ5gHXJ3TEntLThiTh+KFCJNAqZU4kgAitjQTheepOBMNcZI0oQ6JpbTjSZtiNN2PZ400IxHpdiSc07G911M0iFZZYtAStnWilUeBGVLrlEZpmM0elmPlmfO8iOZXl4DZpsGEYmll2bSWWCXLwJXVY1+urhjoGEBSuiSah6K36CKtpZoo4s9CimielZq6aWYZqrpppx26umnoIZ6UkAAOw=='
|
|
29
|
+
|
|
30
|
+
export default class GifView extends HTMLOverlayElement {
|
|
31
|
+
_superGif?: SuperGif
|
|
32
|
+
|
|
33
|
+
async oncreate_element(div: HTMLDivElement) {
|
|
34
|
+
var { src, play } = this.state
|
|
35
|
+
|
|
36
|
+
this.onchangesrc(src)
|
|
37
|
+
this.onchangeplay(play)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
buildImg() {
|
|
41
|
+
/* clear first */
|
|
42
|
+
var div = this.element
|
|
43
|
+
div.innerHTML = ''
|
|
44
|
+
|
|
45
|
+
var gif = document.createElement('img')
|
|
46
|
+
gif.style.width = '100%'
|
|
47
|
+
gif.style.height = '100%'
|
|
48
|
+
|
|
49
|
+
div.appendChild(gif)
|
|
50
|
+
|
|
51
|
+
return gif
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
onchange(after: Properties, before: Properties) {
|
|
55
|
+
super.onchange(after, before)
|
|
56
|
+
|
|
57
|
+
'src' in after && this.onchangesrc(after.src)
|
|
58
|
+
'play' in after && this.onchangeplay(after.play)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
setElementProperties(div: HTMLDivElement) {}
|
|
62
|
+
|
|
63
|
+
onchangeplay(play: boolean) {
|
|
64
|
+
var superGif = this._superGif
|
|
65
|
+
|
|
66
|
+
if (!superGif || !superGif.isReady()) {
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (play) {
|
|
71
|
+
superGif.play()
|
|
72
|
+
} else {
|
|
73
|
+
superGif.pause()
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
onchangesrc(src: string) {
|
|
78
|
+
var gif = this.buildImg()
|
|
79
|
+
|
|
80
|
+
if (!src) src = NOIMAGE_DATA_URI
|
|
81
|
+
|
|
82
|
+
gif.src = src
|
|
83
|
+
gif.setAttribute('rel:animated_src', src)
|
|
84
|
+
gif.setAttribute('rel:auto_play', '0')
|
|
85
|
+
|
|
86
|
+
this._superGif = new SuperGif(gif, {
|
|
87
|
+
autoPlay: false /* Without this setting, the first play's framerate is too fast. */
|
|
88
|
+
})
|
|
89
|
+
//@ts-ignore
|
|
90
|
+
this._superGif!.init()
|
|
91
|
+
|
|
92
|
+
for (const child of this.element.children as any) {
|
|
93
|
+
child.style.width = '100%'
|
|
94
|
+
child.style.height = '100%'
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
var canvas = this._superGif!.getCanvas()
|
|
98
|
+
canvas.style.width = '100%'
|
|
99
|
+
canvas.style.height = '100%'
|
|
100
|
+
|
|
101
|
+
this._superGif.load(() => {
|
|
102
|
+
this._superGif!.moveTo(0)
|
|
103
|
+
|
|
104
|
+
/*
|
|
105
|
+
* FIXME. this.play 는 컴포넌트의 getState()를 통해서 가져오게 되는데, 체크박스의 경우 문제가 있는 것 같다.
|
|
106
|
+
* 문제 해결 후 this.get("play") => this.play로 수정할 것.
|
|
107
|
+
*/
|
|
108
|
+
this.play && this._superGif!.play()
|
|
109
|
+
})
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
ondropfile(transfered: DataTransferItemList, files: FileList) {
|
|
113
|
+
for (let i = 0; i < transfered.length; i++) {
|
|
114
|
+
if (/\.gif$/.test((transfered[i] as any).name)) {
|
|
115
|
+
this.src = files[i]
|
|
116
|
+
return
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
get src() {
|
|
122
|
+
return this.getState('src')
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
set src(src) {
|
|
126
|
+
this.set('src', src)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
get play() {
|
|
130
|
+
return this.getState('play')
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
set play(play) {
|
|
134
|
+
this.setState('play', play)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
get nature() {
|
|
138
|
+
return NATURE
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
get tagName() {
|
|
142
|
+
return 'div'
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
Component.register('gif-view', GifView)
|