littlejsengine 1.14.5 → 1.14.8
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/dist/littlejs.d.ts +53 -19
- package/dist/littlejs.esm.js +183 -106
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +179 -104
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +178 -103
- package/examples/box2d/game.js +1 -3
- package/examples/box2d/gameObjects.js +2 -2
- package/examples/htmlMenu/game.js +1 -1
- package/examples/index.html +92 -51
- package/examples/puzzle/game.js +1 -2
- package/examples/shorts/animation.js +2 -2
- package/examples/shorts/box2d.js +1 -0
- package/examples/shorts/box2dCar.js +1 -0
- package/examples/shorts/flappyGame.js +2 -1
- package/examples/shorts/helloWorld.js +2 -2
- package/examples/shorts/hillGlideGame.js +6 -3
- package/examples/shorts/maze.js +1 -0
- package/examples/shorts/medals.js +3 -0
- package/examples/shorts/music.js +3 -5
- package/examples/shorts/piano.js +24 -25
- package/examples/shorts/platformer.js +1 -0
- package/examples/shorts/shapes.js +6 -6
- package/examples/shorts/sound.js +21 -32
- package/examples/shorts/spriteAtlas.js +1 -2
- package/examples/shorts/tileLayer.js +1 -0
- package/examples/shorts/tiltedView.js +1 -1
- package/examples/shorts/timers.js +34 -31
- package/examples/shorts/topDown.js +2 -1
- package/examples/shorts/uiSystem.js +15 -10
- package/examples/stress/index.html +1 -1
- package/examples/uiSystem/game.js +1 -1
- package/package.json +1 -1
- package/plugins/uiSystem.js +83 -58
- package/reference.md +1 -0
- package/src/engine.js +23 -6
- package/src/engineDebug.js +1 -1
- package/src/engineDraw.js +19 -12
- package/src/engineExport.js +4 -2
- package/src/engineInput.js +7 -0
- package/src/engineObject.js +4 -4
- package/src/engineSettings.js +11 -1
- package/src/engineTileLayer.js +2 -2
- package/src/engineUtilities.js +9 -2
- package/src/engineWebGL.js +20 -18
package/dist/littlejs.release.js
CHANGED
|
@@ -33,7 +33,7 @@ const engineName = 'LittleJS';
|
|
|
33
33
|
* @type {string}
|
|
34
34
|
* @default
|
|
35
35
|
* @memberof Engine */
|
|
36
|
-
const engineVersion = '1.14.
|
|
36
|
+
const engineVersion = '1.14.8';
|
|
37
37
|
|
|
38
38
|
/** Frames per second to update
|
|
39
39
|
* @type {number}
|
|
@@ -172,15 +172,15 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
172
172
|
frameTimeBufferMS += paused ? 0 : frameTimeDeltaMS;
|
|
173
173
|
if (!debugSpeedUp)
|
|
174
174
|
frameTimeBufferMS = min(frameTimeBufferMS, 50); // clamp min framerate
|
|
175
|
-
if (debugVideoCaptureIsActive())
|
|
176
|
-
frameTimeBufferMS = 0; // no time smoothing when capturing video
|
|
177
|
-
updateCanvas();
|
|
178
175
|
|
|
179
176
|
if (paused)
|
|
180
177
|
{
|
|
178
|
+
updateCanvas();
|
|
179
|
+
|
|
181
180
|
// update object transforms even when paused
|
|
182
181
|
for (const o of engineObjects)
|
|
183
182
|
o.parent || o.updateTransforms();
|
|
183
|
+
|
|
184
184
|
inputUpdate();
|
|
185
185
|
pluginUpdateList.forEach(f=>f());
|
|
186
186
|
debugUpdate();
|
|
@@ -205,6 +205,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
205
205
|
time = frame++ / frameRate;
|
|
206
206
|
|
|
207
207
|
// update game and objects
|
|
208
|
+
updateCanvas();
|
|
208
209
|
inputUpdate();
|
|
209
210
|
gameUpdate();
|
|
210
211
|
pluginUpdateList.forEach(f=>f());
|
|
@@ -214,14 +215,23 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
214
215
|
debugUpdate();
|
|
215
216
|
gameUpdatePost();
|
|
216
217
|
inputUpdatePost();
|
|
218
|
+
|
|
219
|
+
if (debugVideoCaptureIsActive())
|
|
220
|
+
renderFrame();
|
|
217
221
|
}
|
|
218
222
|
|
|
219
223
|
// add the time smoothing back in
|
|
220
224
|
frameTimeBufferMS += deltaSmooth;
|
|
221
225
|
}
|
|
222
226
|
|
|
223
|
-
if (!
|
|
227
|
+
if (!debugVideoCaptureIsActive())
|
|
228
|
+
renderFrame();
|
|
229
|
+
requestAnimationFrame(engineUpdate);
|
|
230
|
+
|
|
231
|
+
function renderFrame()
|
|
224
232
|
{
|
|
233
|
+
if (headlessMode) return;
|
|
234
|
+
|
|
225
235
|
// render sort then render while removing destroyed objects
|
|
226
236
|
enginePreRender();
|
|
227
237
|
gameRender();
|
|
@@ -251,7 +261,6 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
251
261
|
}
|
|
252
262
|
drawCount = 0;
|
|
253
263
|
}
|
|
254
|
-
requestAnimationFrame(engineUpdate);
|
|
255
264
|
}
|
|
256
265
|
|
|
257
266
|
function updateCanvas()
|
|
@@ -277,6 +286,14 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
277
286
|
mainCanvas.height = min(innerHeight, canvasMaxSize.y);
|
|
278
287
|
}
|
|
279
288
|
|
|
289
|
+
// apply the clear color to main canvas
|
|
290
|
+
if (canvasClearColor.a > 0)
|
|
291
|
+
{
|
|
292
|
+
mainContext.fillStyle = canvasClearColor.toString();
|
|
293
|
+
mainContext.fillRect(0, 0, mainCanvasSize.x, mainCanvasSize.y);
|
|
294
|
+
mainContext.fillStyle = BLACK.toString();
|
|
295
|
+
}
|
|
296
|
+
|
|
280
297
|
// clear overlay canvas and set size
|
|
281
298
|
overlayCanvas.width = mainCanvas.width;
|
|
282
299
|
overlayCanvas.height = mainCanvas.height;
|
|
@@ -848,8 +865,11 @@ function nearestPowerOfTwo(value) { return 2**Math.ceil(Math.log2(value)); }
|
|
|
848
865
|
* @memberof Utilities */
|
|
849
866
|
function isOverlapping(posA, sizeA, posB, sizeB=vec2())
|
|
850
867
|
{
|
|
851
|
-
|
|
852
|
-
|
|
868
|
+
const dx = (posA.x - posB.x)*2;
|
|
869
|
+
const dy = (posA.y - posB.y)*2;
|
|
870
|
+
const sx = sizeA.x + sizeB.x;
|
|
871
|
+
const sy = sizeA.y + sizeB.y;
|
|
872
|
+
return dx >= -sx && dx < sx && dy >= -sy && dy < sy;
|
|
853
873
|
}
|
|
854
874
|
|
|
855
875
|
/** Returns true if a line segment is intersecting an axis aligned box
|
|
@@ -1678,6 +1698,10 @@ class Timer
|
|
|
1678
1698
|
* @return {number} */
|
|
1679
1699
|
getPercent() { return this.isSet()? 1-percent(this.time - time, 0, this.setTime) : 0; }
|
|
1680
1700
|
|
|
1701
|
+
/** Get the time this timer was set to, returns 0 if not set
|
|
1702
|
+
* @return {number} */
|
|
1703
|
+
getSetTime() { return this.isSet() ? this.setTime : 0; }
|
|
1704
|
+
|
|
1681
1705
|
/** Returns this timer expressed as a string
|
|
1682
1706
|
* @return {string} */
|
|
1683
1707
|
toString() { if (debug) { return this.isSet() ? Math.abs(this.get()) + ' seconds ' + (this.get()<0 ? 'before' : 'after' ) : 'unset'; }}
|
|
@@ -1723,6 +1747,11 @@ let cameraScale = 32;
|
|
|
1723
1747
|
* @memberof Settings */
|
|
1724
1748
|
let canvasColorTiles = true;
|
|
1725
1749
|
|
|
1750
|
+
/** Color to clear the canvas to before render
|
|
1751
|
+
* @type {Color}
|
|
1752
|
+
* @memberof Draw */
|
|
1753
|
+
let canvasClearColor = CLEAR_BLACK;
|
|
1754
|
+
|
|
1726
1755
|
/** The max size of the canvas, centered if window is larger
|
|
1727
1756
|
* @type {Vector2}
|
|
1728
1757
|
* @default Vector2(1920,1080)
|
|
@@ -2001,6 +2030,11 @@ function setCameraScale(scale) { cameraScale = scale; }
|
|
|
2001
2030
|
* @memberof Settings */
|
|
2002
2031
|
function setCanvasColorTiles(colorTiles) { canvasColorTiles = colorTiles; }
|
|
2003
2032
|
|
|
2033
|
+
/** Set color to clear the canvas to before render
|
|
2034
|
+
* @param {Color} color
|
|
2035
|
+
* @memberof Settings */
|
|
2036
|
+
function setCanvasClearColor(color) { canvasClearColor = color; }
|
|
2037
|
+
|
|
2004
2038
|
/** Set max size of the canvas
|
|
2005
2039
|
* @param {Vector2} size
|
|
2006
2040
|
* @memberof Settings */
|
|
@@ -2066,7 +2100,7 @@ function setGLEnable(enable)
|
|
|
2066
2100
|
glCanvas.style.visibility = enable ? 'visible' : 'hidden';
|
|
2067
2101
|
}
|
|
2068
2102
|
|
|
2069
|
-
/** Set how many sided polygons to use when drawing circles and
|
|
2103
|
+
/** Set how many sided polygons to use when drawing circles and ellipses with WebGL
|
|
2070
2104
|
* @param {number} sides
|
|
2071
2105
|
* @memberof Settings */
|
|
2072
2106
|
function setGLCircleSides(sides) { glCircleSides = sides; }
|
|
@@ -2277,7 +2311,7 @@ class EngineObject
|
|
|
2277
2311
|
/** @property {Vector2} - World space position of the object */
|
|
2278
2312
|
this.pos = pos.copy();
|
|
2279
2313
|
/** @property {Vector2} - World space width and height of the object */
|
|
2280
|
-
this.size = size;
|
|
2314
|
+
this.size = size.copy();
|
|
2281
2315
|
/** @property {Vector2} - Size of object used for drawing, uses size if not set */
|
|
2282
2316
|
this.drawSize = undefined;
|
|
2283
2317
|
/** @property {TileInfo} - Tile info to render object (undefined is untextured) */
|
|
@@ -2285,7 +2319,7 @@ class EngineObject
|
|
|
2285
2319
|
/** @property {number} - Angle to rotate the object */
|
|
2286
2320
|
this.angle = angle;
|
|
2287
2321
|
/** @property {Color} - Color to apply when rendered */
|
|
2288
|
-
this.color = color;
|
|
2322
|
+
this.color = color.copy();
|
|
2289
2323
|
/** @property {Color} - Additive color to apply when rendered */
|
|
2290
2324
|
this.additiveColor = undefined;
|
|
2291
2325
|
/** @property {boolean} - Should it flip along y axis when rendered */
|
|
@@ -2409,7 +2443,7 @@ class EngineObject
|
|
|
2409
2443
|
for (const o of engineObjectsCollide)
|
|
2410
2444
|
{
|
|
2411
2445
|
// non solid objects don't collide with each other
|
|
2412
|
-
if (!this.isSolid && !o.isSolid || o.destroyed || o.parent || o === this)
|
|
2446
|
+
if ((!this.isSolid && !o.isSolid) || o.destroyed || o.parent || o === this)
|
|
2413
2447
|
continue;
|
|
2414
2448
|
|
|
2415
2449
|
// check collision
|
|
@@ -2448,7 +2482,7 @@ class EngineObject
|
|
|
2448
2482
|
{
|
|
2449
2483
|
// push outside object collision
|
|
2450
2484
|
this.pos.y = o.pos.y + (sizeBoth.y/2 + epsilon) * sign(oldPos.y - o.pos.y);
|
|
2451
|
-
if (o.groundObject && wasMovingDown || !o.mass)
|
|
2485
|
+
if ((o.groundObject && wasMovingDown) || !o.mass)
|
|
2452
2486
|
{
|
|
2453
2487
|
// set ground object if landed on something
|
|
2454
2488
|
if (wasMovingDown)
|
|
@@ -2829,8 +2863,9 @@ class TileInfo
|
|
|
2829
2863
|
* @param {Vector2} [size=tileSizeDefault] - Size of tile in pixels
|
|
2830
2864
|
* @param {number} [textureIndex] - Texture index to use
|
|
2831
2865
|
* @param {number} [padding] - How many pixels padding around tiles
|
|
2866
|
+
* @param {number} [bleedScale] - How many pixels smaller to draw tiles
|
|
2832
2867
|
*/
|
|
2833
|
-
constructor(pos=vec2(), size=tileSizeDefault, textureIndex=0, padding=0)
|
|
2868
|
+
constructor(pos=vec2(), size=tileSizeDefault, textureIndex=0, padding=0, bleedScale=tileFixBleedScale)
|
|
2834
2869
|
{
|
|
2835
2870
|
/** @property {Vector2} - Top left corner of tile in pixels */
|
|
2836
2871
|
this.pos = pos.copy();
|
|
@@ -2842,6 +2877,8 @@ class TileInfo
|
|
|
2842
2877
|
this.padding = padding;
|
|
2843
2878
|
/** @property {TextureInfo} - The texture info for this tile */
|
|
2844
2879
|
this.textureInfo = textureInfos[this.textureIndex];
|
|
2880
|
+
/** @property {float} - Shrinks tile by this many pixels to prevent neighbors bleeding */
|
|
2881
|
+
this.bleedScale = bleedScale;
|
|
2845
2882
|
}
|
|
2846
2883
|
|
|
2847
2884
|
/** Returns a copy of this tile offset by a vector
|
|
@@ -2849,7 +2886,7 @@ class TileInfo
|
|
|
2849
2886
|
* @return {TileInfo}
|
|
2850
2887
|
*/
|
|
2851
2888
|
offset(offset)
|
|
2852
|
-
{ return new TileInfo(this.pos.add(offset), this.size, this.textureIndex); }
|
|
2889
|
+
{ return new TileInfo(this.pos.add(offset), this.size, this.textureIndex, this.padding, this.bleedScale); }
|
|
2853
2890
|
|
|
2854
2891
|
/** Returns a copy of this tile offset by a number of animation frames
|
|
2855
2892
|
* @param {number} frame - Offset to apply in animation frames
|
|
@@ -2872,6 +2909,8 @@ class TileInfo
|
|
|
2872
2909
|
this.pos = new Vector2;
|
|
2873
2910
|
this.size = new Vector2(image.width, image.height);
|
|
2874
2911
|
this.textureInfo = new TextureInfo(image, glTexture);
|
|
2912
|
+
// do not use padding or bleed
|
|
2913
|
+
this.bleedScale = this.padding = 0;
|
|
2875
2914
|
return this;
|
|
2876
2915
|
}
|
|
2877
2916
|
}
|
|
@@ -2929,6 +2968,7 @@ function drawTile(pos, size=new Vector2(1), tileInfo, color=WHITE,
|
|
|
2929
2968
|
ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
|
|
2930
2969
|
|
|
2931
2970
|
const textureInfo = tileInfo && tileInfo.textureInfo;
|
|
2971
|
+
const bleedScale = tileInfo ? tileInfo.bleedScale : 0;
|
|
2932
2972
|
if (useWebGL)
|
|
2933
2973
|
{
|
|
2934
2974
|
if (screenSpace)
|
|
@@ -2946,10 +2986,10 @@ function drawTile(pos, size=new Vector2(1), tileInfo, color=WHITE,
|
|
|
2946
2986
|
const w = tileInfo.size.x * sizeInverse.x;
|
|
2947
2987
|
const h = tileInfo.size.y * sizeInverse.y;
|
|
2948
2988
|
glSetTexture(textureInfo.glTexture);
|
|
2949
|
-
if (
|
|
2989
|
+
if (bleedScale)
|
|
2950
2990
|
{
|
|
2951
|
-
const tileImageFixBleedX = sizeInverse.x*
|
|
2952
|
-
const tileImageFixBleedY = sizeInverse.y*
|
|
2991
|
+
const tileImageFixBleedX = sizeInverse.x*bleedScale;
|
|
2992
|
+
const tileImageFixBleedY = sizeInverse.y*bleedScale;
|
|
2953
2993
|
glDraw(pos.x, pos.y, mirror ? -size.x : size.x, size.y, angle,
|
|
2954
2994
|
x + tileImageFixBleedX, y + tileImageFixBleedY,
|
|
2955
2995
|
x - tileImageFixBleedX + w, y - tileImageFixBleedY + h,
|
|
@@ -2980,7 +3020,7 @@ function drawTile(pos, size=new Vector2(1), tileInfo, color=WHITE,
|
|
|
2980
3020
|
// calculate uvs and render
|
|
2981
3021
|
const x = tileInfo.pos.x, y = tileInfo.pos.y;
|
|
2982
3022
|
const w = tileInfo.size.x, h = tileInfo.size.y;
|
|
2983
|
-
drawImageColor(context, textureInfo.image, x, y, w, h, -.5, -.5, 1, 1, color, additiveColor);
|
|
3023
|
+
drawImageColor(context, textureInfo.image, x, y, w, h, -.5, -.5, 1, 1, color, additiveColor, bleedScale);
|
|
2984
3024
|
}
|
|
2985
3025
|
else
|
|
2986
3026
|
{
|
|
@@ -3468,15 +3508,16 @@ function combineCanvases()
|
|
|
3468
3508
|
* @param {number} dHeight
|
|
3469
3509
|
* @param {Color} color
|
|
3470
3510
|
* @param {Color} [additiveColor]
|
|
3511
|
+
* @param {number} [bleedScale] - How much to shrink the source, used to fix bleeding
|
|
3471
3512
|
* @memberof Draw */
|
|
3472
|
-
function drawImageColor(context, image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight, color, additiveColor)
|
|
3513
|
+
function drawImageColor(context, image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight, color, additiveColor, bleedScale=0)
|
|
3473
3514
|
{
|
|
3474
3515
|
function isWhite(c) { return c.r >= 1 && c.g >= 1 && c.b >= 1; }
|
|
3475
3516
|
function isBlack(c) { return c.r <= 0 && c.g <= 0 && c.b <= 0 && c.a <= 0; }
|
|
3476
|
-
const sx2 =
|
|
3477
|
-
const sy2 =
|
|
3478
|
-
const sWidth2 = sWidth - 2*
|
|
3479
|
-
const sHeight2 = sHeight - 2*
|
|
3517
|
+
const sx2 = bleedScale;
|
|
3518
|
+
const sy2 = bleedScale;
|
|
3519
|
+
const sWidth2 = sWidth - 2*bleedScale;
|
|
3520
|
+
const sHeight2 = sHeight - 2*bleedScale;
|
|
3480
3521
|
if (!canvasColorTiles || (additiveColor ? isWhite(color.add(additiveColor)) && additiveColor.a <= 0 : isWhite(color)))
|
|
3481
3522
|
{
|
|
3482
3523
|
// white texture with no additive alpha, no need to tint
|
|
@@ -3592,7 +3633,7 @@ class FontImage
|
|
|
3592
3633
|
* @param {Vector2} pos
|
|
3593
3634
|
* @param {number} [scale=.25]
|
|
3594
3635
|
* @param {boolean} [center]
|
|
3595
|
-
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D}[context=drawContext]
|
|
3636
|
+
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=drawContext]
|
|
3596
3637
|
*/
|
|
3597
3638
|
drawText(text, pos, scale=1, center, context=drawContext)
|
|
3598
3639
|
{
|
|
@@ -3859,6 +3900,7 @@ function inputInit()
|
|
|
3859
3900
|
document.addEventListener('wheel', onMouseWheel);
|
|
3860
3901
|
document.addEventListener('contextmenu', onContextMenu);
|
|
3861
3902
|
document.addEventListener('blur', onBlur);
|
|
3903
|
+
document.addEventListener('mouseleave', onMouseLeave);
|
|
3862
3904
|
|
|
3863
3905
|
// init touch input
|
|
3864
3906
|
if (isTouchDevice && touchInputEnable)
|
|
@@ -3917,6 +3959,12 @@ function inputInit()
|
|
|
3917
3959
|
function onMouseWheel(e) { mouseWheel = e.ctrlKey ? 0 : sign(e.deltaY); }
|
|
3918
3960
|
function onContextMenu(e) { e.preventDefault(); } // prevent right click menu
|
|
3919
3961
|
function onBlur() { inputClear(); } // reset input when focus is lost
|
|
3962
|
+
function onMouseLeave()
|
|
3963
|
+
{
|
|
3964
|
+
// set mouse position and delta when leaving canvas
|
|
3965
|
+
mousePosScreen = vec2(Infinity);
|
|
3966
|
+
mouseDeltaScreen = vec2(0);
|
|
3967
|
+
}
|
|
3920
3968
|
}
|
|
3921
3969
|
|
|
3922
3970
|
// convert a mouse or touch event position to screen space
|
|
@@ -5038,7 +5086,7 @@ class TileLayerData
|
|
|
5038
5086
|
/** @property {boolean} - If the tile should be mirrored along the x axis */
|
|
5039
5087
|
this.mirror = mirror;
|
|
5040
5088
|
/** @property {Color} - Color of the tile */
|
|
5041
|
-
this.color = color;
|
|
5089
|
+
this.color = color.copy();
|
|
5042
5090
|
}
|
|
5043
5091
|
|
|
5044
5092
|
/** Set this tile to clear, it will not be rendered */
|
|
@@ -5137,7 +5185,7 @@ class CanvasLayer extends EngineObject
|
|
|
5137
5185
|
* @param {TileInfo} [tileInfo]
|
|
5138
5186
|
* @param {Color} [color=(1,1,1,1)]
|
|
5139
5187
|
* @param {number} [angle=0]
|
|
5140
|
-
* @param {boolean} [mirror=
|
|
5188
|
+
* @param {boolean} [mirror=false] */
|
|
5141
5189
|
drawTile(pos, size=vec2(1), tileInfo, color=new Color, angle, mirror)
|
|
5142
5190
|
{
|
|
5143
5191
|
this.drawCanvas2D(pos, size, angle, mirror, (context)=>
|
|
@@ -6316,7 +6364,8 @@ function glSetTexture(texture, wrap=false)
|
|
|
6316
6364
|
return;
|
|
6317
6365
|
|
|
6318
6366
|
glFlush();
|
|
6319
|
-
|
|
6367
|
+
glActiveTexture = texture;
|
|
6368
|
+
glContext.bindTexture(glContext.TEXTURE_2D, glActiveTexture);
|
|
6320
6369
|
|
|
6321
6370
|
// set wrap mode
|
|
6322
6371
|
const wrapMode = wrap ? glContext.REPEAT : glContext.CLAMP_TO_EDGE;
|
|
@@ -6366,6 +6415,7 @@ function glCreateProgram(vsSource, fsSource)
|
|
|
6366
6415
|
}
|
|
6367
6416
|
|
|
6368
6417
|
/** Create WebGL texture from an image and init the texture settings
|
|
6418
|
+
* Restores the active texture when done
|
|
6369
6419
|
* @param {HTMLImageElement|HTMLCanvasElement|OffscreenCanvas} [image]
|
|
6370
6420
|
* @return {WebGLTexture}
|
|
6371
6421
|
* @memberof WebGL */
|
|
@@ -6375,30 +6425,29 @@ function glCreateTexture(image)
|
|
|
6375
6425
|
|
|
6376
6426
|
// build the texture
|
|
6377
6427
|
const texture = glContext.createTexture();
|
|
6378
|
-
|
|
6428
|
+
let mipMap = false;
|
|
6379
6429
|
if (image && image.width)
|
|
6380
6430
|
{
|
|
6381
6431
|
glSetTextureData(texture, image);
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
// use mipmap filtering
|
|
6385
|
-
glContext.generateMipmap(glContext.TEXTURE_2D);
|
|
6386
|
-
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_MIN_FILTER, glContext.LINEAR_MIPMAP_LINEAR);
|
|
6387
|
-
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_MAG_FILTER, glContext.LINEAR);
|
|
6388
|
-
return texture;
|
|
6389
|
-
}
|
|
6432
|
+
glContext.bindTexture(glContext.TEXTURE_2D, texture);
|
|
6433
|
+
mipMap = !tilesPixelated && isPowerOfTwo(image.width) && isPowerOfTwo(image.height);
|
|
6390
6434
|
}
|
|
6391
6435
|
else
|
|
6392
6436
|
{
|
|
6393
6437
|
// create a white texture
|
|
6394
6438
|
const whitePixel = new Uint8Array([255, 255, 255, 255]);
|
|
6439
|
+
glContext.bindTexture(glContext.TEXTURE_2D, texture);
|
|
6395
6440
|
glContext.texImage2D(glContext.TEXTURE_2D, 0, glContext.RGBA, 1, 1, 0, glContext.RGBA, glContext.UNSIGNED_BYTE, whitePixel);
|
|
6396
6441
|
}
|
|
6397
6442
|
|
|
6398
6443
|
// set texture filtering
|
|
6399
|
-
const
|
|
6400
|
-
|
|
6401
|
-
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_MAG_FILTER,
|
|
6444
|
+
const magFilter = tilesPixelated ? glContext.NEAREST : glContext.LINEAR;
|
|
6445
|
+
const minFilter = mipMap ? glContext.LINEAR_MIPMAP_LINEAR : magFilter;
|
|
6446
|
+
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_MAG_FILTER, magFilter);
|
|
6447
|
+
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_MIN_FILTER, minFilter);
|
|
6448
|
+
if (mipMap)
|
|
6449
|
+
glContext.generateMipmap(glContext.TEXTURE_2D);
|
|
6450
|
+
glContext.bindTexture(glContext.TEXTURE_2D, glActiveTexture); // rebind active texture
|
|
6402
6451
|
return texture;
|
|
6403
6452
|
}
|
|
6404
6453
|
|
|
@@ -6411,7 +6460,7 @@ function glDeleteTexture(texture)
|
|
|
6411
6460
|
glContext.deleteTexture(texture);
|
|
6412
6461
|
}
|
|
6413
6462
|
|
|
6414
|
-
/** Set WebGL texture data from an image
|
|
6463
|
+
/** Set WebGL texture data from an image, restores the active texture when done
|
|
6415
6464
|
* @param {WebGLTexture} texture
|
|
6416
6465
|
* @param {HTMLImageElement|HTMLCanvasElement|OffscreenCanvas} image
|
|
6417
6466
|
* @memberof WebGL */
|
|
@@ -6423,6 +6472,7 @@ function glSetTextureData(texture, image)
|
|
|
6423
6472
|
ASSERT(!!image && image.width > 0, 'Invalid image data.');
|
|
6424
6473
|
glContext.bindTexture(glContext.TEXTURE_2D, texture);
|
|
6425
6474
|
glContext.texImage2D(glContext.TEXTURE_2D, 0, glContext.RGBA, glContext.RGBA, glContext.UNSIGNED_BYTE, image);
|
|
6475
|
+
glContext.bindTexture(glContext.TEXTURE_2D, glActiveTexture); // rebind active texture
|
|
6426
6476
|
}
|
|
6427
6477
|
|
|
6428
6478
|
/** Draw all sprites and clear out the buffer, called automatically by the system whenever necessary
|
|
@@ -6568,7 +6618,7 @@ function glDrawPoints(points, rgba)
|
|
|
6568
6618
|
|
|
6569
6619
|
// setup triangle strip with degenerate verts at start and end
|
|
6570
6620
|
let offset = glBatchCount * gl_INDICES_PER_POLY_VERTEX;
|
|
6571
|
-
for(let i = vertCount; i--;)
|
|
6621
|
+
for (let i = vertCount; i--;)
|
|
6572
6622
|
{
|
|
6573
6623
|
const j = clamp(i-1, 0, vertCount-3);
|
|
6574
6624
|
const point = points[j];
|
|
@@ -6596,7 +6646,7 @@ function glDrawColoredPoints(points, pointColors)
|
|
|
6596
6646
|
|
|
6597
6647
|
// setup triangle strip with degenerate verts at start and end
|
|
6598
6648
|
let offset = glBatchCount * gl_INDICES_PER_POLY_VERTEX;
|
|
6599
|
-
for(let i = vertCount; i--;)
|
|
6649
|
+
for (let i = vertCount; i--;)
|
|
6600
6650
|
{
|
|
6601
6651
|
const j = clamp(i-1, 0, vertCount-3);
|
|
6602
6652
|
const point = points[j];
|
|
@@ -6733,7 +6783,7 @@ function glPolyStrip(points)
|
|
|
6733
6783
|
while (indices.length > 3 && attempts++ < maxAttempts)
|
|
6734
6784
|
{
|
|
6735
6785
|
let foundEar = false;
|
|
6736
|
-
for (let i = indices.length;
|
|
6786
|
+
for (let i = 0; i < indices.length; i++)
|
|
6737
6787
|
{
|
|
6738
6788
|
const i0 = indices[(i + indices.length - 1) % indices.length];
|
|
6739
6789
|
const i1 = indices[i];
|
|
@@ -6770,7 +6820,7 @@ function glPolyStrip(points)
|
|
|
6770
6820
|
if (!foundEar)
|
|
6771
6821
|
{
|
|
6772
6822
|
let worstIndex = -1, worstValue = Infinity;
|
|
6773
|
-
for (let i = indices.length;
|
|
6823
|
+
for (let i = 0; i < indices.length; i++)
|
|
6774
6824
|
{
|
|
6775
6825
|
const i0 = indices[(i + indices.length - 1) % indices.length];
|
|
6776
6826
|
const i1 = indices[i];
|
|
@@ -7319,6 +7369,8 @@ class UISystemPlugin
|
|
|
7319
7369
|
this.defaultLineWidth = 4;
|
|
7320
7370
|
/** @property {number} - Default rounded rect corner radius for UI elements */
|
|
7321
7371
|
this.defaultCornerRadius = 0;
|
|
7372
|
+
/** @property {number} - Default scale to use for fitting text to object */
|
|
7373
|
+
this.defaultTextScale = .8;
|
|
7322
7374
|
/** @property {string} - Default font for UI elements */
|
|
7323
7375
|
this.defaultFont = 'arial';
|
|
7324
7376
|
/** @property {Sound} - Default sound when interactive UI element is pressed */
|
|
@@ -7331,10 +7383,15 @@ class UISystemPlugin
|
|
|
7331
7383
|
this.uiObjects = [];
|
|
7332
7384
|
/** @property {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} - Context to render UI elements to */
|
|
7333
7385
|
this.uiContext = context;
|
|
7386
|
+
/** @property {UIObject} - Top most object user is over */
|
|
7387
|
+
this.hoverObject = undefined;
|
|
7388
|
+
/** @property {UIObject} - Object user is currently interacting with */
|
|
7389
|
+
this.activeObject = undefined;
|
|
7334
7390
|
|
|
7335
7391
|
engineAddPlugin(uiUpdate, uiRender);
|
|
7336
7392
|
|
|
7337
7393
|
// setup recursive update and render
|
|
7394
|
+
// update in reverse order to detect mouse enter/leave
|
|
7338
7395
|
function uiUpdate()
|
|
7339
7396
|
{
|
|
7340
7397
|
function updateInvisibleObject(o)
|
|
@@ -7359,7 +7416,13 @@ class UISystemPlugin
|
|
|
7359
7416
|
else
|
|
7360
7417
|
updateInvisibleObject(o);
|
|
7361
7418
|
}
|
|
7362
|
-
|
|
7419
|
+
// reset hover object at start of update
|
|
7420
|
+
uiSystem.hoverObject = undefined;
|
|
7421
|
+
for (let i = uiSystem.uiObjects.length; i--;)
|
|
7422
|
+
{
|
|
7423
|
+
const o = uiSystem.uiObjects[i];
|
|
7424
|
+
o.parent || updateObject(o)
|
|
7425
|
+
}
|
|
7363
7426
|
}
|
|
7364
7427
|
function uiRender()
|
|
7365
7428
|
{
|
|
@@ -7438,10 +7501,11 @@ class UISystemPlugin
|
|
|
7438
7501
|
* @param {number} [lineWidth=uiSystem.defaultLineWidth]
|
|
7439
7502
|
* @param {Color} [lineColor=uiSystem.defaultLineColor]
|
|
7440
7503
|
* @param {string} [align]
|
|
7441
|
-
* @param {string} [font=uiSystem.defaultFont]
|
|
7442
|
-
|
|
7504
|
+
* @param {string} [font=uiSystem.defaultFont]
|
|
7505
|
+
* @param {boolean} [applyMaxWidth=true] */
|
|
7506
|
+
drawText(text, pos, size, color=uiSystem.defaultColor, lineWidth=uiSystem.defaultLineWidth, lineColor=uiSystem.defaultLineColor, align='center', font=uiSystem.defaultFont, applyMaxWidth=true)
|
|
7443
7507
|
{
|
|
7444
|
-
drawTextScreen(text, pos, size.y, color, lineWidth, lineColor, align, font, size.x, uiSystem.uiContext);
|
|
7508
|
+
drawTextScreen(text, pos, size.y, color, lineWidth, lineColor, align, font, applyMaxWidth ? size.x : undefined, uiSystem.uiContext);
|
|
7445
7509
|
}
|
|
7446
7510
|
}
|
|
7447
7511
|
|
|
@@ -7465,6 +7529,8 @@ class UIObject
|
|
|
7465
7529
|
this.size = size.copy();
|
|
7466
7530
|
/** @property {Color} - Color of the object */
|
|
7467
7531
|
this.color = uiSystem.defaultColor;
|
|
7532
|
+
/** @property {Color} - Color of the object when active, uses color if undefined */
|
|
7533
|
+
this.activeColor = undefined;
|
|
7468
7534
|
/** @property {string} - Text for this ui object */
|
|
7469
7535
|
this.text = undefined;
|
|
7470
7536
|
/** @property {Color} - Color when disabled */
|
|
@@ -7483,15 +7549,19 @@ class UIObject
|
|
|
7483
7549
|
this.cornerRadius = uiSystem.defaultCornerRadius;
|
|
7484
7550
|
/** @property {string} - Font for this objecct */
|
|
7485
7551
|
this.font = uiSystem.defaultFont;
|
|
7552
|
+
/** @property {number} - Override for text width */
|
|
7553
|
+
this.textWidth = undefined;
|
|
7486
7554
|
/** @property {number} - Override for text height */
|
|
7487
7555
|
this.textHeight = undefined;
|
|
7556
|
+
/** @property {number} - Scale text to fit in the object */
|
|
7557
|
+
this.textScale = uiSystem.defaultTextScale;
|
|
7488
7558
|
/** @property {boolean} - Should this object be drawn */
|
|
7489
7559
|
this.visible = true;
|
|
7490
7560
|
/** @property {Array<UIObject>} - A list of this object's children */
|
|
7491
7561
|
this.children = [];
|
|
7492
7562
|
/** @property {UIObject} - This object's parent, position is in parent space */
|
|
7493
7563
|
this.parent = undefined;
|
|
7494
|
-
/** @property {number} -
|
|
7564
|
+
/** @property {number} - Added size to make small buttons easier to touch on mobile devices */
|
|
7495
7565
|
this.extraTouchSize = 0;
|
|
7496
7566
|
/** @property {Sound} - Sound when interactive element is pressed */
|
|
7497
7567
|
this.soundPress = uiSystem.defaultSoundPress;
|
|
@@ -7499,12 +7569,10 @@ class UIObject
|
|
|
7499
7569
|
this.soundRelease = uiSystem.defaultSoundRelease;
|
|
7500
7570
|
/** @property {Sound} - Sound when interactive element is clicked */
|
|
7501
7571
|
this.soundClick = uiSystem.defaultSoundClick;
|
|
7502
|
-
/** @property {boolean} - Is the mouse over this element */
|
|
7503
|
-
this.mouseIsOver = false;
|
|
7504
7572
|
/** @property {boolean} - Is this element interactive */
|
|
7505
7573
|
this.interactive = false;
|
|
7506
|
-
/** @property {boolean} -
|
|
7507
|
-
this.
|
|
7574
|
+
/** @property {boolean} - Activate when dragged over with mouse held down */
|
|
7575
|
+
this.dragActivate = false;
|
|
7508
7576
|
uiSystem.uiObjects.push(this);
|
|
7509
7577
|
}
|
|
7510
7578
|
|
|
@@ -7531,15 +7599,18 @@ class UIObject
|
|
|
7531
7599
|
/** Update the object, called automatically by plugin once each frame */
|
|
7532
7600
|
update()
|
|
7533
7601
|
{
|
|
7534
|
-
const
|
|
7535
|
-
const
|
|
7602
|
+
const wasHover = this.isHoverObject();
|
|
7603
|
+
const isActive = this.isActiveObject();
|
|
7536
7604
|
const mouseDown = mouseIsDown(0);
|
|
7537
|
-
|
|
7605
|
+
const mousePress = this.dragActivate ? mouseDown : mouseWasPressed(0);
|
|
7606
|
+
if (!uiSystem.hoverObject)
|
|
7607
|
+
if (mousePress || !mouseDown || isActive)
|
|
7538
7608
|
{
|
|
7539
7609
|
const size = this.size.add(vec2(isTouchDevice && this.extraTouchSize || 0));
|
|
7540
|
-
|
|
7610
|
+
if (isOverlapping(this.pos, size, mousePosScreen))
|
|
7611
|
+
uiSystem.hoverObject = this;
|
|
7541
7612
|
}
|
|
7542
|
-
if (this.
|
|
7613
|
+
if (this.isHoverObject())
|
|
7543
7614
|
{
|
|
7544
7615
|
if (mousePress)
|
|
7545
7616
|
inputClearKey(0,0,0,1,0); // clear mouse was pressed state
|
|
@@ -7552,10 +7623,12 @@ class UIObject
|
|
|
7552
7623
|
this.onPress();
|
|
7553
7624
|
if (this.soundPress)
|
|
7554
7625
|
this.soundPress.play();
|
|
7626
|
+
if (uiSystem.activeObject && !isActive)
|
|
7627
|
+
uiSystem.activeObject.onRelease();
|
|
7628
|
+
uiSystem.activeObject = this;
|
|
7555
7629
|
}
|
|
7556
|
-
this.mouseIsHeld = true;
|
|
7557
7630
|
}
|
|
7558
|
-
if (!mouseDown &&
|
|
7631
|
+
if (!mouseDown && uiSystem.activeObject === this && this.interactive)
|
|
7559
7632
|
{
|
|
7560
7633
|
this.onClick();
|
|
7561
7634
|
if (this.soundClick)
|
|
@@ -7563,37 +7636,52 @@ class UIObject
|
|
|
7563
7636
|
}
|
|
7564
7637
|
}
|
|
7565
7638
|
}
|
|
7566
|
-
if (!mouseDown)
|
|
7639
|
+
if (isActive && (!mouseDown || !this.isHoverObject()))
|
|
7567
7640
|
{
|
|
7568
|
-
|
|
7569
|
-
|
|
7570
|
-
this.
|
|
7571
|
-
|
|
7572
|
-
this.soundRelease.play();
|
|
7573
|
-
}
|
|
7574
|
-
if (isTouchDevice)
|
|
7575
|
-
this.mouseIsOver = false;
|
|
7576
|
-
this.mouseIsHeld = false;
|
|
7641
|
+
this.onRelease();
|
|
7642
|
+
if (this.soundRelease)
|
|
7643
|
+
this.soundRelease.play();
|
|
7644
|
+
uiSystem.activeObject = undefined;
|
|
7577
7645
|
}
|
|
7578
7646
|
|
|
7579
|
-
if (this.
|
|
7580
|
-
this.
|
|
7647
|
+
if (this.isHoverObject() !== wasHover)
|
|
7648
|
+
this.isHoverObject() ? this.onEnter() : this.onLeave();
|
|
7581
7649
|
}
|
|
7582
7650
|
|
|
7583
7651
|
/** Render the object, called automatically by plugin once each frame */
|
|
7584
7652
|
render()
|
|
7585
7653
|
{
|
|
7586
|
-
if (this.size.x
|
|
7587
|
-
|
|
7654
|
+
if (!this.size.x || !this.size.y) return;
|
|
7655
|
+
|
|
7656
|
+
const lineColor = this.interactive && this.isActiveObject() && !this.disabled ? this.color : this.lineColor;
|
|
7657
|
+
const color = this.interactive ? this.disabled ? this.disabledColor : this.isActiveObject() ? this.activeColor || this.color : this.isHoverObject() ? this.hoverColor : this.color : this.color;
|
|
7658
|
+
uiSystem.drawRect(this.pos, this.size, color, this.lineWidth, lineColor, this.cornerRadius);
|
|
7588
7659
|
}
|
|
7589
7660
|
|
|
7590
7661
|
/** Special update when object is not visible */
|
|
7591
7662
|
updateInvisible()
|
|
7592
7663
|
{
|
|
7593
7664
|
// reset input state when not visible
|
|
7594
|
-
|
|
7665
|
+
if (this.isActiveObject())
|
|
7666
|
+
uiSystem.activeObject = undefined;
|
|
7667
|
+
}
|
|
7668
|
+
|
|
7669
|
+
/** Get the size for text with overrides and scale
|
|
7670
|
+
* @return {Vector2}
|
|
7671
|
+
*/
|
|
7672
|
+
getTextSize()
|
|
7673
|
+
{
|
|
7674
|
+
return vec2(
|
|
7675
|
+
this.textWidth || this.textScale * this.size.x,
|
|
7676
|
+
this.textHeight || this.textScale * this.size.y);
|
|
7595
7677
|
}
|
|
7596
7678
|
|
|
7679
|
+
/** @return {boolean} - Is the mouse hovering over this element */
|
|
7680
|
+
isHoverObject() { return uiSystem.hoverObject === this; }
|
|
7681
|
+
|
|
7682
|
+
/** @return {boolean} - Is the mouse held onto this element */
|
|
7683
|
+
isActiveObject() { return uiSystem.activeObject === this; }
|
|
7684
|
+
|
|
7597
7685
|
/** Called when the mouse enters the object */
|
|
7598
7686
|
onEnter() {}
|
|
7599
7687
|
|
|
@@ -7641,7 +7729,7 @@ class UIText extends UIObject
|
|
|
7641
7729
|
}
|
|
7642
7730
|
render()
|
|
7643
7731
|
{
|
|
7644
|
-
const textSize =
|
|
7732
|
+
const textSize = this.getTextSize();
|
|
7645
7733
|
uiSystem.drawText(this.text, this.pos, textSize, this.textColor, this.lineWidth, this.lineColor, this.align, this.font);
|
|
7646
7734
|
}
|
|
7647
7735
|
}
|
|
@@ -7704,14 +7792,10 @@ class UIButton extends UIObject
|
|
|
7704
7792
|
}
|
|
7705
7793
|
render()
|
|
7706
7794
|
{
|
|
7707
|
-
|
|
7708
|
-
const lineColor = this.mouseIsHeld && !this.disabled ? this.color : this.lineColor;
|
|
7709
|
-
const color = this.disabled ? this.disabledColor : this.mouseIsOver ? this.hoverColor : this.color;
|
|
7710
|
-
uiSystem.drawRect(this.pos, this.size, color, this.lineWidth, lineColor, this.cornerRadius);
|
|
7795
|
+
super.render();
|
|
7711
7796
|
|
|
7712
|
-
// draw the text
|
|
7713
|
-
const
|
|
7714
|
-
const textSize = vec2(this.size.x, this.textHeight || this.size.y*textScale);
|
|
7797
|
+
// draw the text scaled to fit
|
|
7798
|
+
const textSize = this.getTextSize();
|
|
7715
7799
|
uiSystem.drawText(this.text, this.pos, textSize,
|
|
7716
7800
|
this.textColor, 0, undefined, this.align, this.font);
|
|
7717
7801
|
}
|
|
@@ -7749,8 +7833,7 @@ class UICheckbox extends UIObject
|
|
|
7749
7833
|
}
|
|
7750
7834
|
render()
|
|
7751
7835
|
{
|
|
7752
|
-
|
|
7753
|
-
uiSystem.drawRect(this.pos, this.size, color, this.lineWidth, this.lineColor, this.cornerRadius);
|
|
7836
|
+
super.render();
|
|
7754
7837
|
if (this.checked)
|
|
7755
7838
|
{
|
|
7756
7839
|
const p = this.cornerRadius / min(this.size.x, this.size.y) * 2;
|
|
@@ -7760,13 +7843,11 @@ class UICheckbox extends UIObject
|
|
|
7760
7843
|
uiSystem.drawLine(this.pos.add(s.multiply(vec2(-1,1))), this.pos.add(s.multiply(vec2(1,-1))), this.lineWidth, this.lineColor);
|
|
7761
7844
|
}
|
|
7762
7845
|
|
|
7763
|
-
// draw the text to the
|
|
7764
|
-
const
|
|
7765
|
-
const
|
|
7766
|
-
const textSize = vec2(this.size.x, this.textHeight || this.size.y*textScale);
|
|
7767
|
-
const pos = this.pos.add(vec2(this.size.x*gapScale,0));
|
|
7846
|
+
// draw the text next to the checkbox
|
|
7847
|
+
const textSize = this.getTextSize();
|
|
7848
|
+
const pos = this.pos.add(vec2(this.size.x,0));
|
|
7768
7849
|
uiSystem.drawText(this.text, pos, textSize,
|
|
7769
|
-
this.textColor, 0, undefined, 'left', this.font);
|
|
7850
|
+
this.textColor, 0, undefined, 'left', this.font, false);
|
|
7770
7851
|
}
|
|
7771
7852
|
}
|
|
7772
7853
|
|
|
@@ -7802,7 +7883,7 @@ class UIScrollbar extends UIObject
|
|
|
7802
7883
|
update()
|
|
7803
7884
|
{
|
|
7804
7885
|
super.update();
|
|
7805
|
-
if (this.
|
|
7886
|
+
if (this.isActiveObject() && this.interactive)
|
|
7806
7887
|
{
|
|
7807
7888
|
// check if value changed
|
|
7808
7889
|
const handleSize = vec2(this.size.y);
|
|
@@ -7816,12 +7897,7 @@ class UIScrollbar extends UIObject
|
|
|
7816
7897
|
}
|
|
7817
7898
|
render()
|
|
7818
7899
|
{
|
|
7819
|
-
|
|
7820
|
-
const lineColor = this.interactive && this.mouseIsHeld && !this.disabled ?
|
|
7821
|
-
this.color : this.lineColor;
|
|
7822
|
-
const color = this.disabled ? this.disabledColor :
|
|
7823
|
-
this.interactive && this.mouseIsHeld ? this.hoverColor : this.color;
|
|
7824
|
-
uiSystem.drawRect(this.pos, this.size, color, this.lineWidth, lineColor, this.cornerRadius);
|
|
7900
|
+
super.render();
|
|
7825
7901
|
|
|
7826
7902
|
// draw the scrollbar handle
|
|
7827
7903
|
const handleSize = vec2(this.size.y);
|
|
@@ -7830,12 +7906,11 @@ class UIScrollbar extends UIObject
|
|
|
7830
7906
|
const p2 = this.pos.x + handleWidth/2;
|
|
7831
7907
|
const handlePos = vec2(lerp(p1, p2, this.value), this.pos.y);
|
|
7832
7908
|
const handleColor = this.disabled ? this.disabledColor :
|
|
7833
|
-
this.interactive && this.
|
|
7909
|
+
this.interactive && this.isActiveObject() ? this.color : this.handleColor;
|
|
7834
7910
|
uiSystem.drawRect(handlePos, handleSize, handleColor, this.lineWidth, this.lineColor, this.cornerRadius);
|
|
7835
7911
|
|
|
7836
|
-
// draw the text on the scrollbar
|
|
7837
|
-
const
|
|
7838
|
-
const textSize = vec2(this.size.x, this.textHeight || this.size.y*textScale);
|
|
7912
|
+
// draw the text scaled to fit on the scrollbar
|
|
7913
|
+
const textSize = this.getTextSize();
|
|
7839
7914
|
uiSystem.drawText(this.text, this.pos, textSize,
|
|
7840
7915
|
this.textColor, 0, undefined, this.align, this.font);
|
|
7841
7916
|
}
|