# Object Study 1.0.0

A Three.js object viewer with comic-style halftone shading: shadows are formed by ink dots that grow as surfaces turn away from the light. Bold black silhouettes and fine detail lines preserve the illustration look. Stepped black-and-gray shading is available under **Ink**, alongside an unshaded **Line drawing** mode. The default object is a generic game controller with rounded grips, twin analog sticks, a D-pad, and raised buttons, modeled entirely in code.

Try the interactive controls and download the component at [kraft.team/components/object-study](https://kraft.team/components/object-study/).

## Embed on a website

```html
<script defer src="https://kraft.team/components/assets/object-study/1.0.0/component.js"></script>
<object-study
  mode="halftone"
  base-color="#f6b744"
  ink-color="#000000"
  dot-spacing="6"
  dot-size="1"
  light-azimuth="-21"
  light-elevation="35"
  style="display: block; width: 100%; height: 420px"
></object-study>
```

The bundle includes Three.js and registers `<object-study>`. It needs no framework, CDN imports, or separate model files. To host it yourself, copy `object-study.js` from the download and change the script URL. The element initializes when near the viewport and releases its renderer when removed. Drag to rotate, scroll to zoom, and right-drag to pan.

Set attributes initially or change them with `setAttribute()`:

| Attribute | Default | Values |
| --- | --- | --- |
| `mode` | `halftone` | `halftone`, `illustration` (Ink), `line` |
| `silhouette-weight` | `3.5` | 2–8 display pixels |
| `detail-weight` | `0.9` | 0.3–1.8 display pixels |
| `detail-level` | `62` | 0–85; higher reveals more creases |
| `details` | `true` | `true`, `false` |
| `shadow-steps` | `3` | 2–6; Ink mode |
| `shadow-coverage` | `0.28` | 0–0.8 |
| `dot-spacing` | `6` | 3–14 display pixels |
| `dot-size` | `1` | 0.4–1.4; 1 = 100% |
| `dot-angle` | `45` | 0–90 degrees |
| `base-color` | `#f6b744` | Three- or six-digit hex color |
| `ink-color` | `#000000` | Three- or six-digit hex color; Halftone mode |
| `light-azimuth` | `-21` | −180–180 degrees |
| `light-elevation` | `35` | −85–85 degrees |
| `view` | `axonometric` | `axonometric`, `front`, `side`, `top` |

Numeric values are clamped to these ranges; invalid settings use their defaults. The element supports `resetView(view)`, `resetModel()`, `loadModel(file)` (an asynchronous boolean result), and `exportPNG()` (a Promise resolving to a Blob). Call these methods after `object-study-ready`. `object-study-ready` supplies `{ mode }`, `object-study-view-change` supplies `{ view }`, and `object-study-error` supplies `{ message }` in `event.detail`; all three events bubble across the element's shadow boundary.

## Standalone viewer and development

```sh
cd /home/ahmad/creativity/technical-object
npm install
npm run dev
```

Open `http://localhost:4174` on the machine running the server. On a remote host, forward port 4174 or open its reachable preview address. The viewer requires a browser with WebGL 2. Run `npm run build` to generate the standalone site, `dist/object-study.js`, a self-contained `dist/demo.html`, and the source download `dist/object-study-1.0.0.zip`. Use `npm run preview` to serve the built viewer.

Drag to rotate, scroll to zoom, and right-drag to pan. Choose the front, side, top, or three-quarter view. **Halftone** is selected initially: choose the base color and dot ink, then adjust dot spacing in display pixels, dot size, and pattern angle. Shadow coverage changes how much ink appears across the object; dot size varies continuously with the lighting to express highlights and shadows. Switch to **Ink** for the previous two-to-six-step shading that reaches pure black, or **Line drawing** for unshaded faces. Reset drawing restores the warm yellow halftone with black dots, 6 px spacing, 100% size, and a 45° angle.

Silhouette weight sets the bold outside contour independently of the thinner detail weight; detail level controls how many subtle creases appear. Internal detail lines can also be hidden in every style. Save drawing downloads a PNG of the current canvas at its display resolution, including a pixel ratio of up to 2.

Use **Around object** (−180° to 180°) and **Elevation** (−85° to 85°) to change the light direction and move the halftone or stepped shadows. The light stays fixed relative to the object as you rotate the camera. Loading another model preserves your chosen direction; Reset drawing restores −21° around the object and 35° elevation. Line drawing disables these controls while retaining their values.

Load a static GLB, STL, or OBJ file up to 50 MB. Files are parsed locally in the browser. GLB resources must be embedded; OBJ materials are replaced, and no MTL is needed. Draco, KTX2, external resources, animated meshes, and matching detail lines on skinned poses are outside this prototype's scope. Large or highly tessellated meshes can make edge extraction slow. Use simplified static surface meshes for the cleanest illustrations.

## Apply the treatment to a different Three.js object

```js
import { TechnicalIllustration } from './src/illustration.js';

const drawing = new TechnicalIllustration(document.querySelector('#viewport'));
drawing.setObject(myThreeObject);
drawing.setLightDirection({ azimuth: -21, elevation: 35 }); // angles in degrees
drawing.setAppearance({
  mode: 'halftone',    // or 'illustration' for stepped ink, or 'line'
  weight: 3.5,         // silhouette width in display pixels
  detailWeight: 0.9,   // detail width in display pixels
  detailAngle: 28,     // crease threshold in degrees; lower reveals more detail
  steps: 3,           // discrete shadow levels in illustration mode
  shading: 0.28,      // shadow coverage
  details: true,
  dotSpacing: 6,      // spacing in display pixels
  dotSize: 1,         // dot size multiplier; 1 = 100%
  dotAngle: 45,       // pattern rotation in degrees
  baseColor: '#f6b744',
  inkColor: '#000000',
});
```

`setObject` takes ownership of the supplied object and its resources. It recenters and scales the model in a parent group, replaces its materials, and disposes the previous model. Give it a dedicated copy when the object or geometry is also used elsewhere. Call `dispose()` when removing the viewer.

The renderer combines an [OrthographicCamera](https://threejs.org/docs/pages/OrthographicCamera.html), lighting-driven halftone dots or paper-colored cel shading, pixel-sized silhouettes, and [EdgesGeometry](https://threejs.org/docs/pages/EdgesGeometry.html) for sharp creases. Halftone dots use a rotated screen-space grid, grow with shadow coverage, and retain their display-pixel spacing when the model is zoomed. [LineSegments2](https://threejs.org/docs/pages/LineSegments2.html) supplies adjustable internal stroke widths. Depth testing hides rear edges. The default 28-degree crease threshold suppresses the triangle grid on smooth surfaces; changing detail level rebuilds those edges. The outside silhouette always stays bolder than internal details. Ink mode uses discrete neutral levels and a pure-black darkest step. This is an illustration renderer rather than a CAD hidden-line export.

```sh
npm test
npm run build
```

Node tests verify the controller's closed casing and visible controls, sample geometry, centering with nested transforms, OBJ/STL/GLB parsing, invalid-file handling, ink palette boundaries, halftone dot growth and colors, style switching and disposal, custom element settings and lifecycle, and silhouette pass state and pixel sizes. Browser rendering needs visual verification on a Mac; `/home/ahmad/AGENTS.md` prohibits running browser binaries on this VPS.

`component.json` registers this release with the Components catalogue. Build this folder first, then follow `../components-site/README.md` to build, prepare and publish the catalogue. Existing versioned assets stay fixed; bump the version before publishing changes to a released bundle.

The download includes the source, tests, bundled component, standalone demo and `THIRD_PARTY_NOTICES.md`. Three.js is distributed under the MIT license; its notice is included in the browser bundle and download.
