Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating Text content #62

Closed
n1ru4l opened this issue Jul 22, 2020 · 12 comments
Closed

Updating Text content #62

n1ru4l opened this issue Jul 22, 2020 · 12 comments

Comments

@n1ru4l
Copy link

n1ru4l commented Jul 22, 2020

I have the following node:

<Text
  anchorX="center"
  anchorY="middle"
  fontSize={0.8 * initialRadius}
  color="black"
  font={buildUrl("/fonts/Roboto-Bold.ttf")}
>
  {props.textLabel}
</Text>

When the text changes I only see the first character of the new text appearing. The other ones are invisible, the character is still positioned as if the other characters would be present.

When adding a key property to the Text element with the contents of the props.textLabel this issue is resolved. However, I assume this is some kind of a bug and changing the children text should update the text without having to set a key.

Example:

IMG_B45935046C3F-1

The purple token text has been updated from B to asdas

@n1ru4l
Copy link
Author

n1ru4l commented Jul 22, 2020

@drcmda
Copy link
Member

drcmda commented Jul 22, 2020

the way text works internally is a bit unfortunate. in threejs mutation and cloning is normal, but in reacts immutable world that causes problems. this component seems to have some trouble updating. anyway, i have refreshed dependencies and published a new patch.

@n1ru4l
Copy link
Author

n1ru4l commented Jul 22, 2020

Okay I updated to 0.0.64 and now I have the issue that the other texts disappear when changing another text.

@drcmda
Copy link
Member

drcmda commented Jul 22, 2020

could you try with plain troika and see if you figure out a solution?

this is the wrap that drei publishes

import React, { Children, createElement, forwardRef, useMemo, useRef, useLayoutEffect, useState } from 'react'
import { Text as TextMeshImpl } from 'troika-three-text'
import { extend } from 'react-three-fiber'
import mergeRefs from 'react-merge-refs'

extend({ TextMeshImpl })

export const Text = forwardRef(({ anchorX = 'center', anchorY = 'middle', children, ...props }, ref) => {
  const textRef = useRef()
  const [baseMtl, setBaseMtl] = useState()
  const [nodes, text] = useMemo(() => {
    let n: React.ReactNode[] = []
    let t = ''
    Children.forEach(children, (child) => {
      if (typeof child === 'string') t += child
      else if (child && typeof child === 'object' && child.props.attach === 'material') {
        // Instantiate the base material and grab a reference to it, but don't assign any
        // props, and assign it as the `material`, which Troika will replace behind the scenes.
        n.push(createElement(child.type, { ref: setBaseMtl, attach: 'material' }))
        // Once the base material has been assigned, grab the resulting upgraded material,
        // and apply the original material props to that.
        if (baseMtl) {
          n.push(<primitive object={textRef.current.material} {...child.props} attach={null} />)
        }
      } else n.push(child)
    })
    return [n, t]
  }, [children, baseMtl])
  useLayoutEffect(() => void textRef.current.sync())

  return (
    <textMeshImpl ref={mergeRefs([textRef, ref])} text={text} anchorX={anchorX} anchorY={anchorY} {...props}>
      {nodes}
    </textMeshImpl>
  )
})

As you see it's all a little unusual, troika clones the material initially so the original becomes stale. i guess it must be something similar when you update text.

you could copy this into a local file for testing. if you find something a PR would be very welcome!

@n1ru4l
Copy link
Author

n1ru4l commented Jul 22, 2020

I also get the following warning on chrome when the text is updated for the first time:

WebGL: INVALID_OPERATION: drawElementsInstanced: no buffer is bound to enabled attribute
renderInstances @ three.module.js:16994
WebGLRenderer.renderBufferDirect @ three.module.js:25564
renderObject @ three.module.js:25993
renderObjects @ three.module.js:25965
WebGLRenderer.render @ three.module.js:25766
renderGl @ web.js:70
(anonymous) @ web.js:85
renderLoop @ web.js:82
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
requestAnimationFrame (async)
renderLoop @ web.js:89
WebGL: too many errors, no more errors will be reported to the console for this context.
requestAnimationFrame (async)
renderLoop @ web.js:89
three.module.js:16994 WebGL: too many errors, no more errors will be reported to the console for this context.

@n1ru4l
Copy link
Author

n1ru4l commented Jul 22, 2020

Cannot reproduce it either -.- https://codesandbox.io/s/troika-3d-text-via-react-three-fiber-94sv3?file=/src/index.js

The text disappearing also only happens to the (text) element that has been added last to the scene

@n1ru4l
Copy link
Author

n1ru4l commented Jul 22, 2020

Maybe @lojjic has an idea

@lojjic
Copy link
Contributor

lojjic commented Jul 22, 2020

@n1ru4l Thanks -- I'm able to reproduce the new bug in your codesandbox, if I make the text length change on update.

This is definitely related to my attempted fix/workaround in protectwise/troika#69. Three.js changed some internals that broke how I update the geometries, and it looks like my attempted workaround caused this new disappearing text bug. I will fix it and publish a patch release ASAP.

@n1ru4l
Copy link
Author

n1ru4l commented Jul 22, 2020

@lojjic awesome 😍 thanks for the fast response!

lojjic added a commit to protectwise/troika that referenced this issue Jul 22, 2020
…a GlyphsGeometry

Followup fix for #69, reported in pmndrs/drei#62

We were reusing the common plane BufferAttributes across GlyphsGeometry
instances, which used to work but as of Three r118 now throws an error
about unbound buffers when one of the geometries is disposed. We now
clone all the base plane attributes, which keeps things isolated at the
expense of redundancy. Thankfully those attributes are usually very
small so it's not a huge amount of duplicated data.
@lojjic
Copy link
Contributor

lojjic commented Jul 22, 2020

OK, troika-three-text 0.30.2 should fix the disappearing text issue.

@n1ru4l
Copy link
Author

n1ru4l commented Jul 22, 2020

@lojjic Yes it works as expected 🎉 After bumping the version here to 0.30.2 I think we can close this issue! @drcmda Could you push the v0.0.64 changes? Then I could create a pull request for bumping the version

@n1ru4l
Copy link
Author

n1ru4l commented Aug 6, 2020

@n1ru4l n1ru4l closed this as completed Aug 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants