ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [에스비지] SVG -(15편)- 자바스크립트를 이용한 마스크 돋보기 효과 (2/2) (feat. mask, JavaScript)
    SVG 2021. 2. 8. 00:09

    이번 시간은,

    돋보기가 마우스를 따라 움직이며 저 돋보기 안쪽부분에서만 보이도록 할 것이다.

     

    그래서 일러스트레이터로 돋보기를 그렸다.

    그럼 svg는 저 초록영역의 path와

    검정부분의 circle이 있을거라고 예상이 된다.

     

     

    그렇게 svg 파일을 만든다.

     

    <svg id="레이어_1" data-name="레이어 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 97.17 97.17">
      <defs>
        <style>
          .cls-1 {
            fill: #231815;
          }
    
          .cls-2 {
            fill: #1b8964;
          }
        </style>
      </defs>
      <title>magnifier</title>
      <circle class="cls-1" cx="38.88" cy="38.88" r="30.15"/>
      <path class="cls-2" d="M86.32,25.33A38.88,38.88,0,1,0,82.06,84l26.75,26.75a1.25,1.25,0,0,0,1.77,0l6.17-6.17a1.25,1.25,0,0,0,0-1.77L90,76.06A38.88,38.88,0,0,0,86.32,25.33ZM80.15,74.15a30.15,30.15,0,1,1,0-42.64A30.16,30.16,0,0,1,80.15,74.15Z" transform="translate(-19.95 -13.95)"/>
    </svg>
    

    svg 파일의 코드다.

     

    예상대로 circle과 path가 있다.

    circle은 마스크 영역이 될테다.

     

     

    그럼 html에 body 안에 svg태그 안에

    path와 circle을 복사해와서 붙여넣기 하자 색상도 같이 가져오자.

     

    <!DOCTYPE html>
    <html lang="ko">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>SVG: mask</title>
      <style>
        .magnifier {
          position: absolute;
          left: 0;
          top: 0;
          width: 100%;
          height: 100%;
          background-color: #eee;
        }
      </style>
    </head>
    <body>
      <svg class="magnifier">
        <path class="cls-2" d="M86.32,25.33A38.88,38.88,0,1,0,82.06,84l26.75,26.75a1.25,1.25,0,0,0,1.77,0l6.17-6.17a1.25,1.25,0,0,0,0-1.77L90,76.06A38.88,38.88,0,0,0,86.32,25.33ZM80.15,74.15a30.15,30.15,0,1,1,0-42.64A30.16,30.16,0,0,1,80.15,74.15Z" transform="translate(-19.95 -13.95)" fill="#1b8964" />
        <circle class="cls-1" cx="38.88" cy="38.88" r="30.15"/>
      </svg>
    </body>
    </html>

     

    svg 전체 영역잡아준 뒤,

    path의 색상도 inline으로 바로 적어줬다.

     

    여기까지는 아래의 모습이다.

     

     

     

    잘 나오고 있다.

     

     

    자 그럼 마스크를 씌어보자.

    이전시간에 배웠던 마스크 적용하는 것을 해보자.

     

    https://nyjchoi.tistory.com/19

     

    [에스비지] SVG -(14편)- 마스크 효과 (1/2) (feat. mask, id, url)

    이번에 우리가 해볼 것은 바로바로바로!!!!!!!!!!! MASK! 마스크 포토샵을 다뤄봤으면 알것이다. 필요한부분만 보이고, 원치않은 부분은 가리는 것. 자 포토샵을 열어봤다. 저기에서 노트북만 남기

    nyjchoi.tistory.com

    <defs></defs>

    안에

    <mask></mask>

    쓰고 그안에 마스크 씌울

    circle태그 옮겨오면 된다.

     

    <!DOCTYPE html>
    <html lang="ko">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>SVG: mask</title>
      <style>
        .magnifier {
          position: absolute;
          left: 0;
          top: 0;
          width: 100%;
          height: 100%;
          background-color: #eee;
        }
      </style>
    </head>
    <body>
      <svg class="magnifier">
        <defs>
          <mask id="mask-mag">
            <circle class="cls-1" cx="38.88" cy="38.88" r="30.15"/>
          </mask>
        </defs>
        <path class="mag-line" d="M86.32,25.33A38.88,38.88,0,1,0,82.06,84l26.75,26.75a1.25,1.25,0,0,0,1.77,0l6.17-6.17a1.25,1.25,0,0,0,0-1.77L90,76.06A38.88,38.88,0,0,0,86.32,25.33ZM80.15,74.15a30.15,30.15,0,1,1,0-42.64A30.16,30.16,0,0,1,80.15,74.15Z" transform="translate(-19.95 -13.95)" fill="#1b8964" />
      </svg>
    </body>
    </html>

     

    마스크는 설정이 됐다.

    그러나 뒤에 아무것도 없으니 뒤에 배경을 깔고,

    저 마스크 부분이 잘  보이는지 확인을 해보자.

     

    그전에!! 저 circle의 색깔이 현재 검정이니 fill값으로 흰색으로 만들고,

    그뒤에 배경을 깔자.

     

     

    배경은 패턴을 넣어 보자.

    패턴이 기억안난다면,

     

    https://nyjchoi.tistory.com/17?category=875542

     

    [에스비지] SVG -(12편)- 패턴만들기 (1/2) (feat. pattern, viewBox, width, height, defs)

    패턴 만들기 Pattern 오늘 알아야 할 핵심 키워드는 바로바로!! defs pattern width height viewBox 우리가 보통 배경으로 사용하는 그림이나 사진파일 등을 패턴을 넣어서 벽지처럼 깔 수가 있다. 지난시간

    nyjchoi.tistory.com

    https://nyjchoi.tistory.com/18?category=875542

     

    [에스비지] SVG -(13편)- 패턴만들기 (2/2) (feat. keyframes, animation, transform-origin, ...)

    패턴 만들기 Pattern 이번에는, svg를 body안에 넣는것이 아니라, css로 body태그의 background로 이미지를 링크해서 깔아 줄 것이다. 지난번에 사용한 face_hair.svg 파일을 사용하겠다. 그럼 이렇게 작게 나

    nyjchoi.tistory.com

     

     

    이 두곳에서 학습하고 돌아와 보자.

     

     

    우리가 만들었던 그 얼굴모양을 넣어보겠다.

     

     

    1. face.svg 파일의 도형들 및 패스들을 가져와

    pattern 태그 안에 넣어준다.

     

     

    자 지금 우리는 바로 눈에 보이는 것을 작업하고 있는게 아니라

    defs 안에 마스크를 생성했고,

    패턴을 생성했다.

    연결하지 않으면, 확인할 수 없다.

     

    따라서,

     

    2. 우리는 패턴을 설정은 했지만 깔아줘야 보이기 때문에,

     

    <rect></rect>

     

    를 통해서

     

    svg 사이즈에 맞게 너비 와 높이를 설정한 뒤에

    패턴을 넣을 것이다.

    <!DOCTYPE html>
    <html lang="ko">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>SVG: mask</title>
      <style>
        .magnifier {
          position: absolute;
          left: 0;
          top: 0;
          width: 100%;
          height: 100%;
          background-color: #eee;
        }
      </style>
    </head>
    <body>
      <svg class="magnifier">
        <defs>
          <pattern id="pattern_face" x="0" y="0" width="0.1" height="0.1" viewBox="0 0 500 500">
            <circle cx="213.63" cy="186" r="156" stroke-width="10" fill="none" stroke="#231815" stroke-miterlimit="10"/>
            <circle class="cls-2" cx="273.13" cy="162.94" r="23.06"/>
            <circle class="cls-2" cx="154.13" cy="162.94" r="23.06"/>
            <path d="M301.36 240.03a100 100 0 01-175.47 0" stroke-linecap="round" stroke-width="11" fill="none" stroke="#231815" stroke-miterlimit="10"/>
            <circle class="cls-2" cx="85.83" cy="95.33" r="30"/>
            <circle class="cls-2" cx="109.83" cy="68.67" r="30"/>
            <circle class="cls-2" cx="133.83" cy="42" r="30"/>
            <circle class="cls-2" cx="169.83" cy="32.67" r="30"/>
            <circle class="cls-2" cx="203.83" cy="30" r="30"/>
            <circle class="cls-2" cx="243.63" cy="32.67" r="30"/>
            <circle class="cls-2" cx="280.07" cy="42" r="30"/>
            <circle class="cls-2" cx="310.07" cy="60" r="30"/>
            <circle class="cls-2" cx="336.07" cy="85.33" r="30"/>
            <ellipse class="cls-4" cx="29.83" cy="196.33" rx="27.33" ry="36.33"/>
            <ellipse class="cls-4" cx="396.96" cy="196.33" rx="27.33" ry="36.33"/>
            <path class="cls-2" d="M398.29 218.22l3.98 12.27h12.9l-10.43 7.57 3.98 12.26-10.43-7.57-10.43 7.57 3.99-12.26-10.43-7.57h12.89l3.98-12.27zM28.96 218.22l-3.98 12.27h-12.9l10.43 7.57-3.98 12.26 10.43-7.57 10.43 7.57-3.99-12.26 10.43-7.57H32.94l-3.98-12.27z"/>
          </pattern>
          <mask id="mask-mag">
            <circle class="cls-1" cx="38.88" cy="38.88" r="30.15" fill="#fff"/>
          </mask>
          <style>
            <![CDATA[
            .cls-4{fill:none;stroke:#231815;stroke-miterlimit:10}
            .cls-2{fill:#231815}
            .cls-4{stroke-width:5px}    
    
            .bg-pattern {
              fill: url(#pattern_face);
            }
            ]]>
          </style>
        </defs>
        <path class="mag-line" d="M86.32,25.33A38.88,38.88,0,1,0,82.06,84l26.75,26.75a1.25,1.25,0,0,0,1.77,0l6.17-6.17a1.25,1.25,0,0,0,0-1.77L90,76.06A38.88,38.88,0,0,0,86.32,25.33ZM80.15,74.15a30.15,30.15,0,1,1,0-42.64A30.16,30.16,0,0,1,80.15,74.15Z" transform="translate(-19.95 -13.95)" fill="#1b8964" />
        
        <rect class="bg-pattern" x="0" y="0" width="100%" height="100%"></rect>
      </svg>
    </body>
    </html>

     

     

    여기까지의 모습은,

     

    그럼 우리는 마스크를 설정해 뒀기에

     

    3. 우리는 그 마스크를 전체 사각형에 연결시켜주면 될 것이다.

     

        g태그를 통해서!   

     

     

    <!DOCTYPE html>
    <html lang="ko">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>SVG: mask</title>
      <style>
        .magnifier {
          position: absolute;
          left: 0;
          top: 0;
          width: 100%;
          height: 100%;
          background-color: #eee;
        }
      </style>
    </head>
    <body>
      <svg class="magnifier">
        <defs>
          <pattern id="pattern_face" x="0" y="0" width="0.1" height="0.1" viewBox="0 0 500 500">
            <circle cx="213.63" cy="186" r="156" stroke-width="10" fill="none" stroke="#231815" stroke-miterlimit="10"/>
            <circle class="cls-2" cx="273.13" cy="162.94" r="23.06"/>
            <circle class="cls-2" cx="154.13" cy="162.94" r="23.06"/>
            <path d="M301.36 240.03a100 100 0 01-175.47 0" stroke-linecap="round" stroke-width="11" fill="none" stroke="#231815" stroke-miterlimit="10"/>
            <circle class="cls-2" cx="85.83" cy="95.33" r="30"/>
            <circle class="cls-2" cx="109.83" cy="68.67" r="30"/>
            <circle class="cls-2" cx="133.83" cy="42" r="30"/>
            <circle class="cls-2" cx="169.83" cy="32.67" r="30"/>
            <circle class="cls-2" cx="203.83" cy="30" r="30"/>
            <circle class="cls-2" cx="243.63" cy="32.67" r="30"/>
            <circle class="cls-2" cx="280.07" cy="42" r="30"/>
            <circle class="cls-2" cx="310.07" cy="60" r="30"/>
            <circle class="cls-2" cx="336.07" cy="85.33" r="30"/>
            <ellipse class="cls-4" cx="29.83" cy="196.33" rx="27.33" ry="36.33"/>
            <ellipse class="cls-4" cx="396.96" cy="196.33" rx="27.33" ry="36.33"/>
            <path class="cls-2" d="M398.29 218.22l3.98 12.27h12.9l-10.43 7.57 3.98 12.26-10.43-7.57-10.43 7.57 3.99-12.26-10.43-7.57h12.89l3.98-12.27zM28.96 218.22l-3.98 12.27h-12.9l10.43 7.57-3.98 12.26 10.43-7.57 10.43 7.57-3.99-12.26 10.43-7.57H32.94l-3.98-12.27z"/>
          </pattern>
          <mask id="mask-mag">
            <circle class="cls-1" cx="38.88" cy="38.88" r="30.15" fill="#fff"/>
          </mask>
          <style>
            <![CDATA[
            .cls-4{fill:none;stroke:#231815;stroke-miterlimit:10}
            .cls-2{fill:#231815}
            .cls-4{stroke-width:5px}    
    
            .bg-pattern {
              fill: url(#pattern_face);
            }
            ]]>
          </style>
        </defs>
        <path class="mag-line" d="M86.32,25.33A38.88,38.88,0,1,0,82.06,84l26.75,26.75a1.25,1.25,0,0,0,1.77,0l6.17-6.17a1.25,1.25,0,0,0,0-1.77L90,76.06A38.88,38.88,0,0,0,86.32,25.33ZM80.15,74.15a30.15,30.15,0,1,1,0-42.64A30.16,30.16,0,0,1,80.15,74.15Z" transform="translate(-19.95 -13.95)" fill="#1b8964" />
        
        <g mask="url(#mask-mag)">
          <rect class="bg-pattern" x="0" y="0" width="100%" height="100%"></rect>
        </g>
      </svg>
    </body>
    </html>

     

    g태그로 rect를 묶고 mask속성으로 url 연결 해주면,

     

     

    보기와 같이 마스크가 적용이 됐다.

     

     

     

     

    이제는 저 돋보기의 움직임을 자바스크립트를 통해 주면 된다.

     


     

    DOM script로 만들어 줄것이다.

     

    script태그 안에 써주면 된다.

     

     

     <script>
       window.addEventListener('DOMContentLoaded', function(){
              
       });
     </script>

    이렇게 시작을 한다.

     

    이것의 의미는 컴퓨터는 위에서 부터 차례로 읽어들이기 때문에,

    아직 정의되지 않은 이름이거나 셀렉터나 등등이 나오면,

    자바스크립트가 그게 뭔지 알 수 없어

    오류아닌 오류가 난다.

     

    그래서 전체를 로드한 뒤에 자바스크립트를 읽어라 라는 명령문

    저 위에 있는,

     

    <script>
      window.addEventListener('DOMContentLoaded', function(){
    
      });
    </script>

    이다.

     

     

     

    하지만,

     

     

    DOMContentLoaded

     

    대신에

     

    load

     

    를 해도 잘 작동 되지만,

     

     

     

    둘의 차이는 load는 용량이 큰 이미지가 있다면 그런것들까지 다 로드 한 뒤에 명령이 실행된다면,

    DOMContentLoaded는 DOM구조(태그들의 구조)만 로드 되면, 명령문이 실행되는 것이기 때문에,

     

    용량이 큰 어떤 것들이 다 로드 될때까지 기다릴 필요 없이,

     

    속도면에서 조금 더 빠를 수 밖에 없다.

     

     

     

     

    그래서 우리는 변수나 상수로 가져올 것들을 먼저 선언하고 그것들을 이용해

    마우스의 움직임에 따라 움직일 수 있도록 만들어 볼 것이다.

     

     

    우선 변수나 상수부터 만들어보자

     

    <script>
      window.addEventListener('DOMContentLoaded', function(){
      const magnifierElem = document.querySelector('.mag-line');
      const circleElem = document.querySelector('#mask-mag circle');
      });
    </script>

     

    그럼 마우스가 움직일때를 사용할때는,

     

    <script>
      window.addEventListener('DOMContentLoaded', function(){
        const magnifierElem = document.querySelector('.mag-line');
        const circleElem = document.querySelector('#mask-mag circle');
    
    
        window.addEventListener('mousemove', function(){
    
        });
      });
    </script>

    mousemove 이벤트를 사용한다.

     

    그리고 마우스의 이동에 따라 위치값을 가지려면

    이벤트객체가 가진 clientX 와 clientY 값을 사용하면 된다.

     

    <script>
      window.addEventListener('DOMContentLoaded', function(){
        const magnifierElem = document.querySelector('.mag-line');
        const circleElem = document.querySelector('#mask-mag circle');
    
    
        window.addEventListener('mousemove', function(e){
          magnifierElem.style.transform = `translate(${e.clientX}px, ${e.clientY}px)`;
        });
      });
    </script>

    저기서 ``는 키보드에서 보면 숫자 1 왼쪽에 있는 키다.

    보간법이라고 해서,

     

     

    영어로는 

     

    Template Strings

     

    이라고 한다.

     

     

    https://blog.naver.com/nicholasdw/222216524747

     

    [자바스크립트, JavaScript] 함수 function 기본(1) - Template Strings, 선언적 함수, 익명함수, not defined/undef

    #자바스크립트 #javascript #JavaScript #javaScript #JS #js #function #함수​​함수를 선언한다.매...

    blog.naver.com

     

    여기에서 이에대한 설명을 해뒀으니 확인바란다.

     

    1분코딩님이 설명하시길,

     

    예전에는 "" 나 '' 같은 따옴표과 ++를 사용하여 저렇게 넣었다면,

     

    <script>
      window.addEventListener('DOMContentLoaded', function(){
        const magnifierElem = document.querySelector('.mag-line');
        const circleElem = document.querySelector('#mask-mag circle');
    
    
        window.addEventListener('mousemove', function(e){
          magnifierElem.style.transform = "translate("+ e.clientX +"px," + e.clientY +"px)";
        });
      });
    </script>

     

    요즘은 저 위에 설명한

    템플릿 스프링스

    방식으로 간결하게 사용한다고 한다.

     

     

     

    <script>
      window.addEventListener('DOMContentLoaded', function(){
        const magnifierElem = document.querySelector('.mag-line');
        const circleElem = document.querySelector('#mask-mag circle');
    
    
        window.addEventListener('mousemove', function(e){
          magnifierElem.style.transform = `translate(${e.clientX}px, ${e.clientY}px)`;
          circleElem.style.transform = `translate(${e.clientX}px, ${e.clientY}px)`;
        });
      });
    </script>

     

    이렇게 작성해주면,

    마우스가 움직일때 따라다니는 걸 만들 수 있다.

    그리고 그 마스크를 통해

    돋보기 안에만 뒷 배경이 보이게 할 수 있는 것이다.

     

     

     

     

    오늘은 여기까지.

Designed by Tistory.