메모

css 애니메이션 하나 까보기

surimi🍥 2021. 1. 6. 22:34
반응형

See the Pen SVG Gooey Hover Menu Concept by Michael Leonard (@mikel301292) on CodePen.

 

# 추가 플러그인 

 - JQuery

https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js

 

플러그인 추가 방법

 

 

# HTML

<div id="menu">
    <div class="hamburger">
      <div class="line"></div>
      <div class="line"></div>
      <div class="line"></div>
    </div>
    <div class="menu-inner">
      
      <ul>
        <li>Menu Item</li>
        <li>Menu Item</li>
        <li>Menu Item</li>
        <li>Menu Item</li>
        <li>Menu Item</li>
        <li>Menu Item</li>
      </ul>
    </div>
    
    <svg version="1.1" id="blob"xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
      <path id="blob-path" d="M60,500H0V0h60c0,0,20,172,20,250S60,900,60,500z"/>
    </svg>
  </div>


<h2> hover close to the menu </h2>

 

1. SVG

SVG는 Scalable Vector Graphics의 줄임말로, 마크업 언어를 가지고 벡터 기반의 그래픽을 표현한다.

2차원 그래픽을 표현하기 위해 만들어진 XML파일 형식의 마크업 언어인데,
텍스트 편집기에서 CSS나 JS로 수정이 가능하다는 점이 가장 큰 장점이라 할 수 있다.

 

SVG 장점

  - 확대해도 절대 깨지지 않고 절대 늘어나지 않음 -> 웹 그래픽의 표준 - 아이콘 이미지, 그래픽 등에 널리 쓰임

  - JPG, PNG 비트맵 이미지로 사용안하고 SVG로 많이 쓰임

  - 모양이 안복잡하면 파일 사이즈 작음, 모양 복잡할 수록, 그림 구성하는 포인트 많을수록 용량이 커짐, 성능도 떨어짐

    -> 간단한 이미지들이 벡터그래픽인 SVG가 유리

  - 비디오를 통해서만 자연스러운 애니메이션도 SVG를 이용한다면 CSS, Jascript와 함께 자연스러운 애니메이션도 가능.

 

사각형과 원 그리기

사각형을 그릴 수 있는 rect 요소의 경우 다음과 같은 속성을 필요로 한다.

SVG에서 좌표의 원점은 좌측 상단이기 때문에 x, y 속성을 지정하지 않을 경우 이미지 좌측 최상단을 기준으로 시작된다.

x X 좌표 (기본값은 0)
y Y 좌표 (기본값은 0)
width 너비
height 높이
rx 좌우 방향의 둥근 모서리 반지름
ry 위아래 방향의 둥근 모서리 반지름

 

See the Pen vYXaLrO by Soksurim (@soksurim) on CodePen.

 

을 그리는 circle 요소의 경우에는 다음과 같은 속성을 필요로 한다.

cx 원의 중심 X 좌표 (기본값 0)
cy 원의 중심 Y 좌표 (기본값 0)
r 원의 반지름

 

SVG도 CSS를 이용해 스타일을 지정할 수 있다. CSS를 이용해 스타일링 할 경우, 코드와 디자인을 분리하는 데 도움이 된다

 

 

See the Pen poEZgKa by Soksurim (@soksurim) on CodePen.

 

문자 그리기

text 요소를 사용하면 문자를 그릴 수 있다. 자세한 옵션에 대해서는 책을 참고하자.

속성설명

x X 좌표
y Y 좌표
font-family 글꼴
font-size 글자 크기
font-weight 글자 굵기 (100~900 또는 normal, bold 등)
text-anchor 글자를 표시하는 기준 위치를 지정 (start: 왼쪽, middle: 가운데, end: 오른쪽 맞춤)

 

 

See the Pen xxEJZzB by Soksurim (@soksurim) on CodePen.

도형 그룹 만들기

여러 개의 요소들을 한꺼번에 다룰 때는 그룹으로 지정하는 것이 좋다. 파워포인트로 프레젠테이션 만들 때 쓰는 객체 그룹과 비슷한 개념이다.

도형을 그룹으로 다루게 되면 1. 스타일을 한 번에 처리할 수 있고, 2. 위치변화, 회전 등을 적용하기 편해진다

 

See the Pen QWKByBq by Soksurim (@soksurim) on CodePen.

 

svg 예시 추가 : www.w3schools.com/graphics/svg_examples.asp

 

 

2. path

<path>는 요소 경로를 정의하는 데 사용됩니다. 

다음 명령은 경로 데이터를 사용할 수 있습니다 : 

 

  • M = moveTo 
  • L = lineTo 
  • H = 수평 lineTo 
  • V = 수직 lineTo 
  • C = curveTo 
  • S = 매끄러운 curveTo 
  • Q = 베지어 곡선 
  • T = 부드러운 정방형 3차원 curveTo 
  • A = 타원형 호 
  • Z = closePath 

 

위의 모든 명령은 소문자로도 표현 될 수 있습니다. 이때, 

  • 대문자는 절대 위치를, 
  • 소문자는 상대 위치를 의미합니다. 

See the Pen dypjGrP by Soksurim (@soksurim) on CodePen.

M150 0 : 절대위치 x150, y0 위치에서 패스를 시작.
L75 200 : 절대위치 x75, y200 위치까지 선을 도식.
L225 200 : 절대위치 x225, y200 위치까지 선을 도식.
Z  : 패스 시작 위치까지 연결하여 패스 닫음.

 

 

 

 

 

See the Pen mdrjPVR by Soksurim (@soksurim) on CodePen.

# Path 참조 

 

https://developer.mozilla.org/ko/docs/Web/SVG/Tutorial/Paths

 

m.blog.naver.com/PostView.nhn?blogId=pjh445&logNo=220045621716&proxyReferer=https:%2F%2Fwww.google.com%2F

 

 


# CSS

    body, html {
      margin: 0;
      padding: 0;
      width: 100%;
      height: 100%;
      background-color:#26394E ;
    }

    #menu {
      height: 100%;
      position: fixed;
      background-color: #FED057;
      width: 300px;
      transition: 1000ms all cubic-bezier(0.19, 1, 0.22, 1);
      transform: translateX(-100%);
      left: 60px;
    }

    #menu.expanded {
      transform: translateX(0%);
      left: 0px;
    }

    .menu-inner {
      width: 100%;
      height: 100%;
      position: relative;
    }

    #blob {
      top: 0;
      z-index: -1;
      right: 60px;
      transform: translateX(100%);
      height: 100%;
      position: absolute;
    }

    #blob-path {
      height: 100%;
      fill:  #FED057;
    }

    .hamburger {
      right: 20px;
      position: absolute;
      width: 20px;
      height: 20px;
      margin-top: -10px;  
    }

    .hamburger .line {
      width: 100%;
      height: 4px;
      background-color: #fff;
      position: absolute;
    }

    .hamburger .line:nth-child(2) {
      top: 50%;
      margin-top: -2px;
    }

    .hamburger .line:nth-child(3) {
      bottom: 0;
    }

    h1 {
      position: fixed;
      right: 0;
      margin: 0;
    }

    ul {
      padding: 0;
      list-style: none;
      width: 80%;
      margin-left: 10%;
      position: absolute;
      top: 10px;
    }

    ul li {
      color: #fff;
      font-family: sans-serif;
      padding: 20px 0;
    }

    h2 {
      position: absolute;
       left: 50%;
      color: #fff;
      margin: 0;
      font-size: 16px;
      font-family: sans-serif;
      font-weight: 100;
    }


  

 

1. transition

정해진 시간 동안 요소의 속성값을 부드럽게 변화시킬 수 있다.

 

CSS3 transition 속성

transition 모든 transition 속성을 이용한 스타일을 한 줄에 설정할 수 있음.
transition-property 요소에 추가할 전환(transition) 효과를 설정함.
transition-duration 전환(transition) 효과가 지속될 시간을 설정함.
transition-timing-function 전환(transition) 효과의 시간당 속도를 설정함.
transition-delay 전환(transition) 효과가 나타나기 전까지의 지연 시간을 설정함.

 

See the Pen MWjBeXj by Soksurim (@soksurim) on CodePen.

transition-timing-function 속성

transition-timing-function 속성은 전환(transition) 효과의 시간당 속도를 설정합니다.

 

transition-timing-function 속성의 속성값으로는 다음과 같은 값을 설정할 수 있습니다.

 

1. linear : 전환(transition) 효과가 처음부터 끝까지 일정한 속도로 진행됩니다.

2. ease : 기본값으로, 전환(transition) 효과가 천천히 시작되어, 그다음에는 빨라지고, 마지막에는 다시 느려집니다.

3. ease-in : 전환(transition) 효과가 천천히 시작됩니다.

4. ease-out : 전환(transition) 효과가 천천히 끝납니다.

5. ease-in-out : 전환(transition) 효과가 천천히 시작되어, 천천히 끝납니다.

6. cubic-bezier(n,n,n,n) : 전환(transition) 효과가 사용자가 정의한 cubic-bezier 함수에 따라 진행됩니다.

 

See the Pen mdrjEjv by Soksurim (@soksurim) on CodePen.

transition-delay 속성

transition-delay 속성은 전환(transition) 효과가 나타나기 전까지의 지연 시간을 설정합니다.

전환(transition) 효과는 이 메소드로 설정된 시간이 흐른 뒤에야 비로소 시작됩니다.

 

See the Pen dypjXqj by Soksurim (@soksurim) on CodePen.

전환(transition) 효과와 변형(transform) 효과의 동시 적용

전환(transition) 효과와 변형(transform) 효과를 같이 적용할 수도 있습니다.

 

See the Pen KKgBMGz by Soksurim (@soksurim) on CodePen.

 

2. 베지어 곡선(bezier curves)

 

베지어 곡선은 부드러운 곡선을 모델링하기 위해 컴퓨터 그래픽에서 널리 사용된다.
커브가 컨트롤 포인트의 볼록한 선체에 완전히 포함되어 있기 때문에 점을 그래픽으로 표시하고 직관적으로 커브를 조작하는 데 사용할 수 있다.
변환 및 회전과 같은 어피니션 변환은 곡선의 제어점에 각각의 변환을 적용하여 곡선에 적용 할 수 있다.

 

transition 속성을 사용 할 때 아래와 같은 값을 부여했으면,

#target{
transition: width 0.5s cubic-bezier(0.25, 0.25, 0.75, 0.75);
}

해당 엘리먼트의 width

  • 0.5초 동안 제어하되
  • 4개의 컨트롤 포인트(x, y, x2, y2)(0.25, 0.25, 0.75, 0.75)를 가지는 cubic-bezier curve에 의거해 효과를 주겠다.

라는 뜻이 되는데 이걸 그래프로 그리면

이런 형태가 된다.

 

매번 수치로 적어주는 번거로운 작업을 줄이기 위해 

transition-timing-function 속성을 쓸 수 있다.

See the Pen transition by kutar37 (@kutar37) on CodePen.

ease(default)

기본값으로, (0.25, 0.1, 0.25, 1.0) 의 값을 가진다. 

처음과 끝은 상대적으로 느리게, 중간은 빠르게. 

 

linear

위에서 설명한 것으로 직선 모양이다. 

(0.25, 0.25, 0.75, 0.75) 값을 가진다.

ease-in

조금씩 완만하게 상승한다.

처음은 느리고 갈수록 빨라진다.

값은 (0.42, 0.0, 1.0, 1.0) 이다.

ease-out

ease-in과 반대로 처음은 빠르고 갈수록 느려진다.

값은 (0.0, 0.0, 0.58, 1.0) 이다.

ease-in-out

디폴트값인 ease와 유사하지만 조금 더 완만하고 부드러운 느낌을 준다.

값은 (0.42, 0.0, 0.58, 1.0) 이다.

 

참조 : https://matthewlein.com/tools/ceaser
이 사이트에서 직접 그래프를 조정해 애니메이션 효과를 체험해볼 수 있다.

출처 : https://kutar37.tistory.com/entry/CSS-cubic-bezier%EB%9E%80

 

 

3. Transform

 

변형(transform)이라는 것은 쉽게 말해서 특정 요소를 여러 가지 방법으로 모양을 바꾸는 것을 의미합니다.

 

  • traslate : 이동효과
  • scale : 확대/축소 효과
  • rotate : 회전 효과
  • skew : 비틀기(기울임) 효과

See the Pen CSS3 Transform Test by jaeheekim (@jaehee) on CodePen.

 


출처: https://webclub.tistory.com/432 [Web Club]

 

 

 

4. :nth-child(), :nth-last-child()

  • :nth-child()와 :nth-last-child()는 특정 순서에 있는 요소를 선택할 때 사용하는 선택자입니다.
  • :nth-child()는 앞에서부터 세고, :nth-last-child()는 뒤에서부터 셉니다.

# 문법 :nth-last-child( an + b )

  • a와 b는 정수입니다. 0과 음수도 가능합니다.
  • n에는 음이 아닌 정수, 즉 0, 1, 2, 3, …이 차례대로 대입됩니다.
  • an+b 대신에 even, odd를 넣을 수도 있습니다.

 

See the Pen GRjBjZK by Soksurim (@soksurim) on CodePen.

 


# JavaScript

$(window).load(function(){
  var height = window.innerHeight,
  x= 0, y= height/2,
  curveX = 10,
  curveY = 0,
  targetX = 0,
  xitteration = 0,
  yitteration = 0,
  menuExpanded = false;
  
  blob = $('#blob'),
  blobPath = $('#blob-path'),

  hamburger = $('.hamburger');
  
  
// x, y : 마우스 좌표
// curveX : 커브가 생길 '메뉴 늘어난 부분' 모서리 위치 좌표 
// targetX : 마우스 좌표를 향해 늘어날 좌표
// xitteration : 메뉴 늘어나는 기능 x 이동수치

// 마우스 이동시 마우스좌표 (x,y) 갱신
  $(this).on('mousemove', function(e){
    x = e.pageX;
    
    y = e.pageY;
  });
  
// 햄버거버튼(≡)또는 메뉴영역 안에 마우스가 들어갈시 메뉴가 펼쳐짐
  $('.hamburger, .menu-inner').on('mouseenter', function(){
    $(this).parent().addClass('expanded');
    menuExpanded = true;
  });

  $('.menu-inner').on('mouseleave', function(){
    menuExpanded = false;
    $(this).parent().removeClass('expanded');
  });
  
// 메뉴 늘어나는 속도 조정 메소드???
  function easeOutExpo(currentIteration, startValue, changeInValue, totalIterations) {
    return changeInValue * (-Math.pow(2, -10 * currentIteration / totalIterations) + 1) + startValue;
  }
  
// 마우스 호버영역, 확장량(?) 변수 설정
  var hoverZone = 150;
  var expandAmount = 20;
  
  // 열리기 전 메뉴가 마우스 위치를 따라 주욱 늘어나는 기능
  function svgCurve() {
    if ((curveX > x-1) && (curveX < x+1)) {
    // x-1 ~ x+1 의 범위안에 주욱 늘어나는 부분이 들어왔을 경우 멈춤
      xitteration = 0;
    } else {
      if (menuExpanded) { // 메뉴오픈시 타겟 0 (움직임 x)
        targetX = 0;
      } else {
        xitteration = 0;
        if (x > hoverZone) { // 마우스좌표x가 호버영역 밖에 있을경우 타겟 0
          targetX = 0;
        } else {
          targetX = -(((60+expandAmount)/100)*(x-hoverZone));
          	// 메뉴가 닫혀있고 마우스 좌표x가 호버영역 안에 있을경우,
			// x와 호버영역수치의 차액에 확장량을 곱한 수치를 x타겟좌표로 잡는다.
        }     
      }
      //만약 마우스좌표 x의 양옆 1의 범위 밖이면 이 수치가 상승한다.
      xitteration++;
    }

 // 마우스좌표 y (높이)와 주욱 늘어가는 위치 맞추기
   if ((curveY > y-1) && (curveY < y+1)) { 
  // y-1 ~ y+1 의 범위안에 주욱 늘어나는 부분이 들어왔을 경우 멈춤
      yitteration = 0;
    } else {
   // 아닐경우 움직임
      yitteration = 0;
      yitteration++;  
    }

    curveX = easeOutExpo(xitteration, curveX, targetX-curveX, 100);
    curveY = easeOutExpo(yitteration, curveY, y-curveY, 100);

    var anchorDistance = 200;
    var curviness = anchorDistance - 40;

    var newCurve2 = "M60,"+height+"H0V0h60v"+(curveY-anchorDistance)+"c0,"+curviness+","+curveX+","+curviness+","+curveX+","+anchorDistance+"S60,"+(curveY)+",60,"+(curveY+(anchorDistance*2))+"V"+height+"z";

    blobPath.attr('d', newCurve2);

    blob.width(curveX+60);

    hamburger.css('transform', 'translate('+curveX+'px, '+curveY+'px)');
    
    $('h2').css('transform', 'translateY('+curveY+'px)');
    window.requestAnimationFrame(svgCurve);
  }

  window.requestAnimationFrame(svgCurve);
  
});

 

 

출처 : http://rwdb.kr/interestedeffects/

 

웹의 구성을 재미있게 해주는 HTML / CSS 효과들 - RWDB

RWDB Responsive Web Design dB Web awards, 우수 하이브리드웹·반응형웹 모음 사이트

rwdb.kr

 

# blaizer 효과

 

kutar37.tistory.com/entry/CSS-cubic-bezier%EB%9E%80

 

 

 

# 트랜지션 효과

 

webclub.tistory.com/624

반응형