UNPKG

3d-tiles-renderer

Version:

https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/specification

132 lines (89 loc) 2.55 kB
import { useContext, useState, useEffect, useMemo } from 'react'; import { TilesRendererContext } from './TilesRenderer.jsx'; import { CanvasDOMOverlay } from './CanvasDOMOverlay.jsx'; function randomID() { return crypto.getRandomValues( new Uint32Array( 1 ) )[ 0 ].toString( 16 ); } // Overlay for displaying tile data set attributions export function TilesAttributionOverlay( { children, style, generateAttributions, ...rest } ) { const tiles = useContext( TilesRendererContext ); const [ attributions, setAttributions ] = useState( [] ); // Add events for checking when attributions may be updated useEffect( () => { if ( ! tiles ) { return; } let queued = false; const callback = () => { if ( ! queued ) { queued = true; queueMicrotask( () => { setAttributions( tiles.getAttributions() ); queued = false; } ); } }; tiles.addEventListener( 'tile-visibility-change', callback ); tiles.addEventListener( 'load-tile-set', callback ); return () => { tiles.removeEventListener( 'tile-visibility-change', callback ); tiles.removeEventListener( 'load-tile-set', callback ); }; }, [ tiles ] ); // Generate CSS for modifying child elements implicit to the html attributions const classId = useMemo( () => 'class_' + randomID(), [] ); const styles = useMemo( () => ` #${ classId } a { color: white; } #${ classId } img { max-width: 125px; display: block; margin: 5px 0; } `, [ classId ] ); let output; if ( generateAttributions ) { output = generateAttributions( attributions, classId ); } else { // generate elements for each type of attribution const elements = []; attributions.forEach( ( att, i ) => { let element = null; if ( att.type === 'string' ) { element = <div key={ i }>{ att.value }</div>; } else if ( att.type === 'html' ) { element = <div key={ i } dangerouslySetInnerHTML={ { __html: att.value } } style={ { pointerEvents: 'all' } }/>; } else if ( att.type === 'image' ) { element = <div key={ i }><img src={ att.value } /></div>; } if ( element ) { elements.push( element ); } } ); output = ( <> <style>{ styles }</style> { elements } </> ); } return ( <CanvasDOMOverlay id={ classId } style={ { position: 'absolute', bottom: 0, left: 0, padding: '10px', color: 'rgba( 255, 255, 255, 0.75 )', fontSize: '10px', ...style, } } { ...rest } > { children } { output } </CanvasDOMOverlay> ); }