ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Erase canvas with socketIO
    Project using node.js/Cloning Catch-Mind 2020. 12. 17. 08:44

    Client 'A'가 canvas 를 지우는 logic

    // paint.js
    
    let erasing = false;
    
    const handleInputRangeEraser = (e) => {
      if (erasing) {
        const size = e.target.value;
        ctx.lineWidth = size;
      }
    };
    
    const erase = () => {
      erasing = true;
      ctx.globalCompositeOperation = "destination-out";
      ctx.lineWidth = eraserRange.value;
    };
    
    const handleClickEraser = () => {
      erase();
      getSocket().emit(window.events.erase);
    };
    // events.js
    
     erase: "erase",
     erased: "erased",
     setPencil: "setPencil",
     setPenciled: "setPenciled",

    erase()함수에서 ctx.globalCompositeOperation은 도형 합성 API다. type을 "destination-out"으로 해놓으면 마우스로 드래그한 부분이 지우개처럼 지워진다. 그리고 pencil과 eraser의 bold range 값은 각각 따로 놔야 한다. ctx.lineWidth로 width 값이 동기화되어 있기 때문에, 지우개 크기를 엄청 키우고 지웠다가 다시 pencil로 전환했을 때 원치 않는 크기로 지워지기 때문이다.

    // paint.js
    
    const setPencil = () => {
      erasing = false;
      ctx.globalCompositeOperation = "source-over";
      ctx.lineWidth = boldRange.value;
    };
    
    const handleClickColor = (e) => {
      const color = e.target.style.backgroundColor;
      ctx.strokeStyle = color;
      ctx.fillStyle = color;
      setPencil();
      getSocket().emit(window.events.setPencil);
    };
    
    const handleClickFill = () => {
      if (filling && !erasing) {
        fill();
        getSocket().emit(window.events.fill, { color: ctx.strokeStyle });
      }
    };

      erase 함수를 사용하면 여러 문제점들이 발생한다. erase를 사용하고 난 후, pencil이나 fill mode를 사용할 때 erase의 "destination-out"이 적용될 수 있기 때문이다. 그래서 fill mode를 사용할 때 전체 화면에 "destination-out"이 적용되지 않도록 if 문에 !erasing을 추가했다.

      그리고 pencil 부분은 그림을 그릴 때 색깔이 들어가도록 ctx.globalCompositeOperation="source-over"를 해주고 서버에게 setPencil event를 보낸다.

    server

    // socketController.js
    
    socket.on(events.erase, () => broadcast(events.erased));
    socket.on(events.setPencil, () => broadcast(events.setPenciled));

    Client 'A'로 부터 erase와 setPencil event를 수신하면 다른 Client들에게 erased와 setPenciled event를 보낸다.

    Other clients

    // sockets.js
    import {
      handleErased,
      handleSetPenciled,
    } from "./paint";
    
    socket.on(events.erased, handleErased);
    socket.on(events.setPenciled, handleSetPenciled);
    // paint.js
    
    const erase = () => {
      erasing = true;
      ctx.globalCompositeOperation = "destination-out";
      ctx.lineWidth = eraserRange.value;
    };
    
    const setPencil = () => {
      erasing = false;
      ctx.globalCompositeOperation = "source-over";
      ctx.lineWidth = boldRange.value;
    };
    
    export const handleErased = () => erase();
    export const handleSetPenciled = () => setPencil();

    server로부터 erased event를 수신하면 canvas에서 마우스로 드래그 한 부분을 지운다.

    server로부터 setPenciled event를 수신하면 pencil 설정을 한다.

    소스 코드

    github.com/zpskek/guessMind-v3/commit/93f28465e85156df9d795ce39caf5b75e5f66b1b

    'Project using node.js > Cloning Catch-Mind' 카테고리의 다른 글

    Log out event with socketIO  (0) 2020.12.17
    Player update  (0) 2020.12.17
    Fill the canvas with socketIO  (0) 2020.12.17
    Drawing canvas with socketIO  (0) 2020.12.15
    Chat with socketIO  (0) 2020.12.15

    댓글

Designed by Tistory.