エンジニアなら雪も降らせれるでしょ？と言われたら

:::note info
本記事は [株式会社ゆめみ Advent Calendar 2023](https://qiita.com/advent-calendar/2023/yumemi) の 25 日目です。
:::

わい「クリスマスっぽいことしていない」
わい「お取り寄せしたシュトーレンを切るか」

もう一人のわい「クリスマスツリーがないンゴ」
もう一人のわい「🌲🌲🌲が見たいンゴ」

わい「っ！」
わい「よし、ちかくの百均で揃えてくるで！」

![IMG_0129.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24345/6c755099-2af5-a2ad-4259-d9bfa84bf42b.jpeg)


わい「これしか買えなかった」
わい「観葉植物に飾るか」

もう一人のわい「・・・」
もう一人のわい「雪が見たいンゴ」
もう一人のわい「無敵のエンジニアリングで何とかしてくださいよォーー！！」

わい「<ruby>出来<rt>でき</rt></ruby>らあっ！」

<iframe width="560" height="315" src="https://www.youtube.com/embed/Lx0Dz9VxnyM?si=RCzq59REb5X5Un_3" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

わい「ロール紙の回転癖でうまくいかない」
わい「紙に重りを付けるか」

<iframe width="560" height="315" src="https://www.youtube.com/embed/tFCjTRWSc5c?si=3BXmJy5DSRy665V7" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

わい「╭( ･ㅂ･)و ̑̑ 」

![IMG_0123.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24345/5775dee1-900e-081f-6930-0d8f2ec3329e.jpeg)

わい「どう見ても雪だ」
わい「どうや」

もう一人のわい「シュトーレン、おいしい」

## アスキーアートを手軽に印刷する

アスキーアートで雪を表現する。いくつかの丸系統の文字をランダムに配置することで、雪を表現しました。また、プリンタを逆方向に持ち、雪が降っているようにしました。

これらは個人開発しているモバイル印刷アプリの機能追加の一環で作成しました。テキストや画像を印刷するアプリで他に何かできなかと思ってる時に、試しにアスキーアートを印刷したら、思った以上にちゃんと印刷できたので開発しました。

https://github.com/mitsuharu/mobile-printer

アスキーアートはフォントが重要で、印刷環境に応じて調整が必要になります。アプリにアスキーアートの入力フォームを作って調整や確認しながらデータ追加できるようにしたかったのですが、開発時間の都合で今回はハードコーディングをしています。次のような差分が私のアプリの Git に刻まれました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24345/e1258602-e7c9-1263-01b0-0eb23ee924f2.png)

なお、印刷に関する処理は、先日公開した自作の印刷ライブラリーを利用しています。

https://www.npmjs.com/package/@mitsuharu/react-native-sunmi-printer-library

## 「試験先行実装」を実装する

この機能はハードコーディングしているのもあり、試験機能として扱っています。とはいえ、面白いのでちょとリリースしたいと思い、期限限定として実装しました。

- クリスマス（12/24 - 12/25）
- 正月（1/1 - 1/3）

限定機能を実現するため、機能発火を制御するコンポーネントを日付で判定して、表示の有無を制御しています。仕組みは簡単で state に今日の季節イベント状態を保存して、それを読み込んでいます（このアプリは状態管理に Redux Sage を利用しています）。

```typescript
const Component: React.FC<ComponentProps> = (props) => {
    // ボタンなどを含むコンポーネント（実装省略）
}

const Container: React.FC<Props> = (props) => {
  const dispatch = useDispatch()
  const seasonalEvent: SeasonalEvent = useSelector(selectAsciiArtSeasonalEvent)

  useEffect(() => {
    dispatch(updateSeasonalEvent())
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])
  
  const onPressAsciiArt = useCallback(() => {
    dispatch(printAsciiArt())
  }, [dispatch])

  return seasonalEvent !== 'none' ? (
    <Component {...props} {...{onPressAsciiArt}} />
  ) : null
}

export { Container as SeasonalAsciiArtSection }
```

このコンポーネントのマウント時に確認しています。正しく判定するにはマウントだけではなく、タイマーなどを仕込んでマウントされた後でも確認を実行する処理が必要ですが、そこまでしなくてもという判断でオミットしました。

## おまけ

このアプリのデバッグで、ロール紙を１個分ほど消費しました。

![IMG_0114.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24345/b9d42ff4-27a6-1426-0115-ad517977c211.jpeg)

メリークリスマス ＆ 良いお年を

:::note warn
この記事は個人開発かクソアプリのアドカレが相応しいと思いましたが、25日分が空いてたのでえいやで埋めました。お察しください。
:::