[Canvas] 캔버스 resize

2024. 5. 22. 18:00·Canvas
728x90

2024.05.22 - [Canvas] - [Canvas] dat.GUI 사용하기

 

[Canvas] dat.GUI 사용하기

2024.05.21 - [Canvas] - [Canvas] svg 필터 입히기(feGaussianBlur, feColorMatrix) | Gooey Effect [Canvas] svg 필터 입히기(feGaussianBlur, feColorMatrix) | Gooey Effect2024.05.20 - [Canvas] - [Canvas] 파티클 그리기 | 애니메이션 추가(re

gamzaggang7.tistory.com

 

현재 캔버스는 화면의 크기를 변경해도 바뀌지 않는다.

 

처음 js가 로드되었을 때

const canvasWidth = innerWidth
const canvasHeight = innerHeight

 위 코드로 인해 가로 세로 길이가 고정되었기 때문이다.

화면이 resize 될 때마다 캔버스의 크기가 바뀌도록 하자. 윈도우가 resize될 때마다 캔버스의 가로 세로 길이가 새로운 innerWidth와 innerHeight를 가지도록 하면 된다.

 

 

init() 함수를 만들고 캔버스 크기와 관련된 코드를 함수 안으로 가져온다.

function init() {
  const canvasWidth = innerWidth
  const canvasHeight = innerHeight

  canvas.style.width = canvasWidth + 'px'
  canvas.style.height = canvasHeight + 'px'

  canvas.width = canvasWidth * dpr
  canvas.height = canvasHeight * dpr
  ctx.scale(dpr, dpr)
}

canvasWidth와 canvasHeight 변수는 함수 밖에서 let으로 선언해둔다. 

그리고 화면이 resize될 때마다 생성되는 파티클의 랜덤 값들도 바껴야 하므로 해당 코드들도 init함수 안으로 옮긴다.

let canvasWidth
let canvasHeight
let particles

function init() {
  canvasWidth = innerWidth
  canvasHeight = innerHeight

  canvas.style.width = canvasWidth + 'px'
  canvas.style.height = canvasHeight + 'px'

  canvas.width = canvasWidth * dpr
  canvas.height = canvasHeight * dpr
  ctx.scale(dpr, dpr)

  particles = []

  for (let i = 0; i < Total; i++) {
    const x = randomNumBetween(0, canvasWidth)
    const y = randomNumBetween(0, canvasHeight)
    const r = randomNumBetween(50, 100)
    const vy = randomNumBetween(1, 5)
    const particle = new Particle(x, y, r, vy)
    particles.push(particle)
  }
}

윈도우가 resize될 때마다 이 init 함수를 실행시키면 된다.

window.addEventListener('load', () => {
  init()
  animate()
})

window.addEventListener('resize', () => {
  init()
})

윈도우가 로드되면 init과 animate 함수를 실행시키고 resize되면 init함수를 실행시킨다.

 

화면이 커지면 파티클 수가 늘어나게 해보자.

Total 변수를 init 함수 안으로 옮기고 Total값을 가로 사이즈/50 값으로 바꾼다.

const Total = canvasWidth / 50;

 

 

* 전체 코드 *

const canvas = document.querySelector('canvas')
const ctx = canvas.getContext('2d')
const dpr = window.devicePixelRatio

let canvasWidth
let canvasHeight
let particles

function init() {
  canvasWidth = innerWidth
  canvasHeight = innerHeight

  canvas.style.width = canvasWidth + 'px'
  canvas.style.height = canvasHeight + 'px'

  canvas.width = canvasWidth * dpr
  canvas.height = canvasHeight * dpr
  ctx.scale(dpr, dpr)

  particles = []

  const Total = canvasWidth / 50;

  for (let i = 0; i < Total; i++) {
    const x = randomNumBetween(0, canvasWidth)
    const y = randomNumBetween(0, canvasHeight)
    const r = randomNumBetween(50, 100)
    const vy = randomNumBetween(1, 5)
    const particle = new Particle(x, y, r, vy)
    particles.push(particle)
  }
}

const feGaussianBlur = document.querySelector('feGaussianBlur')
const feColorMatrix = document.querySelector('feColorMatrix')

const controls = new function () {
  this.blurValue = 40
  this.alphaChannel = 100
  this.alphaOffset = -23
  this.acc = -1.03
}

let gui = new dat.GUI()

const f1 = gui.addFolder('Gooey Effect')
f1.open()
const f2 = gui.addFolder('Particle Property')

f1.add(controls, 'blurValue', 0, 100).onChange(value => {
  feGaussianBlur.setAttribute('stdDeviation', value)
})
f1.add(controls, 'alphaChannel', 1, 200).onChange(value => {
  feColorMatrix.setAttribute('values', `1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 ${value} ${controls.alphaOffset}`)
})
f1.add(controls, 'alphaOffset', -40, 40).onChange(value => {
  feColorMatrix.setAttribute('values', `1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 ${controls.alphaChannel} ${value}`)
})
f2.add(controls, 'acc', 1, 1.5, 0.01).onChange(value => {
  particles.forEach(particle => particle.acc = value)
})

class Particle {
  constructor(x, y, r, vy) {
    this.x = x
    this.y = y
    this.r = r
    this.vy = vy
    this.acc = 1.05
  }
  update() {
    this.vy *= this.acc
    this.y += this.vy
  }
  draw() {
    ctx.beginPath()
    ctx.arc(this.x, this.y, this.r, 0, Math.PI / 180 * 360)
    ctx.fillStyle = 'skyblue'
    ctx.fill()
    ctx.closePath()
  }
}

const randomNumBetween = (min, max) => {
  return Math.random() * (max - min + 1) + min
}

console.log(particles);

let interval = 1000 / 60
let now, delta
let then = Date.now()

function animate() {
  window.requestAnimationFrame(animate)
  now = Date.now()
  delta = now - then

  if (delta < interval) return

  ctx.clearRect(0, 0, canvasWidth, canvasHeight)

  particles.forEach(particle => {
    particle.update()
    particle.draw()

    if (particle.y - particle.r > canvasHeight) {
      particle.y = -particle.r
      particle.x = randomNumBetween(0, canvasWidth)
      particle.r = randomNumBetween(50, 100)
      particle.vy = randomNumBetween(1, 5)
    }
  })

  then = now - (delta & interval)
}

window.addEventListener('load', () => {
  init()
  animate()
})

window.addEventListener('resize', () => {
  init()
})
728x90

'Canvas' 카테고리의 다른 글

[Canvas] 불꽃놀이 만들기  (1) 2024.06.10
[Canvas] 보일러 플레이트 작성 (캔버스 클래스)  (0) 2024.05.24
[Canvas] dat.GUI 사용하기  (0) 2024.05.22
[Canvas] svg 필터 입히기(feGaussianBlur, feColorMatrix) | Gooey Effect  (0) 2024.05.21
[Canvas] 파티클 그리기 | 애니메이션 추가(requestAnimationFrame)  (1) 2024.05.20
'Canvas' 카테고리의 다른 글
  • [Canvas] 불꽃놀이 만들기
  • [Canvas] 보일러 플레이트 작성 (캔버스 클래스)
  • [Canvas] dat.GUI 사용하기
  • [Canvas] svg 필터 입히기(feGaussianBlur, feColorMatrix) | Gooey Effect
gamzaggang7
gamzaggang7
  • gamzaggang7
    abcdefghklpqrstuvwxyz
    gamzaggang7
  • 전체
    오늘
    어제
    • 분류 전체보기
      • CS
        • OS
        • 자료구조_알고리즘
      • Java
      • Javascript
      • Node.js
      • React
      • Vue.js
      • 코딩테스트
        • 백준-Java
        • 프로그래머스-JS
      • Canvas
      • HTML, CSS
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    canvas
    npm
    정렬
    Next.js
    프로그래머스
    Node.js
    props
    자바공부
    라우팅
    백준풀이
    해시
    vue.js
    자바스크립트
    dat.gui
    서버구축
    큐
    fegaussianblur
    자바백준풀이
    fecolormatrix
    스택
    자바
    BFS
    css
    React
    2차원배열
    vue modal
    hashchange
    til
    오즈코딩스쿨
    vue animation
  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.3
gamzaggang7
[Canvas] 캔버스 resize
상단으로

티스토리툴바