Skip to content

Commit a073937

Browse files
author
310198
committed
three.js库功能添加:提供3d图形绘制功能。
1 parent eb0891e commit a073937

File tree

6 files changed

+221
-10
lines changed

6 files changed

+221
-10
lines changed

index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<html>
33
<head>
44
<meta charset="utf-8">
5-
<title>vue2admin-v2</title>
5+
<title>vue2admin</title>
66
</head>
77
<body>
88
<div id="app"></div>

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"dependencies": {
1515
"element-ui": "^1.2.2",
1616
"js-cookie": "^2.1.3",
17+
"three": "^0.84.0",
1718
"vue": "^2.2.1",
1819
"vue-router": "^2.3.0",
1920
"vuex": "^2.2.1",

src/assets/logo.png

-1.6 KB
Loading

src/components/CWaves.vue

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<style scoped>
2+
.header {
3+
position: absolute;
4+
width: 100%;
5+
text-align: right;
6+
right: 0;
7+
top: 0;
8+
/*padding: 5px 120px;*/
9+
}
10+
11+
.header a {
12+
color: #ffffff !important;
13+
}
14+
15+
.center {
16+
position: absolute;
17+
text-align: center;
18+
top: 36%;
19+
left: 40%;
20+
height: 320px;
21+
width: 420px;
22+
color: #9cd7d1;
23+
}
24+
25+
.canvas-container {
26+
height: 100%;
27+
width: 100%;
28+
flex: 1;
29+
background-image: linear-gradient(70deg, #2061c2 0, #0d0525 100%);
30+
}
31+
</style>
32+
<template>
33+
<div id="waves_container" class="canvas-container">
34+
<div class="header">
35+
<slot name="header"></slot>
36+
</div>
37+
<div class="center">
38+
<slot name="center"></slot>
39+
</div>
40+
</div>
41+
</template>
42+
<script>
43+
import waves from './js/cwaves'
44+
45+
export default {
46+
mounted(){
47+
waves.init('waves_container');
48+
},
49+
beforeDestroy(){
50+
waves.removeEvent();
51+
}
52+
}
53+
</script>

src/components/js/cwaves.js

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/**
2+
* Created by lichb on 2017/4/10.
3+
*/
4+
import {
5+
Scene,
6+
PerspectiveCamera,
7+
WebGLRenderer,
8+
Texture,
9+
Vector3,
10+
SpriteMaterial,
11+
Object3D,
12+
Sprite,
13+
Math2
14+
} from 'three';
15+
const SEPARATION = 100, AMOUNTX = 50, AMOUNTY = 50; // 圆点间隔、x轴方向个数、y轴方向个数
16+
const waveStep = 0.04; // 波动速度
17+
const rotateStep = 0.02; // 旋转速度
18+
const CAMERAMOVERADIUS = 1000; // 相机旋转半径
19+
const cameraDefPos = new Vector3(0, 180, CAMERAMOVERADIUS); // 相机初始位置
20+
const focusDefPos = new Vector3(0, 700, 0); // 相机注视点位置
21+
22+
let container; // canvas容器
23+
let scene, camera, renderer;
24+
let particles, particle, count = 0;
25+
let theta = 0;
26+
let focusObject;
27+
28+
// 生成贴图
29+
function generateTexture() {
30+
let canvas = document.createElement('canvas');
31+
let context = canvas.getContext('2d');
32+
canvas.width = 128;
33+
canvas.height = 128;
34+
drawCircle(context, {x: 64, y: 64, r: 60, c: '#fff'});
35+
return canvas;
36+
}
37+
38+
// 画圆
39+
function drawCircle(context, arg) {
40+
let PI2 = Math.PI * 2;
41+
arg = arg || {x: 0, y: 0, r: 0.5, c: '#fff'};
42+
context.fillStyle = arg.c;
43+
context.beginPath();
44+
context.arc(arg.x, arg.y, arg.r, 0, PI2, true);
45+
context.fill();
46+
}
47+
48+
// 生成材质
49+
function getMaterial() {
50+
let texture = new Texture(generateTexture());
51+
texture.needsUpdate = true; // important!
52+
let material = new SpriteMaterial({color: 0xffffff, map: texture});
53+
return material;
54+
}
55+
56+
function onWindowResize() {
57+
camera.aspect = container.clientWidth / container.clientHeight;
58+
camera.updateProjectionMatrix();
59+
renderer.setSize(container.clientWidth, container.clientHeight);
60+
}
61+
62+
function drawWaves() {
63+
camera = new PerspectiveCamera(100, container.clientWidth / container.clientHeight, 1, 10000);
64+
camera.position.x = cameraDefPos.x;
65+
camera.position.y = cameraDefPos.y;
66+
camera.position.z = cameraDefPos.z;
67+
68+
scene = new Scene();
69+
70+
focusObject = new Object3D();
71+
focusObject.position.x = focusDefPos.x;
72+
focusObject.position.y = focusDefPos.y;
73+
focusObject.position.z = focusDefPos.z;
74+
scene.add(focusObject);
75+
76+
particles = [];
77+
let material = getMaterial();
78+
let i = 0;
79+
for (let ix = 0; ix < AMOUNTX; ix++) {
80+
for (let iy = 0; iy < AMOUNTY; iy++) {
81+
particle = particles[i++] = new Sprite(material);
82+
particle.position.x = ix * SEPARATION - ((AMOUNTX * SEPARATION - 1) / 2);
83+
particle.position.z = iy * SEPARATION - ((AMOUNTY * SEPARATION - 1) / 2);
84+
scene.add(particle);
85+
}
86+
}
87+
88+
renderer = new WebGLRenderer({alpha: true});
89+
renderer.setPixelRatio(window.devicePixelRatio);
90+
renderer.setSize(container.clientWidth, container.clientHeight);
91+
container.appendChild(renderer.domElement);
92+
window.addEventListener('resize', onWindowResize, false);
93+
}
94+
95+
function animate() {
96+
requestAnimationFrame(animate);
97+
render();
98+
}
99+
100+
function render() {
101+
let i = 0;
102+
for (let ix = 0; ix < AMOUNTX; ix++) {
103+
for (let iy = 0; iy < AMOUNTY; iy++) {
104+
particle = particles[i++];
105+
particle.position.y = (Math.sin((ix + count) * 0.3) * 26) +
106+
(Math.sin((iy + count) * 0.4) * 26);
107+
particle.scale.x = particle.scale.y = (Math.sin((ix + count) * 0.3) + 1) * 3 +
108+
(Math.sin((iy + count) * 0.4) + 1) * 3;
109+
}
110+
}
111+
112+
theta += rotateStep;
113+
camera.position.x = CAMERAMOVERADIUS * Math.sin(Math2.degToRad(theta));
114+
camera.position.z = CAMERAMOVERADIUS * Math.cos(Math2.degToRad(theta));
115+
camera.lookAt(focusObject.position);
116+
117+
renderer.render(scene, camera);
118+
count += waveStep;
119+
}
120+
121+
export default {
122+
init(id) {
123+
container = document.querySelector('#' + id);
124+
drawWaves();
125+
animate();
126+
},
127+
removeEvent(){
128+
window.removeEventListener('resize', onWindowResize);
129+
}
130+
}

src/modules/index/index.vue

+36-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
<style scoped>
2+
.full-screen {
3+
position: absolute;
4+
top: 0;
5+
left: 0;
6+
right: 0;
7+
bottom: 0;
8+
}
9+
210
.bg-purple-dark {
311
background: #99a9bf;
412
}
@@ -9,16 +17,35 @@
917
height: 36px;
1018
line-height: 36px;
1119
}
20+
21+
.el-menu--horizontal .el-menu-item {
22+
float: right !important;
23+
}
24+
25+
.el-menu{
26+
padding-right: 60px;
27+
}
1228
</style>
1329
<template>
14-
<div>
15-
<el-row>
16-
<el-col :span="8">&nbsp;</el-col>
17-
<el-col :span="8">
18-
<div class="grid-content bg-purple-dark">
19-
这是首页,点击跳转到<router-link to="/login">登录页面</router-link>
20-
</div>
21-
</el-col>
22-
</el-row>
30+
<div class="full-screen">
31+
<c-waves>
32+
<el-menu slot="header" theme="dark" default-active="1" class="el-menu-demo" mode="horizontal">
33+
<el-menu-item index="2"><router-link to="/login"><i class="el-icon-share"></i>登录</router-link></el-menu-item>
34+
<el-menu-item index="1"><i class="el-icon-menu"></i>首页</el-menu-item>
35+
</el-menu>
36+
<div slot="center">
37+
<img src="../../assets/logo.png" />
38+
<div style="font-size: 46px;">vue2admin</div>
39+
</div>
40+
</c-waves>
2341
</div>
2442
</template>
43+
<script>
44+
import CWaves from 'components/CWaves'
45+
46+
export default {
47+
components: {
48+
CWaves
49+
}
50+
}
51+
</script>

0 commit comments

Comments
 (0)