Skip to content

Commit

Permalink
Sierpinski Triangle Demo
Browse files Browse the repository at this point in the history
Adds some debug information to ReactDOMFiber
  • Loading branch information
sebmarkbage committed Aug 10, 2016
1 parent 32af6b2 commit a535ee3
Show file tree
Hide file tree
Showing 2 changed files with 169 additions and 19 deletions.
133 changes: 121 additions & 12 deletions examples/fiber/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,135 @@ <h1>Fiber Example</h1>
</div>
<script src="../../build/react.js"></script>
<script src="../../build/react-dom-fiber.js"></script>
<script>
function ExampleApplication(props) {
var elapsed = Math.round(props.elapsed / 100);
var seconds = elapsed / 10 + (elapsed % 10 ? '' : '.0' );
var message =
'React has been successfully running for ' + seconds + ' seconds.';
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
<script type="text/babel">

var dotStyle = {
position: 'absolute',
background: '#61dafb',
font: 'normal 15px sans-serif',
textAlign: 'center',
cursor: 'pointer',
};

var containerStyle = {
position: 'absolute',
transformOrigin: '0 0',
left: '50%',
top: '50%',
width: '10px',
height: '10px',
background: '#eee',
};

var targetSize = 25;

return React.DOM.p(null, message);
function updateSelection(idx) {
// TODO
}

// Call React.createFactory instead of directly call ExampleApplication({...}) in React.render
var ExampleApplicationFactory = React.createFactory(ExampleApplication);
function Dot(props) {
var s = props.size;
var idx = props.idx;
var style = {
...dotStyle,
width: s + 'px',
height: s + 'px',
left: (props.x) + 'px',
top: (props.y) + 'px',
borderRadius: (s / 2) + 'px',
lineHeight: (s) + 'px',
// background: idx === hoveredIdx ? '#ff0' : dotStyle.background
};
return (
<div style={style} onMouseEnter={() => updateSelection(idx)}>
{props.text}
</div>
);
}

class SierpinskiTriangle extends React.Component {
shouldComponentUpdate(newProps) {
var o = this.props;
var n = newProps;
return !(
o.x === n.x &&
o.y === n.y &&
o.s === n.s &&
o.idx === n.idx &&
o.depth === n.depth &&
o.hover === n.hover &&
o.children === n.children
);
}
render() {
var { x, y, s, idx, depth, hover, children } = this.props;
if (s <= targetSize) {
return (
<Dot
x={x - (targetSize / 2)}
y={y - (targetSize / 2)}
size={targetSize}
text={children}
idx={idx}
hover={hover}
/>
);
}
var newSize = s / 2;
// Artificially long execution time.
s = 0;
while (s < 100000) {
s++;
}
if (s > newSize) {
s = newSize;
}

return [
<SierpinskiTriangle x={x} y={y - (s / 2)} s={s}>
{children}
</SierpinskiTriangle>,
<SierpinskiTriangle x={x - s} y={y + (s / 2)} s={s}>
{children}
</SierpinskiTriangle>,
<SierpinskiTriangle x={x + s} y={y + (s / 2)} s={s}>
{children}
</SierpinskiTriangle>,
];
}
}

function ExampleApplication(props) {
var seconds = (props.elapsed / 1000) % 10;
var scale = 1 + (seconds > 5 ? 10 - seconds : seconds) / 10;
var transform = 'scale(' + (scale / 2.1) + ') translateZ(0.1px)';
var lowPriChildren = true; // change this to false to see the effect

return (
<div style={{ ...containerStyle, transform }}>
<div hidden={lowPriChildren}>
<SierpinskiTriangle x={0} y={0} s={1000} idx={0}>
{'' + Math.floor(seconds)}
</SierpinskiTriangle>
</div>
</div>
);
}

var start = new Date().getTime();
setInterval(function() {
var f = 0;
function update() {
// ReactDOMFiber.dumpTree();
ReactDOMFiber.render(
ExampleApplicationFactory({elapsed: new Date().getTime() - start}),
<ExampleApplication elapsed={new Date().getTime() - start} />,
document.getElementById('container')
);
}, 50);
//if (f++ < 5) {
requestAnimationFrame(update);
// }
}
requestAnimationFrame(update);
</script>
</body>
</html>
55 changes: 48 additions & 7 deletions src/renderers/dom/fiber/ReactDOMFiber.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,37 +39,76 @@ function recursivelyAppendChildren(parent : Element, child : HostChildren<Instan
}
}

var COLORS = ["#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd", "#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf"];

var DOMRenderer = ReactFiberReconciler({

updateContainer(container : Container, children : HostChildren<Instance>) : void {
if (container.firstChild === children && container.lastChild === children) {
// Rudimentary bail out mechanism.
return;
}
container.innerHTML = '';
recursivelyAppendChildren(container, children);
},

createInstance(type : string, props : Props, children : HostChildren<Instance>) : Instance {
const domElement = document.createElement(type);
recursivelyAppendChildren(domElement, children);
if (typeof props.style === 'object') {
Object.assign(domElement.style, props.style);
}
if (typeof props.onMouseEnter === 'function') {
domElement.addEventListener('mouseenter', props.onMouseEnter);
}
if (typeof props.onMouseLeave === 'function') {
domElement.addEventListener('mouseleave', props.onMouseLeave);
}
if (typeof props.children === 'string') {
domElement.textContent = props.children;
return domElement;
}
domElement.innerHTML = '';
recursivelyAppendChildren(domElement, children);
return domElement;
},

prepareUpdate(
domElement : Instance,
oldProps : Props,
newProps : Props,
domElement : Instance,
oldProps : Props,
newProps : Props,
children : HostChildren<Instance>
) : boolean {
/*
Visualize the reconciliation
*/
if (typeof newProps.children === 'string') {
var c = +newProps.children;
// console.log('prepare', c);
if (!isNaN(c)) {
domElement.style.background = COLORS[c];
}
}
return true;
},

commitUpdate(domElement : Instance, oldProps : Props, newProps : Props, children : HostChildren<Instance>) : void {
domElement.innerHTML = '';
recursivelyAppendChildren(domElement, children);
if (typeof newProps.style === 'object') {
Object.assign(domElement.style, newProps.style);
}
if (typeof newProps.children === 'string') {
// console.log('commit', newProps.children);
domElement.textContent = newProps.children;
return;
}
if (children && (domElement.firstChild === children || domElement.firstChild === children.output)) {
// Rudimentary bail out mechanism.
return;
}
if (domElement.firstChild) {
return;
}
domElement.innerHTML = '';
recursivelyAppendChildren(domElement, children);
},

deleteInstance(instance : Instance) : void {
Expand All @@ -82,11 +121,13 @@ var DOMRenderer = ReactFiberReconciler({

});

var root = null;

var ReactDOM = {

render(element : ReactElement<any>, container : DOMContainerElement) {
if (!container._reactRootContainer) {
container._reactRootContainer = DOMRenderer.mountContainer(element, container);
container._reactRootContainer = root = DOMRenderer.mountContainer(element, container);
} else {
DOMRenderer.updateContainer(element, container._reactRootContainer);
}
Expand Down

0 comments on commit a535ee3

Please sign in to comment.