[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를 가지도록 하면 된다.

 

728x90

 

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
    250x250
  • gamzaggang7
    abcdefghklpqrstuvwxyz
    gamzaggang7
  • 전체
    오늘
    어제
    • 분류 전체보기
      • CS
        • OS
        • 자료구조_알고리즘
      • Java
      • Javascript
      • Node.js
      • React
      • Vue.js
      • 코딩테스트
        • 백준-Java
        • 프로그래머스-JS
      • Canvas
      • HTML, CSS
  • 블로그 메뉴

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

  • 공지사항

  • 인기 글

  • 태그

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

  • 최근 글

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

티스토리툴바