gdsestimating / three-dxf

A dxf viewer for the browser using three.js
MIT License
535 stars 170 forks source link

Unable to load ThreeDxf from the window object in React #63

Open niranjanshukla opened 3 years ago

niranjanshukla commented 3 years ago

I am trying to load the three-dxf script into my React app using below.

useEffect(() => {
    const script = document.createElement("script");
    script.type = 'text/javascript';
    script.src = '/dist/three-dxf.js';
    script.async = true;
    script.onload = () => scriptLoaded();

    document.getElementsByTagName('head')[0].appendChild(script);
  });

The above does not give any error, however, inside the scriptLoaded function, when I try to load the ThreeDxf object from the window object, it gives undefined, i.e.

window.ThreeDxf.Viewer(...) gives an error TypeError: Cannot read property 'Viewer' of undefined

Any idea why the window object does not contain ThreeDxf?

bzuillsmith commented 2 years ago

Sorry, I'm not familiar enough with react to have an immediate answer. I've been meaning to try to create a react sample so I can learn and have it available for people. If anyone wants to make a PR with a simple react sample, I'd happily merge it in.

puxiao commented 2 years ago
# the latest version of three: 0.133.1
yarn add three

yarn add dxf-parser
yarn add three-dxf

Hmm....


/node_modules/three-dxf/src/index.js

+ import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry'

// line: 570
- geometry = new THREE.TextGeometry(entity.text, { font: font, height: 0, size: entity.textHeight || 12 });

+ geometry = new TextGeometry(entity.text, { font: font, height: 0, size: entity.textHeight || 12 });

And...

import { FontLoader } from 'three/examples/jsm/loaders/FontLoader'

//@ts-ignore
import DxfParser from 'dxf-parser'

//@ts-ignore
- import { Viewer } from 'three-dxf'
+ import { Viewer } from 'three-dxf/src/index'


Demo:

import React, { useEffect } from 'react';
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader'
import axios from 'axios';

//@ts-ignore
import DxfParser from 'dxf-parser'

//@ts-ignore
import { Viewer } from 'three-dxf/src/index'

import './App.css';

function App() {

  useEffect(() => {

    const promise = axios.get('./dxf/demo.dxf')
    promise.then(response => {
      console.log('get file text')
      const fileText = response.data as string
      const parser = new DxfParser()
      try {
        const dxf = parser.parseSync(fileText)
        console.log(dxf)

        const cadViewDiv = document.getElementById('cad-view')
        const fontLoader = new FontLoader()
        fontLoader.load('./fonts/helvetiker_regular.typeface.json', (font) => {
          const cadCanvas = new Viewer(dxf, cadViewDiv, 800, 600, font)
          console.log(cadCanvas)
        })

      } catch (error) {
        console.log(error)
      }
    })
    promise.catch(error => {
      console.log(error)
    })

  }, [])

  return (
    <div id='cad-view'></div>
  );
}

export default App;

Please Note:

In the above example code, I use vite + react + typescript.

I tried to use 'create-react-app', but I encountered this error:

./node_modules/@dxfom/mtext/index.mjs 8:14
Module parse failed: Unexpected token (8:14)
File was processed with these loaders:
 * ./node_modules/react-scripts/node_modules/babel-loader/lib/index.js  
You may need an additional loader to handle the result of these loaders.


We know that the create-react-app uses weback4.

I think weback4 does not support it, but I haven't found a solution.

Therefore, there are only two solutions: use webpack5 or vite

595624187 commented 1 year ago

I've the same problem ,I hope the author could solve it.