ふかしぎのReactさんぷるず

Zoomの解説 Componet API - MUI v5 API - Reactさんぷるず

最終更新 2022/02/21
MUI v5の各機能の説明です。
対象のMUIのバージョンは v5.4.1 です。
ここでは初心者向けの基本的な説明をしています。

使用するための下準備

お約束です。取り込まないと使えません。
インポートならば
import { Zoom } from '@mui/material';
CDNで使いたいのなら<script>でMUIを読み込んだ後に
const Zoom  = MaterialUI.Zoom;
で使用できるようになります。
CDNでの詳しいやり方はこちらに移動してください。

Zoomの各プロパティの解説

MUIでのZoomの扱い方の説明です。
ズームは中心に向かってじょじょに大きく表示。中心に向かってじょじょに小さく表示。をする機能です。
ズームはrefを設定しないとエラーになる場合があります。
このサンプルの「onf/off」を押してください。隣に十字が大きくなったり小さくなったりします。
const Zoom = MaterialUI.Zoom;
const createSvgIcon = MaterialUI.createSvgIcon;
const TukuttaIcon = createSvgIcon(<path d="M2 9h20v6h-20M9 2v20h6v-20z" />,'TukuttaIcon');
const Main = () => {
  const [onOff, setonOff] = React.useState(true);
  return (
    <div>
      <Zoom in={onOff}>
        <TukuttaIcon />
      </Zoom>
      <button onClick={()=>setonOff(!onOff)}>on/off</button>
    </div>
  )
};
ReactDOM.render(
<Main />
, document.getElementById('sample')
);

refの設定

SVGではrefを明示的に設定する必要が無かったですが、ものによってはrefの設定が必要になります。
例えばButtonコンポーネントやDIV要素などです。
下のサンプルはrefを設定しています。
const Zoom = MaterialUI.Zoom;
const Button = MaterialUI.Button;
const TukuttaDiv = React.forwardRef((props, ref) => <div {...props} ref={ref}>作ったDIV(ref)</div>);
const TukuttaButton = React.forwardRef((props, ref) => <Button variant="contained" {...props} ref={ref}>ボタン(ref)</Button>);
const Main = () => {
  const [onOff, setonOff] = React.useState(true);
  return (
    <div style={{"display":"flex"}}>
      <Zoom in={onOff}>
        <TukuttaButton />
      </Zoom>
      <Zoom in={onOff}>
        <TukuttaDiv />
      </Zoom>
      <button onClick={()=>setonOff(!onOff)}>on/off</button>
    </div>
  )
};
ReactDOM.render(
<Main />
, document.getElementById('sample')
);
ボタンのrefを設定しない場合はこのようになります。
const TukuttaButton = () => <Button variant="contained">ボタン</Button>;
ですがこれをZoomの子要素に設定するとrefが取得できずにエラーになります。
Warning: Failed prop type: Invalid prop `children` supplied to `ForwardRef(Zoom)`. Expected an element that can hold a ref. Did you accidentally use a plain function component for an element instead? For more information see https://mui.com/r/caveat-with-refs-guide
    at Zoom (https://unpkg.com/@mui/material@5.4.1/umd/material-ui.development.js:41500:7)
    at Main (<anonymous>:99:99)
ref付きでつくりましょう。
const TukuttaButton = React.forwardRef((props, ref) => <Button variant="contained" {...props} ref={ref}>ボタン(ref)</Button>);

children

Zoomのchildrenの使い方の説明です。
childrenに表示するノードを設定できます。
const Zoom = MaterialUI.Zoom;
const Button = MaterialUI.Button;
const createSvgIcon = MaterialUI.createSvgIcon;
const TukuttaIcon = createSvgIcon(<path d="M2 9h20v6h-20M9 2v20h6v-20z" />,'TukuttaIcon');
const Main = () => {
  const [onOff, setonOff] = React.useState(true);
  return (
    <div>
      <Zoom in={onOff} children={<TukuttaIcon />}></Zoom>
      <button onClick={()=>setonOff(!onOff)}>on/off</button>
    </div>
  )
};
ReactDOM.render(
<Main />
, document.getElementById('sample')
);

addEndListener

ZoomのaddEndListenerの使い方の説明です。
ズームの終了後に付け加える関数を設定できます。
のはずですが実際にはズームのアニメーションが始まる前に実行されます。
このサンプルはaddEndListenerで「addEndListener実行」というウインドウを出します。
const Zoom = MaterialUI.Zoom;
const createSvgIcon = MaterialUI.createSvgIcon;
const TukuttaIcon = createSvgIcon(<path d="M2 9h20v6h-20M9 2v20h6v-20z" />,'TukuttaIcon');
const Main = () => {
  const [onOff, setonOff] = React.useState(false);
  return (
    <div>
      <Zoom in={onOff} addEndListener={()=>{alert('addEndListener実行');}}>
        <TukuttaIcon />
      </Zoom>
      <button onClick={()=>{setonOff(!onOff)}}>on/off</button>
    </div>
  )
};
ReactDOM.render(
<Main />
, document.getElementById('sample')
);

appear

Zoomのappearの使い方の説明です。
inがtrueの時、つまり最初から表示している際にアニメーションをしてから表示するかの設定です。
inがtrueでappearもtrueだと最初にアニメーションをしてから表示します。
inがtrueでappearがfalseだとアニメーションなしでいきなり表示します。
デフォルトはtrueです。
サンプルの1つ目はtrueなのでこのページを開いた際にアニメーションで表示されます。
2つ目はfalseなのでいきなり表示されます。
この位置でCtrlキー+Rキーや、F5キーなどでブラウザーをリロードすると違いがわかります。
const Zoom = MaterialUI.Zoom;
const createSvgIcon = MaterialUI.createSvgIcon;
const TukuttaIcon = createSvgIcon(<path d="M2 9h20v6h-20M9 2v20h6v-20z" />,'TukuttaIcon');
const Main = () => {
  return (
    <div>
      <Zoom in={true} appear={true}>
        <TukuttaIcon />
      </Zoom>
      <Zoom in={true} appear={false}>
        <TukuttaIcon />
      </Zoom>
    </div>
  )
};
ReactDOM.render(
<Main />
, document.getElementById('sample')
);

easing

Zoomのeasingの使い方の説明です。
イージング関数を設定できます。
enterで表示する際の設定、exitで消える際の設定ができます。
サンプルの1つ目は標準
2つ目は表示する際に最初は遅く、そして最後の方はサイズオーバーしてから元のサイズに戻ります。消える際のexitは設定していないので1つ目の標準と同じタイミングで消えます。
3つ目は表示する際と消える際に最初は遅く、そして最後の方で急激に動作を加速させます。
違いを分かりやすくするためにtimeoutで長めの時間でアニメーションさせています。
const Zoom = MaterialUI.Zoom;
const createSvgIcon = MaterialUI.createSvgIcon;
const TukuttaIcon = createSvgIcon(<path d="M2 9h20v6h-20M9 2v20h6v-20z" />,'TukuttaIcon');
const Main = () => {
  const [onOff, setonOff] = React.useState(false);
  return (
    <div>
      <Zoom in={onOff} timeout={1000}>
        <TukuttaIcon style={{"width":"4rem","height":"4rem"}} />
      </Zoom>
      <Zoom in={onOff} easing={{"enter":"cubic-bezier(1, 0, 0.9, 1.7)"}} timeout={1000}>
        <TukuttaIcon style={{"width":"4rem","height":"4rem"}} />
      </Zoom>
      <Zoom in={onOff} easing={{"enter":"cubic-bezier(0.5, 0, 0.75, 0)","exit":"cubic-bezier(0.5, 0, 0.75, 0)"}} timeout={1000}>
        <TukuttaIcon style={{"width":"4rem","height":"4rem"}} />
      </Zoom>
      <button onClick={()=>{setonOff(!onOff)}}>on/off</button>
    </div>
  )
};
ReactDOM.render(
<Main />
, document.getElementById('sample')
);

in

Zoomのinの使い方の説明です。
表示するかしないかをブール値で設定します。
trueの場合は表示し、falseの場合は非表示です。
未設定のデフォルトはfalseです。
サンプルではZoomを3つ定義していますが、2つ目がfalse、3つ目は未設定なので結果として1つ目の1個しか表示されていません。
const Zoom = MaterialUI.Zoom;
const createSvgIcon = MaterialUI.createSvgIcon;
const TukuttaIcon = createSvgIcon(<path d="M2 9h20v6h-20M9 2v20h6v-20z" />,'TukuttaIcon');
const Main = () => {
  return (
    <div>
      <Zoom in={true}>
        <TukuttaIcon/>
      </Zoom>
      <Zoom in={false}>
        <TukuttaIcon/>
      </Zoom>
      <Zoom>
        <TukuttaIcon/>
      </Zoom>
    </div>
  )
};
ReactDOM.render(
<Main />
, document.getElementById('sample')
);

timeout

Zoomのtimeoutの使い方の説明です。
数値を設定するとその時間をかけて表示・非表示をします。数値はms(ミリ秒)です。1000ms=1秒です。
さらに細かく時間指定できます。
appearは画面で初めて表示する際の時間(これが有効になるのは最初から表示しているinがtrueの場合です。そしてアニメーションする必要があるのでappearがtrueの場合です。)
enterは非表示から表示へ切り替える時間
exitは表示から非表示へ切り替える時間
数字だけの場合はappear、enter、exitを同じ数字にした設定になります。
サンプルの1つ目は1秒(1000ms)かけて表示・非表示します。
2つ目は1つ目と同じ意味になります。
3つ目は画面を初めて表示した際は1秒、表示する際には2秒、消える際には3秒かけてアニメーションします。
4つ目は画面を初めて表示した際は4秒、表示する際には5秒、消える際には6秒かけてアニメーションします。
const Zoom = MaterialUI.Zoom;
const createSvgIcon = MaterialUI.createSvgIcon;
const TukuttaIcon = createSvgIcon(<path d="M2 9h20v6h-20M9 2v20h6v-20z" />,'TukuttaIcon');
const Main = () => {
  const [onOff, setonOff] = React.useState(true);
  return (
    <div>
      <Zoom in={onOff} timeout={1000}>
        <TukuttaIcon style={{"width":"4rem","height":"4rem"}} />
      </Zoom>
      <Zoom in={onOff} timeout={{"appear":1000,"enter":1000,"exit":1000}}>
        <TukuttaIcon style={{"width":"4rem","height":"4rem"}} />
      </Zoom>
      <Zoom in={onOff} timeout={{"appear":1000,"enter":2000,"exit":3000}}>
        <TukuttaIcon style={{"width":"4rem","height":"4rem"}} />
      </Zoom>
      <Zoom in={onOff} timeout={{"appear":4000,"enter":5000,"exit":6000}}>
        <TukuttaIcon style={{"width":"4rem","height":"4rem"}} />
      </Zoom>
      <button onClick={()=>{setonOff(!onOff)}}>on/off</button>
    </div>
  )
};
ReactDOM.render(
<Main />
, document.getElementById('sample')
);

ズームが機能しない

書き方によってはズームが機能しない場合があります。
このサンプルは二つ目が消えるときにズームが機能せずにいきなり消えます。
原因はZoomさせる子コンポーネントが宣言している場所にあります。
レンダリングされるたびにTukuttaIcon2が再作成されています。
開発者ツールでコンソールの出力をみるとレンダリングされているタイミングがわかります。
const Collapse = MaterialUI.Collapse;
const createSvgIcon = MaterialUI.createSvgIcon;
const TukuttaIcon1 = createSvgIcon(<path d="M2 9h20v6h-20M9 2v20h6v-20z" />,'TukuttaIcon');
const Main = () => {
  const TukuttaIcon2 = createSvgIcon(<path d="M2 9h20v6h-20M9 2v20h6v-20z" />,'TukuttaIcon');
  console.log('レンダリング');
  const [onOff, setonOff] = React.useState(true);
  return (
    <div>
      <Zoom in={onOff} timeout={3000}>
        <TukuttaIcon1 style={{"width":"4rem","height":"4rem"}} />
      </Zoom>
      <Zoom in={onOff} timeout={3000}>
        <TukuttaIcon2 style={{"width":"4rem","height":"4rem"}} />
      </Zoom>
      <button onClick={()=>setonOff(!onOff)}>on/off</button>
    </div>
  )
};
ReactDOM.render(
<Main />
, document.getElementById('sample')
);

その他のアニメーション(Transitions)

コラプス(Collapse)、フェード(Fade)、ズーム(Zoom)、グロー(Grow)、スライド(Slide)の5つがあります。
コラプス(Collapse)は、その場で縦方向・横方向から現れます。
フェード(Fade)は、じょじょに透明度を変化しながら現れます。
ズーム(Slide)は、中心からサイズを変えながらじょじょに現れます。
グロー(Zoom)は、中心からサイズと透明度を変えながら現れる。(フェードとズームの組み合わせ)
スライド(Grow)は上・下・左・右から移動しながら現れます。
const Collapse = MaterialUI.Collapse;
const Fade = MaterialUI.Fade;
const Zoom = MaterialUI.Zoom;
const Grow = MaterialUI.Grow;
const Slide = MaterialUI.Slide;
const createSvgIcon = MaterialUI.createSvgIcon;
const TukuttaIcon = createSvgIcon(<path d="M2 9h20v6h-20M9 2v20h6v-20z" />,'TukuttaIcon');
const Main = () => {
  const [onOff, setonOff] = React.useState(true);
  return (
<div>
<div style={{"display":"grid","gridTemplateColumns":"repeat(5, 1fr)"}}>
      <Collapse in={onOff} timeout={2000}>
        <TukuttaIcon style={{"width":"4rem","height":"4rem"}} />
      </Collapse>
      <Fade in={onOff} timeout={2000}>
        <TukuttaIcon style={{"width":"4rem","height":"4rem"}} />
      </Fade>
      <Zoom in={onOff} timeout={2000}>
        <TukuttaIcon style={{"width":"4rem","height":"4rem"}} />
      </Zoom>
      <Grow in={onOff} timeout={2000}>
        <TukuttaIcon style={{"width":"4rem","height":"4rem"}} />
      </Grow>
      <Slide in={onOff} timeout={2000}>
        <TukuttaIcon style={{"width":"4rem","height":"4rem"}} />
      </Slide>
      <div>コラプス(<a href="/react/mui/apiCollapse.php">Collapse</a>)</div>
      <div>フェード(<a href="/react/mui/apiFade.php">Fade</a>)</div>
      <div>ズーム(<a href="/react/mui/apiSlide.php">Slide</a>)</div>
      <div>グロー(<a href="/react/mui/apiZoom.php">Zoom</a>)</div>
      <div>スライド(<a href="/react/mui/apiGrow.php">Grow</a>)</div>
    </div>
    <button onClick={()=>{setonOff(!onOff)}}>on/off</button>
</div>
  )
};
ReactDOM.render(
<Main />
, document.getElementById('sample')
);
menu

React 目次

最初に現在のReactについて
世界一シンプルなサンプル
React Router v6
React Router v6 API
MUI v5
sxの解説
マテリアルアイコンの解説
Autocomplete
Avatar
AvatarGroup
Badge
Button
ButtonGroup
Checkbox
Chip
Collapse
Divider
Floating Action Button(Fab)
Fade
FormControlLabel
Grow
Icon
List
ListItem
ListItemAvatar
ListItemButton
ListItemIcon
ListItemSecondaryAction
ListItemText
ListSubheader
Radio
RadioGroup
Rating
Select
Slide
Slider
Switch
TextField
ToggleButton
ToggleButtonGroup
Zoom
エラー対処
HTMl select
戻る

全体目次