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가 로드되었을 때
위 코드로 인해 가로 세로 길이가 고정되었기 때문이다.
화면이 resize 될 때마다 캔버스의 크기가 바뀌도록 하자. 윈도우가 resize될 때마다 캔버스의 가로 세로 길이가 새로운 innerWidth와 innerHeight를 가지도록 하면 된다.
init() 함수를 만들고 캔버스 크기와 관련된 코드를 함수 안으로 가져온다.
canvasWidth와 canvasHeight 변수는 함수 밖에서 let으로 선언해둔다.
그리고 화면이 resize될 때마다 생성되는 파티클의 랜덤 값들도 바껴야 하므로 해당 코드들도 init함수 안으로 옮긴다.
윈도우가 resize될 때마다 이 init 함수를 실행시키면 된다.
윈도우가 로드되면 init과 animate 함수를 실행시키고 resize되면 init함수를 실행시킨다.
화면이 커지면 파티클 수가 늘어나게 해보자.
Total 변수를 init 함수 안으로 옮기고 Total값을 가로 사이즈/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()
})
'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 |