오픈 소스 모험: 에피소드 21: Imba 2 Matrix Rain

7463 단어 javascriptimba
또 다른 Imba 1 앱을 Imba 2로 이식해 보겠습니다. 이번에는 Matrix와 유사한 화면 보호기인 Matrix Rain입니다.

You can see it in action herethe source code of Imba 1 version here .

Imba 1 앱.imba



이 앱은 App (최상위 수준) 및 Stream (떨어지는 문자의 단일 스트림)의 두 가지 구성 요소와 setIntervalsetup 가 포함된 몇 가지 수명 주기 후크를 사용합니다.

비정상적으로 보이는 몇 가지 느슨한 기능도 있습니다let def.

let def random_int(min, max)
  min + Math.floor( Math.random() * (max - min + 1) )

let def random_katakana
  String.fromCharCode(random_int(0x30A0, 0x30FF))

let def random_symbols
  for i in [0..random_int(5, 30)]
    { v: random_katakana() }

tag Stream
  def render
    <self css:top=data:y css:left=data:x>
      for symbol, index in data:symbols
        <div.symbol .first=(index==0)>
          symbol:v

tag App
  def setup
    @streams = []
    let x = 10
    while x + 30 < window:inner-width
      @streams.push({
        x: x,
        y: Math.random() * window:inner-height,
        speed: 10 + Math.random() * 20,
        symbols: random_symbols()
      })
      x += 30

  def mount
    setInterval(&,10) do
      for stream in @streams
        stream:y += stream:speed
        if stream:y > window:inner-height + stream:symbols:length * 20
          stream:symbols = random_symbols()
          stream:speed = 10 + Math.random() * 20
          stream:y = - stream:symbols:length * 20
        for symbol in stream:symbols
          if Math.random() < 0.01
            symbol:v = random_katakana()
      Imba.commit

  def render
    <self>
      for stream in @streams
        <Stream[stream]>

Imba.mount <App>


임바 1 앱.scss



여기에는 거의 사용되지 않는 약간의 특이한 스타일이 있습니다flex-direction: column-reverse. 늘 그렇듯이 SCSS는 네스팅에만 사용되며 화려한 용도에는 사용되지 않습니다.

@import 'normalize-scss';
@include normalize();

body {
  overflow: hidden;
}

.App {
  background-color: black;
  height: 100vh;
  width: 100vw;
  overflow: hidden;

  .Stream {
    position: absolute;
    display: flex;
    flex-direction: column-reverse;

    .symbol {
      height: 20px;
      width: 20px;
      line-height: 20px;
      position: relative;
      font-size: 16px;
      text-align: center;
      color: #8f4;

      &.first {
        color: #dfa;
      }
    }
  }
}


Imba 2 앱.imba



Imba 2로 포팅된 앱은 다음과 같습니다.

global css body
  background-color: black
  overflow: hidden
  margin: 0
  height: 100vh
  width: 100vw

def random_int(min, max)
  min + Math.floor( Math.random() * (max - min + 1) )

def random_katakana
  String.fromCharCode(random_int(0x30A0, 0x30FF))

def random_symbols
  for i in [0 .. random_int(5, 30)]
    { v: random_katakana() }

tag stream
  prop x
  prop y
  prop symbols

  <self[top:{y}px left:{x}px]>
    for symbol, index in symbols
      <div.symbol>
        symbol.v

  css
    position: absolute
    display: flex
    flex-direction: column-reverse

    .symbol
      height: 20px
      width: 20px
      line-height: 20px
      position: relative
      font-size: 16px
      text-align: center
      color: #8f4

      &:first-child
        color: #dfa

tag app
  def setup
    streams = []
    let x = 10
    while x + 30 < window.innerWidth
      streams.push({
        x: x
        y: Math.random() * window.innerHeight
        speed: 3 + Math.random() * 5
        symbols: random_symbols()
      })
      x += 30

  def mount
    imba.setInterval(&, 10) do
      for stream in streams
        stream.y += stream.speed
        if stream.y > window.innerHeight
          stream.symbols = random_symbols()
          stream.speed = 3 + Math.random() * 5
          stream.y = - stream.symbols.length * 20
        for symbol in stream.symbols
          if Math.random() < 0.01
            symbol.v = random_katakana()

  <self>
    for stream in streams
      <stream x=stream.x y=stream.y symbols=stream.symbols>

  css
    height: 100vh
    width: 100vw
    overflow: hidden

imba.mount <app>


참고 사항:
  • 구문이 표준 JavaScript
  • 에 조금 더 가깝습니다.
  • imba.setInterval 는 일반 setInterval 과 같지만 속성이 변경되었을 수 있음을 Imba에 알립니다. Svelte와는 다른 반응성 모델입니다.
  • 각 기호는 {v: ...}로 래핑되어 루프에서 더 쉽게 업데이트할 수 있습니다
  • .
  • 한 가지 당혹스러운 것은 <self[top:{y}px left:{x}px]>였습니다. 처음에는 픽셀이 기본 단위가 될 것으로 기대하고 <self[top:{y} left:{x}]> DOM에 대한 모든 것이 작동하는 방식이었지만, 어떻게든 Imba는 1040px로 변환했습니다. 진짜 씨발 뭐야? 전혀 말이되지 않습니다. h-1height: 0.25rem 를 의미하고 그것은 4px 입니다. 그것은 프레임워크 수준에서 완전히 당혹스럽습니다.
  • Imba의 CSS에는 SCSS를 사용할 필요가 없는 충분한 SCSS 기능(예: &:first-child)이 있습니다
  • .

    소스 코드



    소스 코드는 imba2-matrix-rain repository에 있습니다. 언젠가는 GitHub Pages 지원을 추가하려고 합니다.

    다음에 온다



    다음 몇 개의 에피소드에서는 Imba 1 앱을 몇 개 더 Imba 2로 이식한 다음 Imba 상황에 대한 제 생각을 요약하겠습니다.

    좋은 웹페이지 즐겨찾기