@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.
Files changed (147) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +0 -0
  3. package/demo/index.html +158 -0
  4. package/demo/things-scene-basic.html +6 -0
  5. package/dist/anchors/ellipse-anchors.d.ts +7 -0
  6. package/dist/anchors/ellipse-anchors.js +43 -0
  7. package/dist/anchors/ellipse-anchors.js.map +1 -0
  8. package/dist/audio.d.ts +25 -0
  9. package/dist/audio.js +141 -0
  10. package/dist/audio.js.map +1 -0
  11. package/dist/cloud.d.ts +13 -0
  12. package/dist/cloud.js +30 -0
  13. package/dist/cloud.js.map +1 -0
  14. package/dist/donut.d.ts +15 -0
  15. package/dist/donut.js +74 -0
  16. package/dist/donut.js.map +1 -0
  17. package/dist/ellipse.d.ts +24 -0
  18. package/dist/ellipse.js +72 -0
  19. package/dist/ellipse.js.map +1 -0
  20. package/dist/gif-view.d.ts +18 -0
  21. package/dist/gif-view.js +116 -0
  22. package/dist/gif-view.js.map +1 -0
  23. package/dist/image-view.d.ts +19 -0
  24. package/dist/image-view.js +180 -0
  25. package/dist/image-view.js.map +1 -0
  26. package/dist/index.d.ts +11 -0
  27. package/dist/index.js +15 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/outline/ellipse-outline.d.ts +2 -0
  30. package/dist/outline/ellipse-outline.js +11 -0
  31. package/dist/outline/ellipse-outline.js.map +1 -0
  32. package/dist/polygon.d.ts +19 -0
  33. package/dist/polygon.js +84 -0
  34. package/dist/polygon.js.map +1 -0
  35. package/dist/polyline.d.ts +18 -0
  36. package/dist/polyline.js +102 -0
  37. package/dist/polyline.js.map +1 -0
  38. package/dist/rect.d.ts +19 -0
  39. package/dist/rect.js +60 -0
  40. package/dist/rect.js.map +1 -0
  41. package/dist/star.d.ts +13 -0
  42. package/dist/star.js +80 -0
  43. package/dist/star.js.map +1 -0
  44. package/dist/templates/audio.d.ts +14 -0
  45. package/dist/templates/audio.js +15 -0
  46. package/dist/templates/audio.js.map +1 -0
  47. package/dist/templates/color-image.d.ts +22 -0
  48. package/dist/templates/color-image.js +23 -0
  49. package/dist/templates/color-image.js.map +1 -0
  50. package/dist/templates/donut.d.ts +22 -0
  51. package/dist/templates/donut.js +23 -0
  52. package/dist/templates/donut.js.map +1 -0
  53. package/dist/templates/ellipse.d.ts +21 -0
  54. package/dist/templates/ellipse.js +22 -0
  55. package/dist/templates/ellipse.js.map +1 -0
  56. package/dist/templates/gif-image.d.ts +14 -0
  57. package/dist/templates/gif-image.js +15 -0
  58. package/dist/templates/gif-image.js.map +1 -0
  59. package/dist/templates/gray-image.d.ts +22 -0
  60. package/dist/templates/gray-image.js +23 -0
  61. package/dist/templates/gray-image.js.map +1 -0
  62. package/dist/templates/index.d.ts +74 -0
  63. package/dist/templates/index.js +15 -0
  64. package/dist/templates/index.js.map +1 -0
  65. package/dist/templates/polygon.d.ts +22 -0
  66. package/dist/templates/polygon.js +25 -0
  67. package/dist/templates/polygon.js.map +1 -0
  68. package/dist/templates/polyline.d.ts +22 -0
  69. package/dist/templates/polyline.js +25 -0
  70. package/dist/templates/polyline.js.map +1 -0
  71. package/dist/templates/rect.d.ts +21 -0
  72. package/dist/templates/rect.js +22 -0
  73. package/dist/templates/rect.js.map +1 -0
  74. package/dist/templates/star.d.ts +23 -0
  75. package/dist/templates/star.js +24 -0
  76. package/dist/templates/star.js.map +1 -0
  77. package/dist/templates/text.d.ts +27 -0
  78. package/dist/templates/text.js +28 -0
  79. package/dist/templates/text.js.map +1 -0
  80. package/dist/templates/triangle.d.ts +23 -0
  81. package/dist/templates/triangle.js +24 -0
  82. package/dist/templates/triangle.js.map +1 -0
  83. package/dist/text.d.ts +6 -0
  84. package/dist/text.js +11 -0
  85. package/dist/text.js.map +1 -0
  86. package/dist/triangle.d.ts +14 -0
  87. package/dist/triangle.js +75 -0
  88. package/dist/triangle.js.map +1 -0
  89. package/icons/audio.png +0 -0
  90. package/icons/both-arrow.png +0 -0
  91. package/icons/color-image.png +0 -0
  92. package/icons/container.png +0 -0
  93. package/icons/dash.png +0 -0
  94. package/icons/donut.png +0 -0
  95. package/icons/ellipse.png +0 -0
  96. package/icons/gif-image.png +0 -0
  97. package/icons/global-reference.png +0 -0
  98. package/icons/gray-image.png +0 -0
  99. package/icons/humidity-sensor.png +0 -0
  100. package/icons/info-window.png +0 -0
  101. package/icons/line.png +0 -0
  102. package/icons/local-reference.png +0 -0
  103. package/icons/no-image.png +0 -0
  104. package/icons/ortholine.png +0 -0
  105. package/icons/person.png +0 -0
  106. package/icons/polygon.png +0 -0
  107. package/icons/polyline.png +0 -0
  108. package/icons/popup.png +0 -0
  109. package/icons/rect.png +0 -0
  110. package/icons/single-arrow.png +0 -0
  111. package/icons/star.png +0 -0
  112. package/icons/text.png +0 -0
  113. package/icons/triangle.png +0 -0
  114. package/package.json +61 -0
  115. package/src/anchors/ellipse-anchors.ts +46 -0
  116. package/src/audio.ts +173 -0
  117. package/src/cloud.ts +40 -0
  118. package/src/donut.ts +92 -0
  119. package/src/ellipse.ts +90 -0
  120. package/src/gif-view.ts +146 -0
  121. package/src/image-view.ts +215 -0
  122. package/src/index.ts +16 -0
  123. package/src/outline/ellipse-outline.ts +15 -0
  124. package/src/polygon.ts +103 -0
  125. package/src/polyline.ts +122 -0
  126. package/src/rect.ts +71 -0
  127. package/src/star.ts +104 -0
  128. package/src/templates/audio.ts +15 -0
  129. package/src/templates/color-image.ts +23 -0
  130. package/src/templates/donut.ts +23 -0
  131. package/src/templates/ellipse.ts +22 -0
  132. package/src/templates/gif-image.ts +15 -0
  133. package/src/templates/gray-image.ts +23 -0
  134. package/src/templates/index.ts +16 -0
  135. package/src/templates/polygon.ts +25 -0
  136. package/src/templates/polyline.ts +25 -0
  137. package/src/templates/rect.ts +22 -0
  138. package/src/templates/star.ts +24 -0
  139. package/src/templates/text.ts +28 -0
  140. package/src/templates/triangle.ts +24 -0
  141. package/src/text.ts +12 -0
  142. package/src/triangle.ts +87 -0
  143. package/test/basic-test.html +63 -0
  144. package/test/index.html +22 -0
  145. package/things-scene.config.js +5 -0
  146. package/tsconfig.json +23 -0
  147. 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)
@@ -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)