🍩

CSSでルーレットを作ろう

2024/12/03に公開
3

Commune Advent Calendar 2024シリーズ1の 3日目の記事です

HTMLとCSSで四角や丸以外の形のものを作ることは、Webサービス開発の仕事を毎日やっていてもそう経験することではないと思います。
今回は普段あまり作ることのないUIとして、ルーレットの作り方について紹介したいと思います。よろしくおねがいします。

つくったもの

こんなかんじ。
「回す」ボタンをおすと回転が始まります。

作り方

1. 扇形パネルを作る

まずは扇形を作ることから。扇形の塗りつぶしはconic-gradientを使うことで簡単に実現できます。

const StyledArcBG = styled.div`
  position: absolute;
  top: 0;
  left: 0;
  width: 400px;
  height: 400px;
  background-image: conic-gradient(
    rgba(0, 0, 0, 0) 0,
    rgba(0, 0, 0, 0) ${(props) => props.start}%,
    ${(props) => props.color} ${(props) => props.start}%,
    ${(props) => props.color} ${(props) => props.end}%,
    rgba(0, 0, 0, 0) ${(props) => props.end}%,
    rgba(0, 0, 0, 0) 100%
  );
`;

これでstart%〜end%の領域の角度でcolorの色がついて、それ以外の領域は透明な円(扇形)が描画されるようになります。

テキストを縦書きにするのはwriting-mode: vertical-rl;を適用するだけ。

2. 丸く並べる

1でつくった扇形は、実体としては円なので、扇の角(?)の部分がそのまま中心として扱えるので、Rotateをそのまま適用すれば円の中心を軸に回転出来ます。

const StyledArcRoot = styled.div`
  position: absolute;
  top: 0px;
  left: 0px;
  width: 400px;
  height: 400px;
  transform: rotate(
    ${(props) => props.start * 3.6 + ((props.end - props.start) / 2) * 3.6}deg
  );
`;

3. 回転アニメーションを付ける

const RoulettePanel = styled.div`
  position: relative;
  width: 400px;
  height: 400px;
  background-color: #fff;
  border-radius: 200px;
  overflow: hidden;
  transform: rotate(${(props) => props.deg}deg) ;
  transition-duration: ${(props) => props.deg * 10}ms;
  transition-property: transform;
   transition-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
`;

transformtransition-durationを適用するだけ。
ルーレットの回転の動きをよりそれっぽくするためにcubic-bezierをつかってイージングを調整しています。

完成

ボタンを押したらdegが設定されるようにしたら完成。です。
かんたん〜

コミューン株式会社

Discussion