0
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?

ボーダラインアニメーションをいくつか調べて実装したのでまとめてみる[Next.js, SCSS]

Posted at

ボーダーラインアニメーションをいくつか実装してみたいなと思い、色々調べて実装してみたので、今回は備忘録として実装したボーダラインアニメーションのやり方について紹介しようと思います。

開発環境

Next.jsでReactを使用して、今回のアニメーションはSCSSを使って実装しました

  • Next.js
  • SCSS(SCSS modules)

CSS modulesとは

CSSのクラス名をグローバルスコープではなく、ローカルスコープで定義できるようにする技術です。

CSSでは別ファイルで同じで同じクラス名を使うことができません。

しかしCSS modulesを使うと自動的に名前がユニークになり、それを使って下のようにスタイルを適用できるようになります。

style.module.scss
.title{
    color: #000000
}
index.tsx
import style from "./style.module.scss":

const Components = () =>{
    return(
        <div className={style.title}>Hello</div>
    )
}

メニューバー(ヘッダ-)がhoverされたら線が出るように

メニューバーで要素をhoverしたら、紫の線が伸びるアニメーションを実装しました。
タイトルなし.gif

  • tsxファイル
index.tsx
import style from "@/features/header/styles/style.module.scss"

export const Header = () =>{
    return (
        <div className={style.headerContainer}>
            <div className={style.menuContainer}>
                <div className={style.headerContent}>Home</div>
                <div className={style.headerContent}>About</div>
                <div className={style.headerContent}>Works</div>
            </div>
        </div>
    )
}
  • scssファイル
style.module.scss
.headerContainer {
  display: flex;
  position: relative;
}

.menuContainer{
  display: flex;
  position: absolute;
  right: 0;
}

.headerContent{
  font-size: 2rem;
  margin: 1rem 1rem 1rem 4rem;

  position: relative;
  &::after {
    content: '';
    position: absolute;
    bottom: 0;
    right: 0;
    width: 0;
    height: 3px;
    background-color: theme.$purple;
    transition: width 0.3s ease;
  }

  &:hover::after {
    width: 100%;
    left: 0;
  }
}

やり方

ここでは擬似要素afterを使って下の紫の線を作っています。

beforeとafterとは

タグで囲んでいる要素の前方に追加要素を加えることができる擬似要素のことです。

beforeは要素の前方に、afterは要素の後方に追加します。

例えば、下のようなhtmlがあったとします。

<h1>こんにちわ</h1>

下のようなcssを追加したとします。

h1::before {
  content: "☀️";
}

このような場合には、webサイト上では下のように表示されます。

See the Pen Untitled by mao ozaki (@maooz4426) on CodePen.

&::after {
    content: '';
    position: absolute;
    bottom: 0;
    right: 0;
    width: 0;
    height: 3px;
    background-color: theme.$purple;
    transition: width 0.3s ease;
  }

position:absoluteを指定して、親要素から右下の位置のに高さ3pxだけある紫色の物体を配置しています。

positionの注意点

position:absoluteは一つ上のタグにposition:relativeが当てられている必要があります。

absoluteは親要素からの絶対位置で要素の場所を指定します。
親要素は勝手に決められるわけでなく、relativeで指定する必要があるので注意してください。

そこからtransitionで横に広がるアニメーションが0.3sで適度な速度で加減速するようにしています

そこからafter要素がhoverされたら左からwidthを100%になるようにしています。これによって紫の線が、scssに当てている要素の下に右から左に流れるようにアニメーションすることができます。

  &:hover::after {
    width: 100%;
    left: 0;
  }

Imageコンポーネントの周りを小さな光が回るように

このXでのツイートのようにアイコンの周りをうっすら光るものが動くアニメーションを追加しました。

page.tsx
<div  className={style.icon}>
    <Image
        src={`/icon.png`}
        alt="icon"
        width={500}
        height={500}
    />
</div>
style.module.scss
.icon{
  border-radius: 50%;
  box-shadow: 0 0 10px 5px theme.$darkpurple;
  position: relative;
  display: inline-block;
  width: 500px;
  height: 500px;
}

@property --angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}
.icon::after ,.icon::before{
  content: '';
  position: absolute;
  border-radius: 50%;
  background-image:
          conic-gradient(from var(--angle),     transparent 0%,
                  transparent 65%,
                  theme.$darkpurple 71%,
                  theme.$purple 72%,
                  theme.$darkpurple 73%,
                  transparent 79%,
                  transparent 100%);
  top: 50%;
  left: 50%;
  width: 103%;
  height: 103%;
  translate: -50% -50%;
  display: block;
  z-index: -1;

  animation: border-animation 1.5s linear infinite;
}

.icon::before{
  filter: blur(1.5rem);
}

@keyframes border-animation {
  from{
    --angle: 0deg;
  }
  to{
    --angle: 360deg;
  }
}

どうやっているのか

点の表現はまず下の部分で主に行っています。

↓この部分

.icon::after ,.icon::before{
  content: '';
  position: absolute;
  border-radius: 50%;
  background-image:
          conic-gradient(from var(--angle),     transparent 0%,
                  transparent 65%,
                  theme.$darkpurple 71%,
                  theme.$purple 72%,
                  theme.$darkpurple 73%,
                  transparent 79%,
                  transparent 100%);
  top: 50%;
  left: 50%;
  width: 103%;
  height: 103%;
  translate: -50% -50%;
  display: block;
  z-index: -1;

  animation: border-animation 1.5s linear infinite;
}

擬似要素であるbefore、afterを使って、htmlに記述せず要素を追加します。

これらの要素はアイコンの周りに見える必要があります。
Imageタグが中央にあるのでpositionやtop、leftプロパティを使って中央に持ってきています。

position: absolute;
top: 50%;
left: 50%;
translate: -50% -50%;

border-radiusで完全に円形にします。

border-radius: 50%;

widthとheightで大きさを調節します。
100%だと完全に重なって見えないので少しだけ大きさを調節します。

width: 103%;
height: 103%;

background-imageで背景イメージを設定しています。

 background-image:

そのイメージとしてconic-gradientで作成したイメージを使っています。

conic-gradientは放射状に色を変えていく関数です

conic-gradient(開始角度、どの位置でどの色か)

今回の場合で言うと、まずアニメーション用にカスタムプロパティを設定しています。

@property --angle {
  syntax: "<angle>"; //角度を扱う
  initial-value: 0deg; //0度から
  inherits: false; //継承しないので指定した要素のみで扱う
}

conic-gradient上で先ほどのカスタムプロパティを開始位置として使用します。
そこからどの角度でどのような色をしているかを記述しています。
今回は360度の内71%の位置は濃いめの紫、72%は普通の紫、73%は濃いめの紫とコントラストをつけて光ってる感じをだすようにしています。

conic-gradient(from var(--angle),     transparent 0%,
        transparent 65%,
        theme.$darkpurple 71%,
        theme.$purple 72%,
        theme.$darkpurple 73%,
        transparent 79%,
        transparent 100%);

ここにアニメーションをつけて回転するようにします。
@keyframesでcssのアニメーション制御を行うことができます。これを使ってカスタムプロパティを0度から360度変動するようにしています。

@keyframes border-animation {
  from{
    --angle: 0deg;
  }
  to{
    --angle: 360deg;
  }
}

そこからanimationで何秒でそのアニメーションを行うか指定します。

animation: border-animation 1.5s linear infinite;

animationの使い方

今回のanimationでは下のように指定しています。

animation: <名前> <間隔> <アニメーションの緩急> <アニメーション回数>

また、blurをつけて少しネオンが光ってる感じも出しています。

.icon::before{
  filter: blur(1.5rem);
}

remとは

remはhtmlタグ内で使われている文字サイズを基準とした相対的な文字サイズ指定の単位です。

親の文字サイズに合わせて変更されるので、pxや%よりもレスポンシブ対応させやすいです

参考にした動画

0
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
0
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?