오픈 소스 모험: 에피소드 55: BATTLETECH 무기 순위 앱용 슬라이더

앱을 좀 더 대화식으로 만들 시간입니다. 다음 슬라이더를 추가했습니다.
  • 휴대할 탄약의 양
  • 보상할 열량
  • 가지고 있는 이중 방열판 수

  • 나는 또한 이 모델에 맞지 않는 Flamers와 Infernos를 제거했고 그다지 관련이 없는 최소 범위를 제거했습니다.

    Slider.svelte



    러시아 손실 앱에서 복사한 것입니다.

    <script>
    export let label, min, max, value, format
    let id = Math.random().toString(36).slice(2)
    </script>
    
    <label for={id}>{label}:</label>
    <input type="range" {min} {max} bind:value id={id} />
    <span>{format(value)}</span>
    


    Form.svelte



    확인란이나 라디오와 같은 다른 컨트롤 유형을 여기에 추가해야 할 수도 있습니다. 지금은 모든 슬라이더입니다.

    <script>
    import Slider from "./Slider.svelte"
    
    export let ammoRounds
    export let heatPercentage
    export let doubleHeatSinksPercentage
    </script>
    
    <form>
      <Slider label="Ammo for how many rounds" bind:value={ammoRounds} min={1} max={30} format={(v) => `${v}`}/>
      <Slider label="Heat to compensate for" bind:value={heatPercentage} min={0} max={100} format={(v) => `${v}%`}/>
      <Slider label="How many double heat sinks" bind:value={doubleHeatSinksPercentage} min={0} max={100} format={(v) => `${v}%`}/>
    </form>
    
    <style>
    form {
      display: grid;
      grid-template-columns: auto auto auto;
      margin-bottom: 1em;
    }
    </style>
    


    헤더.svelte


    App를 작게 유지하기 위해 일부 정적 콘텐츠를 Headers 구성 요소로 옮겼습니다.

    <tr>
      <th>Name</th>
      <th>Damage</th>
      <th>Heat</th>
      <th>Weight</th>
      <th>Ammo Weight</th>
      <th>Range</th>
      <th>Value</th>
      <th>Cost</th>
      <th>Ratio</th>
    </tr>
    


    App.svelte



    내가 원하는 방식으로 반응성이 작동하도록 하려면 row.id로 약간의 속임수를 써야 합니다. 여기서 내가 하고 있는 것은 특별히 우아한 해결책이 아닙니다.

    <script>
    import {sortBy} from "lodash"
    import data from "./data.json"
    import Form from "./Form.svelte"
    import Headers from "./Headers.svelte"
    import Row from "./Row.svelte"
    
    let ammoRounds = 10
    let heatPercentage = 80
    let doubleHeatSinksPercentage = 0
    
    let round100 = (v) => Math.round(v * 100) / 100
    
    $: heatSinkingPerTon = 3.0 + 3.0 * doubleHeatSinksPercentage / 100
    $: costPerHeat = (heatPercentage / 100) / heatSinkingPerTon
    
    let sortedData
    $: {
      for(let row of data) {
        row.value = row.shots * row.baseDamage
        row.ammoWeight = round100(ammoRounds * row.ammoTonnagePerShot)
        row.cost = round100(row.tonnage + row.ammoWeight + row.heat * costPerHeat)
        row.ratio = round100(row.value / row.cost)
        row.id = Math.random().toString(36).slice(2)
      }
      sortedData = sortBy(data, [(x) => -x.ratio, (x) => x.name])
    }
    </script>
    
    <h1>BATTLETECH Weapons Data</h1>
    
    <Form bind:ammoRounds bind:heatPercentage bind:doubleHeatSinksPercentage />
    
    <table>
      <Headers />
      {#each sortedData as row (row.id)}
        <Row data={row} />
      {/each}
    </table>
    
    <style>
    :global(body) {
      margin: 0;
      min-height: 100vh;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
    }
    table :global(tr):nth-child(even) {
      background-color: #f2f2f2;
    }
    table :global(tr):nth-child(odd) {
      background-color: #e0e0e0;
    }
    </style>
    


    지금까지의 이야기



    All the code is on GitHub .

    저는 이것을 GitHub Pagesyou can see it here에 배포했습니다.

    다음에 온다



    다음 몇 개의 에피소드에 걸쳐 저는 계속해서 앱을 개선할 것입니다.

    좋은 웹페이지 즐겨찾기