/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

  1. <!doctype html>
  2. <html>
  3. <head>
  4. <meta charset=utf-8>
  5. <meta http-equiv=X-UA-Compatible content=IE=edge>
  6. <meta name=viewport content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  7. <title>Sierpinski Triangle</title>
  8. <script src=https://unpkg.com/dyo></script>
  9. </head>
  10. <body>
  11. <main></main>
  12. <style>
  13. html {width: 100%; height: 100%; overflow: hidden}
  14. </style>
  15. <script>
  16. const {h, memo, render, Fragment, useState, useEffect} = dyo
  17. const start = performance.now()
  18. const target = document.querySelector('main')
  19. const dotStyle = {
  20. position: 'absolute',
  21. background: '#61dafb',
  22. font: 'normal 15px sans-serif',
  23. textAlign: 'center',
  24. cursor: 'pointer',
  25. }
  26. const containerStyle = {
  27. position: 'absolute',
  28. transformOrigin: '0 0',
  29. left: '50%',
  30. top: '50%',
  31. width: '10px',
  32. height: '10px',
  33. background: '#eee',
  34. }
  35. const targetSize = 25
  36. const Dot = ({x, y, size, text}) => {
  37. const [{hover}, setState] = useState({hover: false})
  38. const s = size * 1.3
  39. return (
  40. h('div', {
  41. style: {
  42. ...dotStyle,
  43. width: s + 'px',
  44. height: s + 'px',
  45. left: x + 'px',
  46. top: y + 'px',
  47. borderRadius: (s / 2) + 'px',
  48. lineHeight: s + 'px',
  49. background: hover ? '#ff0' : dotStyle.background
  50. },
  51. onMouseEnter: () => setState({hover: true}),
  52. onMouseLeave: () => setState({hover: false})
  53. },
  54. hover ? '*' + text + '*' : text
  55. )
  56. )
  57. }
  58. const Triangle = ({x, y, s, children}) => {
  59. if (s <= targetSize) {
  60. return h(Dot, {x: x - (targetSize / 2), y: y - (targetSize / 2), size: targetSize, text: children})
  61. }
  62. s /= 2
  63. return h(Fragment, {},
  64. h(Triangle, {x: x, y: y - (s / 2), s: s}, children),
  65. h(Triangle, {x: x - s, y: y + (s / 2), s: s}, children),
  66. h(Triangle, {x: x + s, y: y + (s / 2), s: s}, children)
  67. )
  68. }
  69. const Main = ({elapsed}) => {
  70. const [{seconds}, setState] = useState({seconds: 0})
  71. useEffect(() => {
  72. const interval = setInterval(() => {
  73. setState(state => ({seconds: (state.seconds % 10) + 1}))
  74. }, 1000)
  75. return () => {
  76. clearInterval(interval)
  77. }
  78. }, [])
  79. const t = (elapsed / 200) % 10
  80. const scale = 1 + (t > 5 ? 10 - t : t) / 10
  81. return h('div', {style: {...containerStyle, transform: 'scaleX(' + (scale / 2.1) + ') scaleY(0.7) translateZ(0.1px)'}},
  82. h('div', {}, h(Triangle, {x: 0, y: 0, s: 1000}, seconds))
  83. )
  84. }
  85. requestAnimationFrame(function update (now) {
  86. render(h(Main, {elapsed: now - start}), document)
  87. requestAnimationFrame(update)
  88. })
  89. </script>
  90. </body>
  91. </html>