@@ -35,7 +35,7 @@ const engineName = 'LittleJS';
3535 * @type {string}
3636 * @default
3737 * @memberof Engine */
38- const engineVersion = '1.18.17';
38+ const engineVersion = '1.18.17.1 ';
3939
4040/** Frames per second to update
4141 * @type {number}
@@ -2233,6 +2233,16 @@ class Color
22332233 * @return {Color} */
22342234 setFrom(c) { return this.set(c.r, c.g, c.b, c.a); }
22352235
2236+ /** Sets the alpha of this color and returns self
2237+ * @param {number} [a] - alpha
2238+ * @return {Color} */
2239+ setAlpha(a=1)
2240+ {
2241+ this.a = a;
2242+ ASSERT_COLOR_VALID(this);
2243+ return this;
2244+ }
2245+
22362246 /** Returns a new color that is a copy of this
22372247 * @return {Color} */
22382248 copy() { return new Color(this.r, this.g, this.b, this.a); }
@@ -5078,6 +5088,62 @@ function screenToWorldTransform(screenPos, screenSize, screenAngle=0)
50785088 * @memberof Draw */
50795089function getCameraSize() { return mainCanvasSize.scale(1/cameraScale); }
50805090
5091+ /** Fit the camera to a rectangle in world space by setting cameraPos and cameraScale
5092+ * - worldMargin pads the content rectangle in world units, so the gap scales with the content on resize
5093+ * - screenInset reserves space in screen pixels on each viewport edge (for example a HUD band) and
5094+ * re-centers the content away from that edge, so the reserved band stays a fixed pixel size on resize
5095+ * - worldMargin and screenInset may each be a number for all sides, a Vector2 (x=left/right, y=top/bottom),
5096+ * or an object with any of {top, right, bottom, left}
5097+ * @param {Vector2} center - Center of the rectangle in world space
5098+ * @param {Vector2} size - Size of the rectangle in world space
5099+ * @param {number|Vector2|Object} [worldMargin] - World space padding added around the content rectangle
5100+ * @param {number|Vector2|Object} [screenInset] - Screen space padding in pixels reserved on each viewport edge
5101+ * @return {number} - The new camera scale
5102+ * @memberof Draw */
5103+ function cameraFit(center, size, worldMargin, screenInset)
5104+ {
5105+ ASSERT(isVector2(center), 'center must be a vec2');
5106+ ASSERT(isVector2(size), 'size must be a vec2');
5107+
5108+ // pad the content
5109+ const margin = padSides(worldMargin);
5110+ const inset = padSides(screenInset);
5111+ const worldW = size.x + margin.left + margin.right;
5112+ const worldH = size.y + margin.top + margin.bottom;
5113+ const viewW = mainCanvasSize.x - inset.left - inset.right;
5114+ const viewH = mainCanvasSize.y - inset.top - inset.bottom;
5115+
5116+ // bail on a degenerate rect or viewport
5117+ if (!(worldW > 0 && worldH > 0 && viewW > 0 && viewH > 0))
5118+ return cameraScale;
5119+
5120+ // bail on a degenerate rect or viewport rather than NaN the camera
5121+ cameraScale = min(viewW / worldW, viewH / worldH);
5122+
5123+ // calculate offset vectors
5124+ const marginVector = vec2(margin.right - margin.left, margin.top - margin.bottom).scale(.5);
5125+ const insetVector = vec2(inset.right - inset.left, inset.top - inset.bottom).scale(.5 / cameraScale);
5126+
5127+ // apply the offsets and return camera scale
5128+ cameraPos = center.add(marginVector).add(insetVector);
5129+ return cameraScale;
5130+
5131+ function padSides(p)
5132+ {
5133+ // normalize a padding option to {top, right, bottom, left}
5134+ if (p === undefined || isNumber(p))
5135+ p = vec2(p);
5136+ if (isVector2(p))
5137+ return { top: p.y, right: p.x, bottom: p.y, left: p.x };
5138+ return {
5139+ top: p.top || 0,
5140+ right: p.right || 0,
5141+ bottom: p.bottom || 0,
5142+ left: p.left || 0,
5143+ };
5144+ }
5145+ }
5146+
50815147/** Check if a box, point, or circle is on screen with a circle test
50825148 * If size is a Vector2, uses the length as diameter
50835149 * This can be used to cull offscreen objects from render or update
@@ -16346,6 +16412,7 @@ export
1634616412 toggleFullscreen,
1634716413 setCursor,
1634816414 getCameraSize,
16415+ cameraFit,
1634916416 isOnScreen,
1635016417
1635116418 // WebGL
0 commit comments