Skip to content

Commit

Permalink
fix(troika-3d-ui): prevent sync of text nodes before flex layout fini…
Browse files Browse the repository at this point in the history
…shes

This prevents a flash of incorrectly-sized text, though it can still
give a flash of old text; that should also be fixed in the future. This
is preferable in the short term because by skipping the initial sync it
frees up the worker thread to more quickly complete the flex layout.
This is particularly noticeable when the text nodes are extremely large.
  • Loading branch information
lojjic committed Apr 16, 2020
1 parent 912f95c commit 4769cac
Showing 1 changed file with 15 additions and 4 deletions.
19 changes: 15 additions & 4 deletions packages/troika-3d-ui/src/facade/UITextNode3DFacade.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,23 @@ import { Text3DFacade } from 'troika-3d-text'
import { getInheritable } from '../uiUtils.js'

const flexLayoutTextProps = ['text', 'font', 'fontSize', 'lineHeight', 'letterSpacing', 'whiteSpace', 'overflowWrap']

const noop = () => {}

/**
* Wrapper for Text3DFacade that lets it act as a flex layout node. This shouldn't be used
* directly, but will be created as an implicit child by {@link UIBlock3DFacade} when
* configured with a `text` property.
*/
class UITextNode3DFacade extends Text3DFacade {
constructor (props) {
super(props)

// Override the sync method so we can have control over when it's called
let mesh = this.threeObject
mesh._actuallySync = mesh.sync
mesh.sync = noop
}

afterUpdate() {
// Read computed layout
const {
Expand All @@ -25,7 +34,6 @@ class UITextNode3DFacade extends Text3DFacade {
let parent = this.parentFlexNode
this.x = offsetLeft - parent.scrollLeft
this.y = -(offsetTop - parent.scrollTop)
this.maxWidth = offsetWidth

// Update clip rect based on parent
const clipRect = this.clipRect || (this.clipRect = [0, 0, 0, 0])
Expand All @@ -50,11 +58,14 @@ class UITextNode3DFacade extends Text3DFacade {
}
}

this.threeObject.visible = hasLayout

super.afterUpdate()
}

onAfterFlexLayoutApplied() {
this.threeObject.maxWidth = this.offsetWidth
this.threeObject._actuallySync(this._afterSync)
}

getBoundingSphere() {
return null //parent UIBlock3DFacade will handle bounding sphere and raycasting
}
Expand Down

0 comments on commit 4769cac

Please sign in to comment.