PienMoji その① 構想と下調べ

2020-03-16

Reactを少し勉強したので、その範囲内でPienMojiという簡単なアプリを作ってみたいと思います。

Pien(ぴえん)とはnikoさんのQiita記事「CSSぴえんチャレンジ」のような絵文字で、今考えているPienMojiは、Neumorphism.io のようなスライダを操作して自分のぴえんを作るものです。

create-react-appでReact雛形アプリを生成

まずは、create-react-app でReactアプリの雛形を作ります。

適当なフォルダにて以下のコマンドを実行するだけです。

> npx create-react-app pien-moji
> cd pien-moji
> yarn start 

これで次のようにReactアプリが表示されます(Visual Studio Codeで yarn start の前にプロジェクトを開いています)。

create-react-app で生成された React App

このあと、src/App.jsを次のように変更した上で、logo.svgも不要なので削除します。

これで単に左上に”Hello”と表示されるだけになります。

import React from 'react';
import './App.css';

function App() {
  return (
    <div>
      Hello
    </div>
  );
}

export default App;

Reactでスライダーを使いたい

bit.dev でキーワード”slider”で検索したら色々出てきました。

mui-org / material-ui というのが、ピンときたのですが、bit.dev の使い方がよくわからないので、こちらを見てインストールしました。

npm install @material-ui/core

srcフォルダの下にcomponentsフォルダを作り、Slider.js というファイルを作りました。

そこに、こちらのコードを抜粋して次のようにしました。 コピペして不要部分を削除して「大きさ:」 のところを変更しただけです。

import React from 'react';
import PropTypes from 'prop-types';
import { makeStyles } from '@material-ui/core/styles';
import Slider from '@material-ui/core/Slider';
import Typography from '@material-ui/core/Typography';
import Tooltip from '@material-ui/core/Tooltip';

const useStyles = makeStyles(theme => ({
  root: {
    width: 300 + theme.spacing(3) * 2,
  },
  margin: {
    height: theme.spacing(3),
  },
}));

function ValueLabelComponent(props) {
  const { children, open, value } = props;

  return (
    <Tooltip open={open} enterTouchDelay={0} placement="top" title={value}>
      {children}
    </Tooltip>
  );
}

ValueLabelComponent.propTypes = {
  children: PropTypes.element.isRequired,
  open: PropTypes.bool.isRequired,
  value: PropTypes.number.isRequired,
};

export default function CustomizedSlider() {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      <div className={classes.margin} />
      <Typography gutterBottom>大きさ:</Typography>
      <Slider
        ValueLabelComponent={ValueLabelComponent}
        aria-label="custom thumb label"
        defaultValue={20}
      />
    </div>
  );
}

そして、App.js を次のように2行だけ変更しました。

import React from 'react';
import Slider from './components/Slider';
import './App.css';

function App() {
  return <div><Slider /></div>;
}

export default App;

これで0から100まで設定できるスライダーが表示されました。

Slider React component

複数のスライダーを表示するには?

例えば、高さと幅の値を設定する2つのスライダーを表示し、それぞれタイトルをつけて、初期値と設定範囲も変えるということをやってみたいと思います。

App.js

App()を次のように変えました。

function App() {
  return (
    <div>
      <Slider name='高さ:' min={10} max={50} defaultValue={20} />
      <Slider name='幅:' min={20} max={60} defaultValue={30} />
    </div>
  );
}

Sliders.js

CostomizedSlider関数を次のようにしました。

export default function CustomizedSlider(props) {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      <div className={classes.margin} />
      <Typography gutterBottom>{props.name}:</Typography>
      <Slider
        ValueLabelComponent={ValueLabelComponent}
        min={props.min}
        max={props.max}
        defaultValue={props.defaultValue}
      />
    </div>
  );
}

これでスライダーが2つ表示できました。

2つのスライダーを表示

スライダーの値の変化を知るには?

こちらを読むとスライダーが動くと発火される onChange と、スライダーを動かし終わってマウスボタンを離したときに発火される onChangeCommitted があります。

後者でSliders.jsを書き直してみました。CustomaizedSlider関数に1行追加し、onChangeComittedHandler を追加しています。

const onChangeCommittedHandler = (event, value) => {
  console.dir(event.target.parentElement.dataset.parameterName);
  console.log(value);
};

export default function CustomizedSlider(props) {
  const classes = useStyles();

  return (
    <div className={classes.root} style={userStyle}>
      <div className={classes.margin} />
      <Typography gutterBottom style={labelStyle}>
        {props.name}:
      </Typography>
      <Slider
        ValueLabelComponent={ValueLabelComponent}
        min={props.min}
        max={props.max}
        defaultValue={props.defaultValue}
        onChangeCommitted={onChangeCommittedHandler}
        data-parameter-name={props.name}
      />
    </div>
  );
}

実行結果は次です。警告が出ていますが、とりあえずスライダーの値の変化を検出することができました。

各スライダーの値の変化を検出

これで基礎調査は終わりですので、ここからPienMojiを作っていきます。