@operato/scene-gauge 0.0.16
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/@types/global/index.d.ts +1 -0
- package/CHANGELOG.md +16 -0
- package/LICENSE +21 -0
- package/README.md +15 -0
- package/assets/gauge-circle.png +0 -0
- package/assets/gauge-horizontal.png +0 -0
- package/assets/gauge-vertical.png +0 -0
- package/dist/gauge-circle.d.ts +57 -0
- package/dist/gauge-circle.js +211 -0
- package/dist/gauge-circle.js.map +1 -0
- package/dist/gauge-horizon.d.ts +56 -0
- package/dist/gauge-horizon.js +145 -0
- package/dist/gauge-horizon.js.map +1 -0
- package/dist/gauge-properties.d.ts +39 -0
- package/dist/gauge-properties.js +114 -0
- package/dist/gauge-properties.js.map +1 -0
- package/dist/gauge-vertical.d.ts +56 -0
- package/dist/gauge-vertical.js +143 -0
- package/dist/gauge-vertical.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/helps/scene/component/gauge-circle.ko.md +168 -0
- package/helps/scene/component/gauge-circle.md +167 -0
- package/helps/scene/component/gauge-circle.zh.md +164 -0
- package/helps/scene/component/gauge-horizon.ko.md +145 -0
- package/helps/scene/component/gauge-horizon.md +145 -0
- package/helps/scene/component/gauge-horizon.zh.md +145 -0
- package/helps/scene/component/gauge-vertical.ko.md +12 -0
- package/helps/scene/component/gauge-vertical.md +9 -0
- package/helps/scene/component/gauge-vertical.zh.md +10 -0
- package/helps/scene/images/gauge-circle-01.png +0 -0
- package/helps/scene/images/gauge-circle-02.png +0 -0
- package/helps/scene/images/gauge-circle-03.png +0 -0
- package/helps/scene/images/gauge-circle-04.png +0 -0
- package/helps/scene/images/gauge-circle-05.png +0 -0
- package/helps/scene/images/gauge-circle-06.png +0 -0
- package/helps/scene/images/gauge-circle-07.png +0 -0
- package/helps/scene/images/gauge-circle-08.png +0 -0
- package/helps/scene/images/gauge-circle-09.png +0 -0
- package/helps/scene/images/gauge-circle-10.png +0 -0
- package/helps/scene/images/gauge-circle-11.png +0 -0
- package/helps/scene/images/gauge-circle-12.png +0 -0
- package/helps/scene/images/gauge-circle-13.png +0 -0
- package/helps/scene/images/gauge-circle-14.png +0 -0
- package/helps/scene/images/gauge-circle-15.png +0 -0
- package/helps/scene/images/gauge-circle-16.png +0 -0
- package/helps/scene/images/gauge-circle-17.png +0 -0
- package/helps/scene/images/gauge-circle-18.png +0 -0
- package/helps/scene/images/gauge-circle-19.png +0 -0
- package/helps/scene/images/gauge-circle-20.png +0 -0
- package/helps/scene/images/gauge-circle-21.png +0 -0
- package/helps/scene/images/gauge-horizontal-01.png +0 -0
- package/helps/scene/images/gauge-vertical-01.png +0 -0
- package/helps/scene/images/gauge-vertical-02.png +0 -0
- package/helps/scene/images/gauge-vertical-03.png +0 -0
- package/helps/scene/images/gauge-vertical-04.png +0 -0
- package/helps/scene/images/gauge-vertical-05.png +0 -0
- package/helps/scene/images/gauge-vertical-06.png +0 -0
- package/helps/scene/images/gauge-vertical-07.png +0 -0
- package/helps/scene/images/gauge-vertical-08.png +0 -0
- package/helps/scene/images/gauge-vertical-09.png +0 -0
- package/helps/scene/images/gauge-vertical-10.png +0 -0
- package/helps/scene/images/gauge-vertical-11.png +0 -0
- package/helps/scene/images/gauge-vertical-12.png +0 -0
- package/helps/scene/images/gauge-vertical-13.png +0 -0
- package/helps/scene/images/gauge-vertical-14.png +0 -0
- package/helps/scene/images/gauge-vertical-15.png +0 -0
- package/helps/scene/images/gauge-vertical-16.png +0 -0
- package/helps/scene/images/gauge-vertical-17.png +0 -0
- package/helps/scene/images/gauge-vertical-18.png +0 -0
- package/package.json +61 -0
- package/src/gauge-circle.ts +310 -0
- package/src/gauge-horizon.ts +204 -0
- package/src/gauge-properties.ts +114 -0
- package/src/gauge-vertical.ts +203 -0
- package/src/index.ts +6 -0
- package/test/basic-test.html +67 -0
- package/test/index.html +22 -0
- package/things-scene.config.js +158 -0
- package/translations/en.json +3 -0
- package/translations/ko.json +3 -0
- package/translations/ms.json +3 -0
- package/translations/zh.json +3 -0
- package/tsconfig.json +22 -0
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module '*.png'
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Change Log
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
|
+
|
|
6
|
+
### [0.0.16](https://github.com/things-scene/operato-scene/compare/v0.0.15...v0.0.16) (2021-12-09)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### :rocket: New Features
|
|
10
|
+
|
|
11
|
+
* add indoor-map and gauge component ([35d8a75](https://github.com/things-scene/operato-scene/commit/35d8a75f7d691dd23ea299fd772b79d19eec5d2f))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### :bug: Bug Fix
|
|
15
|
+
|
|
16
|
+
* upgrade [@operato](https://github.com/operato) dependencies ([92985c7](https://github.com/things-scene/operato-scene/commit/92985c76d2b7e6d3941c2c809a85b3676a579b0e))
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 Hearty, Oh
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# things-scene-gauge
|
|
2
|
+
|
|
3
|
+
## build
|
|
4
|
+
|
|
5
|
+
`$ yarn build`
|
|
6
|
+
|
|
7
|
+
| type | filename | for | tested |
|
|
8
|
+
| ---- | ------------------------ | -------------- | ------ |
|
|
9
|
+
| UMD | things-scene-gauge.js | modern browser | O |
|
|
10
|
+
| UMD | things-scene-gauge-ie.js | ie 11 | O |
|
|
11
|
+
| ESM | things-scene-gauge.mjs | modern browser | O |
|
|
12
|
+
|
|
13
|
+
## publish
|
|
14
|
+
|
|
15
|
+
`$ yarn publish`
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Donut } from '@hatiolab/things-scene';
|
|
2
|
+
declare const GaugeCircle_base: (new (...args: any[]) => {
|
|
3
|
+
value: number;
|
|
4
|
+
animValue: number;
|
|
5
|
+
animOnValueChange(value: number, animFromBase: boolean, base: number): void;
|
|
6
|
+
}) & typeof Donut;
|
|
7
|
+
export default class GaugeCircle extends GaugeCircle_base {
|
|
8
|
+
_draw(context: CanvasRenderingContext2D): void;
|
|
9
|
+
contains(x: number, y: number): boolean;
|
|
10
|
+
_post_draw(context: CanvasRenderingContext2D): void;
|
|
11
|
+
get nature(): {
|
|
12
|
+
mutable: boolean;
|
|
13
|
+
resizable: boolean;
|
|
14
|
+
rotatable: boolean;
|
|
15
|
+
properties: ({
|
|
16
|
+
type: string;
|
|
17
|
+
label: string;
|
|
18
|
+
name: string;
|
|
19
|
+
property: string;
|
|
20
|
+
observe?: undefined;
|
|
21
|
+
} | {
|
|
22
|
+
type: string;
|
|
23
|
+
label: string;
|
|
24
|
+
name: string;
|
|
25
|
+
observe: (this: HTMLElement, startValue: number) => void;
|
|
26
|
+
property: string;
|
|
27
|
+
} | {
|
|
28
|
+
type: string;
|
|
29
|
+
label: string;
|
|
30
|
+
name: string;
|
|
31
|
+
property: {
|
|
32
|
+
min: number;
|
|
33
|
+
max: number;
|
|
34
|
+
label?: undefined;
|
|
35
|
+
};
|
|
36
|
+
observe?: undefined;
|
|
37
|
+
} | {
|
|
38
|
+
type: string;
|
|
39
|
+
label: string;
|
|
40
|
+
name: string;
|
|
41
|
+
property: {
|
|
42
|
+
label: string;
|
|
43
|
+
min?: undefined;
|
|
44
|
+
max?: undefined;
|
|
45
|
+
};
|
|
46
|
+
observe?: undefined;
|
|
47
|
+
} | {
|
|
48
|
+
type: string;
|
|
49
|
+
label: string;
|
|
50
|
+
name: string;
|
|
51
|
+
property?: undefined;
|
|
52
|
+
observe?: undefined;
|
|
53
|
+
})[];
|
|
54
|
+
help: string;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export {};
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
import { Component, Donut, ValueHolder } from '@hatiolab/things-scene';
|
|
5
|
+
import { PROPERTIES } from './gauge-properties';
|
|
6
|
+
const NATURE = {
|
|
7
|
+
mutable: false,
|
|
8
|
+
resizable: true,
|
|
9
|
+
rotatable: true,
|
|
10
|
+
properties: [
|
|
11
|
+
...PROPERTIES,
|
|
12
|
+
{
|
|
13
|
+
type: 'number',
|
|
14
|
+
label: 'start-angle',
|
|
15
|
+
name: 'startAngle',
|
|
16
|
+
property: 'startAngle'
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
type: 'number',
|
|
20
|
+
label: 'end-angle',
|
|
21
|
+
name: 'endAngle',
|
|
22
|
+
property: 'endAngle'
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
type: 'color',
|
|
26
|
+
label: 'text-fill-style',
|
|
27
|
+
name: 'textFillStyle',
|
|
28
|
+
property: 'textFillStyle'
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
type: 'color',
|
|
32
|
+
label: 'needle-fill-style',
|
|
33
|
+
name: 'needleFillStyle',
|
|
34
|
+
property: 'needleFillStyle'
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
type: 'color',
|
|
38
|
+
label: 'inner-circle-fill-style',
|
|
39
|
+
name: 'innerCircleFillStyle',
|
|
40
|
+
property: 'innerCircleFillStyle'
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
type: 'checkbox',
|
|
44
|
+
label: 'in-text',
|
|
45
|
+
name: 'inText',
|
|
46
|
+
property: 'inText'
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
help: 'scene/component/gauge-circle'
|
|
50
|
+
};
|
|
51
|
+
function drawStepLine(context, ang, rx, stepNeedleSize) {
|
|
52
|
+
context.rotate(ang);
|
|
53
|
+
context.translate(0, -rx);
|
|
54
|
+
context.fillRect(0, -rx * 0.14, stepNeedleSize, rx * 0.175);
|
|
55
|
+
context.translate(0, rx);
|
|
56
|
+
context.rotate(-ang);
|
|
57
|
+
}
|
|
58
|
+
function drawSubStepLine(context, ang, rx, stepNeedleSize) {
|
|
59
|
+
context.rotate(ang);
|
|
60
|
+
context.translate(0, -rx);
|
|
61
|
+
context.fillRect(0, -rx * 0.04, stepNeedleSize, rx * 0.075);
|
|
62
|
+
context.translate(0, rx);
|
|
63
|
+
context.rotate(-ang);
|
|
64
|
+
}
|
|
65
|
+
function drawStepText(context, text, ang, rx) {
|
|
66
|
+
context.rotate(ang);
|
|
67
|
+
context.translate(0, -rx * 0.83);
|
|
68
|
+
context.rotate(-ang);
|
|
69
|
+
context.fillText(text, 0, 0);
|
|
70
|
+
context.rotate(ang);
|
|
71
|
+
context.translate(0, rx * 0.83);
|
|
72
|
+
context.rotate(-ang);
|
|
73
|
+
}
|
|
74
|
+
function drawNeedle(context, rx, ang) {
|
|
75
|
+
context.rotate(ang);
|
|
76
|
+
context.beginPath();
|
|
77
|
+
context.moveTo(rx * 0.035, 0); // 중앙 두께
|
|
78
|
+
context.lineTo(0, rx * 0.8); // 끝 점
|
|
79
|
+
context.lineTo(-rx * 0.035, 0); // 중앙 두께
|
|
80
|
+
context.lineTo(-rx * 0.015, -rx * 0.2); // 뒷쪽 두께
|
|
81
|
+
context.lineTo(rx * 0.015, -rx * 0.2); // 뒷쪽 두께
|
|
82
|
+
context.rotate(-ang);
|
|
83
|
+
}
|
|
84
|
+
export default class GaugeCircle extends ValueHolder(Donut) {
|
|
85
|
+
_draw(context) {
|
|
86
|
+
var { lineWidth = 20, startValue, endValue, step, subStep, startAngle = 0, endAngle = 180, fontColor = 'black', showStepText = true, showStartValue = true, showEndValue = true, showStepLine = true, showSubStep = true, inText = true, colorStops, // 스텝별 각각 다른 색
|
|
87
|
+
fillStyle, textFillStyle = 'black', needleFillStyle = 'black', innerCircleFillStyle = 'gray', stepNeedleSize = 2, stepFillStyle, stepTextSize, cx, cy, rx, ry, ratio, animFromBase = false } = this.model;
|
|
88
|
+
startValue = Number(startValue);
|
|
89
|
+
this.animOnValueChange(this.value, animFromBase, startValue);
|
|
90
|
+
const RADIAN = 0.0174533 / Math.PI;
|
|
91
|
+
const rxRatio = (rx / 100) * ratio; // 원 안에 지워지는 비율을 계산한 rx - ratio의 비율에 따라 크기가 변함
|
|
92
|
+
const ryRatio = (ry / 100) * ratio; // 원 안에 지워지는 비율을 계산한 ry - ratio의 비율에 따라 크기가 변함
|
|
93
|
+
const circleSize = (endAngle - startAngle) / 180; // 원의 총 길이. - PI * 2가 원이므로 (360도 = 2, 180도 = 1)
|
|
94
|
+
const totalValue = endValue - startValue; // 게이지의 시작과 끝 값의 크기
|
|
95
|
+
startAngle = startAngle * RADIAN - 0.5; // 맨 위쪽을 중심으로 앵글의 범위에 따라 왼쪽으로 넓어짐
|
|
96
|
+
endAngle = endAngle * RADIAN - 0.5; // 맨 위쪽을 중심으로 앵글의 범위에 따라 오른쪽으로 넓어짐
|
|
97
|
+
context.translate(cx, cy);
|
|
98
|
+
//// 메인 게이지 원 그리기 ////
|
|
99
|
+
context.beginPath();
|
|
100
|
+
context.ellipse(0, 0, Math.abs(rx), Math.abs(ry), 0, startAngle * Math.PI, endAngle * Math.PI);
|
|
101
|
+
this.drawStroke(context);
|
|
102
|
+
context.ellipse(0, 0, Math.abs(rxRatio), Math.abs(ryRatio), 0, endAngle * Math.PI, startAngle * Math.PI, true); // 반대로 그리며 원을 지움.
|
|
103
|
+
// this.drawFill(context)
|
|
104
|
+
context.closePath();
|
|
105
|
+
//// 스텝별 색 칠하기 ////
|
|
106
|
+
if (colorStops) {
|
|
107
|
+
let beforeValue = 0;
|
|
108
|
+
let endStepAngle = 0;
|
|
109
|
+
context.moveTo(0, 0);
|
|
110
|
+
colorStops.forEach(function (v, idx, arr) {
|
|
111
|
+
context.beginPath();
|
|
112
|
+
let value = Math.max(Math.min(v.position - startValue, totalValue), 0); // v.position 범위의 최소값은 0, 최대값은 totalValue가 되야함.
|
|
113
|
+
let startStepAngle = endStepAngle || Math.PI * (startAngle + (circleSize * beforeValue) / totalValue);
|
|
114
|
+
if (idx === arr.length - 1)
|
|
115
|
+
// 마지막값은 무조건 끝까지 채워주도록 한다
|
|
116
|
+
endStepAngle = Math.PI * (startAngle + circleSize);
|
|
117
|
+
else
|
|
118
|
+
endStepAngle = Math.PI * (startAngle + (circleSize * value) / totalValue);
|
|
119
|
+
if (beforeValue > totalValue || beforeValue > value)
|
|
120
|
+
// 값이 게이지의 최대 값을 넘어가거나 이전 값 보다 현재값이 작으면 다시 그릴 필요 없음
|
|
121
|
+
return false;
|
|
122
|
+
context.ellipse(0, 0, Math.abs(rx), Math.abs(ry), 0, startStepAngle, endStepAngle);
|
|
123
|
+
context.ellipse(0, 0, Math.abs(rxRatio), Math.abs(ryRatio), 0, endStepAngle, startStepAngle, true);
|
|
124
|
+
context.fillStyle = v.color;
|
|
125
|
+
context.fill();
|
|
126
|
+
beforeValue = value;
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
context.scale(1, ry / rx);
|
|
130
|
+
//// 바늘 그리기 ////
|
|
131
|
+
context.beginPath();
|
|
132
|
+
let drawingValue = this.animValue;
|
|
133
|
+
drawingValue = Math.max(Math.min(drawingValue, endValue), startValue); // 그려지는 값은 startValue보다 작을 수 없고, endValue보다 클 수 없음.
|
|
134
|
+
let ang = Math.PI * ((circleSize * (drawingValue - startValue)) / totalValue + startAngle - 0.5);
|
|
135
|
+
drawNeedle(context, rx, ang);
|
|
136
|
+
context.fillStyle = needleFillStyle;
|
|
137
|
+
context.fill();
|
|
138
|
+
//// 중앙 원 그리기 ////
|
|
139
|
+
context.beginPath();
|
|
140
|
+
context.ellipse(0, 0, Math.abs(rx) / 15, Math.abs(rx) / 15, 0, 0, 2 * Math.PI);
|
|
141
|
+
context.fillStyle = innerCircleFillStyle;
|
|
142
|
+
context.fill();
|
|
143
|
+
//// 스텝 선 그리기 ////
|
|
144
|
+
context.fillStyle = stepFillStyle;
|
|
145
|
+
if (showStepLine) {
|
|
146
|
+
let count = totalValue / step;
|
|
147
|
+
// Draw StartValue
|
|
148
|
+
drawStepLine(context, Math.PI * (startAngle + 0.5), rx * 0.8, stepNeedleSize); // 원을 그릴때 PI는 45도 부터 그리지만 angle은 0도부터 틀어서 + 0.5도를 곱해줘야함
|
|
149
|
+
// Draw StepValue
|
|
150
|
+
for (let num = 1; num < count; num++) {
|
|
151
|
+
let ang = Math.PI * ((circleSize / count) * num + startAngle + 0.5);
|
|
152
|
+
drawStepLine(context, ang, rx * 0.8, stepNeedleSize);
|
|
153
|
+
}
|
|
154
|
+
// Draw EndValue
|
|
155
|
+
drawStepLine(context, Math.PI * (endAngle + 0.5), rx * 0.8, stepNeedleSize);
|
|
156
|
+
}
|
|
157
|
+
//// 서브 스탭 그리기 ////
|
|
158
|
+
if (showSubStep) {
|
|
159
|
+
let count = totalValue;
|
|
160
|
+
// Draw StepValue
|
|
161
|
+
for (let num = 1; num <= count; num++) {
|
|
162
|
+
if (num % step == 0 || num % subStep != 0) {
|
|
163
|
+
// 메인 스탭과 서브 스탭은 그리지 않음
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
let ang = Math.PI * ((circleSize / count) * num + startAngle + 0.5);
|
|
167
|
+
drawSubStepLine(context, ang, rx * 0.8, stepNeedleSize);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//// 스텝 텍스트 그리기 ////
|
|
171
|
+
context.fillStyle = textFillStyle;
|
|
172
|
+
context.font = (rx * stepTextSize) / 50 + 'px arial';
|
|
173
|
+
context.textBaseline = 'middle';
|
|
174
|
+
context.textAlign = 'center';
|
|
175
|
+
let textLocation = inText ? 0.8 : 1.35;
|
|
176
|
+
if (showStartValue) {
|
|
177
|
+
// Draw StartText
|
|
178
|
+
drawStepText(context, startValue, Math.PI * (startAngle + 0.5), rx * textLocation);
|
|
179
|
+
}
|
|
180
|
+
if (showEndValue) {
|
|
181
|
+
// Draw EndText
|
|
182
|
+
drawStepText(context, endValue, Math.PI * (endAngle + 0.5), rx * textLocation);
|
|
183
|
+
}
|
|
184
|
+
if (showStepText) {
|
|
185
|
+
// Draw StepText
|
|
186
|
+
let count = totalValue / step;
|
|
187
|
+
for (let num = 1; num < count; num++) {
|
|
188
|
+
let value = startValue + step * num;
|
|
189
|
+
let ang = Math.PI * ((circleSize / count) * num + startAngle + 0.5);
|
|
190
|
+
drawStepText(context, value, ang, rx * textLocation);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
context.scale(1, rx / ry);
|
|
194
|
+
context.translate(-cx, -cy);
|
|
195
|
+
}
|
|
196
|
+
contains(x, y) {
|
|
197
|
+
// 컨테인즈는 Ellipse로 정의함
|
|
198
|
+
var { cx, cy, rx, ry } = this.model;
|
|
199
|
+
var normx = (x - cx) / (rx * 2 - 0.5);
|
|
200
|
+
var normy = (y - cy) / (ry * 2 - 0.5);
|
|
201
|
+
return normx * normx + normy * normy < 0.25;
|
|
202
|
+
}
|
|
203
|
+
_post_draw(context) {
|
|
204
|
+
this.drawText(context);
|
|
205
|
+
}
|
|
206
|
+
get nature() {
|
|
207
|
+
return NATURE;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
Component.register('gauge-circle', GaugeCircle);
|
|
211
|
+
//# sourceMappingURL=gauge-circle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gauge-circle.js","sourceRoot":"","sources":["../src/gauge-circle.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { Component, Donut, ValueHolder } from '@hatiolab/things-scene';\n\nimport { PROPERTIES } from './gauge-properties';\n\nconst NATURE = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n ...PROPERTIES,\n {\n type: 'number',\n label: 'start-angle',\n name: 'startAngle',\n property: 'startAngle'\n },\n {\n type: 'number',\n label: 'end-angle',\n name: 'endAngle',\n property: 'endAngle'\n },\n {\n type: 'color',\n label: 'text-fill-style',\n name: 'textFillStyle',\n property: 'textFillStyle'\n },\n {\n type: 'color',\n label: 'needle-fill-style',\n name: 'needleFillStyle',\n property: 'needleFillStyle'\n },\n {\n type: 'color',\n label: 'inner-circle-fill-style',\n name: 'innerCircleFillStyle',\n property: 'innerCircleFillStyle'\n },\n {\n type: 'checkbox',\n label: 'in-text',\n name: 'inText',\n property: 'inText'\n }\n ],\n help: 'scene/component/gauge-circle'\n}\n\nfunction drawStepLine(context: CanvasRenderingContext2D, ang: number, rx: number, stepNeedleSize: number) {\n context.rotate(ang)\n context.translate(0, -rx)\n\n context.fillRect(0, -rx * 0.14, stepNeedleSize, rx * 0.175)\n context.translate(0, rx)\n context.rotate(-ang)\n}\n\nfunction drawSubStepLine(context: CanvasRenderingContext2D, ang: number, rx: number, stepNeedleSize: number) {\n context.rotate(ang)\n context.translate(0, -rx)\n\n context.fillRect(0, -rx * 0.04, stepNeedleSize, rx * 0.075)\n context.translate(0, rx)\n context.rotate(-ang)\n}\n\nfunction drawStepText(context: CanvasRenderingContext2D, text: string, ang: number, rx: number) {\n context.rotate(ang)\n context.translate(0, -rx * 0.83)\n context.rotate(-ang)\n\n context.fillText(text, 0, 0)\n context.rotate(ang)\n context.translate(0, rx * 0.83)\n context.rotate(-ang)\n}\n\nfunction drawNeedle(context: CanvasRenderingContext2D, rx: number, ang: number) {\n context.rotate(ang)\n\n context.beginPath()\n\n context.moveTo(rx * 0.035, 0) // 중앙 두께\n\n context.lineTo(0, rx * 0.8) // 끝 점\n\n context.lineTo(-rx * 0.035, 0) // 중앙 두께\n\n context.lineTo(-rx * 0.015, -rx * 0.2) // 뒷쪽 두께\n context.lineTo(rx * 0.015, -rx * 0.2) // 뒷쪽 두께\n\n context.rotate(-ang)\n}\n\nexport default class GaugeCircle extends ValueHolder(Donut) {\n _draw(context: CanvasRenderingContext2D) {\n var {\n lineWidth = 20,\n startValue,\n endValue,\n step,\n subStep,\n startAngle = 0,\n endAngle = 180,\n fontColor = 'black',\n showStepText = true,\n showStartValue = true,\n showEndValue = true,\n showStepLine = true,\n showSubStep = true,\n inText = true,\n colorStops, // 스텝별 각각 다른 색\n fillStyle,\n textFillStyle = 'black',\n needleFillStyle = 'black',\n innerCircleFillStyle = 'gray',\n stepNeedleSize = 2,\n stepFillStyle,\n stepTextSize,\n cx,\n cy,\n rx,\n ry,\n ratio,\n animFromBase = false\n } = this.model\n\n startValue = Number(startValue)\n\n this.animOnValueChange(this.value, animFromBase, startValue)\n\n const RADIAN = 0.0174533 / Math.PI\n const rxRatio = (rx / 100) * ratio // 원 안에 지워지는 비율을 계산한 rx - ratio의 비율에 따라 크기가 변함\n const ryRatio = (ry / 100) * ratio // 원 안에 지워지는 비율을 계산한 ry - ratio의 비율에 따라 크기가 변함\n const circleSize = (endAngle - startAngle) / 180 // 원의 총 길이. - PI * 2가 원이므로 (360도 = 2, 180도 = 1)\n const totalValue = endValue - startValue // 게이지의 시작과 끝 값의 크기\n\n startAngle = startAngle * RADIAN - 0.5 // 맨 위쪽을 중심으로 앵글의 범위에 따라 왼쪽으로 넓어짐\n endAngle = endAngle * RADIAN - 0.5 // 맨 위쪽을 중심으로 앵글의 범위에 따라 오른쪽으로 넓어짐\n\n context.translate(cx, cy)\n\n //// 메인 게이지 원 그리기 ////\n context.beginPath()\n\n context.ellipse(\n 0,\n 0,\n Math.abs(rx),\n Math.abs(ry),\n 0,\n startAngle * Math.PI,\n endAngle * Math.PI\n )\n this.drawStroke(context)\n context.ellipse(\n 0,\n 0,\n Math.abs(rxRatio),\n Math.abs(ryRatio),\n 0,\n endAngle * Math.PI,\n startAngle * Math.PI,\n true\n ) // 반대로 그리며 원을 지움.\n // this.drawFill(context)\n\n context.closePath()\n\n //// 스텝별 색 칠하기 ////\n if (colorStops) {\n let beforeValue = 0\n let endStepAngle = 0\n context.moveTo(0, 0)\n\n colorStops.forEach(function (v: {position: number; color: string;}, idx: number, arr: {position: number; color: string;}[]) {\n context.beginPath()\n\n let value = Math.max(Math.min(v.position - startValue, totalValue), 0) // v.position 범위의 최소값은 0, 최대값은 totalValue가 되야함.\n let startStepAngle = endStepAngle || Math.PI * (startAngle + (circleSize * beforeValue) / totalValue)\n\n if (idx === arr.length - 1)\n // 마지막값은 무조건 끝까지 채워주도록 한다\n endStepAngle = Math.PI * (startAngle + circleSize)\n else endStepAngle = Math.PI * (startAngle + (circleSize * value) / totalValue)\n\n if (beforeValue > totalValue || beforeValue > value)\n // 값이 게이지의 최대 값을 넘어가거나 이전 값 보다 현재값이 작으면 다시 그릴 필요 없음\n return false\n\n context.ellipse(0, 0, Math.abs(rx), Math.abs(ry), 0, startStepAngle, endStepAngle)\n context.ellipse(0, 0, Math.abs(rxRatio), Math.abs(ryRatio), 0, endStepAngle, startStepAngle, true)\n context.fillStyle = v.color\n context.fill()\n\n beforeValue = value\n })\n }\n context.scale(1, ry / rx)\n\n //// 바늘 그리기 ////\n context.beginPath()\n let drawingValue = this.animValue\n drawingValue = Math.max(Math.min(drawingValue, endValue), startValue) // 그려지는 값은 startValue보다 작을 수 없고, endValue보다 클 수 없음.\n\n let ang = Math.PI * ((circleSize * (drawingValue - startValue)) / totalValue + startAngle - 0.5)\n\n drawNeedle(context, rx, ang)\n\n context.fillStyle = needleFillStyle\n context.fill()\n\n //// 중앙 원 그리기 ////\n context.beginPath()\n context.ellipse(0, 0, Math.abs(rx) / 15, Math.abs(rx) / 15, 0, 0, 2 * Math.PI)\n context.fillStyle = innerCircleFillStyle\n context.fill()\n\n //// 스텝 선 그리기 ////\n context.fillStyle = stepFillStyle\n if (showStepLine) {\n let count = totalValue / step\n\n // Draw StartValue\n drawStepLine(context, Math.PI * (startAngle + 0.5), rx * 0.8, stepNeedleSize) // 원을 그릴때 PI는 45도 부터 그리지만 angle은 0도부터 틀어서 + 0.5도를 곱해줘야함\n // Draw StepValue\n for (let num = 1; num < count; num++) {\n let ang = Math.PI * ((circleSize / count) * num + startAngle + 0.5)\n\n drawStepLine(context, ang, rx * 0.8, stepNeedleSize)\n }\n // Draw EndValue\n drawStepLine(context, Math.PI * (endAngle + 0.5), rx * 0.8, stepNeedleSize)\n }\n\n //// 서브 스탭 그리기 ////\n if (showSubStep) {\n let count = totalValue\n\n // Draw StepValue\n for (let num = 1; num <= count; num++) {\n if (num % step == 0 || num % subStep != 0) {\n // 메인 스탭과 서브 스탭은 그리지 않음\n continue\n }\n let ang = Math.PI * ((circleSize / count) * num + startAngle + 0.5)\n\n drawSubStepLine(context, ang, rx * 0.8, stepNeedleSize)\n }\n }\n\n //// 스텝 텍스트 그리기 ////\n context.fillStyle = textFillStyle\n context.font = (rx * stepTextSize) / 50 + 'px arial'\n context.textBaseline = 'middle'\n context.textAlign = 'center'\n let textLocation = inText ? 0.8 : 1.35\n\n if (showStartValue) {\n // Draw StartText\n drawStepText(context, startValue, Math.PI * (startAngle + 0.5), rx * textLocation)\n }\n\n if (showEndValue) {\n // Draw EndText\n drawStepText(context, endValue, Math.PI * (endAngle + 0.5), rx * textLocation)\n }\n\n if (showStepText) {\n // Draw StepText\n let count = totalValue / step\n\n for (let num = 1; num < count; num++) {\n let value = startValue + step * num\n let ang = Math.PI * ((circleSize / count) * num + startAngle + 0.5)\n\n drawStepText(context, value, ang, rx * textLocation)\n }\n }\n\n context.scale(1, rx / ry)\n context.translate(-cx, -cy)\n }\n\n contains(x: number, y: number): boolean {\n // 컨테인즈는 Ellipse로 정의함\n var { cx, cy, rx, ry } = this.model\n\n var normx = (x - cx) / (rx * 2 - 0.5)\n var normy = (y - cy) / (ry * 2 - 0.5)\n\n return normx * normx + normy * normy < 0.25\n }\n\n _post_draw(context: CanvasRenderingContext2D) {\n this.drawText(context)\n }\n\n get nature() {\n return NATURE\n }\n}\n\nComponent.register('gauge-circle', GaugeCircle)\n"]}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Shape } from '@hatiolab/things-scene';
|
|
2
|
+
declare const GaugeHorizon_base: (new (...args: any[]) => {
|
|
3
|
+
value: number;
|
|
4
|
+
animValue: number;
|
|
5
|
+
animOnValueChange(value: number, animFromBase: boolean, base: number): void;
|
|
6
|
+
}) & typeof Shape;
|
|
7
|
+
export default class GaugeHorizon extends GaugeHorizon_base {
|
|
8
|
+
_draw(context: CanvasRenderingContext2D): void;
|
|
9
|
+
_post_draw(context: CanvasRenderingContext2D): void;
|
|
10
|
+
get nature(): {
|
|
11
|
+
mutable: boolean;
|
|
12
|
+
resizable: boolean;
|
|
13
|
+
rotatable: boolean;
|
|
14
|
+
properties: ({
|
|
15
|
+
type: string;
|
|
16
|
+
label: string;
|
|
17
|
+
name: string;
|
|
18
|
+
property: string;
|
|
19
|
+
observe?: undefined;
|
|
20
|
+
} | {
|
|
21
|
+
type: string;
|
|
22
|
+
label: string;
|
|
23
|
+
name: string;
|
|
24
|
+
observe: (this: HTMLElement, startValue: number) => void;
|
|
25
|
+
property: string;
|
|
26
|
+
} | {
|
|
27
|
+
type: string;
|
|
28
|
+
label: string;
|
|
29
|
+
name: string;
|
|
30
|
+
property: {
|
|
31
|
+
min: number;
|
|
32
|
+
max: number;
|
|
33
|
+
label?: undefined;
|
|
34
|
+
};
|
|
35
|
+
observe?: undefined;
|
|
36
|
+
} | {
|
|
37
|
+
type: string;
|
|
38
|
+
label: string;
|
|
39
|
+
name: string;
|
|
40
|
+
property: {
|
|
41
|
+
label: string;
|
|
42
|
+
min?: undefined;
|
|
43
|
+
max?: undefined;
|
|
44
|
+
};
|
|
45
|
+
observe?: undefined;
|
|
46
|
+
} | {
|
|
47
|
+
type: string;
|
|
48
|
+
label: string;
|
|
49
|
+
name: string;
|
|
50
|
+
property?: undefined;
|
|
51
|
+
observe?: undefined;
|
|
52
|
+
})[];
|
|
53
|
+
help: string;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export {};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
import { Component, RectPath, Shape, ValueHolder, } from '@hatiolab/things-scene';
|
|
5
|
+
import { PROPERTIES } from './gauge-properties';
|
|
6
|
+
const NATURE = {
|
|
7
|
+
mutable: false,
|
|
8
|
+
resizable: true,
|
|
9
|
+
rotatable: true,
|
|
10
|
+
properties: [
|
|
11
|
+
...PROPERTIES,
|
|
12
|
+
{
|
|
13
|
+
type: 'color',
|
|
14
|
+
label: 'text-fill-style',
|
|
15
|
+
name: 'textFillStyle',
|
|
16
|
+
property: 'textFillStyle'
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
type: 'color',
|
|
20
|
+
label: 'needle-fill-style',
|
|
21
|
+
name: 'needleFillStyle',
|
|
22
|
+
property: 'needleFillStyle'
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
type: 'number',
|
|
26
|
+
label: 'needle-size',
|
|
27
|
+
name: 'needleSize',
|
|
28
|
+
property: 'needleSize'
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
help: 'scene/component/gauge-horizon'
|
|
32
|
+
};
|
|
33
|
+
export default class GaugeHorizon extends ValueHolder(RectPath(Shape)) {
|
|
34
|
+
_draw(context) {
|
|
35
|
+
var { startValue, endValue, step, subStep, colorStops, needleFillStyle, stepFillStyle, textFillStyle, needleSize, stepNeedleSize, stepTextSize, showStepText = true, showStartValue = true, showEndValue = true, showStepLine = true, showSubStep = true, width, height, top, left, animFromBase = false } = this.model;
|
|
36
|
+
startValue = Number(startValue);
|
|
37
|
+
this.animOnValueChange(this.value, animFromBase, startValue);
|
|
38
|
+
const totalValue = endValue - startValue; // 게이지의 시작과 끝 값의 크기
|
|
39
|
+
context.translate(left, top); // top과 left의 좌표에 영향을 받지 않기 위해 transalate를 한다음 모든 탑과 레프트의 좌표를 0으로 줌
|
|
40
|
+
//// 메인 막대 그리기 ////
|
|
41
|
+
context.beginPath();
|
|
42
|
+
context.rect(0, 0, width, height);
|
|
43
|
+
this.drawFill(context);
|
|
44
|
+
this.drawStroke(context);
|
|
45
|
+
context.closePath();
|
|
46
|
+
//// 스텝별 색 칠하기 ////
|
|
47
|
+
if (colorStops) {
|
|
48
|
+
let beforeValue = 0;
|
|
49
|
+
colorStops.forEach(function (v, idx, arr) {
|
|
50
|
+
context.beginPath();
|
|
51
|
+
let value = Math.max(Math.min(v.position - startValue, totalValue), 0); // v.position 범위의 최소값은 0, 최대값은 totalValue가 되야함.
|
|
52
|
+
let startStepPosition = (width * beforeValue) / totalValue;
|
|
53
|
+
let endStepPosition;
|
|
54
|
+
// console.log(startStepPosition + (width * value / totalValue));
|
|
55
|
+
if (idx == arr.length - 1 || startStepPosition + (width * value) / totalValue)
|
|
56
|
+
// 배열의 마지막 값이거나 중간 시작값 + 그려지는 값이 width 를 넘을 경우는 무조건 끝까지 채워주도록 한다
|
|
57
|
+
endStepPosition = width - startStepPosition;
|
|
58
|
+
else
|
|
59
|
+
endStepPosition = (width * value) / totalValue;
|
|
60
|
+
if (beforeValue > totalValue || beforeValue > value)
|
|
61
|
+
// 값이 게이지의 최대 값을 넘어가거나 이전 값 보다 현재값이 작으면 다시 그릴 필요 없음
|
|
62
|
+
return false;
|
|
63
|
+
context.rect(startStepPosition, 0, endStepPosition, height);
|
|
64
|
+
context.fillStyle = v.color;
|
|
65
|
+
context.fill();
|
|
66
|
+
beforeValue = value;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
//// 스텝 선 그리기 ////
|
|
70
|
+
context.fillStyle = stepFillStyle;
|
|
71
|
+
if (showStepLine) {
|
|
72
|
+
let count = totalValue / step;
|
|
73
|
+
let stepSize = width * 0.06;
|
|
74
|
+
// Draw StartValue
|
|
75
|
+
context.fillRect(0, height - stepSize, stepNeedleSize, stepSize);
|
|
76
|
+
// Draw StepValue
|
|
77
|
+
for (let num = 1; num < count; num++) {
|
|
78
|
+
let locate = (width / count) * num;
|
|
79
|
+
context.fillRect(locate, height - stepSize, stepNeedleSize, stepSize);
|
|
80
|
+
}
|
|
81
|
+
// Draw EndValue
|
|
82
|
+
context.fillRect(width, height - stepSize, stepNeedleSize, stepSize);
|
|
83
|
+
}
|
|
84
|
+
//// 서브 스탭 그리기 ////
|
|
85
|
+
if (showSubStep) {
|
|
86
|
+
let count = totalValue;
|
|
87
|
+
let subStepSize = width * 0.027;
|
|
88
|
+
// Draw StartValue
|
|
89
|
+
context.fillRect(0, height - subStepSize, stepNeedleSize, subStepSize);
|
|
90
|
+
// Draw StepValue
|
|
91
|
+
for (let num = 1; num <= count; num++) {
|
|
92
|
+
if (num % step == 0 || num % subStep != 0) {
|
|
93
|
+
// 메인 스탭과 서브 스탭은 그리지 않음
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
let locate = (width / count) * num;
|
|
97
|
+
context.fillRect(locate, height - subStepSize, stepNeedleSize, subStepSize);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
//// 스텝 텍스트 그리기 ////
|
|
101
|
+
let fontSize = (width * stepTextSize) / 150;
|
|
102
|
+
context.fillStyle = textFillStyle;
|
|
103
|
+
context.font = fontSize + 'px arial';
|
|
104
|
+
context.textBaseline = 'middle';
|
|
105
|
+
context.textAlign = 'center';
|
|
106
|
+
if (showStartValue) {
|
|
107
|
+
// Draw StartText
|
|
108
|
+
context.fillText(startValue, 0, height + fontSize * 0.75);
|
|
109
|
+
}
|
|
110
|
+
if (showEndValue) {
|
|
111
|
+
// Draw EndText
|
|
112
|
+
context.fillText(endValue, width, height + fontSize * 0.75);
|
|
113
|
+
}
|
|
114
|
+
if (showStepText) {
|
|
115
|
+
// Draw StepText
|
|
116
|
+
let count = totalValue / step;
|
|
117
|
+
for (let num = 1; num < count; num++) {
|
|
118
|
+
let value = startValue + step * num;
|
|
119
|
+
let locate = (width / count) * num;
|
|
120
|
+
context.fillText(value, locate, height + fontSize * 0.75);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//// 바늘 그리기 ////
|
|
124
|
+
context.beginPath();
|
|
125
|
+
let drawingValue = this.animValue;
|
|
126
|
+
drawingValue = Math.max(Math.min(drawingValue, endValue), startValue); // 그려지는 값은 startValue보다 작을 수 없고, endValue보다 클 수 없음.
|
|
127
|
+
let position = ((drawingValue - startValue) / totalValue) * width;
|
|
128
|
+
needleSize *= 4;
|
|
129
|
+
context.moveTo(position, height + fontSize * 1.4);
|
|
130
|
+
context.lineTo(position + needleSize / 2, height + needleSize + fontSize * 1.4);
|
|
131
|
+
context.lineTo(position - needleSize / 2, height + needleSize + fontSize * 1.4);
|
|
132
|
+
context.fillStyle = needleFillStyle;
|
|
133
|
+
context.fill();
|
|
134
|
+
context.closePath();
|
|
135
|
+
context.translate(-left, -top);
|
|
136
|
+
}
|
|
137
|
+
_post_draw(context) {
|
|
138
|
+
this.drawText(context);
|
|
139
|
+
}
|
|
140
|
+
get nature() {
|
|
141
|
+
return NATURE;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
Component.register('gauge-horizon', GaugeHorizon);
|
|
145
|
+
//# sourceMappingURL=gauge-horizon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gauge-horizon.js","sourceRoot":"","sources":["../src/gauge-horizon.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport {\n Component,\n RectPath,\n Shape,\n ValueHolder,\n} from '@hatiolab/things-scene';\n\nimport { PROPERTIES } from './gauge-properties';\n\nconst NATURE = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n ...PROPERTIES,\n {\n type: 'color',\n label: 'text-fill-style',\n name: 'textFillStyle',\n property: 'textFillStyle'\n },\n {\n type: 'color',\n label: 'needle-fill-style',\n name: 'needleFillStyle',\n property: 'needleFillStyle'\n },\n {\n type: 'number',\n label: 'needle-size',\n name: 'needleSize',\n property: 'needleSize'\n }\n ],\n help: 'scene/component/gauge-horizon'\n}\n\nexport default class GaugeHorizon extends ValueHolder(RectPath(Shape)) {\n _draw(context: CanvasRenderingContext2D) {\n var {\n startValue,\n endValue,\n step,\n subStep,\n colorStops,\n needleFillStyle,\n stepFillStyle,\n textFillStyle,\n needleSize,\n stepNeedleSize,\n stepTextSize,\n showStepText = true,\n showStartValue = true,\n showEndValue = true,\n showStepLine = true,\n showSubStep = true,\n width,\n height,\n top,\n left,\n animFromBase = false\n } = this.model\n\n startValue = Number(startValue)\n\n this.animOnValueChange(this.value, animFromBase, startValue)\n\n const totalValue = endValue - startValue // 게이지의 시작과 끝 값의 크기\n\n context.translate(left, top) // top과 left의 좌표에 영향을 받지 않기 위해 transalate를 한다음 모든 탑과 레프트의 좌표를 0으로 줌\n\n //// 메인 막대 그리기 ////\n context.beginPath()\n\n context.rect(0, 0, width, height)\n\n this.drawFill(context)\n this.drawStroke(context)\n context.closePath()\n\n //// 스텝별 색 칠하기 ////\n if (colorStops) {\n let beforeValue = 0\n colorStops.forEach(function (v: {position: number; color: string;}, idx: number, arr: {position: number; color: string;}[]) {\n context.beginPath()\n\n let value = Math.max(Math.min(v.position - startValue, totalValue), 0) // v.position 범위의 최소값은 0, 최대값은 totalValue가 되야함.\n let startStepPosition = (width * beforeValue) / totalValue\n let endStepPosition\n // console.log(startStepPosition + (width * value / totalValue));\n if (idx == arr.length - 1 || startStepPosition + (width * value) / totalValue)\n // 배열의 마지막 값이거나 중간 시작값 + 그려지는 값이 width 를 넘을 경우는 무조건 끝까지 채워주도록 한다\n endStepPosition = width - startStepPosition\n else endStepPosition = (width * value) / totalValue\n\n if (beforeValue > totalValue || beforeValue > value)\n // 값이 게이지의 최대 값을 넘어가거나 이전 값 보다 현재값이 작으면 다시 그릴 필요 없음\n return false\n\n context.rect(startStepPosition, 0, endStepPosition, height)\n\n context.fillStyle = v.color\n context.fill()\n\n beforeValue = value\n })\n }\n\n //// 스텝 선 그리기 ////\n context.fillStyle = stepFillStyle\n if (showStepLine) {\n let count = totalValue / step\n let stepSize = width * 0.06\n\n // Draw StartValue\n context.fillRect(0, height - stepSize, stepNeedleSize, stepSize)\n // Draw StepValue\n for (let num = 1; num < count; num++) {\n let locate = (width / count) * num\n\n context.fillRect(locate, height - stepSize, stepNeedleSize, stepSize)\n }\n // Draw EndValue\n context.fillRect(width, height - stepSize, stepNeedleSize, stepSize)\n }\n\n //// 서브 스탭 그리기 ////\n if (showSubStep) {\n let count = totalValue\n let subStepSize = width * 0.027\n // Draw StartValue\n context.fillRect(0, height - subStepSize, stepNeedleSize, subStepSize)\n\n // Draw StepValue\n for (let num = 1; num <= count; num++) {\n if (num % step == 0 || num % subStep != 0) {\n // 메인 스탭과 서브 스탭은 그리지 않음\n continue\n }\n let locate = (width / count) * num\n context.fillRect(locate, height - subStepSize, stepNeedleSize, subStepSize)\n }\n }\n\n //// 스텝 텍스트 그리기 ////\n let fontSize = (width * stepTextSize) / 150\n context.fillStyle = textFillStyle\n context.font = fontSize + 'px arial'\n context.textBaseline = 'middle'\n context.textAlign = 'center'\n if (showStartValue) {\n // Draw StartText\n context.fillText(startValue, 0, height + fontSize * 0.75)\n }\n\n if (showEndValue) {\n // Draw EndText\n context.fillText(endValue, width, height + fontSize * 0.75)\n }\n\n if (showStepText) {\n // Draw StepText\n let count = totalValue / step\n\n for (let num = 1; num < count; num++) {\n let value = startValue + step * num\n let locate = (width / count) * num\n\n context.fillText(value, locate, height + fontSize * 0.75)\n }\n }\n\n //// 바늘 그리기 ////\n context.beginPath()\n let drawingValue = this.animValue\n drawingValue = Math.max(Math.min(drawingValue, endValue), startValue) // 그려지는 값은 startValue보다 작을 수 없고, endValue보다 클 수 없음.\n let position = ((drawingValue - startValue) / totalValue) * width\n\n needleSize *= 4\n context.moveTo(position, height + fontSize * 1.4)\n context.lineTo(position + needleSize / 2, height + needleSize + fontSize * 1.4)\n context.lineTo(position - needleSize / 2, height + needleSize + fontSize * 1.4)\n\n context.fillStyle = needleFillStyle\n context.fill()\n context.closePath()\n\n context.translate(-left, -top)\n }\n\n _post_draw(context: CanvasRenderingContext2D) {\n this.drawText(context)\n }\n\n get nature() {\n return NATURE\n }\n}\n\nComponent.register('gauge-horizon', GaugeHorizon)\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export declare const PROPERTIES: ({
|
|
2
|
+
type: string;
|
|
3
|
+
label: string;
|
|
4
|
+
name: string;
|
|
5
|
+
property: string;
|
|
6
|
+
observe?: undefined;
|
|
7
|
+
} | {
|
|
8
|
+
type: string;
|
|
9
|
+
label: string;
|
|
10
|
+
name: string;
|
|
11
|
+
observe: (this: HTMLElement, startValue: number) => void;
|
|
12
|
+
property: string;
|
|
13
|
+
} | {
|
|
14
|
+
type: string;
|
|
15
|
+
label: string;
|
|
16
|
+
name: string;
|
|
17
|
+
property: {
|
|
18
|
+
min: number;
|
|
19
|
+
max: number;
|
|
20
|
+
label?: undefined;
|
|
21
|
+
};
|
|
22
|
+
observe?: undefined;
|
|
23
|
+
} | {
|
|
24
|
+
type: string;
|
|
25
|
+
label: string;
|
|
26
|
+
name: string;
|
|
27
|
+
property: {
|
|
28
|
+
label: string;
|
|
29
|
+
min?: undefined;
|
|
30
|
+
max?: undefined;
|
|
31
|
+
};
|
|
32
|
+
observe?: undefined;
|
|
33
|
+
} | {
|
|
34
|
+
type: string;
|
|
35
|
+
label: string;
|
|
36
|
+
name: string;
|
|
37
|
+
property?: undefined;
|
|
38
|
+
observe?: undefined;
|
|
39
|
+
})[];
|