1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Nihon UniversityAdvent Calendar 2023

Day 15

react-moveableを使ってドリトライに出てくる正統後継者の福笑いもどきをつくる

Posted at

はじめに

皆さんはドリトライという漫画をご存知でしょうか。
週刊少年ジャンプで連載されていたボクシング漫画です。

全19話と短命に終わった本作ですが、登場人物の一人である虹村凶作という人物がコラ画像に使われている点で一部で有名な漫画です。

あまりにも特徴的だったので、「福笑いしたら面白そう」という動機で作りました。

試作段階なので雑な部分はありますが、以下は今回作る正統後継者福笑いです。
image.png

要素を移動したり、、、
image.png

回転させたり、、、
image.png

画像を変更したり、、、
image.png

好き放題して遊びます。

react-moveableとは

要素に拡大縮小、回転などの動きを実装できるライブラリです。

今回のリポジトリ

ディレクトリ構成及び使用する画像です。

環境構築

viteで環境構築します。この辺あたりが参考になると思います。

react-moveableをインストールします。

npm install react-moveable

実装

App.tsx

App.tsx
import React, { useState } from 'react';
import './App.css';

import NijimuraHana from './component/nijimuraHana.tsx';
import NijimuraKuchi from './component/nijimuraKuchi.tsx';
import NijimuraHidarime from './component/nijiruraHidarime.tsx';
import NijimuraMigime from './component/nijimuraMigime.tsx';
import NijimuraHidariMayu from './component/nijimuraHidariMayu.tsx';
import NijimuraMigiMayu from './component/nijimuraMigiMayu.tsx';
import NijimuraHidariShiwa from './component/nijimuraHidariShiwa.tsx';
import NijimuraMigiShiwa from './component/nijimuraMigiShiwa.tsx';
import NijimuraMiken from './component/nijimuraMiken.tsx';

const App = () => {
  // useState()で画像のパスを保持
  const [profileImage, setProfileImage] = useState('seitoukoukeisya.png');

  const onFileInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (!e.target.files) return;

    // React.ChangeEvent<HTMLInputElement>よりファイルを取得
    const fileObject = e.target.files[0];
    // オブジェクトURLを生成し、useState()を更新
    setProfileImage(window.URL.createObjectURL(fileObject));
  };
  return (
    <React.Fragment>
      <input type="file" accept="image/*" onChange={onFileInputChange} />
      <div style={{backgroundImage: `url('${profileImage}')`, backgroundRepeat: "no-repeat"}}>
        <NijimuraHana/>
        <NijimuraKuchi/>
        <NijimuraHidarime/>
        <NijimuraMigime/>
        <NijimuraHidariMayu/>
        <NijimuraMigiMayu/>
        <NijimuraHidariShiwa/>
        <NijimuraMigiShiwa/>
        <NijimuraMiken/>
      </div>
    </React.Fragment>
  );
};
export default App;

背景画像のアップロードとそれぞれのパーツを配置しています。
backgroundImagediv内の背景画像を指定しています。

各コンポーネント

nijimuraMigime.tsx
import React, { useState, useEffect } from 'react';
import Moveable from 'react-moveable';

import nijimuraMigime from '/nijimuramigime.png';

const NijimuraMigime = () => {
  const [target, setTarget] = useState(null);

  useEffect(() => {
    setTarget(document.querySelector('.migime'));
  }, []);

  return (
    <>
      <div className={'moveable migime'}><img src={nijimuraMigime}/></div>
      <Moveable
        target={target}
        draggable={true}
        scalable={true}
        rotatable={true}
        origin={false}
        throttleScale={0}
        keepRatio={true}
        onDrag={e => {
          e.target.style.transform = e.transform;
        }}
        onScale={e => {
          e.target.style.transform = e.transform;
        }}
        onRotate={e => {
          e.target.style.transform = e.transform;
        }}
      />
    </>
  );
};

export default NijimuraMigime

moveable migime内の要素が操作可能になります。この中にnijimuraMigimeから取得した画像が含まれています。
MoveableコンポーネントではuseStateで指定したtargetを対象にしています。このMoveableコンポーネント内の

        draggable={true}
        scalable={true}
        rotatable={true}

は指定された要素をドラッグ可能、サイズ変更可能、回転可能にします。
onDrag, onScale, onRotateはそれぞれ、要素がドラッグ、サイズ変更、回転されたときの処理を定義します。

これを顔のパーツごとにコンポーネントを作成していきます。

App.css

!importantをつけることで、要素のカスタマイズができるようになります。

.moveable {
  width: 50px!important;
  height: 100px!important;
  margin: 0 0 0 auto;
}

.moveable-control {
  width: 10px!important;
  height: 10px!important;
  margin-top: -10px!important;
  margin-left: -10px!important;
}

.moveable-line {
  position: absolute!important;
  width: 1px!important;
  height: 1px!important;
  background: #000!important;
  transform-origin: 0px 0.5px!important;
}

.moveableは高さ長さを指定することで要素の判定を変更できます。
moveable-controlは拡大、縮小、回転の際の頂点を示します。
moveable-lineは頂点のつなぎ目になります。

他にもいろいろいじれる点があります。詳しくは以下の公式ドキュメントをご覧ください。

まとめ

かなり短くなりましたがこれで完成です。
やはり正統後継者の顔はインパクトあって、動かしているだけでも結構楽しいです。

とはいえ試作段階なので、完成したものを画像に起こすといった機能も追加して公開してみたいなと思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?