vagran / dxf-viewer-example-src

Source for dxf-viewer-example GitHub pages repository
MIT License
47 stars 27 forks source link

A WebGL context could not be created. in React.js + Typescript #13

Closed dotoritos-kim closed 1 year ago

dotoritos-kim commented 1 year ago

THREE.WebGLRenderer: A WebGL context could not be created. Reason: Canvas has an existing context of a different type

The error occurs about here. DxfViewer.js

        renderer.setSize(this.canvasWidth, this.canvasHeight)

        this.canvas = renderer.domElement
        this.canvas.getContext("webgl", { premultipliedAlpha: false }) <--
        domContainer.style.display = "block"
        if (options.autoResize) {
            this.canvas.style.position = "absolute"
            this.resizeObserver = new ResizeObserver(entries => this._OnResize(entries[0]))
            this.resizeObserver.observe(domContainer)
        }
vagran commented 1 year ago

Hello, Please ensure your code does not occupy the same canvas context, creating it with differrent type. For example, you may have a code which obtains the same canvas context by canvas.getContext('2d') thus creating there 2D drawing context while the viewer needs WebGL context.

dotoritos-kim commented 1 year ago

index.tsx file

const TestCanvas= () => {
    const [canvasWidth, setCanvasWidth] = useState(
        document.documentElement.offsetWidth,
    );
    const [canvasHeight, setCanvasHeight] = useState(
        document.documentElement.offsetHeight,
    );

    const dispatch = useDispatch();
    const { title } = useSelector((state: RootState) => state.siteSetting);

    useEffect(() => {
        dispatch(commitSiteTitle({ title: '캔버스', url: '/viewer/canvas' }));
    }, [dispatch]);

    const canvasRef = document.getElementById('canvasContainer');

    useEffect(() => {
        if (canvasRef) {
            const dxfViewer = new DxfViewer(canvasRef, {
                canvasWidth: canvasWidth,
                canvasHeight: canvasHeight,
                autoResize: true,
                clearColor: new Three.Color('#fff'),
                clearAlpha: 1,
                canvasAlpha: true,
                canvasPremultipliedAlpha: true,
                antialias: true,
                colorCorrection: true,
                blackWhiteInversion: false,
                pointSize: 2,
                sceneOptions: {
                    /** Target angle for each segment of tessellated arc. */
                    arcTessellationAngle: (10 / 180) * Math.PI,
                    /** Divide arc to at least the specified number of segments. */
                    minArcTessellationSubdivisions: 8,
                    /** Render meshes (3DFACE group) as wireframe instead of solid. */
                    wireframeMesh: false,
                    /** Text rendering options. */
                    textOptions: {
                        curveSubdivision: 2,
                        /** Character to use when the specified fonts does not contain necessary glyph. Several ones can
                         * be specified, the first one available is used.
                         */
                        fallbackChar: '\uFFFD?',
                    },
                },
            });
            DxfViewer.SetupWorker();
            dxfViewer.Load({
                url: `https://cadview-media.connectforyouserver.net/flange.dxf`,
                fonts: null,
                progressCbk: (phase, size, total) => {},
                workerFactory: null,
            });
            const Subscribe = (eventName: string) => {
                dxfViewer.Subscribe(eventName, (e) => {
                    console.log(e);
                });
            };
            const events: EventName = [
                'loaded',
                'cleared',
                'destroyed',
                'resized',
                'pointerdown',
                'pointerup',
                'viewChanged',
                'message',
            ] as unknown as EventName;
            for (const eventName of events) {
                Subscribe(eventName);
            }
            dxfViewer.GetLayers();
        }
    }, [canvasRef]);

    return <div id="canvasContainer" className="canvasContainer"></div>;
};
export default TestCanvas;

I wrote and tested the source code as above.

vagran commented 1 year ago

Sorry, just re-checked it and found this error on the deployed demo as well. Seems this issue was made visible by recent changes in three.js, this was not visible before. I have removed context access in DxfViewer code, which does not look necessary anymore. Fix is available in version 1.0.20 which was just published.