-
Notifications
You must be signed in to change notification settings - Fork 58
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
eliminate the flickering when re-evaluating code in an iFrame. #188
Comments
It appears this could be implemented entirely within the https://github.com/enjalot/blockbuilder/blob/master/public/js/components/renderer.js#L89 |
Here's the React implementation we're using in Datavis.tech: import React, { Component } from 'react'
import magicSandbox from 'magic-sandbox'
// Z Indices for layering iframe buffers.
const BACK = 4
const FRONT = 5
const defaultUpdateInterval = 300
// This "dumb" component runs the code for a visualization in an iframe.
export default class RunnerRenderer extends Component {
constructor (props) {
super(props)
const updateInterval = props.updateInterval || defaultUpdateInterval
this.contentChanged = true
this.swapped = true
this.interval = setInterval(() => {
if (this.iFrameRefA && this.iFrameRefB) {
if (this.needsBufferSwap) {
this.swapBuffers()
this.needsBufferSwap = false
}
if (this.contentChanged) {
this.updateBackBuffer()
this.needsBufferSwap = true
this.contentChanged = false
}
}
}, updateInterval)
}
swapBuffers () {
this.swapped = !this.swapped
this.backBuffer().style.zIndex = BACK
this.frontBuffer().style.zIndex = FRONT
}
updateBackBuffer () {
const {template, files} = this.props
const srcDoc = magicSandbox(template, files)
this.backBuffer().setAttribute('srcDoc', srcDoc)
}
backBuffer () {
return this.swapped ? this.iFrameRefA : this.iFrameRefB
}
frontBuffer () {
return this.swapped ? this.iFrameRefB : this.iFrameRefA
}
componentWillUnmount () {
clearInterval(this.interval)
}
shouldComponentUpdate (nextProps) {
this.contentChanged = true
return false
}
render () {
const width = '100%'
const height = '500'
const style = { position: 'absolute', top: '0px', left: '0px' }
return (
<div style={{position: 'relative', height: height + 'px'}} >
<iframe
ref={el => { this.iFrameRefA = el }}
style={style}
width={width}
height={height}
scrolling='no'
/>
<iframe
ref={el => { this.iFrameRefB = el }}
style={style}
width={width}
height={height}
scrolling='no'
/>
</div>
)
}
} |
thanks for sharing this @curran 😄 would be happy to review a PR to add this improvement if you'd like to contribute it in that form 😄 |
I'm noticing Blockbuilder handles the rendering if the iFrame a bit differently, using a Blob source URL rather than setting |
curran/example-viewer#12
https://curran.github.io/d3-in-motion/#1/1/11
The text was updated successfully, but these errors were encountered: