vue / webpack / three.js
프론트 개발환경을 vue로 정했고.
https://ing-min.tistory.com/31?category=1052709
Vue_시작하기
[작업 환경 만들기] 0.node 설치(14.18.2 버전) https://nodejs.org/ko/download/releases/ 이전 릴리스 | Node.js Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. nodejs.org 윈도..
ing-min.tistory.com
3d 오브젝트를 mqtt를 활용해 제어하고 싶다.
그러기 위해서 three.js를 사용하기로 했고,
내 obj 파일을 three.js의 obj loader 로 올리려고했다 하지만 obj 파일을 경로에서 읽지 못한다.
-> public 경로를 사용해 axios를 활용해 불러올 수 있지만
경로의 특정 파일을 webpack의 file loader로 쉽게 활용한다 하니 이참에 vue + webpack 환경을 구현해보기로 했다.
- vue : 우리가 사용할 JS 프레임워크.
- vue-loader : Vue 파일을 JS로 변환해준다.
- vue-template-compiler : Vue 파일을 JS로 변환해준다.
- webpack : 파일을 일부 변형하여 코드를 전달하고 하나로 묶어주는 도구. ⚠️버전주의
- webpack-cli : webpack 명령을 실행하는 사용하는 cli. ⚠️버전주의
- webpack-dev-server : 로컬에서 개발 서버를 실행하기 위해 사용하는 도구. ⚠️버전주의
- babel-loader : 우리의 코드를 브라우저에 맞는 코드로 변환해준다. (ES6 => ES5)
- css-loader : vue에서 구현한 css 파일을 가져와서 해당 파일의 경로로 확인해준다. ⚠️버전주의
- vue-style-loader : css-loader로 불어온 css 파일을 html에 삽입해준다.
- sass-loader : vue에서 구현한 sass 파일을 가져와서 해당 파일의 경로로 확인해준다.
- mini-css-extract-plugin : 자바스크립트 파일에서 css를 별도의 파일로 분리해서 번들링하게 해준다.
- html-webpack-plugin : index.html을 가져와서 번들된 JS파일을 header에 삽입한다.
- rimraf : 명령줄에서 파일삭제를 허용해준다. 여러번 프로젝트를 빌드할때 유용하며, 오래된 빌드를 삭제해준다.
- -D : 하나의 파일로 모든 파일의 종속성을 묶어준다.
https://chb2005.tistory.com/16
[Vue] 웹팩 설치 및 사용법
전에 만들었던 더하기 문제 맞추기 예시를 통해 웹팩 개념 정리 ● 웹팩이란? 웹팩 : HTML, CSS, Javascript 등 많은 파일들을 하나의 js 파일로 변환 해주는 도구 코드 관리 용이, 로딩 속도 증가, 버전
chb2005.tistory.com
웹펙 / 뷰 설치
그렇다면 webpack이 도데체 뭘까
웹팩은 HTML,CSS, Javascript 등 많은 파일들을 하나의 js 파일로 변환해주는 도구라고 .. 한다.
코드관리가 용이하고 로딩 속도가 증가하고 버전 관리가 용이하여 다들 사용한다고 한다..
후.
일단 설치해보다가 많은 문제가 발생했다.
npm run serve 자체가 안 된다. 뭐가 문제일까 ... -> 버전 문제였다. 으으
- 설치 과정
node.js를 설치하여 npm을 사용할 수 있어야한다.
경로 파일을 하나 만든다.
npm init -y
npm install -g @vue/cli@4.5.15
vue create vueproj
#여기 설정은 위의 사이트 경로에서 확인 vue 버전이 2여야 three.js 오류 없다 !!!!주의
npm i webpack@4.10.0 -D
npm i webpack-cli@4.10.0 -D
npm i vue-loader@15.0.0 -D
npm i vue-template-compiler -D
(+ CSS 사용하려면 'npm i css-loader -D', 'npm i vue-sytle-loader -D' 입력)
npm install
webpack.config.js 파일 만들기
const path = require("path");
const { VueLoaderPlugin } = require('vue-loader');
module.exports = {
//진입점
entry: {
app: path.join(__dirname, "main.js"), //웹팩으로 빌드할 파일
},
// 결과물에 대한 설정
output: {
filename: "[name].js", //app.js 결과물을 담은 파일
path: path.join(__dirname, "dist"), // 결과물이 저장될 디렉토리
},
//모듈 rules를 통해 .vue로 끝나는 파일들은 vue-loader를 사용하겠다고 정의 vue->js
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
},
//플러그인 vue-loder를 위해 vueloaderplugin 가져옴
plugins: [
new VueLoaderPlugin()
]
};
const VueLoaderPlugin 불러올 수 없다는 오류 -> const { VueLoaderPlugin } = require('vue-loader'); 대괄호 이렇게 쳐주니 수정됨..
package.json(버전 확인 !!!!! webpack 들어간 애들은 다 버전이 같아야한다 하하하)
(버전확인 !!! vue loader 버전 17-> 15로 :cannot find module 'vue/compiler-sfc' 이 오류 뜰 때 ..)
{
"name": "vuewebpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"serve": "webpack-dev-server --mode development",
"build": "webpack --watch"
},
"author": "",
"license": "ISC",
"devDependencies": {
"vue-loader": "^15.0.0",
"vue-template-compiler": "^2.7.9",
"webpack": "^4.10.0",
"webpack-cli": "^4.10.0"
},
"dependencies": {
"html-webpack-plugin": "^5.5.0",
"vue-gl": "^1.0.0",
"webpack-dev-server": "^4.10.0"
}
}
scripts 부분 test일 경우 serve로 고쳐주기
"scripts": {
"serve": "webpack-dev-server --mode development"
},
이래야 npm run serve 가능 (웹 띄우는 코드)
build 명령어를 사용하면 계속 껏다켰다 안 하고 수정하는 대로 바로 run 되서 편리함.
프로젝트를 배포하기 위해서는 빌드작업을 해줘야한다. webpack-dev-server는 작업을 할때, 진행사항을 눈으로 확인하기위해 사용하는 서버이지 배포용 서버가 아니기 때문이다. package.json에 clean과 build를 스크립트를 추가하자. 한 단계전인 [serve] 추가하기에 있는 이미지를 참고하면 작업이 더욱 쉬울 것이다. 아래내용을 작성하자.
"scripts": {
"clean": "rimraf dist",
"build": "npm run clean && webpack --mode production",
"serve": "webpack-dev-server --mode development"
},
빌드를 시작하면 dist라는 폴더가 생기는데 Webpack이 프로젝트를 빌드 할 때 자동으로 생성되는 폴더이니 신경쓰지 말자! 아래 명령어를 사용하면 프로젝트가 빌드된다.
npm run build
참고
https://hj-tilblog.tistory.com/75
Vue.js Webpack 초기세팅
webpack으로 초기세팅을 하자! 사실 해당 글은 예전에도 정리한적이 있는데, 동기분들이 읽고 따라하기에 부족한점이 있는 것같아 내용을 보충하여 새로 정리하고자 한다. 순서대로 따라 진행한
hj-tilblog.tistory.com
.eslintrc.js
module.exports = {
root: true,
env: {
node: true,
},
// extends: ["plugin:vue/essential", "eslint:recommended", "@vue/prettier"],
extends: ["plugin:vue/recommended", "eslint:recommended", "@vue/prettier"],
parserOptions: {
parser: "babel-eslint",
},
rules: {
"prettier/prettier": [
"error", {
singleQuote: true,
semi: false,
useTabs: false,
tabWidth: 2,
trailingComma: "none",
printWidth: 120,
bracketSpacing: true,
arrowParens: "avoid",
endOfLine: "auto",
}
],
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
"no-unused-vars": ["warn", { vars: "all", args: "after-used", ignoreRestSiblings: false }],
},
};
setting.js
{
"eslint.validate": ["vue", "javascript", "html"],
"eslint.alwaysShowStatus": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"eslint.workingDirectories": [{ "mode": "auto" }],
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": false,
"prettier.trailingComma": "all"
}
부트스트랩 설치\
npm install bootstrap@4.5.3 bootstrap-vue@2.21.2 --save
https://archijude.tistory.com/487
Vue.js) global(전역) 함수 만들어서 콘솔 로고 사용하기
개발중에 console.log를 사용했던것 들을 개발이 끝난뒤 일일히 지우기가 매우 번거로워 처음부터 전역 함수로 만들어서 사용하기로 하였습니다. 생성 방벙에 대해 적어보겠습니다. - 개발환경 (vue
archijude.tistory.com
main.js 에 use 추가하기 : 글로벌로 선언하여 모든 파일에서 쓸수 있게한다 !.
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
// bootstrap
import { BootstrapVue } from 'bootstrap-vue'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
Vue.use(BootstrapVue)
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
이제 three.js!!!!!!!
npm install --save three
main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import * as Three from 'three'
Vue.config.productionTip = false
// bootstrap
import { BootstrapVue } from 'bootstrap-vue'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
Vue.use(BootstrapVue)
Vue.use(Three)
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
views/Three.vue
<template>
<div id="container"></div>
</template>
<script>
import * as THREE from 'three'
export default {
name: 'ThreeTest',
data() {
return {
cube: null,
renderer: null,
scene: null,
camera: null
}
},
mounted() {
this.init()
this.animate()
},
methods: {
init: function () {
this.scene = new THREE.Scene()
this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
this.renderer = new THREE.WebGLRenderer()
this.renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(this.renderer.domElement)
const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 })
this.cube = new THREE.Mesh(geometry, material)
this.scene.add(this.cube)
this.camera.position.z = 5
const animate = function () {}
},
animate: function () {
requestAnimationFrame(this.animate)
this.cube.rotation.x += 0.01
this.cube.rotation.y += 0.01
this.renderer.render(this.scene, this.camera)
}
}
}
</script>
router 설정
index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/three',
name: 'Three',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "three", webpackPrefetch:ture */ '../views/Three.vue')
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
home 에서 three로 경로 이동하게 만들기
App.vue
<template>
<div>
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/three">Three</router-link>
</div>
<router-view />
</div>
</template>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {
padding: 30px;
}
#nav a {
font-weight: bold;
color: #2c3e50;
}
#nav a.router-link-exact-active {
color: #42b983;
}
</style>
이렇게 오류없이 출력가능 ..
이제 원하는 obj를 띄워보자 ...
[three.js obj loader]
https://github.com/fritx/vue-threejs
GitHub - fritx/vue-threejs: Vue bindings for Three.js
Vue bindings for Three.js. Contribute to fritx/vue-threejs development by creating an account on GitHub.
github.com
obj 경로 꼭 public / static에 넣어야한다 !
example / SF03
<template>
<object3d :position="pos" base-url="static/threex/spaceships/">
<mesh>
<m-obj-mtl obj-url="SpaceFighter03.obj"
mtl-url="SpaceFighter03.mtl"
:process="getBody">
</m-obj-mtl>
</mesh>
<mesh v-for="n in 2" :key="`1-${n}`" :scale="4"
:position="{ x: 5 * Math.sign(n - 1.5), z: 0.8 }">
<geometry type="Plane" :args="[1, 1]"></geometry>
<material type="MeshBasic" :options="detonation.matOpts">
<texture url="lensflare0_alpha.png"></texture>
</material>
</mesh>
<object3d v-for="n in 2" :key="`2-${n}`"
:rotation="{ y: Math.PI / 2 }" :scale="4"
:position="{ x: 5 * Math.sign(n - 1.5), z: 2.6 }">
<mesh v-for="n1 in 4" :key="n1"
:rotation="{ x: (n1 - 1) * Math.PI / 4 }">
<geometry type="Plane" :args="[1, 1]"></geometry>
<material type="MeshBasic" :options="shoot.matOpts">
<texture :canvas="shoot.txtCanvas"></texture>
</material>
</mesh>
</object3d>
<animation :fn="animate"></animation>
</object3d>
</template>
<script>
import * as THREE from 'three'
import { Object3D } from '@'
export default {
name: 'SF03',
mixins: [Object3D],
data () {
return {
detonation: {
matOpts: {
color: 0x00ffff,
side: THREE.DoubleSide,
blending: THREE.AdditiveBlending,
opacity: 2,
depthWrite: false,
transparent: true
}
},
shoot: {
matOpts: {
color: 0xffaacc,
side: THREE.DoubleSide,
blending: THREE.AdditiveBlending,
depthWrite: false,
transparent: true
},
txtCanvas: this.generateShootCanvas()
},
pos: null
}
},
methods: {
animate (tt) {
this.pos = { y: Math.sin(tt) }
},
getBody (group) {
let body = group.children[0]
body.material.color.set(0xffffff)
return body
},
/* eslint-disable semi, space-in-parens */
generateShootCanvas () {
// init canvas
var canvas = document.createElement( 'canvas' );
var context = canvas.getContext( '2d' );
canvas.width = 16;
canvas.height = 64;
// set gradient
var gradient = context.createRadialGradient(
canvas.width / 2, canvas.height / 2, 0,
canvas.width / 2, canvas.height / 2, canvas.width / 2
);
gradient.addColorStop( 0, 'rgba(255,255,255,1)' );
gradient.addColorStop( 0.5, 'rgba(192,192,192,1)' );
gradient.addColorStop( 0.8, 'rgba(128,128,128,0.7)' );
gradient.addColorStop( 1, 'rgba(0,0,0,0)' );
// fill the rectangle
context.fillStyle = gradient;
context.fillRect(0, 0, canvas.width, canvas.height);
// return the just built canvas
return canvas;
}
}
}
</script>
여기 코드를 바꿔서 썼다.
잘 로드되긴하는데..
회전..페어런트 가능한지 알아봐야한다,-> 그룹 가능 : 회전 순거 정하기 가능 diamond.eulerOrder = 'ZYX';
Three.js Editor
three.js editor
threejs.org
http://benchung.com/using-three-js-editor/