I'm trying to render a 3D avatar using react-three-fiber and React, but I'm experiencing some difficulties with positioning the avatar. As you can see from from the following CodeSandbox https://codesandbox.io/s/vigorous-ardinghelli-ypwjsb?file=/pages/index.js, the top of the avatar's head is not visible when you first render the page. However, if you change the position of the model (e.g. from [0.025, -0.9, 1] to [0.025, -1, 1]) and re-render the page, suddenly the avatar is showing correctly. Why is that?
Reposting the solution I got from a Reddit user:
it looks like the keyframe track actions["Armature|mixamo.com|Layer0"].play() pushes the model up and down.
i reexported the model
npx gltfjsx model.glb --keepnames
https://codesandbox.io/s/interesting-lewin-rnq66m?file=/pages/index.js and that seems to do it. it should preserve names by default when animations are present, i don't get why it's omitting them. but either way, it works.
should be fixed upstream (gltfjsx) as well now. another export should include names
Related
I currently have a Radar chart in chart.js using the react integration.
I was suprised to note that, when I updated the data, instead of showing a completely new plot, it just transitioned smoothly from the previous dataset to the new one.
What I am interested in is to understand how it works under the hood, which honestly I can't understand, at least from looking at the code.
First: my understanding of React is that, when a prop or state changes, it computes the new DOM, and then merges the new DOM and the current DOM, applying only the difference between the two. However, chartjs seem to be implemented as a Canvas element.
The chartjs integration with react does not do much. Taking the Radar plot, this is what it does
export const Radar = /* #__PURE__ */ createTypedChart('radar', RadarController);
which is nothing but declare a <Chart> element and leave it to ChartJS to plot it. In fact, in ChartJS, we have this code, which basically manages the Canvas element and it is smart to perform transitions using animations and so on. This I understand (relatively): a lot of animation and transition helper functions, but this makes sense to me. However, this part is pure JavaScript. There's nothing that is aware of React.
What does not make sense is therefore how the react synchronization system is integrated with this JavaScript library so that the state invalidation of the props/state is synchronised to an animation, instead of a complete rewrite of the Canvas element. I don't seem to find where this magic happens in react-chartjs-2.
As you explained the canvas element does not get changed so it gets reused. To animate the chart chart.js itself has an update method. React-chartjs-2 uses a useeffect function that checks if the data you pass it has changed. If this is the case it calls the update function from chart.js itself and they handle the animations and updates itself:
useEffect(() => {
if (!chartRef.current) return;
if (redraw) {
destroyChart();
setTimeout(renderChart);
} else {
chartRef.current.update();
}
}, [redraw, options, data.labels, data.datasets]);
https://github.com/reactchartjs/react-chartjs-2/blob/4a010540ac01b1e4b299705ddd93f412df4875d1/src/chart.tsx#L78-L87
This is my understanding of the whole process after diving into the code base quite a bit. I've tried to be as detailed as possible with links to the exact line of code I am talking about. Hope this helps:
Beginning with the code snippet you shared:
export const Radar = /* #__PURE__ */ createTypedChart('radar', RadarController);
If you follow the RadarController via the import statement, you see that it is fetched from chart.js
Now we move to the Chart.js code and look for this controller RadarController. It is found in a file called src/controllers/controller.radar.js.
Within that file, you see an update function
This function then calls updateElements with the points information
This function gets the new point position which is then set in properties and passed into the updateElement function
This updateElement function directly takes us to the core.datasetController
Here you see a condition to check if the chart is in directUpdateMode. If not, it calls a function to _resolveAnimations
Within this function, you will see the new Animations(args) object
This eventually brings us to the core.animations file which consists of all the animation related information and processing.
One interesting bit I found here was: this is what seems to be making the beautiful movement of points to the changed location.
You can explore this Animations class further for more detailed understanding
So yeah essentially, it is the js part under the hood that facilitates the smooth transitions and this is how it does it. React code is essentially just like a wrapper of Chart.js calling this update method with the new values.
You can see here: https://github.com/reactchartjs/react-chartjs-2/blob/master/src/chart.tsx
The react-chartjs-2 library creates a component that adds a canvas and when the props update the component creates/updates an internal Chart object that uses the rendered canvas.
From what I saw the animation starts when the props are changed.
The path is props->react-chartjs-2 component->chart object->animation
I currently have a React page with multiple images that are based on an array of minutes that make up a total time period: [15, 10, 15, 5]. The images depict a bar graph, that shows the current period in light blue and the previous periods in dark blue:
Currently the images are hard coded but I am trying to use D3 to dynamically generate them. I can do it in a unit using SVG but when I try to insert it into React it's giving me problems. Each image needs the overall minute array to show the correct information. I have the array in a props variable at the high level of the page component. I have tried to create a component based on the D3 component I programmed but I can't figure out how to append SVG elements in React. Before, I could append an "svg" onto "body" but I can't do that in React.
I've tried to follow this guide:
https://react-d3-library.github.io
I have my D3 component in a file called ChunkGraph.js.
But in that react-d3-library guide it imports node (a DOM element) from the D3 file, which gives me a compile error when I try it.
EDIT: Figured it out... for anyone who comes after and needs to know... useRef is the key here, to form a dynamic link between react and your d3 element. react-d3-library isn't needed.
We are developing a huge application with React. One of our forms includes 60+ plus components placed on different Tab items.
When i try to edit an input it took 190ms to see typed chars in the textbox. After digging the problem for hours we realized adding a component increases the response time. Then we decided that the problem is antdesign s render logic. Then we tried it with PrimeReact using "why-did-you-update" package. The result was same!
When any change occurred in the state, all the components ( including Icons :) ) tried to render per "why-did-you-update" messages.
Here is the sandbox : https://codesandbox.io/s/6w30ro2l9w
Are the "why-did-you-update" messages wrong or we missing something?
I have an issue with my images in react. When i let the image render like this:
import road from '../../../../assets/images/icons/road.png';
<img src={road} />
It will work but i want it to be dynamic relying on the input of data.
So i tried it this way (where icon is refering to a data set resulting in road):
import road from '../../../../assets/images/icons/road.png';
...
render() {
const { place, date, icon, progress } = this.props.stage;
...
<img src={icon} />
So my guess is that there is an issue with referencing here. From my question you can understand that i am absolutely new to react. What i also noticed is that with the method above i will get an unused var error if i dont load this image. So for example i have a couple of these icons but depending on the data in the dataset it will only render a few. Which i find kind of messy.
I hope you can steer me towards the right direction. Kinda frustrating not being able to implement an image...
With this: Load images based on dynamic path in ReactJs
posted from Subham Khatri i was able to get the answer i desired.
<img src={require(`../../../../assets/images/icons/${icon}.png)`} />
As I understand you are trying to pass the image from this.props.stage. Did you first try console.log(icon). what do you see in the console window. First we need to know whether the data is being passed from props.
I've added React, React-DOM, and React Addons library to my pen.
Here's my pen:
https://codepen.io/graven_whismas/pen/QBQQmj
On clicking the button, the word in state should appear, from initial opacity of 0.4 to 1.
But as I click the button, all the content on the page disappears.
This is the error I get:
https://reactjs.org/docs/error-decoder.html?invariant=254&args[]=.0
There's a few things wrong with the code in your pen that will bring about the problem you are having.
The first step is to use the development versions of the libraries, in order to get better error messages. Use https://cdnjs.cloudflare.com/ajax/libs/react/15.4.1/react-with-addons.js instead of https://cdnjs.cloudflare.com/ajax/libs/react/15.4.1/react-with-addons.min.js.
Second, loading several versions of React can cause the issue your are having. Remove https://cdnjs.cloudflare.com/ajax/libs/react/16.4.1/umd/react.production.min.js from the list of external scripts you are loading.
Thirdly, there is a typo when you specify the leave timeout of the animation. You have written transtionLeaveTimeout, where it should be transitionLeaveTimeout. With this type, the transition library will complain about a missing property.
This CodePen summarizes the changes you need to make.