/docs/examples/sierpinski.html
https://github.com/thysultan/dio.js · HTML · 105 lines · 91 code · 14 blank · 0 comment · 0 complexity · c3af438ac724ed07e6211439beb309a8 MD5 · raw file
- <!doctype html>
- <html>
- <head>
- <meta charset=utf-8>
- <meta http-equiv=X-UA-Compatible content=IE=edge>
- <meta name=viewport content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
- <title>Sierpinski Triangle</title>
- <script src=https://unpkg.com/dyo></script>
- </head>
- <body>
- <main></main>
- <style>
- html {width: 100%; height: 100%; overflow: hidden}
- </style>
- <script>
- const {h, memo, render, Fragment, useState, useEffect} = dyo
- const start = performance.now()
- const target = document.querySelector('main')
- const dotStyle = {
- position: 'absolute',
- background: '#61dafb',
- font: 'normal 15px sans-serif',
- textAlign: 'center',
- cursor: 'pointer',
- }
- const containerStyle = {
- position: 'absolute',
- transformOrigin: '0 0',
- left: '50%',
- top: '50%',
- width: '10px',
- height: '10px',
- background: '#eee',
- }
- const targetSize = 25
- const Dot = ({x, y, size, text}) => {
- const [{hover}, setState] = useState({hover: false})
- const s = size * 1.3
- return (
- h('div', {
- style: {
- ...dotStyle,
- width: s + 'px',
- height: s + 'px',
- left: x + 'px',
- top: y + 'px',
- borderRadius: (s / 2) + 'px',
- lineHeight: s + 'px',
- background: hover ? '#ff0' : dotStyle.background
- },
- onMouseEnter: () => setState({hover: true}),
- onMouseLeave: () => setState({hover: false})
- },
- hover ? '*' + text + '*' : text
- )
- )
- }
- const Triangle = ({x, y, s, children}) => {
- if (s <= targetSize) {
- return h(Dot, {x: x - (targetSize / 2), y: y - (targetSize / 2), size: targetSize, text: children})
- }
- s /= 2
- return h(Fragment, {},
- h(Triangle, {x: x, y: y - (s / 2), s: s}, children),
- h(Triangle, {x: x - s, y: y + (s / 2), s: s}, children),
- h(Triangle, {x: x + s, y: y + (s / 2), s: s}, children)
- )
- }
- const Main = ({elapsed}) => {
- const [{seconds}, setState] = useState({seconds: 0})
- useEffect(() => {
- const interval = setInterval(() => {
- setState(state => ({seconds: (state.seconds % 10) + 1}))
- }, 1000)
- return () => {
- clearInterval(interval)
- }
- }, [])
- const t = (elapsed / 200) % 10
- const scale = 1 + (t > 5 ? 10 - t : t) / 10
- return h('div', {style: {...containerStyle, transform: 'scaleX(' + (scale / 2.1) + ') scaleY(0.7) translateZ(0.1px)'}},
- h('div', {}, h(Triangle, {x: 0, y: 0, s: 1000}, seconds))
- )
- }
- requestAnimationFrame(function update (now) {
- render(h(Main, {elapsed: now - start}), document)
- requestAnimationFrame(update)
- })
- </script>
- </body>
- </html>