@tscircuit/3d-viewer 0.0.605 → 0.0.606

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.
Files changed (2) hide show
  1. package/dist/index.js +49 -47
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -39224,7 +39224,7 @@ import * as THREE23 from "three";
39224
39224
  // package.json
39225
39225
  var package_default = {
39226
39226
  name: "@tscircuit/3d-viewer",
39227
- version: "0.0.604",
39227
+ version: "0.0.605",
39228
39228
  repository: {
39229
39229
  type: "git",
39230
39230
  url: "https://github.com/tscircuit/3d-viewer"
@@ -39872,16 +39872,23 @@ var Canvas = forwardRef(
39872
39872
  onCreatedRef.current?.({ camera, renderer });
39873
39873
  let animationFrameId;
39874
39874
  const clock = new THREE16.Clock();
39875
+ let isVisible = true;
39876
+ const visibilityObserver = new IntersectionObserver(([entry]) => {
39877
+ isVisible = entry?.isIntersecting ?? false;
39878
+ if (isVisible) handleResize();
39879
+ });
39880
+ visibilityObserver.observe(mountRef.current);
39875
39881
  const animate = () => {
39882
+ animationFrameId = requestAnimationFrame(animate);
39883
+ if (!isVisible) return;
39876
39884
  const time = clock.getElapsedTime();
39877
39885
  const delta = clock.getDelta();
39878
39886
  frameListeners.current.forEach((listener) => listener(time, delta));
39879
39887
  renderer.render(scene, camera);
39880
- animationFrameId = requestAnimationFrame(animate);
39881
39888
  };
39882
39889
  animate();
39883
39890
  const handleResize = () => {
39884
- if (mountRef.current) {
39891
+ if (mountRef.current?.clientWidth && mountRef.current.clientHeight) {
39885
39892
  const newAspect = mountRef.current.clientWidth / mountRef.current.clientHeight;
39886
39893
  if (camera instanceof THREE16.PerspectiveCamera) {
39887
39894
  camera.aspect = newAspect;
@@ -39907,6 +39914,7 @@ var Canvas = forwardRef(
39907
39914
  };
39908
39915
  window.removeEventListener("resize", handleResize);
39909
39916
  cancelAnimationFrame(animationFrameId);
39917
+ visibilityObserver.disconnect();
39910
39918
  if (mountRef.current && renderer.domElement) {
39911
39919
  mountRef.current.removeChild(renderer.domElement);
39912
39920
  }
@@ -40404,7 +40412,14 @@ var OrientationCubeCanvas = () => {
40404
40412
  group.add(topText);
40405
40413
  group.add(bottomText);
40406
40414
  let animationFrameId = null;
40415
+ let isVisible = true;
40416
+ const visibilityObserver = new IntersectionObserver(([entry]) => {
40417
+ isVisible = entry?.isIntersecting ?? false;
40418
+ });
40419
+ visibilityObserver.observe(canvas);
40407
40420
  const animate = () => {
40421
+ animationFrameId = requestAnimationFrame(animate);
40422
+ if (!isVisible) return;
40408
40423
  if (mainCameraRef.current) {
40409
40424
  const cameraPosition = computePointInFront(
40410
40425
  mainCameraRef.current.rotation ?? new THREE20.Euler(0, 0, 0),
@@ -40416,10 +40431,10 @@ var OrientationCubeCanvas = () => {
40416
40431
  }
40417
40432
  }
40418
40433
  renderer.render(scene, camera);
40419
- animationFrameId = requestAnimationFrame(animate);
40420
40434
  };
40421
40435
  animate();
40422
40436
  return () => {
40437
+ visibilityObserver.disconnect();
40423
40438
  canvas.remove();
40424
40439
  if (animationFrameId !== null) {
40425
40440
  cancelAnimationFrame(animationFrameId);
@@ -44657,6 +44672,7 @@ var createDataTexture = (canvas) => {
44657
44672
  var createBoardReliefTextures = (texture, maskedCopperMask) => {
44658
44673
  const sourceCanvas = texture.image;
44659
44674
  if (!sourceCanvas?.width || !sourceCanvas.height) return null;
44675
+ const { width: canvasWidth, height: canvasHeight } = sourceCanvas;
44660
44676
  const sourceCtx = sourceCanvas.getContext("2d");
44661
44677
  if (!sourceCtx) return null;
44662
44678
  const maskCanvas = maskedCopperMask?.image;
@@ -44664,48 +44680,37 @@ var createBoardReliefTextures = (texture, maskedCopperMask) => {
44664
44680
  const maskWidth = maskCanvas?.width ?? 0;
44665
44681
  const maskHeight = maskCanvas?.height ?? 0;
44666
44682
  const maskImageData = maskCtx && maskWidth && maskHeight ? maskCtx.getImageData(0, 0, maskWidth, maskHeight) : null;
44667
- const imageData = sourceCtx.getImageData(
44668
- 0,
44669
- 0,
44670
- sourceCanvas.width,
44671
- sourceCanvas.height
44672
- );
44683
+ const imageData = sourceCtx.getImageData(0, 0, canvasWidth, canvasHeight);
44673
44684
  const data = imageData.data;
44674
- const heights = new Float32Array(sourceCanvas.width * sourceCanvas.height);
44685
+ const heights = new Float32Array(canvasWidth * canvasHeight);
44675
44686
  const roughnessCanvas = document.createElement("canvas");
44676
44687
  const metalnessCanvas = document.createElement("canvas");
44677
- roughnessCanvas.width = metalnessCanvas.width = sourceCanvas.width;
44678
- roughnessCanvas.height = metalnessCanvas.height = sourceCanvas.height;
44688
+ roughnessCanvas.width = metalnessCanvas.width = canvasWidth;
44689
+ roughnessCanvas.height = metalnessCanvas.height = canvasHeight;
44679
44690
  const roughnessCtx = roughnessCanvas.getContext("2d");
44680
44691
  const metalnessCtx = metalnessCanvas.getContext("2d");
44681
44692
  if (!roughnessCtx || !metalnessCtx) return null;
44682
44693
  const roughnessImageData = roughnessCtx.createImageData(
44683
- sourceCanvas.width,
44684
- sourceCanvas.height
44694
+ canvasWidth,
44695
+ canvasHeight
44685
44696
  );
44686
44697
  const metalnessImageData = metalnessCtx.createImageData(
44687
- sourceCanvas.width,
44688
- sourceCanvas.height
44698
+ canvasWidth,
44699
+ canvasHeight
44689
44700
  );
44690
44701
  const roughnessData = roughnessImageData.data;
44691
44702
  const metalnessData = metalnessImageData.data;
44692
44703
  for (let i = 0; i < data.length; i += 4) {
44693
44704
  const pixelIndex = i / 4;
44694
- const x = pixelIndex % sourceCanvas.width;
44695
- const y = Math.floor(pixelIndex / sourceCanvas.width);
44705
+ const x = pixelIndex % canvasWidth;
44706
+ const y = Math.floor(pixelIndex / canvasWidth);
44696
44707
  const alpha = data[i + 3] ?? 0;
44697
44708
  if (alpha < 16) {
44698
44709
  heights[pixelIndex] = invertSurfaceHeight(PLAIN_SOLDERMASK_HEIGHT);
44699
44710
  continue;
44700
44711
  }
44701
- const maskX = maskImageData ? Math.min(
44702
- maskWidth - 1,
44703
- Math.floor(x / sourceCanvas.width * maskWidth)
44704
- ) : 0;
44705
- const maskY = maskImageData ? Math.min(
44706
- maskHeight - 1,
44707
- Math.floor(y / sourceCanvas.height * maskHeight)
44708
- ) : 0;
44712
+ const maskX = maskImageData ? Math.min(maskWidth - 1, Math.floor(x / canvasWidth * maskWidth)) : 0;
44713
+ const maskY = maskImageData ? Math.min(maskHeight - 1, Math.floor(y / canvasHeight * maskHeight)) : 0;
44709
44714
  const maskAlpha = maskImageData ? maskImageData.data[(maskY * maskWidth + maskX) * 4 + 3] ?? 0 : 0;
44710
44715
  const profile = getBoardSurfaceProfile(
44711
44716
  data[i] ?? 0,
@@ -44713,13 +44718,13 @@ var createBoardReliefTextures = (texture, maskedCopperMask) => {
44713
44718
  data[i + 2] ?? 0,
44714
44719
  maskAlpha >= 16
44715
44720
  );
44716
- const salt = sourceCanvas.width + sourceCanvas.height;
44721
+ const salt = canvasWidth + canvasHeight;
44717
44722
  const fineGrain = profile.isExposedCopper ? createCopperDetail(x, y, salt) : profile.isMaskedCopper ? createMaskedTraceDetail(x, y, salt) : 0;
44718
- const height10 = clamp01(
44723
+ const surfaceHeight = clamp01(
44719
44724
  invertSurfaceHeight(profile.height) + fineGrain * profile.microSurfaceWeight
44720
44725
  );
44721
- heights[pixelIndex] = height10;
44722
- const heightChannel = height10 * 255;
44726
+ heights[pixelIndex] = surfaceHeight;
44727
+ const heightChannel = surfaceHeight * 255;
44723
44728
  data[i] = data[i + 1] = data[i + 2] = heightChannel;
44724
44729
  data[i + 3] = 255;
44725
44730
  const roughness = profile.isExposedCopper ? clamp01(
@@ -44737,31 +44742,28 @@ var createBoardReliefTextures = (texture, maskedCopperMask) => {
44737
44742
  roughnessCtx.putImageData(roughnessImageData, 0, 0);
44738
44743
  metalnessCtx.putImageData(metalnessImageData, 0, 0);
44739
44744
  const bumpCanvas = document.createElement("canvas");
44740
- bumpCanvas.width = sourceCanvas.width;
44741
- bumpCanvas.height = sourceCanvas.height;
44745
+ bumpCanvas.width = canvasWidth;
44746
+ bumpCanvas.height = canvasHeight;
44742
44747
  const bumpCtx = bumpCanvas.getContext("2d");
44743
44748
  if (!bumpCtx) return null;
44744
44749
  bumpCtx.putImageData(imageData, 0, 0);
44745
44750
  const normalCanvas = document.createElement("canvas");
44746
- normalCanvas.width = sourceCanvas.width;
44747
- normalCanvas.height = sourceCanvas.height;
44751
+ normalCanvas.width = canvasWidth;
44752
+ normalCanvas.height = canvasHeight;
44748
44753
  const normalCtx = normalCanvas.getContext("2d");
44749
44754
  if (!normalCtx) return null;
44750
- const normalImageData = normalCtx.createImageData(
44751
- sourceCanvas.width,
44752
- sourceCanvas.height
44753
- );
44755
+ const normalImageData = normalCtx.createImageData(canvasWidth, canvasHeight);
44754
44756
  const normalData = normalImageData.data;
44755
- const getHeight4 = (x, y) => heights[Math.max(0, Math.min(sourceCanvas.height - 1, y)) * sourceCanvas.width + Math.max(0, Math.min(sourceCanvas.width - 1, x))] ?? 0;
44756
- for (let y = 0; y < sourceCanvas.height; y++) {
44757
- for (let x = 0; x < sourceCanvas.width; x++) {
44757
+ const getHeight4 = (x, y) => heights[Math.max(0, Math.min(canvasHeight - 1, y)) * canvasWidth + Math.max(0, Math.min(canvasWidth - 1, x))] ?? 0;
44758
+ for (let y = 0; y < canvasHeight; y++) {
44759
+ for (let x = 0; x < canvasWidth; x++) {
44758
44760
  const dx = (getHeight4(x + 1, y) - getHeight4(x - 1, y)) * 4;
44759
44761
  const dy = (getHeight4(x, y + 1) - getHeight4(x, y - 1)) * 4;
44760
- const normal = new THREE40.Vector3(-dx, -dy, 1).normalize();
44761
- const i = (y * sourceCanvas.width + x) * 4;
44762
- normalData[i] = (normal.x * 0.5 + 0.5) * 255;
44763
- normalData[i + 1] = (normal.y * 0.5 + 0.5) * 255;
44764
- normalData[i + 2] = (normal.z * 0.5 + 0.5) * 255;
44762
+ const inverseLength = 1 / Math.sqrt(dx * dx + dy * dy + 1);
44763
+ const i = (y * canvasWidth + x) * 4;
44764
+ normalData[i] = (-dx * inverseLength * 0.5 + 0.5) * 255;
44765
+ normalData[i + 1] = (-dy * inverseLength * 0.5 + 0.5) * 255;
44766
+ normalData[i + 2] = (inverseLength * 0.5 + 0.5) * 255;
44765
44767
  normalData[i + 3] = 255;
44766
44768
  }
44767
44769
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/3d-viewer",
3
- "version": "0.0.605",
3
+ "version": "0.0.606",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/tscircuit/3d-viewer"