
this.eraserEl = this.toolbarEl.querySelector('#eraser');
event.currentTarget.classList.toggle('active')
class DrawingBoard {
  MODE = 'NONE'; // 브러시 모드 : NONE BRUSH ERASER
  IsMouseDown = false; // T/F
  eraserColor = '#FFFFFF'; // !지우개 변수
  backgroundColor = '#FFFFFF'; // !배경색 변수
  constructor() {
    this.assignElement();
    this.initContext();
    this.initCanvasBackgroundColor(); // !
    this.addEvent();
  }
  assignElement() {
    ...
    
    this.eraserEl = this.toolbarEl.querySelector('#eraser');
  }
  // 캔버스 초기화 (초기화 시 캔버스 크기만큼의 직사각형을 그리고 시작하는 개념)
  initCanvasBackgroundColor() {
    this.context.fillStyle = this.backgroundColor;
    this.context.fillRect(0, 0, this.canvasEl.width, this.canvasEl.height);
  }
  addEvent() {
	...
    
    this.eraserEl.addEventListener('click', this.onClickEraser.bind(this));
  }
  onMouseOut() {
	... 
    // 조건문으로 변경
    if (this.MODE === 'BRUSH') {
      this.context.strokeStyle = this.colorPickerEl.value; // 컬러피커의 값
      this.context.lineWidth = this.brushSliderEl.value; // 브러시슬라이더의 값
    } else if (this.MODE === 'ERASER') {
      // 지우개를 배경색(흰색)인 브러시로 덮는 개념이라고 보면 됨
      this.context.strokeStyle = this.eraserColor;
      this.context.lineWidth = 50;
    }
  }
  // 마우스를 움직일 때
    const IsActive = event.currentTarget.classList.contains('active'); // 반복 코드 정리
    this.MODE = IsActive ? 'NONE' : 'BRUSH';
    this.canvasEl.style.cursor = IsActive ? 'default' : 'crosshair';
    this.brushPanelEl.classList.toggle('hide'); // 브러시 패널 활성화
    event.currentTarget.classList.toggle('active'); // !
    // this.brushEl.classList.toggle('active');
    this.eraserEl.classList.remove('active');
  }
  // 지우개 기능 (브러시 기능 응용)
  // 지우개를 눌렀을 때 상태 변경
  onClickEraser() {
    const IsActive = event.currentTarget.classList.contains('active');
    this.MODE = IsActive ? 'NONE' : 'ERASER';
    this.canvasEl.style.cursor = IsActive ? 'default' : 'crosshair';
    this.brushPanelEl.classList.add('hide');
    event.currentTarget.classList.toggle('active'); // !
    // this.eraserEl.classList.toggle('active');
    this.brushEl.classList.remove('active');
  }
}
fillRect()
event target과 currentTarget의 차이

    this.navigatorEl = this.toolbarEl.querySelector('#navigator');
    this.navigatorImageContainerEl = this.containerEl.querySelector('#imgNav');
    this.navigatorImageEl = this.containerEl.querySelector('#canvasImg');
class DrawingBoard {
  ...
    
  assignElement() {
	...
    
    this.navigatorEl = this.toolbarEl.querySelector('#navigator');
    this.navigatorImageContainerEl = this.containerEl.querySelector('#imgNav');
    this.navigatorImageEl = this.containerEl.querySelector('#canvasImg');
  }
  
  addEvent() {
	...
    
    this.navigatorEl.addEventListener(
      'click',
      this.onClickNavigator.bind(this),
    );
  }
  
  onMouseOut() {
    if (this.MODE === 'NONE') return;
    this.IsMouseDown = false;
    this.updateNavigator(); // !
  }
  
  onMouseUp() {
    if (this.MODE === 'NONE') return;
    this.IsMouseDown = false;
    this.updateNavigator(); // !
  }
  
  // 네비게이터(미니맵)
  onClickNavigator(event) {
    event.currentTarget.classList.toggle('active');
    this.navigatorImageContainerEl.classList.toggle('hide');
    // console.log(this.canvasEl.toDataURL());
    this.updateNavigator();
  }
  updateNavigator() {
    this.navigatorImageEl.src = this.canvasEl.toDataURL();
  }
  
}
HTMLCanvasElement.toDataURL()
매개변수 에서 지정한 형식의 이미지 표현을 포함하는 데이터 URLtype 을 반환
캔버스에 그린 그림을 문자열 형태로 변환할 수 있는데, 이 문자열에는 이미지 MIME 타입과 인코딩 방법 그리고 인코딩 된 이미지 데이터 문자열이 포함된다
이미지의 컨텍스트 에서 데이터 URL 은 기본적 으로 ASCII 문자열로 표시되는 Base64 로 인코딩된 이미지 파일의 이진 데이터

~ing