@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.
- package/dist/index.js +49 -47
- 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.
|
|
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(
|
|
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 =
|
|
44678
|
-
roughnessCanvas.height = metalnessCanvas.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
|
-
|
|
44684
|
-
|
|
44694
|
+
canvasWidth,
|
|
44695
|
+
canvasHeight
|
|
44685
44696
|
);
|
|
44686
44697
|
const metalnessImageData = metalnessCtx.createImageData(
|
|
44687
|
-
|
|
44688
|
-
|
|
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 %
|
|
44695
|
-
const y = Math.floor(pixelIndex /
|
|
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
|
-
|
|
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 =
|
|
44721
|
+
const salt = canvasWidth + canvasHeight;
|
|
44717
44722
|
const fineGrain = profile.isExposedCopper ? createCopperDetail(x, y, salt) : profile.isMaskedCopper ? createMaskedTraceDetail(x, y, salt) : 0;
|
|
44718
|
-
const
|
|
44723
|
+
const surfaceHeight = clamp01(
|
|
44719
44724
|
invertSurfaceHeight(profile.height) + fineGrain * profile.microSurfaceWeight
|
|
44720
44725
|
);
|
|
44721
|
-
heights[pixelIndex] =
|
|
44722
|
-
const heightChannel =
|
|
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 =
|
|
44741
|
-
bumpCanvas.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 =
|
|
44747
|
-
normalCanvas.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(
|
|
44756
|
-
for (let y = 0; y <
|
|
44757
|
-
for (let x = 0; 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
|
|
44761
|
-
const i = (y *
|
|
44762
|
-
normalData[i] = (
|
|
44763
|
-
normalData[i + 1] = (
|
|
44764
|
-
normalData[i + 2] = (
|
|
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
|
}
|