@guinetik/gcanvas 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/release.yaml +70 -0
- package/.jshintrc +4 -0
- package/.vscode/settings.json +22 -0
- package/CLAUDE.md +310 -0
- package/blackhole.jpg +0 -0
- package/demo.png +0 -0
- package/demos/CNAME +1 -0
- package/demos/animations.html +31 -0
- package/demos/basic.html +38 -0
- package/demos/baskara.html +31 -0
- package/demos/bezier.html +35 -0
- package/demos/beziersignature.html +29 -0
- package/demos/blackhole.html +28 -0
- package/demos/blob.html +35 -0
- package/demos/demos.css +289 -0
- package/demos/easing.html +28 -0
- package/demos/events.html +195 -0
- package/demos/fluent.html +647 -0
- package/demos/fractals.html +36 -0
- package/demos/genart.html +26 -0
- package/demos/gendream.html +26 -0
- package/demos/group.html +36 -0
- package/demos/home.html +587 -0
- package/demos/index.html +364 -0
- package/demos/isometric.html +34 -0
- package/demos/js/animations.js +452 -0
- package/demos/js/basic.js +204 -0
- package/demos/js/baskara.js +751 -0
- package/demos/js/bezier.js +692 -0
- package/demos/js/beziersignature.js +241 -0
- package/demos/js/blackhole/accretiondisk.obj.js +379 -0
- package/demos/js/blackhole/blackhole.obj.js +318 -0
- package/demos/js/blackhole/index.js +409 -0
- package/demos/js/blackhole/particle.js +56 -0
- package/demos/js/blackhole/starfield.obj.js +218 -0
- package/demos/js/blob.js +2263 -0
- package/demos/js/easing.js +477 -0
- package/demos/js/fluent.js +183 -0
- package/demos/js/fractals.js +931 -0
- package/demos/js/fractalworker.js +93 -0
- package/demos/js/genart.js +268 -0
- package/demos/js/gendream.js +209 -0
- package/demos/js/group.js +140 -0
- package/demos/js/info-toggle.js +25 -0
- package/demos/js/isometric.js +863 -0
- package/demos/js/kerr.js +1556 -0
- package/demos/js/lavalamp.js +590 -0
- package/demos/js/layout.js +354 -0
- package/demos/js/mondrian.js +285 -0
- package/demos/js/opacity.js +275 -0
- package/demos/js/painter.js +484 -0
- package/demos/js/particles-showcase.js +514 -0
- package/demos/js/particles.js +299 -0
- package/demos/js/patterns.js +397 -0
- package/demos/js/penrose/artifact.js +69 -0
- package/demos/js/penrose/blackhole.js +121 -0
- package/demos/js/penrose/constants.js +73 -0
- package/demos/js/penrose/game.js +943 -0
- package/demos/js/penrose/lore.js +278 -0
- package/demos/js/penrose/penrosescene.js +892 -0
- package/demos/js/penrose/ship.js +216 -0
- package/demos/js/penrose/sounds.js +211 -0
- package/demos/js/penrose/voidparticle.js +55 -0
- package/demos/js/penrose/voidscene.js +258 -0
- package/demos/js/penrose/voidship.js +144 -0
- package/demos/js/penrose/wormhole.js +46 -0
- package/demos/js/pipeline.js +555 -0
- package/demos/js/scene.js +304 -0
- package/demos/js/scenes.js +320 -0
- package/demos/js/schrodinger.js +410 -0
- package/demos/js/schwarzschild.js +1023 -0
- package/demos/js/shapes.js +628 -0
- package/demos/js/space/alien.js +171 -0
- package/demos/js/space/boom.js +98 -0
- package/demos/js/space/boss.js +353 -0
- package/demos/js/space/buff.js +73 -0
- package/demos/js/space/bullet.js +102 -0
- package/demos/js/space/constants.js +85 -0
- package/demos/js/space/game.js +1884 -0
- package/demos/js/space/hud.js +112 -0
- package/demos/js/space/laserbeam.js +179 -0
- package/demos/js/space/lightning.js +277 -0
- package/demos/js/space/minion.js +192 -0
- package/demos/js/space/missile.js +212 -0
- package/demos/js/space/player.js +430 -0
- package/demos/js/space/powerup.js +90 -0
- package/demos/js/space/starfield.js +58 -0
- package/demos/js/space/starpower.js +90 -0
- package/demos/js/spacetime.js +559 -0
- package/demos/js/svgtween.js +204 -0
- package/demos/js/tde/accretiondisk.js +418 -0
- package/demos/js/tde/blackhole.js +219 -0
- package/demos/js/tde/blackholescene.js +209 -0
- package/demos/js/tde/config.js +59 -0
- package/demos/js/tde/index.js +695 -0
- package/demos/js/tde/jets.js +290 -0
- package/demos/js/tde/lensedstarfield.js +147 -0
- package/demos/js/tde/tdestar.js +317 -0
- package/demos/js/tde/tidalstream.js +356 -0
- package/demos/js/tde_old/blackhole.obj.js +354 -0
- package/demos/js/tde_old/debris.obj.js +791 -0
- package/demos/js/tde_old/flare.obj.js +239 -0
- package/demos/js/tde_old/index.js +448 -0
- package/demos/js/tde_old/star.obj.js +812 -0
- package/demos/js/tiles.js +312 -0
- package/demos/js/tweendemo.js +79 -0
- package/demos/js/visibility.js +102 -0
- package/demos/kerr.html +28 -0
- package/demos/lavalamp.html +27 -0
- package/demos/layouts.html +37 -0
- package/demos/logo.svg +4 -0
- package/demos/loop.html +84 -0
- package/demos/mondrian.html +32 -0
- package/demos/og_image.png +0 -0
- package/demos/opacity.html +36 -0
- package/demos/painter.html +39 -0
- package/demos/particles-showcase.html +28 -0
- package/demos/particles.html +24 -0
- package/demos/patterns.html +33 -0
- package/demos/penrose-game.html +31 -0
- package/demos/pipeline.html +737 -0
- package/demos/scene.html +33 -0
- package/demos/scenes.html +96 -0
- package/demos/schrodinger.html +27 -0
- package/demos/schwarzschild.html +27 -0
- package/demos/shapes.html +16 -0
- package/demos/space.html +85 -0
- package/demos/spacetime.html +27 -0
- package/demos/svgtween.html +29 -0
- package/demos/tde.html +28 -0
- package/demos/tiles.html +28 -0
- package/demos/transforms.html +400 -0
- package/demos/tween.html +45 -0
- package/demos/visibility.html +33 -0
- package/disk_example.png +0 -0
- package/docs/README.md +222 -0
- package/docs/concepts/architecture-overview.md +204 -0
- package/docs/concepts/lifecycle.md +255 -0
- package/docs/concepts/rendering-pipeline.md +279 -0
- package/docs/concepts/tde-zorder.md +106 -0
- package/docs/concepts/two-layer-architecture.md +229 -0
- package/docs/getting-started/first-game.md +354 -0
- package/docs/getting-started/hello-world.md +269 -0
- package/docs/getting-started/installation.md +157 -0
- package/docs/modules/collision/README.md +453 -0
- package/docs/modules/fluent/README.md +1075 -0
- package/docs/modules/game/README.md +303 -0
- package/docs/modules/isometric-camera.md +210 -0
- package/docs/modules/isometric.md +275 -0
- package/docs/modules/painter/README.md +328 -0
- package/docs/modules/particle/README.md +559 -0
- package/docs/modules/shapes/README.md +221 -0
- package/docs/modules/shapes/base/euclidian.md +123 -0
- package/docs/modules/shapes/base/geometry2d.md +204 -0
- package/docs/modules/shapes/base/renderable.md +215 -0
- package/docs/modules/shapes/base/shape.md +262 -0
- package/docs/modules/shapes/base/transformable.md +243 -0
- package/docs/modules/shapes/hierarchy.md +218 -0
- package/docs/modules/state/README.md +577 -0
- package/docs/modules/util/README.md +99 -0
- package/docs/modules/util/camera3d.md +412 -0
- package/docs/modules/util/scene3d.md +395 -0
- package/index.html +17 -0
- package/jsdoc.json +50 -0
- package/package.json +55 -0
- package/readme.md +599 -0
- package/scripts/build-demo.js +69 -0
- package/scripts/bundle4llm.js +276 -0
- package/scripts/clearconsole.js +48 -0
- package/src/collision/collision-system.js +332 -0
- package/src/collision/collision.js +303 -0
- package/src/collision/index.js +10 -0
- package/src/fluent/fluent-game.js +430 -0
- package/src/fluent/fluent-go.js +1060 -0
- package/src/fluent/fluent-layer.js +152 -0
- package/src/fluent/fluent-scene.js +291 -0
- package/src/fluent/index.js +98 -0
- package/src/fluent/sketch.js +380 -0
- package/src/game/game.js +467 -0
- package/src/game/index.js +49 -0
- package/src/game/objects/go.js +220 -0
- package/src/game/objects/imagego.js +30 -0
- package/src/game/objects/index.js +54 -0
- package/src/game/objects/isometric-scene.js +260 -0
- package/src/game/objects/layoutscene.js +549 -0
- package/src/game/objects/scene.js +175 -0
- package/src/game/objects/scene3d.js +118 -0
- package/src/game/objects/text.js +221 -0
- package/src/game/objects/wrapper.js +232 -0
- package/src/game/pipeline.js +243 -0
- package/src/game/ui/button.js +396 -0
- package/src/game/ui/cursor.js +93 -0
- package/src/game/ui/fps.js +91 -0
- package/src/game/ui/index.js +5 -0
- package/src/game/ui/togglebutton.js +93 -0
- package/src/game/ui/tooltip.js +249 -0
- package/src/index.js +25 -0
- package/src/io/events.js +20 -0
- package/src/io/index.js +86 -0
- package/src/io/input.js +70 -0
- package/src/io/keys.js +152 -0
- package/src/io/mouse.js +61 -0
- package/src/io/touch.js +39 -0
- package/src/logger/debugtab.js +138 -0
- package/src/logger/index.js +3 -0
- package/src/logger/loggable.js +47 -0
- package/src/logger/logger.js +113 -0
- package/src/math/complex.js +37 -0
- package/src/math/constants.js +1 -0
- package/src/math/fractal.js +1271 -0
- package/src/math/gr.js +201 -0
- package/src/math/heat.js +202 -0
- package/src/math/index.js +12 -0
- package/src/math/noise.js +433 -0
- package/src/math/orbital.js +191 -0
- package/src/math/patterns.js +1339 -0
- package/src/math/penrose.js +259 -0
- package/src/math/quantum.js +115 -0
- package/src/math/random.js +195 -0
- package/src/math/tensor.js +1009 -0
- package/src/mixins/anchor.js +131 -0
- package/src/mixins/draggable.js +72 -0
- package/src/mixins/index.js +2 -0
- package/src/motion/bezier.js +132 -0
- package/src/motion/bounce.js +58 -0
- package/src/motion/easing.js +349 -0
- package/src/motion/float.js +130 -0
- package/src/motion/follow.js +125 -0
- package/src/motion/hop.js +52 -0
- package/src/motion/index.js +82 -0
- package/src/motion/motion.js +1124 -0
- package/src/motion/orbit.js +49 -0
- package/src/motion/oscillate.js +39 -0
- package/src/motion/parabolic.js +141 -0
- package/src/motion/patrol.js +147 -0
- package/src/motion/pendulum.js +48 -0
- package/src/motion/pulse.js +88 -0
- package/src/motion/shake.js +83 -0
- package/src/motion/spiral.js +144 -0
- package/src/motion/spring.js +150 -0
- package/src/motion/swing.js +47 -0
- package/src/motion/tween.js +92 -0
- package/src/motion/tweenetik.js +139 -0
- package/src/motion/waypoint.js +210 -0
- package/src/painter/index.js +8 -0
- package/src/painter/painter.colors.js +331 -0
- package/src/painter/painter.effects.js +230 -0
- package/src/painter/painter.img.js +229 -0
- package/src/painter/painter.js +295 -0
- package/src/painter/painter.lines.js +189 -0
- package/src/painter/painter.opacity.js +41 -0
- package/src/painter/painter.shapes.js +277 -0
- package/src/painter/painter.text.js +273 -0
- package/src/particle/emitter.js +124 -0
- package/src/particle/index.js +11 -0
- package/src/particle/particle-system.js +322 -0
- package/src/particle/particle.js +71 -0
- package/src/particle/updaters.js +170 -0
- package/src/shapes/arc.js +43 -0
- package/src/shapes/arrow.js +33 -0
- package/src/shapes/bezier.js +42 -0
- package/src/shapes/circle.js +62 -0
- package/src/shapes/clouds.js +56 -0
- package/src/shapes/cone.js +219 -0
- package/src/shapes/cross.js +70 -0
- package/src/shapes/cube.js +244 -0
- package/src/shapes/cylinder.js +254 -0
- package/src/shapes/diamond.js +48 -0
- package/src/shapes/euclidian.js +111 -0
- package/src/shapes/figure.js +115 -0
- package/src/shapes/geometry.js +220 -0
- package/src/shapes/group.js +375 -0
- package/src/shapes/heart.js +42 -0
- package/src/shapes/hexagon.js +26 -0
- package/src/shapes/image.js +192 -0
- package/src/shapes/index.js +111 -0
- package/src/shapes/line.js +29 -0
- package/src/shapes/pattern.js +90 -0
- package/src/shapes/pin.js +44 -0
- package/src/shapes/poly.js +31 -0
- package/src/shapes/prism.js +226 -0
- package/src/shapes/rect.js +35 -0
- package/src/shapes/renderable.js +333 -0
- package/src/shapes/ring.js +26 -0
- package/src/shapes/roundrect.js +95 -0
- package/src/shapes/shape.js +117 -0
- package/src/shapes/slice.js +26 -0
- package/src/shapes/sphere.js +314 -0
- package/src/shapes/sphere3d.js +537 -0
- package/src/shapes/square.js +15 -0
- package/src/shapes/star.js +99 -0
- package/src/shapes/svg.js +408 -0
- package/src/shapes/text.js +553 -0
- package/src/shapes/traceable.js +83 -0
- package/src/shapes/transform.js +357 -0
- package/src/shapes/transformable.js +172 -0
- package/src/shapes/triangle.js +26 -0
- package/src/sound/index.js +17 -0
- package/src/sound/sound.js +473 -0
- package/src/sound/synth.analyzer.js +149 -0
- package/src/sound/synth.effects.js +207 -0
- package/src/sound/synth.envelope.js +59 -0
- package/src/sound/synth.js +229 -0
- package/src/sound/synth.musical.js +160 -0
- package/src/sound/synth.noise.js +85 -0
- package/src/sound/synth.oscillators.js +293 -0
- package/src/state/index.js +10 -0
- package/src/state/state-machine.js +371 -0
- package/src/util/camera3d.js +438 -0
- package/src/util/index.js +6 -0
- package/src/util/isometric-camera.js +235 -0
- package/src/util/layout.js +317 -0
- package/src/util/position.js +147 -0
- package/src/util/tasks.js +47 -0
- package/src/util/zindex.js +287 -0
- package/src/webgl/index.js +9 -0
- package/src/webgl/shaders/sphere-shaders.js +994 -0
- package/src/webgl/webgl-renderer.js +388 -0
- package/tde.png +0 -0
- package/test/math/orbital.test.js +61 -0
- package/test/math/tensor.test.js +114 -0
- package/test/particle/emitter.test.js +204 -0
- package/test/particle/particle-system.test.js +310 -0
- package/test/particle/particle.test.js +116 -0
- package/test/particle/updaters.test.js +386 -0
- package/test/setup.js +120 -0
- package/test/shapes/euclidian.test.js +44 -0
- package/test/shapes/geometry.test.js +86 -0
- package/test/shapes/group.test.js +86 -0
- package/test/shapes/rectangle.test.js +64 -0
- package/test/shapes/transform.test.js +379 -0
- package/test/util/camera3d.test.js +428 -0
- package/test/util/scene3d.test.js +352 -0
- package/types/collision.d.ts +249 -0
- package/types/common.d.ts +155 -0
- package/types/game.d.ts +497 -0
- package/types/index.d.ts +309 -0
- package/types/io.d.ts +188 -0
- package/types/logger.d.ts +127 -0
- package/types/math.d.ts +268 -0
- package/types/mixins.d.ts +92 -0
- package/types/motion.d.ts +678 -0
- package/types/painter.d.ts +378 -0
- package/types/shapes.d.ts +864 -0
- package/types/sound.d.ts +672 -0
- package/types/state.d.ts +251 -0
- package/types/util.d.ts +253 -0
- package/vite.config.js +50 -0
- package/vitest.config.js +13 -0
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
/***************************************************************
|
|
2
|
+
* Button.js
|
|
3
|
+
*
|
|
4
|
+
* A basic UI Button GameObject that combines a Rectangle shape
|
|
5
|
+
* and a Text label using a Group. It supports hover and press
|
|
6
|
+
* states, and fires an optional onClick callback when clicked.
|
|
7
|
+
***************************************************************/
|
|
8
|
+
|
|
9
|
+
import { Group, Rectangle, TextShape, Shape } from "../../shapes";
|
|
10
|
+
import { GameObject } from "../objects/go";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Button - A clickable UI element as a GameObject.
|
|
14
|
+
*
|
|
15
|
+
* The Button uses:
|
|
16
|
+
* - A background Rectangle (or a custom shape if supplied).
|
|
17
|
+
* - A TextShape (label).
|
|
18
|
+
* - A Group to position both.
|
|
19
|
+
*
|
|
20
|
+
* The button responds to pointer events and has states:
|
|
21
|
+
* "default", "hover", and "pressed". An optional onClick callback
|
|
22
|
+
* is fired when the user completes a press on the button.
|
|
23
|
+
*
|
|
24
|
+
* Example usage:
|
|
25
|
+
* ```js
|
|
26
|
+
* const btn = new Button(game, {
|
|
27
|
+
* x: 200,
|
|
28
|
+
* y: 100,
|
|
29
|
+
* width: 150,
|
|
30
|
+
* height: 50,
|
|
31
|
+
* text: "Click Me",
|
|
32
|
+
* onClick: () => this.logger.log("Button pressed!")
|
|
33
|
+
* });
|
|
34
|
+
* game.pipeline.add(btn);
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export class Button extends GameObject {
|
|
38
|
+
/**
|
|
39
|
+
* Create a Button instance.
|
|
40
|
+
* @param {Game} game - The main game instance.
|
|
41
|
+
* @param {object} [options={}] - Configuration for the Button.
|
|
42
|
+
* @param {number} [options.x=0] - X-position of the Button (center).
|
|
43
|
+
* @param {number} [options.y=0] - Y-position of the Button (center).
|
|
44
|
+
* @param {number} [options.width=120] - Width of the Button.
|
|
45
|
+
* @param {number} [options.height=40] - Height of the Button.
|
|
46
|
+
* @param {string} [options.text="Button"] - Label text for the Button.
|
|
47
|
+
* @param {string} [options.font="14px monospace"] - Font for the text.
|
|
48
|
+
* @param {string} [options.textColor="#000"] - Text color for the Button.
|
|
49
|
+
* @param {string} [options.textAlign="center"] - Alignment of the text.
|
|
50
|
+
* @param {string} [options.textBaseline="middle"] - Baseline of the text.
|
|
51
|
+
* @param {Rectangle|Shape} [options.shape=null] - Custom shape for the Button background. Defaults to a Rectangle.
|
|
52
|
+
* @param {TextShape} [options.label=null] - Custom text shape. Defaults to a center-aligned TextShape.
|
|
53
|
+
* @param {Function} [options.onClick=null] - Callback to invoke upon button click.
|
|
54
|
+
* @param {Function} [options.onHover=null] - Callback to invoke upon button hover.
|
|
55
|
+
* @param {Function} [options.onPressed=null] - Callback to invoke upon button pressed.
|
|
56
|
+
* @param {Function} [options.onRelease=null] - Callback to invoke upon button release.
|
|
57
|
+
* @param {string} [options.anchor] - Optional anchor for positioning (e.g. "top-left").
|
|
58
|
+
* @param {number} [options.padding] - Extra padding if using anchor.
|
|
59
|
+
* @param {string} [options.colorDefaultBg="#eee"] - Background color in default state.
|
|
60
|
+
* @param {string} [options.colorDefaultStroke="#999"] - Stroke color in default state.
|
|
61
|
+
* @param {string} [options.colorDefaultText="#333"] - Text color in default state.
|
|
62
|
+
* @param {string} [options.colorHoverBg="#222"] - Background color in hover state.
|
|
63
|
+
* @param {string} [options.colorHoverStroke="#16F529"] - Stroke color in hover state.
|
|
64
|
+
* @param {string} [options.colorHoverText="#16F529"] - Text color in hover state.
|
|
65
|
+
* @param {string} [options.colorPressedBg="#111"] - Background color in pressed state.
|
|
66
|
+
* @param {string} [options.colorPressedStroke="#00aaff"] - Stroke color in pressed state.
|
|
67
|
+
* @param {string} [options.colorPressedText="#00aaff"] - Text color in pressed state.
|
|
68
|
+
* @param {...any} rest - Additional properties passed to the superclass.
|
|
69
|
+
*/
|
|
70
|
+
constructor(game, options = {}) {
|
|
71
|
+
// Pass options to the GameObject constructor
|
|
72
|
+
super(game, options);
|
|
73
|
+
|
|
74
|
+
// Extract button-specific config
|
|
75
|
+
const {
|
|
76
|
+
x = 0,
|
|
77
|
+
y = 0,
|
|
78
|
+
width = 120,
|
|
79
|
+
height = 40,
|
|
80
|
+
text = "Button",
|
|
81
|
+
font = "14px monospace",
|
|
82
|
+
textColor = "#000",
|
|
83
|
+
textAlign = "center",
|
|
84
|
+
textBaseline = "middle",
|
|
85
|
+
shape = null,
|
|
86
|
+
label = null,
|
|
87
|
+
onClick = null,
|
|
88
|
+
onHover = null,
|
|
89
|
+
onPressed = null,
|
|
90
|
+
onRelease = null,
|
|
91
|
+
padding = 10,
|
|
92
|
+
colorDefaultBg = "#eee",
|
|
93
|
+
colorDefaultStroke = "#999",
|
|
94
|
+
colorDefaultText = "#333",
|
|
95
|
+
colorHoverBg = "#222",
|
|
96
|
+
colorHoverStroke = "#16F529",
|
|
97
|
+
colorHoverText = "#16F529",
|
|
98
|
+
colorPressedBg = "#111",
|
|
99
|
+
colorPressedStroke = "#00aaff",
|
|
100
|
+
colorPressedText = "#00aaff",
|
|
101
|
+
} = options;
|
|
102
|
+
|
|
103
|
+
// Basic position and sizing
|
|
104
|
+
this.x = x;
|
|
105
|
+
this.y = y;
|
|
106
|
+
this.width = width;
|
|
107
|
+
this.height = height;
|
|
108
|
+
this.padding = padding;
|
|
109
|
+
this.textAlign = textAlign;
|
|
110
|
+
this.textBaseline = textBaseline;
|
|
111
|
+
|
|
112
|
+
// Initialize the button components
|
|
113
|
+
this.initColorScheme({
|
|
114
|
+
colorDefaultBg,
|
|
115
|
+
colorDefaultStroke,
|
|
116
|
+
colorDefaultText,
|
|
117
|
+
colorHoverBg,
|
|
118
|
+
colorHoverStroke,
|
|
119
|
+
colorHoverText,
|
|
120
|
+
colorPressedBg,
|
|
121
|
+
colorPressedStroke,
|
|
122
|
+
colorPressedText
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
this.initBackground(shape);
|
|
126
|
+
this.initLabel(text, font, textColor, label);
|
|
127
|
+
this.initGroup();
|
|
128
|
+
this.initEvents(onClick, onHover, onPressed, onRelease);
|
|
129
|
+
|
|
130
|
+
// Initialize to default state
|
|
131
|
+
this.setState("default");
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Initialize the color scheme for different button states
|
|
136
|
+
* @param {object} colors - Configuration for button colors in different states
|
|
137
|
+
* @private
|
|
138
|
+
*/
|
|
139
|
+
initColorScheme(colors) {
|
|
140
|
+
this.colors = {
|
|
141
|
+
default: {
|
|
142
|
+
bg: colors.colorDefaultBg,
|
|
143
|
+
stroke: colors.colorDefaultStroke,
|
|
144
|
+
text: colors.colorDefaultText
|
|
145
|
+
},
|
|
146
|
+
hover: {
|
|
147
|
+
bg: colors.colorHoverBg,
|
|
148
|
+
stroke: colors.colorHoverStroke,
|
|
149
|
+
text: colors.colorHoverText
|
|
150
|
+
},
|
|
151
|
+
pressed: {
|
|
152
|
+
bg: colors.colorPressedBg,
|
|
153
|
+
stroke: colors.colorPressedStroke,
|
|
154
|
+
text: colors.colorPressedText
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Initialize the background shape of the button
|
|
161
|
+
* @param {Shape|null} shape - Custom shape or null to use default Rectangle
|
|
162
|
+
* @private
|
|
163
|
+
*/
|
|
164
|
+
initBackground(shape) {
|
|
165
|
+
this.bg = shape ?? new Rectangle({
|
|
166
|
+
width: this.width,
|
|
167
|
+
height: this.height,
|
|
168
|
+
color: this.colors.default.bg,
|
|
169
|
+
stroke: this.colors.default.stroke,
|
|
170
|
+
lineWidth: 2
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Initialize the text label of the button
|
|
176
|
+
* @param {string} text - Button text
|
|
177
|
+
* @param {string} font - Text font
|
|
178
|
+
* @param {string} textColor - Text color
|
|
179
|
+
* @param {TextShape|null} label - Custom label or null to create a new one
|
|
180
|
+
* @private
|
|
181
|
+
*/
|
|
182
|
+
initLabel(text, font, textColor, label) {
|
|
183
|
+
this.label = label ?? new TextShape(text, {
|
|
184
|
+
font: font,
|
|
185
|
+
color: textColor,
|
|
186
|
+
align: this.textAlign,
|
|
187
|
+
baseline: this.textBaseline
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
this.alignText();
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Update label position based on alignment and baseline settings
|
|
195
|
+
* @private
|
|
196
|
+
*/
|
|
197
|
+
alignText() {
|
|
198
|
+
if (!this.label) return;
|
|
199
|
+
|
|
200
|
+
const halfWidth = this.width / 2;
|
|
201
|
+
const halfHeight = this.height / 2;
|
|
202
|
+
|
|
203
|
+
// Horizontal alignment
|
|
204
|
+
switch (this.textAlign) {
|
|
205
|
+
case "left":
|
|
206
|
+
this.label.x = -halfWidth + this.padding;
|
|
207
|
+
break;
|
|
208
|
+
case "right":
|
|
209
|
+
this.label.x = halfWidth - this.padding;
|
|
210
|
+
break;
|
|
211
|
+
case "center":
|
|
212
|
+
default:
|
|
213
|
+
this.label.x = 0; // Center aligned means x=0 in center-based coords
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Vertical alignment
|
|
218
|
+
switch (this.textBaseline) {
|
|
219
|
+
case "top":
|
|
220
|
+
this.label.y = -halfHeight + this.padding;
|
|
221
|
+
break;
|
|
222
|
+
case "bottom":
|
|
223
|
+
this.label.y = halfHeight - this.padding;
|
|
224
|
+
break;
|
|
225
|
+
case "middle":
|
|
226
|
+
default:
|
|
227
|
+
this.label.y = 0; // Middle aligned means y=0 in center-based coords
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Initialize the group that will contain both background and label
|
|
234
|
+
* @private
|
|
235
|
+
*/
|
|
236
|
+
initGroup() {
|
|
237
|
+
this.group = new Group();
|
|
238
|
+
this.group.add(this.bg);
|
|
239
|
+
this.group.add(this.label);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Set up event handlers for mouse/touch interactions
|
|
244
|
+
* @param {Function|null} onClick - Callback to execute when button is clicked
|
|
245
|
+
* @private
|
|
246
|
+
*/
|
|
247
|
+
initEvents(onClick, onHover, onPressed, onRelease) {
|
|
248
|
+
this.interactive = true;
|
|
249
|
+
this.onHover = onHover;
|
|
250
|
+
this.onPressed = onPressed;
|
|
251
|
+
this.onRelease = onRelease;
|
|
252
|
+
|
|
253
|
+
this.on("mouseover", this.setState.bind(this, "hover"));
|
|
254
|
+
this.on("mouseout", this.setState.bind(this, "default"));
|
|
255
|
+
this.on("inputdown", this.setState.bind(this, "pressed"));
|
|
256
|
+
this.on("inputup", () => {
|
|
257
|
+
// Fire onClick if user was in "pressed" state
|
|
258
|
+
if (this.state === "pressed" && typeof onClick === "function") {
|
|
259
|
+
onClick();
|
|
260
|
+
}
|
|
261
|
+
// Return to hover state if the pointer is still over the button
|
|
262
|
+
this.setState("hover");
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Set the Button's state and update its visual appearance.
|
|
268
|
+
* @param {string} state - "default", "hover", or "pressed".
|
|
269
|
+
*/
|
|
270
|
+
setState(state) {
|
|
271
|
+
if (this.state === state) return;
|
|
272
|
+
this.state = state;
|
|
273
|
+
|
|
274
|
+
// Adjust shape & label appearance based on the new state
|
|
275
|
+
switch (state) {
|
|
276
|
+
case "default":
|
|
277
|
+
if (this.game.cursor) {
|
|
278
|
+
setTimeout(() => {
|
|
279
|
+
this.game.cursor.activate();
|
|
280
|
+
}, 0);
|
|
281
|
+
}
|
|
282
|
+
this.bg.color = this.colors.default.bg;
|
|
283
|
+
this.bg.stroke = this.colors.default.stroke;
|
|
284
|
+
this.label.color = this.colors.default.text;
|
|
285
|
+
this.game.canvas.style.cursor = "default";
|
|
286
|
+
this.onRelease?.();
|
|
287
|
+
break;
|
|
288
|
+
|
|
289
|
+
case "hover":
|
|
290
|
+
if (this.game.cursor) {
|
|
291
|
+
this.game.cursor.deactivate();
|
|
292
|
+
}
|
|
293
|
+
this.bg.color = this.colors.hover.bg;
|
|
294
|
+
this.bg.stroke = this.colors.hover.stroke;
|
|
295
|
+
this.label.color = this.colors.hover.text;
|
|
296
|
+
this.game.canvas.style.cursor = "pointer";
|
|
297
|
+
this.onHover?.();
|
|
298
|
+
break;
|
|
299
|
+
|
|
300
|
+
case "pressed":
|
|
301
|
+
if (this.game.cursor) {
|
|
302
|
+
this.game.cursor.deactivate();
|
|
303
|
+
}
|
|
304
|
+
this.bg.color = this.colors.pressed.bg;
|
|
305
|
+
this.bg.stroke = this.colors.pressed.stroke;
|
|
306
|
+
this.label.color = this.colors.pressed.text;
|
|
307
|
+
this.game.canvas.style.cursor = "pointer";
|
|
308
|
+
this.onPressed?.();
|
|
309
|
+
break;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Update method called each frame
|
|
315
|
+
* @param {number} dt - Delta time in seconds
|
|
316
|
+
*/
|
|
317
|
+
update(dt) {
|
|
318
|
+
super.update(dt);
|
|
319
|
+
|
|
320
|
+
// Check if we need to reposition the label
|
|
321
|
+
if (this._boundsDirty) {
|
|
322
|
+
this.alignText();
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Get the text of the Button.
|
|
328
|
+
* @returns {string} The text of the Button.
|
|
329
|
+
*/
|
|
330
|
+
get text() {
|
|
331
|
+
return this.label.text;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Set the text of the Button.
|
|
336
|
+
* @param {string} text - The new text for the Button.
|
|
337
|
+
*/
|
|
338
|
+
set text(text) {
|
|
339
|
+
this.label.text = text;
|
|
340
|
+
this._boundsDirty = true;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Change text alignment
|
|
345
|
+
* @param {string} align - New text alignment: "left", "center", or "right"
|
|
346
|
+
*/
|
|
347
|
+
setTextAlign(align) {
|
|
348
|
+
this.textAlign = align;
|
|
349
|
+
this.label.align = align;
|
|
350
|
+
this._boundsDirty = true;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Change text baseline
|
|
355
|
+
* @param {string} baseline - New text baseline: "top", "middle", or "bottom"
|
|
356
|
+
*/
|
|
357
|
+
setTextBaseline(baseline) {
|
|
358
|
+
this.textBaseline = baseline;
|
|
359
|
+
this.label.baseline = baseline;
|
|
360
|
+
this._boundsDirty = true;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Set the font for the button label
|
|
365
|
+
* @param {string} font - CSS font string (e.g., "14px Arial")
|
|
366
|
+
*/
|
|
367
|
+
setFont(font) {
|
|
368
|
+
this.label.font = font;
|
|
369
|
+
this._boundsDirty = true;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Resize the button and update child elements
|
|
374
|
+
* @param {number} width - New button width
|
|
375
|
+
* @param {number} height - New button height
|
|
376
|
+
*/
|
|
377
|
+
resize(width, height) {
|
|
378
|
+
this.width = width;
|
|
379
|
+
this.height = height;
|
|
380
|
+
|
|
381
|
+
// Update background size
|
|
382
|
+
this.bg.width = width;
|
|
383
|
+
this.bg.height = height;
|
|
384
|
+
|
|
385
|
+
// Reposition the label
|
|
386
|
+
this._boundsDirty = true;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Render the Button each frame by drawing the underlying Group.
|
|
391
|
+
*/
|
|
392
|
+
draw() {
|
|
393
|
+
super.draw();
|
|
394
|
+
this.group.render();
|
|
395
|
+
}
|
|
396
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { GameObject } from "../objects/go.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Cursor
|
|
5
|
+
*
|
|
6
|
+
* A GameObject that replaces the native mouse pointer with a custom shape.
|
|
7
|
+
* - Provide a normal shape (e.g. small Circle or custom icon).
|
|
8
|
+
* - Optionally provide a pressed shape to show while the mouse/touch is down.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* const cursor = new Cursor(game, normalShape, pressedShape);
|
|
12
|
+
* myScene.add(cursor);
|
|
13
|
+
*/
|
|
14
|
+
export class Cursor extends GameObject {
|
|
15
|
+
/**
|
|
16
|
+
* @param {Game} game - The main game instance.
|
|
17
|
+
* @param {Shape} normalShape - The shape to display when not pressed.
|
|
18
|
+
* @param {Shape} [pressedShape] - Optional shape to display when pressed.
|
|
19
|
+
*/
|
|
20
|
+
constructor(game, normalShape, pressedShape = null, options = {}) {
|
|
21
|
+
super(game, options);
|
|
22
|
+
/**
|
|
23
|
+
* Shape shown when the mouse is not pressed.
|
|
24
|
+
* @type {Shape}
|
|
25
|
+
*/
|
|
26
|
+
this.normalShape = normalShape;
|
|
27
|
+
/**
|
|
28
|
+
* Shape shown when the mouse is pressed.
|
|
29
|
+
* Fallback to normalShape if not provided.
|
|
30
|
+
* @type {Shape}
|
|
31
|
+
*/
|
|
32
|
+
this.pressedShape = pressedShape || normalShape;
|
|
33
|
+
/**
|
|
34
|
+
* If the cursor is active.
|
|
35
|
+
*/
|
|
36
|
+
this.active = false;
|
|
37
|
+
/**
|
|
38
|
+
* How far the cursor is offset from the mouse position.
|
|
39
|
+
*/
|
|
40
|
+
this.offsetX = 0.0;
|
|
41
|
+
/**
|
|
42
|
+
* How far the cursor is offset from the mouse position.
|
|
43
|
+
*/
|
|
44
|
+
this.offsetY = 0.0;
|
|
45
|
+
/**
|
|
46
|
+
* Whether the mouse (or touch) is currently pressed.
|
|
47
|
+
* @type {boolean}
|
|
48
|
+
*/
|
|
49
|
+
this.isDown = false;
|
|
50
|
+
// Listen for pointer movements on the entire game
|
|
51
|
+
this.game.events.on("inputmove", (e) => {
|
|
52
|
+
this.x = e.x;
|
|
53
|
+
this.y = e.y;
|
|
54
|
+
});
|
|
55
|
+
this.game.events.on("inputdown", () => {
|
|
56
|
+
this.isDown = true;
|
|
57
|
+
});
|
|
58
|
+
this.game.events.on("inputup", () => {
|
|
59
|
+
this.isDown = false;
|
|
60
|
+
});
|
|
61
|
+
this.game.events.on("mouseover", () => {
|
|
62
|
+
this.visible = false;
|
|
63
|
+
});
|
|
64
|
+
this.game.events.on("mouseout", () => {
|
|
65
|
+
this.visible = true;
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
activate() {
|
|
70
|
+
this.active = true;
|
|
71
|
+
// Hide the native cursor
|
|
72
|
+
this.game.canvas.style.cursor = "none";
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
deactivate() {
|
|
76
|
+
this.active = false;
|
|
77
|
+
// Show the native cursor
|
|
78
|
+
this.game.canvas.style.cursor = "default";
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Renders whichever shape is appropriate based on mouse pressed state.
|
|
82
|
+
*/
|
|
83
|
+
draw() {
|
|
84
|
+
super.draw();
|
|
85
|
+
//this.logger.log("render cursor", this.normalShape);
|
|
86
|
+
if (!this.active) return;
|
|
87
|
+
// Decide which shape to draw
|
|
88
|
+
const shape = this.isDown && this.pressedShape ? this.pressedShape : this.normalShape;
|
|
89
|
+
if (!shape) return;
|
|
90
|
+
// Draw it
|
|
91
|
+
shape.render();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { Text } from "../objects";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* FPSCounter - A simple text object displaying frames per second
|
|
5
|
+
* @extends Text
|
|
6
|
+
*/
|
|
7
|
+
export class FPSCounter extends Text {
|
|
8
|
+
/**
|
|
9
|
+
* Create an FPS counter
|
|
10
|
+
* @param {Game} game - The main game instance
|
|
11
|
+
* @param {Object} [options={}] - Configuration options
|
|
12
|
+
*/
|
|
13
|
+
constructor(game, options = {}) {
|
|
14
|
+
// Spread the user options but provide defaults for FPS counter
|
|
15
|
+
super(game, "0 FPS", {
|
|
16
|
+
x: 0,
|
|
17
|
+
y: 0,
|
|
18
|
+
font: "12px monospace",
|
|
19
|
+
color: "#0f0", // Default to green
|
|
20
|
+
align: "center",
|
|
21
|
+
baseline: "middle",
|
|
22
|
+
debug:false,
|
|
23
|
+
...options, // This will override defaults with user provided values
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// FPS tracking properties
|
|
27
|
+
this.fps = 0;
|
|
28
|
+
this._frames = 0;
|
|
29
|
+
this._accum = 0;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Update the FPS counter
|
|
34
|
+
* @param {number} dt - Delta time in seconds
|
|
35
|
+
*/
|
|
36
|
+
update(dt) {
|
|
37
|
+
const fps = this.game.actualFps;
|
|
38
|
+
if (!fps) return;
|
|
39
|
+
|
|
40
|
+
this._frames++;
|
|
41
|
+
this._accum += dt;
|
|
42
|
+
|
|
43
|
+
if (this._accum >= 0.5) {
|
|
44
|
+
this.fps = Math.round(fps);
|
|
45
|
+
this.text = `${this.fps} FPS`;
|
|
46
|
+
this._accum = 0;
|
|
47
|
+
this._frames = 0;
|
|
48
|
+
}
|
|
49
|
+
super.update(dt);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Override getBounds to return correct bounding box
|
|
54
|
+
* @returns {Object} Bounding box with x, y, width, and height
|
|
55
|
+
*/
|
|
56
|
+
getBounds() {
|
|
57
|
+
// Use the shape's getTextBounds method if available
|
|
58
|
+
if (this.shape && this.shape.getTextBounds) {
|
|
59
|
+
const bounds = this.shape.getTextBounds();
|
|
60
|
+
|
|
61
|
+
// Return bounds with the current object's x and y
|
|
62
|
+
return {
|
|
63
|
+
x: bounds.x,
|
|
64
|
+
y: bounds.y,
|
|
65
|
+
width: bounds.width,
|
|
66
|
+
height: bounds.height
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Fallback to parent implementation
|
|
71
|
+
return super.getBounds();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
getDebugBounds() {
|
|
75
|
+
// Use the shape's getTextBounds method if available
|
|
76
|
+
if (this.shape && this.shape.getDebugBounds) {
|
|
77
|
+
const bounds = this.shape.getDebugBounds();
|
|
78
|
+
|
|
79
|
+
// Return bounds with the current object's x and y
|
|
80
|
+
return {
|
|
81
|
+
x: bounds.x,
|
|
82
|
+
y: bounds.y,
|
|
83
|
+
width: bounds.width,
|
|
84
|
+
height: bounds.height
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Fallback to parent implementation
|
|
89
|
+
return super.getDebugBounds();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { Button } from "./button.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ToggleButton - A variant of Button with a persistent "toggled" (active) state.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* const myToggle = new ToggleButton(game, {
|
|
8
|
+
* text: "Tool 1",
|
|
9
|
+
* startToggled: true, // if you want it initially on
|
|
10
|
+
* onToggle: (isOn) => {
|
|
11
|
+
* this.logger.log("Tool 1 toggled?", isOn);
|
|
12
|
+
* },
|
|
13
|
+
* onClick: () => {
|
|
14
|
+
* this.logger.log("A normal click as well");
|
|
15
|
+
* }
|
|
16
|
+
* });
|
|
17
|
+
*/
|
|
18
|
+
export class ToggleButton extends Button {
|
|
19
|
+
constructor(game, options = {}) {
|
|
20
|
+
// We'll intercept the user's onClick, so we can handle toggling
|
|
21
|
+
const userOnClick = options.onClick;
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
super(game, {
|
|
25
|
+
...options,
|
|
26
|
+
onClick: () => {
|
|
27
|
+
// Flip the toggled state
|
|
28
|
+
this.toggled = !this.toggled;
|
|
29
|
+
|
|
30
|
+
// If there's an onToggle callback, call it
|
|
31
|
+
if (typeof options.onToggle === "function") {
|
|
32
|
+
options.onToggle(this.toggled);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Also call the user's original onClick if provided
|
|
36
|
+
if (typeof userOnClick === "function") {
|
|
37
|
+
userOnClick();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Update our visual style for toggled vs. not
|
|
41
|
+
this.refreshToggleVisual();
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
this.colorActiveBg = options.colorActiveBg || "#444";
|
|
45
|
+
this.colorActiveStroke = options.colorActiveStroke || "#0f0";
|
|
46
|
+
this.colorActiveText = options.colorActiveText || "#0f0";
|
|
47
|
+
// Track toggled state. Default is false unless 'startToggled' is set
|
|
48
|
+
this.toggled = !!options.startToggled;
|
|
49
|
+
|
|
50
|
+
// Apply the initial style according to toggled or not
|
|
51
|
+
this.refreshToggleVisual();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
toggle(v) {
|
|
55
|
+
// Toggle the button state and refresh visuals
|
|
56
|
+
this.toggled = v;
|
|
57
|
+
this.refreshToggleVisual();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Decide how this ToggleButton looks when toggled vs. not toggled.
|
|
62
|
+
*/
|
|
63
|
+
refreshToggleVisual() {
|
|
64
|
+
if (this.toggled) {
|
|
65
|
+
// E.g. "active" styling
|
|
66
|
+
this.bg.fillColor = this.colorActiveBg;
|
|
67
|
+
this.bg.strokeColor = this.colorActiveStroke;
|
|
68
|
+
this.label.color = this.colorActiveText;
|
|
69
|
+
} else {
|
|
70
|
+
// Revert to normal styling
|
|
71
|
+
this.bg.fillColor = this.colors.default.bg;
|
|
72
|
+
this.bg.strokeColor = this.colors.default.stroke;
|
|
73
|
+
this.label.color = this.colors.default.text;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* If we want ephemeral states (hover, pressed) to remain visible briefly,
|
|
79
|
+
* we can let parent setState run, then immediately re-apply toggled style
|
|
80
|
+
* so we don't lose the "toggled" color. This is optional.
|
|
81
|
+
*/
|
|
82
|
+
setState(state) {
|
|
83
|
+
super.setState(state);
|
|
84
|
+
|
|
85
|
+
// If we're toggled on, ensure it stays in the toggled visuals
|
|
86
|
+
// after the parent sets hover/pressed colors.
|
|
87
|
+
if (this.toggled) {
|
|
88
|
+
this.bg.fillColor = this.colorActiveBg;
|
|
89
|
+
this.bg.strokeColor = this.colorActiveStroke;
|
|
90
|
+
this.label.color = this.colorActiveText;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|