diff --git a/apps/storybook/package.json b/apps/storybook/package.json index 218a21ed4..d3743d9f7 100644 --- a/apps/storybook/package.json +++ b/apps/storybook/package.json @@ -24,7 +24,7 @@ "react": "18.3.1", "react-dom": "18.3.1", "react-icons": "5.4.0", - "three": "0.182.0" + "three": "0.185.1" }, "devDependencies": { "@esrf/eslint-config": "2.3.1", @@ -37,7 +37,7 @@ "@types/node": "^24.13.2", "@types/react": "^18.3.31", "@types/react-dom": "^18.3.7", - "@types/three": "0.183.1", + "@types/three": "0.185.3", "eslint": "9.39.4", "remark-gfm": "4.0.1", "storybook": "10.4.6", diff --git a/apps/storybook/src/GettingStarted.mdx b/apps/storybook/src/GettingStarted.mdx index 44d616b9d..905a37cf6 100644 --- a/apps/storybook/src/GettingStarted.mdx +++ b/apps/storybook/src/GettingStarted.mdx @@ -22,7 +22,7 @@ import { Meta } from '@storybook/addon-docs/blocks'; 1. Install the library and its peer dependencies: ```bash - npm install @h5web/lib "three<=0.182" @react-three/fiber@8 + npm install @h5web/lib three @react-three/fiber@8 ``` 1. Install `ndarray` and, if you use TypeScript, its types package: diff --git a/packages/app/package.json b/packages/app/package.json index cec426b75..5cfbc2640 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -64,7 +64,7 @@ "react-error-boundary": "6.1.2", "react-icons": "5.4.0", "react-resizable-panels": "4.12.0", - "three": "0.182.0", + "three": "0.185.1", "zustand": "5.0.14" }, "devDependencies": { diff --git a/packages/app/src/setupTests.ts b/packages/app/src/setupTests.ts index 973fb022d..6dd38c8cb 100644 --- a/packages/app/src/setupTests.ts +++ b/packages/app/src/setupTests.ts @@ -7,7 +7,12 @@ vi.mock(import('./providers/mock/utils'), { spy: true }); enableBigIntSerialization(); -failOnConsole(); +failOnConsole({ + silenceMessage: (message) => + message.includes( + 'THREE.Clock: This module has been deprecated. Please use THREE.Timer instead.', + ), +}); beforeEach(() => { localStorage.clear(); diff --git a/packages/lib/README.md b/packages/lib/README.md index 85c8ddc37..8389b4bb8 100644 --- a/packages/lib/README.md +++ b/packages/lib/README.md @@ -36,10 +36,9 @@ separate `@types/` package. > > - React v18.* > - React-three-fiber v8.* -> - three <= v0.182 ```bash -npm install @h5web/lib "three<=0.182" @react-three/fiber@8 ndarray +npm install @h5web/lib three @react-three/fiber@8 ndarray ``` ```tsx diff --git a/packages/lib/package.json b/packages/lib/package.json index 3e60e3491..c1be4ba79 100644 --- a/packages/lib/package.json +++ b/packages/lib/package.json @@ -34,10 +34,10 @@ "@react-three/fiber": "8.x", "@types/react": "18.x", "@types/react-dom": "18.x", - "@types/three": ">=0.138 <=0.182", + "@types/three": ">=0.138", "react": "18.x", "react-dom": "18.x", - "three": ">=0.138 <=0.182", + "three": ">=0.138", "typescript": ">=4.5" }, "peerDependenciesMeta": { @@ -93,7 +93,7 @@ "@types/node": "^24.13.2", "@types/react": "^18.3.31", "@types/react-dom": "^18.3.7", - "@types/three": "0.183.1", + "@types/three": "0.185.3", "@vitejs/plugin-react": "6.0.3", "dot-json": "1.3.0", "eslint": "9.39.4", @@ -101,7 +101,7 @@ "react-dom": "18.3.1", "rollup": "4.62.2", "rollup-plugin-dts": "6.4.1", - "three": "0.182.0", + "three": "0.185.1", "typescript": "5.9.3", "vite": "8.1.2", "vite-css-modules": "1.16.0", diff --git a/packages/lib/src/vis/shared/R3FCanvas.tsx b/packages/lib/src/vis/shared/R3FCanvas.tsx index 699626cbe..b061a1800 100644 --- a/packages/lib/src/vis/shared/R3FCanvas.tsx +++ b/packages/lib/src/vis/shared/R3FCanvas.tsx @@ -1,7 +1,7 @@ import { Canvas } from '@react-three/fiber'; -import { type PropsWithChildren } from 'react'; +import { type PropsWithChildren, useMemo } from 'react'; -import { CAMERA_FAR, CAMERA_NEAR, CAMERA_Z } from '../utils'; +import { ScaledOrthographicCamera } from './ScaledOrthographicCamera'; interface Props { className?: string; @@ -11,6 +11,8 @@ interface Props { function R3FCanvas(props: PropsWithChildren) { const { className, orthographic, children } = props; + const camera = useMemo(() => new ScaledOrthographicCamera(), []); + return ( ) { dpr={[1, 3]} // https://discoverthreejs.com/tips-and-tricks/#performance resize={{ debounce: { scroll: 20, resize: 200 }, scroll: false }} // https://github.com/pmndrs/react-three-fiber/discussions/1906 gl={{ preserveDrawingBuffer: true }} // for "Save Image As..." and snapshot feature to work - camera={ - orthographic - ? { - // Customize visible `z` range: https://github.com/silx-kit/h5web/issues/1626 - near: CAMERA_NEAR, - far: CAMERA_FAR, - position: [0, 0, CAMERA_Z], - } - : undefined - } + camera={orthographic ? camera : undefined} > {children} diff --git a/packages/lib/src/vis/shared/ScaledOrthographicCamera.ts b/packages/lib/src/vis/shared/ScaledOrthographicCamera.ts new file mode 100644 index 000000000..775228a74 --- /dev/null +++ b/packages/lib/src/vis/shared/ScaledOrthographicCamera.ts @@ -0,0 +1,29 @@ +import { OrthographicCamera } from 'three'; + +import { CAMERA_FAR, CAMERA_NEAR, CAMERA_Z } from '../utils'; + +export class ScaledOrthographicCamera extends OrthographicCamera { + /* An OrthographicCamera that keeps the scale in matrixWorldInverse (removed in three@0.183) */ + public constructor() { + super(); + // Customize visible `z` range: https://github.com/silx-kit/h5web/issues/1626 + this.near = CAMERA_NEAR; + this.far = CAMERA_FAR; + this.translateZ(CAMERA_Z); + } + + // https://github.com/mrdoob/three.js/pull/32805/changes + public override updateMatrixWorld(force?: boolean): void { + super.updateMatrixWorld(force); + this.matrixWorldInverse.copy(this.matrixWorld).invert(); + } + + // https://github.com/mrdoob/three.js/pull/32805/changes + public override updateWorldMatrix( + updateParents: boolean, + updateChildren: boolean, + ): void { + super.updateWorldMatrix(updateParents, updateChildren); + this.matrixWorldInverse.copy(this.matrixWorld).invert(); + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 876e7eba1..2dce2d48a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -333,7 +333,7 @@ importers: version: 25.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-three/fiber': specifier: 8.18.0 - version: 8.18.0(@types/react@18.3.31)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(three@0.182.0) + version: 8.18.0(@types/react@18.3.31)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(three@0.185.1) d3-array: specifier: 3.2.4 version: 3.2.4 @@ -359,8 +359,8 @@ importers: specifier: 5.4.0 version: 5.4.0(react@18.3.1) three: - specifier: 0.182.0 - version: 0.182.0 + specifier: 0.185.1 + version: 0.185.1 devDependencies: '@esrf/eslint-config': specifier: 2.3.1 @@ -393,8 +393,8 @@ importers: specifier: ^18.3.7 version: 18.3.7(@types/react@18.3.31) '@types/three': - specifier: 0.183.1 - version: 0.183.1 + specifier: 0.185.3 + version: 0.185.3 eslint: specifier: 9.39.4 version: 9.39.4 @@ -421,7 +421,7 @@ importers: version: 25.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-three/fiber': specifier: 8.18.0 - version: 8.18.0(@types/react@18.3.31)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(three@0.182.0) + version: 8.18.0(@types/react@18.3.31)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(three@0.185.1) '@types/d3-format': specifier: ~3.0.4 version: 3.0.4 @@ -447,8 +447,8 @@ importers: specifier: 4.12.0 version: 4.12.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) three: - specifier: 0.182.0 - version: 0.182.0 + specifier: 0.185.1 + version: 0.185.1 zustand: specifier: 5.0.14 version: 5.0.14(@types/react@18.3.31)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1)) @@ -679,7 +679,7 @@ importers: version: link:../shared '@react-three/fiber': specifier: 8.18.0 - version: 8.18.0(@types/react@18.3.31)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(three@0.182.0) + version: 8.18.0(@types/react@18.3.31)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(three@0.185.1) '@rollup/plugin-alias': specifier: 6.0.0 version: 6.0.0(rollup@4.62.2) @@ -693,8 +693,8 @@ importers: specifier: ^18.3.7 version: 18.3.7(@types/react@18.3.31) '@types/three': - specifier: 0.183.1 - version: 0.183.1 + specifier: 0.185.3 + version: 0.185.3 '@vitejs/plugin-react': specifier: 6.0.3 version: 6.0.3(vite@8.1.2(@types/node@24.13.2)(esbuild@0.28.1)) @@ -717,8 +717,8 @@ importers: specifier: 6.4.1 version: 6.4.1(rollup@4.62.2)(typescript@5.9.3) three: - specifier: 0.182.0 - version: 0.182.0 + specifier: 0.185.1 + version: 0.185.1 typescript: specifier: 5.9.3 version: 5.9.3 @@ -2027,8 +2027,8 @@ packages: '@types/stats.js@0.17.4': resolution: {integrity: sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==} - '@types/three@0.183.1': - resolution: {integrity: sha512-f2Pu5Hrepfgavttdye3PsH5RWyY/AvdZQwIVhrc4uNtvF7nOWJacQKcoVJn0S4f0yYbmAE6AR+ve7xDcuYtMGw==} + '@types/three@0.185.3': + resolution: {integrity: sha512-8TqTn1+fjPWuJ4mR6Igtg56DCf9b5EeAlwhb5xaa6WlBrsg7SvG0NQbyctGRkHCKwg0uftfCspOEsTXelgktMA==} '@types/tmp@0.2.6': resolution: {integrity: sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==} @@ -2338,9 +2338,6 @@ packages: '@webcontainer/env@1.1.1': resolution: {integrity: sha512-6aN99yL695Hi9SuIk1oC88l9o0gmxL1nGWWQ/kNy81HigJ0FoaoTXpytCj6ItzgyCEwA9kF1wixsTuv5cjsgng==} - '@webgpu/types@0.1.69': - resolution: {integrity: sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ==} - acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -3179,9 +3176,6 @@ packages: picomatch: optional: true - fflate@0.8.2: - resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} - fflate@0.8.3: resolution: {integrity: sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA==} @@ -3887,8 +3881,8 @@ packages: merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - meshoptimizer@1.0.1: - resolution: {integrity: sha512-Vix+QlA1YYT3FwmBBZ+49cE5y/b+pRrcXKqGpS5ouh33d3lSp2PoTpCw19E0cKDFWalembrHnIaZetf27a+W2g==} + meshoptimizer@1.1.1: + resolution: {integrity: sha512-oRFNWJRDA/WTrVj7NWvqa5HqE1t9MYDj2VaWirQCzCCrAd2GHrqR/sQezCxiWATPNlKTcRaPRHPJwIRoPBAp5g==} micromark-core-commonmark@2.0.3: resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} @@ -4752,8 +4746,8 @@ packages: terminal-columns@2.0.0: resolution: {integrity: sha512-6IByuUjyNZJXUtwDNm+OIe62zgwwaRbH+WMNTcx05O2G5V9WhvluAAHJY8OvUdwmzMPpqAD/7EUpGdI6ae1aiQ==} - three@0.182.0: - resolution: {integrity: sha512-GbHabT+Irv+ihI1/f5kIIsZ+Ef9Sl5A1Y7imvS5RQjWgtTPfPnZ43JmlYI7NtCRDK9zir20lQpfg8/9Yd02OvQ==} + three@0.185.1: + resolution: {integrity: sha512-5aojFCXKwnjBRZvUnt3WFfEcvUJgkN5LlijRFN95hMy8WVkG4I0QNcJE+OuWvuJ0bOdStrbfXn0pkd6/QyiAlg==} throttleit@1.0.1: resolution: {integrity: sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==} @@ -5242,7 +5236,7 @@ snapshots: '@babel/compat-data@7.29.7': {} - '@babel/core@7.29.7(supports-color@8.1.1)': + '@babel/core@7.29.7': dependencies: '@babel/code-frame': 7.29.7 '@babel/generator': 7.29.7 @@ -5289,7 +5283,7 @@ snapshots: '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@8.1.1) + '@babel/core': 7.29.7 '@babel/helper-module-imports': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 '@babel/traverse': 7.29.7 @@ -5546,7 +5540,7 @@ snapshots: eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.4(supports-color@8.1.1)) eslint-plugin-promise: 7.3.0(eslint@9.39.4(supports-color@8.1.1)) eslint-plugin-react: 7.37.5(eslint@9.39.4(supports-color@8.1.1)) - eslint-plugin-react-hooks: 7.1.1(eslint@9.39.4(supports-color@8.1.1))(supports-color@8.1.1) + eslint-plugin-react-hooks: 7.1.1(eslint@9.39.4(supports-color@8.1.1)) eslint-plugin-regexp: 3.1.0(eslint@9.39.4(supports-color@8.1.1)) eslint-plugin-simple-import-sort: 13.0.0(eslint@9.39.4(supports-color@8.1.1)) eslint-plugin-storybook: 10.3.5(eslint@9.39.4(supports-color@8.1.1))(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@18.3.31)(prettier@3.9.4)(react@18.3.1))(typescript@5.9.3) @@ -5836,7 +5830,7 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@react-three/fiber@8.18.0(@types/react@18.3.31)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(three@0.182.0)': + '@react-three/fiber@8.18.0(@types/react@18.3.31)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(three@0.185.1)': dependencies: '@babel/runtime': 7.28.4 '@types/react-reconciler': 0.26.7 @@ -5849,7 +5843,7 @@ snapshots: react-use-measure: 2.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1) scheduler: 0.21.0 suspend-react: 0.1.3(react@18.3.1) - three: 0.182.0 + three: 0.185.1 zustand: 3.7.2(react@18.3.1) optionalDependencies: react-dom: 18.3.1(react@18.3.1) @@ -6322,15 +6316,14 @@ snapshots: '@types/stats.js@0.17.4': {} - '@types/three@0.183.1': + '@types/three@0.185.3': dependencies: '@dimforge/rapier3d-compat': 0.12.0 '@tweenjs/tween.js': 23.1.3 '@types/stats.js': 0.17.4 '@types/webxr': 0.5.24 - '@webgpu/types': 0.1.69 - fflate: 0.8.2 - meshoptimizer: 1.0.1 + fflate: 0.8.3 + meshoptimizer: 1.1.1 '@types/tmp@0.2.6': {} @@ -6396,8 +6389,8 @@ snapshots: '@typescript-eslint/project-service@8.59.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.59.0(typescript@5.9.3) - '@typescript-eslint/types': 8.59.0 + '@typescript-eslint/tsconfig-utils': 8.60.0(typescript@5.9.3) + '@typescript-eslint/types': 8.60.0 debug: 4.4.3(supports-color@8.1.1) typescript: 5.9.3 transitivePeerDependencies: @@ -6826,8 +6819,6 @@ snapshots: '@webcontainer/env@1.1.1': {} - '@webgpu/types@0.1.69': {} - acorn-jsx@5.3.2(acorn@8.16.0): dependencies: acorn: 8.16.0 @@ -7713,9 +7704,9 @@ snapshots: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) eslint: 9.39.4 - eslint-plugin-react-hooks@7.1.1(eslint@9.39.4(supports-color@8.1.1))(supports-color@8.1.1): + eslint-plugin-react-hooks@7.1.1(eslint@9.39.4(supports-color@8.1.1)): dependencies: - '@babel/core': 7.29.7(supports-color@8.1.1) + '@babel/core': 7.29.7 '@babel/parser': 7.29.7 eslint: 9.39.4(supports-color@8.1.1) hermes-parser: 0.25.1 @@ -7726,7 +7717,7 @@ snapshots: eslint-plugin-react-hooks@7.1.1(eslint@9.39.4): dependencies: - '@babel/core': 7.29.7(supports-color@8.1.1) + '@babel/core': 7.29.7 '@babel/parser': 7.29.7 eslint: 9.39.4 hermes-parser: 0.25.1 @@ -8036,8 +8027,6 @@ snapshots: optionalDependencies: picomatch: 4.0.4 - fflate@0.8.2: {} - fflate@0.8.3: {} file-entry-cache@8.0.0: @@ -8766,7 +8755,7 @@ snapshots: merge-stream@2.0.0: {} - meshoptimizer@1.0.1: {} + meshoptimizer@1.1.1: {} micromark-core-commonmark@2.0.3: dependencies: @@ -9300,7 +9289,7 @@ snapshots: react-docgen@8.0.3: dependencies: - '@babel/core': 7.29.7(supports-color@8.1.1) + '@babel/core': 7.29.7 '@babel/traverse': 7.29.7 '@babel/types': 7.29.7 '@types/babel__core': 7.20.5 @@ -9871,7 +9860,7 @@ snapshots: terminal-columns@2.0.0: {} - three@0.182.0: {} + three@0.185.1: {} throttleit@1.0.1: {}