React

by brigand

HTML

<div id="app"></div>

CSS

body,
html,
#app {
  margin: 0;
  height: 100%;
}

#app {
  position: relative;
}

.point {
  position: absolute;
  width: 2em;
  height: 2em;
  background: #999;
  border-radius: 50%;
}

.box {
 position: absolute;
 width: 12em;
 height: 5em;
 background: rgba(0, 0, 0, 0.2);
}

React

const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

async function scaleLoop(setter) {
  while (true) {
  let min = 0.1;
  let max = 2;
  let i = 1;
    for (i = min; i < max; i += 0.01) {
      await delay(10);
      setter(i)
    }
    for (; i > min; i -= 0.01) {
      await delay(10);
      setter(i)
    }
  }
}

function App() {
  const [scale,setScale] = React.useState(1)
  React.useEffect(() => {
    scaleLoop(setScale);
  }, []);

  return <React.Fragment><div className="point" style={{
  transformOrigin: 'calc(100px + 1em) 1em',
  top: '50%',
  left: '50%',
  transform: `translateX(-100px) scale(${scale})`
  }} />
  <div className="point" style={{
  transformOrigin: 'calc(50px + 1em) calc(-50px + 1em)',
  top: '50%',
  left: '50%',
  transform: `translate(-50px, 50px) scale(${scale})`
  }} />
   <div className="point" style={{
  transformOrigin: 'calc(-30px + 1em) calc(-18px + 1em)',
  top: '50%',
  left: '50%',
  transform: `translate(30px, 18px) scale(${scale})`
  }} />
    <div className="box" style={{
  transformOrigin: 'center center',
  top: '50%',
  left: '50%',
  transform: `translate(-50%, -50%) scale(${scale})`
  }} />
  </React.Fragment>
}
ReactDOM.render(<App />, document.querySelector("#app"))