cavans.html
cavans.ts
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import {
initRenderer,
initCamera,
initScene,
initLight,
initGrid,
initStats
} from 'src/app/config/base';
import { PickService } from '../../service/pick.service';
import { fromEvent } from 'rxjs';
import { FollowpathService } from '../../service/followpath.service';
import { Followpath2Service } from 'src/app/service/followpath2.service';
import { UvMapService } from '../../service/uv-map.service';
import { TweenjsService } from '../../service/tweenjs.service';
@Component({
selector: 'app-canva',
templateUrl: './canva.component.html',
styleUrls: ['./canva.component.scss']
})
export class CanvaComponent implements OnInit {
@ViewChild('canvasFrame', { static: true }) canvasContainer: ElementRef;
constructor(
private followpath: FollowpathService,
private followpath2: Followpath2Service,
private pick: PickService,
private uv: UvMapService,
private tween: TweenjsService
) {}
ngOnInit(): void {
this.init();
}
init() {
initRenderer(this.canvasContainer.nativeElement);
initCamera(this.canvasContainer.nativeElement);
initScene();
initLight();
initGrid();
initStats(this.canvasContainer.nativeElement);
this.addFunc();
// 以下代码用来更改demo star
// this.followpath.init();
// this.followpath2.init();
// this.uv.init();
this.tween.init();
// end
// // 监听鼠标事件,触发渲染函数,更新canvas画布渲染效果
// CONTROLS.addEventListener('change', requestAnimationFrame(rendererOut););
}
addFunc() {
fromEvent(this.canvasContainer.nativeElement, 'mousemove').subscribe(r => {
this.pick.getThings(r, this.canvasContainer.nativeElement);
});
}
}
base.ts
import {
Scene,
AmbientLight,
PointLight,
WebGLRenderer,
PerspectiveCamera,
GridHelper,
Color,
DirectionalLight
} from 'three';
import { OrbitControls, CSS3DRenderer } from 'three-full';
import * as Stats from 'stats.js';
// import * as TWEEN from '@tweenjs/tween.js';
// 渲染器
export const RENDERER = new WebGLRenderer({ antialias: true }); // 渲染器(去据此){ antialias: true }
export function initRenderer(doc) {
RENDERER.setSize(doc.clientWidth, doc.clientHeight);
RENDERER.shadowMap.enabled = true; // 辅助线
doc.appendChild(RENDERER.domElement);
}
// 场景
export const SCENE = new Scene();
export function initScene() {
SCENE.background = new Color(0xcccccc);
}
// 灯光
export function initLight() {
// 全局光
const ambientLight = new AmbientLight(0xffffff, 1);
SCENE.add(ambientLight);
// // 半球光
// const light = new HemisphereLight(0xffffff, 0x080820, 1);
// // CAMERA.add(light);
// SCENE.add(light);
// 点光源
const pointLight = new PointLight(0xffffff);
pointLight.distance = 0;
CAMERA.add(pointLight);
SCENE.add(CAMERA);
// 方向灯
const directionalLight = new DirectionalLight(0xffffff, 2);
SCENE.add(directionalLight);
}
// 相机
export let CAMERA;
export let CONTROLS;
export function initCamera(doc) {
const d = {
fov: 30, // 拍摄距离 视野角值越大,场景中的物体越小
near: 1, // 最小范围
far: 1000 // 最大范围
};
CAMERA = new PerspectiveCamera(
d.fov,
doc.clientWidth / doc.clientHeight,
d.near,
d.far
);
const p = {
x: 20,
y: 10,
z: 10
};
CAMERA.position.set(p.x, p.y, p.z);
CAMERA.lookAt(0, 0, 0);
CONTROLS = new OrbitControls(CAMERA, doc); // 控制镜头
}
// 网格
export function initGrid() {
const gridHelper = new GridHelper(100, 50);
SCENE.add(gridHelper);
}
// 性能检测
export const STATS = new Stats();
export function initStats(doc) {
STATS.setMode(0);
STATS.domElement.style.position = 'absolute';
STATS.domElement.left = '0px';
STATS.domElement.top = '0px';
doc.appendChild(STATS.domElement);
}
// css
export const CSS3D = new CSS3DRenderer();
export function initCSS3D(doc) {
CSS3D.setSize(doc.clientWidth, doc.clientHeight);
CSS3D.domElement.style.position = 'absolute';
CSS3D.domElement.style.zIndex = '1';
CSS3D.domElement.style.top = 0;
doc.appendChild(CSS3D.domElement);
}
// 动画混合器
export const MIX = [];
// export class MIXER {
// public mx;
// }
home直接放了cavans组件
service是放demo的
followpath.service.ts
import { Injectable } from '@angular/core';
import { RENDERER, SCENE, CAMERA, CONTROLS, STATS } from '../config/base';
import {
CatmullRomCurve3,
Vector3,
BufferGeometry,
LineBasicMaterial,
Line,
BoxBufferGeometry,
MeshBasicMaterial,
Mesh
} from 'three';
@Injectable({
providedIn: 'root'
})
export class FollowpathService {
constructor() {}
box;
points;
init() {
this.addBox();
this.addLine();
let i = 0;
const rendererOut = () => {
if (i < 500) {
this.box.position.set(
this.points[i].x,
this.points[i].y,
this.points[i].z
);
this.box.lookAt(
this.points[i + 1].x,
this.points[i + 1].y,
this.points[i].z
);
i++;
}
// 每个service里面都必须包含一下内容
requestAnimationFrame(rendererOut);
RENDERER.render(SCENE, CAMERA);
CONTROLS.update();
STATS.update();
// end
};
rendererOut();
}
addLine() {
const curve = new CatmullRomCurve3([
new Vector3(-10, 0, 0),
new Vector3(-5, 5, 0),
new Vector3(0, 0, 0),
new Vector3(5, -5, 0),
new Vector3(10, 0, 0)
]);
const points = curve.getPoints(500);
this.points = points;
const geometry = new BufferGeometry().setFromPoints(points);
const material = new LineBasicMaterial({ color: 0xff0000 });
// Create the final object to add to the scene
const splineObject = new Line(geometry, material);
SCENE.add(splineObject);
}
addBox() {
const geometry = new BoxBufferGeometry(1, 1, 1);
const material = new MeshBasicMaterial({ color: 0x00ff00 });
const cube = new Mesh(geometry, material);
this.box = cube;
SCENE.add(cube);
}
}