음악, 삶, 개발
Vue 에서 p5.js 사용하기 : p5 의 instance 모드 본문
< 참고 자료 >
Youtube : Instance mode (a.k.a name spacing)
< p5.js 란? >
p5.js 는 HTML5 의 <canvas> 를 엄청나게 확장해주는 그래픽 라이브러리이다.
물론 <canvas> 가 기본적으로 제공하는 함수들만으로도 그려볼수있겠지만
복잡한 도형들을 그려낼려면 엄청난 노가다를 해야한다.
p5.js 가 제공하는 수많은 함수들을 사용하면, 훨씬 더 우아한 그림들을 그려낼수있다.
< 하지만 vue 애서 어떻게 p5.js 를? >
구글에서 p5 를 vue 에서 사용하는 것을 검색했을때,
결과가 거의 나오지않았다.
나오더라도 vue 3 의 composition api 를 사용하지않은 예제들이 대부분이었다.
그래서 엄청나게 디깅을 하고, 혼자 이것저것 코드를 해본 결과 방법을 마침내 찾아내었다.
다행인것은 p5 가 npm 모듈로도 출시되었다는것이다.
먼저 아래와 같이 설치한다.
npm i p5
그 다음 .vue 를 일단 아래와 같이 작성한다.
<!-- App.vue -->
<template>
<div id="container"></div>
</template>
<script>
import P5 from 'p5'
</script>
이제 p5 의 instance 를 만드는 코드를 추가해야한다.
function createP5(parentId, w, h, backgroundColor) {
const sketch = (p) => {
p.setup = () => {
p.noLoop()
p.createCanvas(w, h)
}
p.draw = () => p.background(backgroundColor)
}
return new P5(sketch, parentId)
}
위의 함수는 내가 만들었다.
이 함수는 p5 인스턴스를 초기화하고 생성해주는 코드이다.
깊게 이해하려하기보다는 외우는것이 편하다.
p5 의 instance 는 <canvas> 요소를 만들어낸다.
이 <canvas> 요소가 생성되면 들어갈 부모 태그가 필요한데, 이때 사용하는것이 parentId 이다.
그후의 인자인 w, h 는 <canvas> 의 width 와 height 속성이 된다.
backgroundColor 는 p5 의 background 함수의 인자로 넘겨지게된다.
이 createP5 함수는 p5 인스턴스를 초기화하면서 생성해주는데,
반드시 Vue 의 onMounted() 훅에서 호출되어야한다.
왜냐면 부모 컴포넌트가 먼저 생성되고 <canvas> 요소가 이 안으로 삽입되어야하기때문이다.
import { reactive, onMounted } from 'vue'
export default {
setup() {
const state = reactive({
p5 : {}
})
onMounted(() => {
state.p5 = createP5('container', 500, 500, 'green')
})
}
}
createP5 로 return 된 p5 인스턴스는 반드시 state 로 저장되어야한다.
그래야 추후 이 p5 인스턴스에 접근하여 무언가를 추가적으로 런타임에서 그려낼수있기때문이다.
위와 같이 onMounted 에서 p5 instance 를 생성하였다면,
p5 가 제공하는 모든 함수들을 호출하면서 그림을 그려내면된다.
function mouseDown() {
state.p5.background('red')
state.p5.ellipse(0, 0, 100, 100)
}
보이는것처럼, p5 인스턴스에서 무언가를 그리기위해서는
p5.draw() 를 우리가 호출할 필요가없고, 다이렉트로 p5 의 인스턴스에서
ellipse 같이 원하는 함수를 호출해버리면 바로 그려진다.
만약 Vue 의 일반적인 방법처럼 state 안에 데이터와
연동하고싶다면 초기화할때 draw 안에 모든것을 정의한뒤
state 가 변할때 redraw() 함수를 호출하는것이 현명할것이다.
< 모듈로 만들자 >
이 p5 인스턴스를 만드는 함수는 매우 자주 사용할것이므로,
따로 .js 파일로 만든뒤 .vue 에서 import 하여 사용하는것이 좋을것이다.
/* p5.js */
import P5 from 'p5'
function createP5(parentId, w, h, backgroundColor) {
const sketch = p => {
p.setup = () => {
p.noLoop()
p.createCanvas(w, h)
}
p.draw = () => p.background(backgroundColor)
}
return new P5(sketch, parentId)
}
export default createP5
로 정의후..
<!-- App.vue -->
<template>
<div id="p5-container"></div>
</template>
<script>
import { onMounted } from 'vue'
import createP5 from '../library/p5.js'
export default {
setup() {
onMounted(() => {
createP5('p5-container', 200, 200, 'green')
})
}
}
</script>
<style scoped>
#p5-container {
width : 500px;
height : 500px;
background-color : black;
}
</style>
같이 작성하면..