figureone 1.9.1 → 1.10.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/llms-full.txt CHANGED
@@ -560,6 +560,39 @@ const points = Fig.surfaceGrid({
560
560
  figure.add({ make: 'surface', points, color: [1, 0, 0, 1], normals: 'curve' });
561
561
  ```
562
562
 
563
+ ### OBJ_RotateControl (`make: 'rotateControl'`)
564
+
565
+ Rotates a 3D element with drag gestures. Produces the same on-screen motion as
566
+ `cameraControl`, but rotates the object instead of orbiting the camera — so the
567
+ world-fixed lights shade the object differently as it turns.
568
+
569
+ | Property | Type | Default | Description |
570
+ |---|---|---|---|
571
+ | left | number | `0` | Screen left (0-1) |
572
+ | bottom | number | `0` | Screen bottom (0-1) |
573
+ | width | number | `1` | Width (0-1) |
574
+ | height | number | `1` | Height (0-1) |
575
+ | axis | TypeParsablePoint | `[0, 1, 0]` | Vertical axis |
576
+ | controlElement | FigureElement \| string | | Element to rotate (required; must not be an ancestor of the control) |
577
+ | sensitivity | number | `5` | Overall sensitivity |
578
+ | xSensitivity | number | `1` | Horizontal sensitivity (0 = no azimuth) |
579
+ | ySensitivity | number | `1` | Vertical sensitivity (0 = no elevation) |
580
+ | back | boolean | `false` | If true, other touchable elements are touched first (object rotates only on empty-space drags) |
581
+
582
+ ```js
583
+ const figure = new Fig.Figure({
584
+ scene: {
585
+ style: 'orthographic',
586
+ near: 0.1,
587
+ far: 10,
588
+ camera: { position: [1, 0.6, 1.5], lookAt: [0, 0, 0], up: [0, 1, 0] },
589
+ light: { directional: [0.7, 0.5, 1], ambient: 0.4 },
590
+ },
591
+ });
592
+ const cube = figure.add({ make: 'cube', side: 0.6, color: [1, 0, 0, 1], light: 'directional' });
593
+ figure.add({ make: 'rotateControl', controlElement: cube });
594
+ ```
595
+
563
596
  ---
564
597
 
565
598
  ## 5. Collections
package/llms.txt CHANGED
@@ -63,6 +63,7 @@ Other `Fig.Figure` options: `textStyle` (`'italic'` default | `'normal'` — def
63
63
  | `prism` | 3D prism |
64
64
  | `revolve` | 3D surface of revolution |
65
65
  | `cameraControl` | Enables 3D camera rotation via drag |
66
+ | `rotateControl` | Rotates a 3D element via drag (object turns, camera/light fixed); set `controlElement` |
66
67
 
67
68
  Shorthand `make: 'polygon'` is equivalent to `make: 'primitives.polygon'`.
68
69
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "figureone",
3
- "version": "1.9.1",
3
+ "version": "1.10.0",
4
4
  "description": "Draw, animate and interact with shapes, text, plots and equations in Javascript. Create interactive slide shows, and interactive videos.",
5
5
  "main": "index.js",
6
6
  "types": "types/index.d.ts",
@@ -2,6 +2,7 @@ import type { TypeGLBufferUsage } from '../DrawingObjects/GLObject/GLObject';
2
2
  import type { CPY_Step } from '../geometries/copy/copy';
3
3
  import type { TypeParsablePoint } from '../../tools/geometry/Point';
4
4
  import type Scene from '../../tools/geometry/scene';
5
+ import type { FigureElement } from '../Element';
5
6
  import type { TypeColor } from '../../tools/types';
6
7
  import type { TypeParsableLine } from '../../tools/geometry/Line';
7
8
  import type { OBJ_Line3Arrow } from '../../tools/d3/line3';
@@ -1103,3 +1104,94 @@ export type OBJ_CameraControl = {
1103
1104
  ySensitivity?: number;
1104
1105
  back?: boolean;
1105
1106
  } & OBJ_FigurePrimitive;
1107
+ /**
1108
+ * Rotate control definition object that extends {@link OBJ_FigurePrimitive}.
1109
+ *
1110
+ * A rotate control is a transparent rectangle that uses touch and drag gestures
1111
+ * to rotate a 3D element. It produces the same on-screen motion as
1112
+ * {@link OBJ_CameraControl}, but rotates the *object* rather than orbiting the
1113
+ * camera. Because the scene lights are fixed in world space, the object's faces
1114
+ * are shaded differently as it turns (with `cameraControl` the shading stays
1115
+ * fixed relative to the object).
1116
+ *
1117
+ * Left/right movements rotate the object around the vertical `axis` (azimuth),
1118
+ * while up/down movements change its elevation relative to that axis.
1119
+ *
1120
+ * The transparent rectangle is positioned relative to the 2D HTML canvas. The
1121
+ * `left`, `bottom`, `width` and `height` properties are numbers from 0 to 1
1122
+ * representing a percentage of the screen width and height. For the rectangle to
1123
+ * cover the entire screen use `left: 0`, `bottom: 0`, `width: 1`, `height: 1`
1124
+ * (the defaults).
1125
+ *
1126
+ * Set `controlElement` (by name or reference) to the element to rotate. This is
1127
+ * required - it must not be an ancestor of the control (e.g. its parent
1128
+ * collection), otherwise rotating it would corrupt the control's own gesture
1129
+ * coordinates. With no `controlElement` the control does nothing. The element
1130
+ * should be centered on its scene's camera `lookAt` point so that it spins in
1131
+ * place.
1132
+ *
1133
+ * @property {number} [left] screen left position to place the control rectangle.
1134
+ * 0 is the left edge, while 1 is the right edge (`0`).
1135
+ * @property {number} [bottom] screen bottom position to place the control
1136
+ * rectangle. 0 is the bottom edge, while 1 is the top edge (`0`).
1137
+ * @property {number} [width] width of control rectangle. 1 is the full width of
1138
+ * the drawing canvas (`1`).
1139
+ * @property {number} [height] height of control rectangle. 1 is the full height
1140
+ * of the drawing canvas (`1`).
1141
+ * @property {TypeParsablePoint} [axis] axis to keep vertical as the object is
1142
+ * rotated. The axis vector and scene.camera.up vector should be in the same
1143
+ * plane (`[0, 1, 0]`)
1144
+ * @property {FigureElement | string} [controlElement] element to rotate (by name
1145
+ * or reference). Required; must not be an ancestor of the control. With no value
1146
+ * the control does nothing.
1147
+ * @property {number} [sensitivity] sensitivity of object rotation relative to
1148
+ * user movement where larger numbers result in more rotation for the same
1149
+ * movement (`5`)
1150
+ * @property {number} [xSensitivity] sensitivity to a horizontal user movement.
1151
+ * Setting this to 0 will mean the object does not rotate azimuthally (`1`)
1152
+ * @property {number} [ySensitivity] sensitivity to a vertical user movement.
1153
+ * Setting this to 0 will mean the elevation does not change (`1`)
1154
+ * @property {boolean} [back] if `false` (the default) the control captures all
1155
+ * drags, so dragging the object (or anywhere) rotates it. If `true`, all 2D and
1156
+ * 3D objects that can be touched are touched before the rotate control, so the
1157
+ * object only rotates when dragging empty space - use this when other elements
1158
+ * also need to be interactive (`false`)
1159
+ *
1160
+ * @example
1161
+ * // Cube that can be rotated by dragging anywhere on the figure.
1162
+ * // Set the 3D scene in the constructor so figure.scene and
1163
+ * // figure.elements.scene are wired consistently.
1164
+ * const figure = new Fig.Figure({
1165
+ * scene: {
1166
+ * style: 'orthographic',
1167
+ * near: 0.1,
1168
+ * far: 10,
1169
+ * camera: { position: [1, 0.6, 1.5], lookAt: [0, 0, 0], up: [0, 1, 0] },
1170
+ * light: { directional: [0.7, 0.5, 1], ambient: 0.4 },
1171
+ * },
1172
+ * });
1173
+ *
1174
+ * const cube = figure.add({
1175
+ * make: 'cube',
1176
+ * side: 0.6,
1177
+ * color: [1, 0, 0, 1],
1178
+ * light: 'directional',
1179
+ * });
1180
+ *
1181
+ * figure.add({ make: 'rotateControl', controlElement: cube });
1182
+ *
1183
+ * @interface
1184
+ * @group Interactivity
1185
+ */
1186
+ export type OBJ_RotateControl = {
1187
+ left?: number;
1188
+ bottom?: number;
1189
+ width?: number;
1190
+ height?: number;
1191
+ axis?: TypeParsablePoint;
1192
+ controlElement?: FigureElement | string;
1193
+ sensitivity?: number;
1194
+ xSensitivity?: number;
1195
+ ySensitivity?: number;
1196
+ back?: boolean;
1197
+ } & OBJ_FigurePrimitive;
@@ -13,7 +13,7 @@ import FigureElementPrimitiveGesture from './FigureElementPrimitiveGesture';
13
13
  import type { OBJ_Gesture } from './FigureElementPrimitiveGesture';
14
14
  import type { OBJ_LineStyleSimple, OBJ_GenericGL, OBJ_Morph, OBJ_Text } from './FigurePrimitiveTypes';
15
15
  import type { OBJ_Generic, OBJ_Polyline, OBJ_Polygon, OBJ_Polygon_Defined, OBJ_Star, OBJ_Rectangle, OBJ_Ellipse, OBJ_Arc, OBJ_Triangle, OBJ_Line, OBJ_Grid, OBJ_Arrow } from './FigurePrimitiveTypes2D';
16
- import type { OBJ_Generic3, OBJ_Sphere, OBJ_Cube, OBJ_Cylinder, OBJ_Cone, OBJ_Revolve, OBJ_Surface, OBJ_Line3, OBJ_CameraControl, OBJ_Prism } from './FigurePrimitiveTypes3D';
16
+ import type { OBJ_Generic3, OBJ_Sphere, OBJ_Cube, OBJ_Cylinder, OBJ_Cone, OBJ_Revolve, OBJ_Surface, OBJ_Line3, OBJ_CameraControl, OBJ_RotateControl, OBJ_Prism } from './FigurePrimitiveTypes3D';
17
17
  type OBJ_PolyLineTris = OBJ_LineStyleSimple & {
18
18
  drawBorderBuffer: number | Array<Array<Point>>;
19
19
  };
@@ -106,6 +106,18 @@ export default class FigurePrimitives {
106
106
  * @see {@link OBJ_CameraControl} for options and examples.
107
107
  */
108
108
  cameraControl(...options: Array<OBJ_CameraControl>): any;
109
+ /**
110
+ * {@link FigureElementPrimitive} that rotates a 3D element with touch and drag
111
+ * gestures.
112
+ *
113
+ * This produces the same on-screen motion as {@link OBJ_CameraControl}, but
114
+ * rotates the *object* instead of orbiting the camera. As the scene's lights
115
+ * are fixed in world space, the object's faces are shaded differently as it
116
+ * turns (with `cameraControl` the shading stays fixed relative to the object).
117
+ *
118
+ * @see {@link OBJ_RotateControl} for options and examples.
119
+ */
120
+ rotateControl(...options: Array<OBJ_RotateControl>): any;
109
121
  /**
110
122
  * {@link FigureElementPrimitive} that draws an ellipse.
111
123
  * @see {@link OBJ_Ellipse} for options and examples.