Skip to content

Commit

Permalink
add react example
Browse files Browse the repository at this point in the history
  • Loading branch information
ibon eskudero committed Jun 10, 2024
1 parent 9689f00 commit b590578
Show file tree
Hide file tree
Showing 6 changed files with 241 additions and 0 deletions.
101 changes: 101 additions & 0 deletions example/react/cubeWithDXF.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import React, { useRef, useEffect, useState } from 'react';
import { Scene, WebGLRenderer, OrthographicCamera, Box3, MOUSE, LinearToneMapping, SRGBColorSpace, Color } from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { DXFViewer } from '../../src/dxfViewer.js';

const CubeWithDXF = () => {
const canvasRef = useRef(null);
const [dxfData, setDxfData] = useState(null);
const [scene] = useState(new Scene());

useEffect(() => {

// renderer
const renderer = new WebGLRenderer({ canvas: canvasRef.current });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.outputColorSpace = SRGBColorSpace;
renderer.toneMapping = LinearToneMapping;
renderer.toneMappingExposure = 3;

// scene
scene.background = new Color( 0x212830 );

// camera
const size = 10000;
let aspect = canvasRef.current.offsetWidth / canvasRef.current.offsetHeight;
const camera = new OrthographicCamera( -size * aspect , size * aspect , size, -size, -size/2, size );

//controls
const controls = new OrbitControls( camera, renderer.domElement );
controls.zoomSpeed = 2;
controls.enableRotate = false;
controls.mouseButtons = {
LEFT: MOUSE.PAN,
MIDDLE: MOUSE.DOLLY,
RIGHT: MOUSE.PAN
};

// Animation loop
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}

function centerCamera() {
let box = new Box3().setFromObject( scene );

let bigAxis = box.max.x - box.min.x > box.max.y - box.min.y ? 'x' : 'y';
let size = bigAxis === 'x' ? box.max.x - box.min.x : box.max.y - box.min.y;
let sizeFrustum = bigAxis === 'x' ? camera.right - camera.left : camera.top - camera.bottom;

let lateralMargin = 0.9; //percentage of screento leave on the sides. 1 means no margin
if( size < sizeFrustum ) {
camera.zoom = lateralMargin * ( sizeFrustum / size );
camera.updateProjectionMatrix();
}
else
camera.zoom = 1;

let center = box.min.add( box.max.sub( box.min ).divideScalar( 2 ) );

camera.position.set( center.x , center.y, center.z + 100 );
controls.target.set( camera.position.x, camera.position.y, center.z );

camera.updateProjectionMatrix();
}

if( dxfData ) centerCamera();
animate();

return () => {
// Cleanup on unmount
renderer.dispose();
};
}, [dxfData]);

const handleFileChange = async (event) => {
const file = event.target.files[0];
const font = 'fonts/helvetiker_regular.typeface.json'; // Adjust font path if needed

try {
const dxf = await new DXFViewer().getFromFile(file, font);

// Add the DXF geometry to the scene
scene.add(dxf);

setDxfData(dxf);
} catch (error) {
console.error('Error loading DXF file:', error);
}
};

return (
<div>
<canvas ref={canvasRef} style={{ width: '100%', height: '100%' }} />
<input type="file" id="file" onChange={handleFileChange} />
</div>
);
};

export default CubeWithDXF;
46 changes: 46 additions & 0 deletions example/react/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#loading {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: black;
color: white;
opacity: 50%;
font-size: 5vh;
text-align: center;
padding-top: 15vh;
z-index: 1000;
display: none;
}

#headerTitle{
font-size: 25px;
font-weight: bold;
color: white;
text-align: center;
position: fixed;
top: 0;
top: 1vh;
left: 50%;
width: 24vh;
margin-left: -12vh;
z-index: 1;
}

#file{
position: fixed;
top: 1vh;
left: 1vh;
color: white;
font-size: 1.5vh;
z-index: 2;
}

#canvas3d {
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
}
21 changes: 21 additions & 0 deletions example/react/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>

<head>
<title>React scene</title>
<style type="text/css">
html,
body {
margin: 0;
padding: 0;
overflow: hidden
}
</style>
</head>

<body>
<div id="headerTitle"> Drop or Paste File </div>
<div id="root"></div>
</body>

</html>
11 changes: 11 additions & 0 deletions example/react/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import CubeWithDXF from './cubeWithDXF';

const root = ReactDOM.createRoot( document.getElementById('root') );
root.render(
<React.StrictMode>
<CubeWithDXF />
</React.StrictMode>
);
9 changes: 9 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"files": [ "dist" ],
"type": "module",
"scripts": {
"devr": "vite -c vite.dev.react.config.js --force",
"dev": "vite -c vite.dev.config.js --force",
"build": "vite -c vite.prod.config.js build",
"page": "vite -c vite.page.config.js build",
Expand All @@ -32,6 +33,14 @@
"eslint": "9.4.0",
"eslint-config-recommended": "4.1.0",
"eslint-plugin-import": "2.29.1",
"eslint-plugin-react": "7.34.2",
"eslint-plugin-react-hooks": "4.6.2",
"eslint-plugin-react-refresh": "0.4.7",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"@types/react": "18.3.3",
"@types/react-dom": "18.3.0",
"@vitejs/plugin-react": "4.3.0",
"lil-gui": "0.19.2"
},
"dependencies": {
Expand Down
53 changes: 53 additions & 0 deletions vite.dev.react.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { defineConfig } from 'vite';

import { createHtmlPlugin } from 'vite-plugin-html';
import { viteStaticCopy } from 'vite-plugin-static-copy';
import react from '@vitejs/plugin-react';
import dns from 'dns'

dns.setDefaultResultOrder('verbatim');

export default defineConfig( {
root: './example/react',
base: '',
server: {
port: 9009,
open: true
},
build: {
rollupOptions: {
input: {
main: 'index.html',
},
output: {
dir: 'dist',
entryFileNames: '[name].jsx',
assetFileNames: '[name].css',
chunkFileNames: 'chunk-[name].js',
manualChunks: undefined,
}
}
},
plugins: [
createHtmlPlugin( {
minify: true,
entry: 'index.jsx', //relative to root
template: 'index.html', //relative to root
inject: {
data: {
title: 'index',
injectScript: '<script src="./index.jsx"></script>',
}
},
} ),
viteStaticCopy( {
targets: [
{
src: '../fonts/helvetiker_regular.typeface.json', //RELATIVE TO ROOT
dest: 'fonts'
}
]
} ),
react()
]
} );

0 comments on commit b590578

Please sign in to comment.