I am playing with React Fiber and React Drei but i do not want to use Typescript like in the examples i have found in their git
I have converted the following example Stars.tsx with typescriptlang tool
This is the output
JavaScript
x
128
128
1
import React, { useState, useRef, useEffect, useMemo } from "react";
2
import { useFrame } from "@react-three/fiber";
3
import {
4
Points,
5
Vector3,
6
Spherical,
7
Color,
8
AdditiveBlending,
9
ShaderMaterial
10
} from "three";
11
12
class StarfieldMaterial extends ShaderMaterial {
13
constructor() {
14
super({
15
uniforms: { time: { value: 0.0 }, fade: { value: 1.0 } },
16
vertexShader: /* glsl */ `
17
uniform float time;
18
attribute float size;
19
varying vec3 vColor;
20
void main() {
21
vColor = color;
22
vec4 mvPosition = modelViewMatrix * vec4(position, 0.5);
23
gl_PointSize = size * (30.0 / -mvPosition.z) * (3.0 + sin(mvPosition.x + 2.0 * time + 100.0));
24
gl_Position = projectionMatrix * mvPosition;
25
}`,
26
fragmentShader: /* glsl */ `
27
uniform sampler2D pointTexture;
28
uniform float fade;
29
varying vec3 vColor;
30
void main() {
31
float opacity = 1.0;
32
if (fade == 1.0) {
33
float d = distance(gl_PointCoord, vec2(0.5, 0.5));
34
opacity = 1.0 / (1.0 + exp(16.0 * (d - 0.25)));
35
}
36
gl_FragColor = vec4(vColor, opacity);
37
38
#include <tonemapping_fragment>
39
#include <encodings_fragment>
40
}`
41
});
42
}
43
}
44
45
const genStar = (r) => {
46
return new Vector3().setFromSpherical(
47
new Spherical(
48
r,
49
Math.acos(1 - Math.random() * 2),
50
Math.random() * 2 * Math.PI
51
)
52
);
53
};
54
55
export const Stars = React.forwardRef(
56
(
57
{
58
radius = 10,
59
depth = 30,
60
count = 10,
61
saturation = 5,
62
factor = 4,
63
fade = false
64
},
65
ref
66
) => {
67
const material = useRef(StarfieldMaterial);
68
const [position, color, size] = useMemo(() => {
69
const positions = [];
70
const colors = [];
71
const sizes = Array.from(
72
{ length: count },
73
() => (5 + 5 * Math.random()) * factor
74
);
75
const color = new Color();
76
let r = radius + depth;
77
const increment = depth / count;
78
for (let i = 0; i < count; i++) {
79
r -= increment * Math.random();
80
positions.push(genStar(r).toArray());
81
color.setHSL(i / count, saturation, 0.9);
82
colors.push(color.r, color.g, color.b);
83
}
84
return [
85
new Float32Array(positions),
86
new Float32Array(colors),
87
new Float32Array(sizes)
88
];
89
}, [count, depth, factor, radius, saturation]);
90
useFrame(
91
(state) =>
92
material.current &&
93
(material.current.uniforms.time.value = state.clock.getElapsedTime())
94
);
95
const [starfieldMaterial] = useState(() => new StarfieldMaterial());
96
return React.createElement(
97
"points",
98
{ ref: ref },
99
React.createElement(
100
"bufferGeometry",
101
{ attach: "geometry" },
102
React.createElement("bufferAttribute", {
103
attachObject: ["attributes", "position"],
104
args: [position, 3]
105
}),
106
React.createElement("bufferAttribute", {
107
attachObject: ["attributes", "color"],
108
args: [color, 3]
109
}),
110
React.createElement("bufferAttribute", {
111
attachObject: ["attributes", "size"],
112
args: [size, 1]
113
})
114
),
115
React.createElement("primitive", {
116
dispose: undefined,
117
ref: material,
118
object: starfieldMaterial,
119
attach: "material",
120
blending: AdditiveBlending,
121
"uniforms-fade-value": fade,
122
transparent: true,
123
vertexColors: true
124
})
125
);
126
}
127
);
128
Then i have paste this Stars component in my codesandbox
The component is now commented at the row 28 of index.js because i get the following error
JavaScript
1
5
1
Error
2
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
3
4
Check the render method of `App`.
5
I do not understand exactly where the problems is with this error.
What is wrong with stars.js component that i have converted from typescript to javascript? How can i fix it?
Advertisement
Answer
Import the named Stars
, like:
JavaScript
1
2
1
import { Stars } from "./stars";
2
Working example: https://codesandbox.io/s/elegant-lumiere-1wf3uo