Skip to content

Instantly share code, notes, and snippets.

@stillefront
Last active March 7, 2023 12:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stillefront/f5ee6ef7767884d50d66d9190d23a543 to your computer and use it in GitHub Desktop.
Save stillefront/f5ee6ef7767884d50d66d9190d23a543 to your computer and use it in GitHub Desktop.
<template>
<div id="landing-animation-container" class="landing-animation-container">
<DebugControls />
</div>
</template>
<script>
import DebugControls from "../landing/DebugControls.vue";
import acumin from "@/assets/AcuminProRegular.json";
import {
Scene,
TrackballControls,
PerspectiveCamera,
WebGLRenderer,
Color,
FogExp2,
CylinderBufferGeometry,
MeshPhongMaterial,
Mesh,
DirectionalLight,
AmbientLight,
LineBasicMaterial,
Geometry,
Vector3,
//Quaternion,
Line,
FontLoader,
TextGeometry,
// GeometryUtils,
// QuaternionKeyframeTrack,
VectorKeyframeTrack,
AnimationClip,
AnimationMixer,
EffectComposer,
RenderPass,
BokehPass,
// ShaderPass,
// BokehShader
} from "three-full";
export default {
name: "BackgroundAnimation",
components: {
DebugControls,
},
props: {
mousecoords: Object,
opacity: Number,
},
data() {
return {
height: 0,
width: 0,
camera: null,
controls: null,
scene: null,
renderer: null,
postprocessing: {},
acumin: acumin,
mixer: null,
mixerO: null,
mixerI: null,
mixerN: null,
mixerBang: null,
axisLines: [],
pyramids: [],
letters: [],
};
},
mounted() {
this.INIT(this.$el.offsetWidth, this.$el.offsetHeight, this.$el);
this.ANIMATE();
this.RESIZE(this.$el.offsetWidth, this.$el.offsetHeight);
},
computed: {},
methods: {
SET_VIEWPORT_SIZE(width, height) {
this.width = width;
this.height = height;
},
INITIALIZE_RENDERER(el) {
this.renderer = new WebGLRenderer({ antialias: false });
this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.setSize(this.width, this.height);
this.renderer.gammaInput = true;
this.renderer.gammaOutput = true;
el.appendChild(this.renderer.domElement);
},
INITIALIZE_POSTPROCESSING() {
const composer = new EffectComposer(this.renderer);
const renderPass = new RenderPass(this.scene, this.camera);
renderPass.clear = false;
composer.addPass(renderPass);
const bokehPass = new BokehPass(this.scene, this.camera, {
focus: 500.0,
aperture: 5,
maxblur: 20.0,
width: this.width,
height: this.height,
});
bokehPass.renderToScreen = true;
composer.addPass(bokehPass);
this.postprocessing.composer = composer;
},
INITIALIZE_CAMERA() {
this.camera = new PerspectiveCamera(
// 1. Field of View (degrees)
110,
// 2. Aspect ratio
this.width / this.height,
// 3. Near clipping plane
1,
// 4. Far clipping plane
1000
);
this.camera.position.z = 135;
},
INITIALIZE_CONTROLS() {
this.controls = new TrackballControls(
this.camera,
this.renderer.domElement
);
this.controls.rotateSpeed = 1.0;
this.controls.zoomSpeed = 1.2;
this.controls.panSpeed = 0.8;
this.controls.noZoom = false;
this.controls.noPan = false;
this.controls.staticMoving = true;
this.controls.dynamicDampingFactor = 0.3;
},
INITIALIZE_SCENE() {
this.scene = new Scene();
this.scene.background = new Color(0xffffff);
this.scene.fog = new FogExp2(0xffffff, 0.003);
let geometry = new CylinderBufferGeometry(0, 10, 30, 4, 1);
let material = new MeshPhongMaterial({
color: 0xffffff,
flatShading: false,
});
for (var i = 0; i < 500; i++) {
var mesh = new Mesh(geometry, material);
mesh.position.x = (Math.random() - 0.5) * 1000;
mesh.position.y = (Math.random() - 0.5) * 1000;
mesh.position.z = (Math.random() - 0.5) * 1000;
mesh.updateMatrix();
mesh.matrixAutoUpdate = false;
this.pyramids.push(mesh);
}
var fontloader = new FontLoader();
let font = fontloader.parse(acumin);
function letterMesh(symbol, font, size, segments) {
const geometry = new TextGeometry(symbol, {
font: font,
size: size,
height: 0,
curveSegments: segments,
});
let material = new MeshPhongMaterial({
color: 0xff0000,
flatShading: false,
});
let mesh = new Mesh(geometry, material);
mesh.matrixAutoUpdate = true;
return mesh;
}
function poseMesh(mesh, x, y, z) {
mesh.geometry.center();
mesh.position.x = x;
mesh.position.y = y;
mesh.position.z = z;
}
function rotateMesh(mesh, xDeg, yDeg, zDeg) {
/* let rotQuaternion = new Quaternion();
const xAxis = new Vector3(1, 0, 0);
const yAxis = new Vector3(0, 1, 0);
const zAxis = new Vector3(0, 0, 1);
rotQuaternion.setFromAxisAngle(xAxis, xDeg);
rotQuaternion.setFromAxisAngle(yAxis, yDeg);
rotQuaternion.setFromAxisAngle(zAxis, zDeg); */
mesh.geometry.center();
mesh.rotation.x = xDeg;
mesh.rotation.y = yDeg;
mesh.rotation.z = zDeg;
}
/* function rotateQuaternion(mesh, xDeg, yDeg, zDeg) {
let meshCopy = structuredClone(mesh);
rotateMesh(meshCopy, xDeg, yDeg, zDeg);
return meshCopy.quaternion;
} */
let M = letterMesh("M", font, 80, 16);
poseMesh(M, -100, 70, 0);
rotateMesh(M, -0.2, -0.3, 0.6);
let o = letterMesh("o", font, 80, 16);
poseMesh(o, -30, 30, 60);
rotateMesh(o, 0.2, 0.1, 0);
let I = letterMesh("i", font, 80, 16);
poseMesh(I, 0, 0, -10);
rotateMesh(I, 0.4, -0.5, 0.5);
let n = letterMesh("n", font, 80, 16);
poseMesh(n, 50, 0, -70);
rotateMesh(n, -0.3, 0.5, 0.1);
let bang = letterMesh("!", font, 80, 16);
poseMesh(bang, 130, -10, -180);
rotateMesh(bang, -0.3, 0.4, -0.4);
this.letters.push(M);
this.letters.push(o);
this.letters.push(I);
this.letters.push(n);
this.letters.push(bang);
this.scene.add(...this.letters);
this.scene.add(...this.pyramids);
// animation testing
// Create an animation clip that moves the cube back and forth along the x-axis
const positionKFM = new VectorKeyframeTrack(
".position",
[0, 1, 2],
[
M.position.x,
M.position.y,
M.position.z,
M.position.x,
M.position.y + 10,
M.position.z,
M.position.x,
M.position.y,
M.position.z,
]
);
const positionKFo = new VectorKeyframeTrack(
".position",
[0, 1, 2],
[
o.position.x,
o.position.y,
o.position.z,
o.position.x + 5,
o.position.y - 20,
o.position.z,
o.position.x,
o.position.y,
o.position.z,
]
);
const positionKFi = new VectorKeyframeTrack(
".position",
[0, 1, 2],
[
I.position.x,
I.position.y,
I.position.z,
I.position.x - 5,
I.position.y - 15,
I.position.z + 10,
I.position.x,
I.position.y,
I.position.z,
]
);
const positionKFn = new VectorKeyframeTrack(
".position",
[0, 1, 2],
[
n.position.x,
n.position.y,
n.position.z,
n.position.x - 12,
n.position.y - 12,
n.position.z - 12,
n.position.x,
n.position.y,
n.position.z,
]
);
const positionKFbang = new VectorKeyframeTrack(
".position",
[0, 1, 2],
[
bang.position.x,
bang.position.y,
bang.position.z,
bang.position.x - 14,
bang.position.y,
bang.position.z,
bang.position.x,
bang.position.y,
bang.position.z,
]
);
// set up rotation about y axis
/* const qInitial = M.quaternion;
const qFinal = rotateQuaternion(M, 0.5, 0, 0);
const rotationKFo = new QuaternionKeyframeTrack(
".quaternion",
[0, 1, 2],
[
qInitial.x,
qInitial.y,
qInitial.z,
qInitial.w,
qFinal.x,
qFinal.y,
qFinal.z,
qFinal.w,
qInitial.x,
qInitial.y,
qInitial.z,
qInitial.w,
]
); */
const clipM = new AnimationClip("UpAndDown", -1, [positionKFM]);
const clipO = new AnimationClip("UpAndDown", -1, [positionKFo]);
const clipI = new AnimationClip("UpAndDown", -1, [positionKFi]);
const clipN = new AnimationClip("UpAndDown", -1, [positionKFn]);
const clipBang = new AnimationClip("UpAndDown", -1, [positionKFbang]);
// Create an animation mixer and add the clip to it
this.mixer = new AnimationMixer(this.letters[0]);
const actionM = this.mixer.clipAction(clipM);
actionM.play();
this.mixerO = new AnimationMixer(this.letters[1]);
const actionO = this.mixerO.clipAction(clipO);
actionO.play();
this.mixerI = new AnimationMixer(this.letters[2]);
const actionI = this.mixerI.clipAction(clipI);
actionI.play();
this.mixerN = new AnimationMixer(this.letters[3]);
const actionN = this.mixerN.clipAction(clipN);
actionN.play();
this.mixerBang = new AnimationMixer(this.letters[4]);
const actionBang = this.mixerBang.clipAction(clipBang);
actionBang.play();
// lights
var lightA = new DirectionalLight(0xffffff);
lightA.position.set(10, 10, 10);
this.scene.add(lightA);
var lightB = new DirectionalLight(0xffffff);
lightB.position.set(-5, -5, -5);
this.scene.add(lightB);
var lightC = new AmbientLight(0x222222);
this.scene.add(lightC);
var lightD = new DirectionalLight(0xffffff);
lightD.position.set(-5, -5, 5);
this.scene.add(lightD);
// Axis Line 1
var materialB = new LineBasicMaterial({ color: 0x0000ff });
var geometryB = new Geometry();
geometryB.vertices.push(new Vector3(0, 0, 0));
geometryB.vertices.push(new Vector3(0, 1000, 0));
var lineA = new Line(geometryB, materialB);
this.axisLines.push(lineA);
// Axis Line 2
var materialC = new LineBasicMaterial({ color: 0x00ff00 });
var geometryC = new Geometry();
geometryC.vertices.push(new Vector3(0, 0, 0));
geometryC.vertices.push(new Vector3(1000, 0, 0));
var lineB = new Line(geometryC, materialC);
this.axisLines.push(lineB);
// Axis 3
var materialD = new LineBasicMaterial({ color: 0xff0000 });
var geometryD = new Geometry();
geometryD.vertices.push(new Vector3(0, 0, 0));
geometryD.vertices.push(new Vector3(0, 0, 1000));
var lineC = new Line(geometryD, materialD);
this.axisLines.push(lineC);
this.scene.add(...this.axisLines);
},
RESIZE(width, height) {
this.width = width;
this.height = height;
this.camera.aspect = width / height;
this.camera.updateProjectionMatrix();
this.renderer.setSize(width, height);
// state.postprocessing.composer.setSize(width, height);
this.controls.handleResize();
this.postprocessing.composer.renderer.render(this.scene, this.camera);
// state.renderer.render(state.scene, state.camera);
},
INIT(width, height, el) {
this.SET_VIEWPORT_SIZE(width, height);
this.INITIALIZE_RENDERER(el);
this.INITIALIZE_CAMERA();
this.INITIALIZE_CONTROLS();
this.INITIALIZE_SCENE();
this.INITIALIZE_POSTPROCESSING();
// this.renderer.render(this.scene, this.camera);
this.postprocessing.composer.render(0.1);
this.controls.addEventListener("change", () => {
this.postprocessing.composer.render(0.1);
// this.renderer.render(this.scene, this.camera);
});
},
ANIMATE() {
window.requestAnimationFrame(this.ANIMATE);
this.mixer.update(0.002);
this.mixerO.update(0.001);
this.mixerI.update(0.003);
this.mixerN.update(0.002);
this.mixerBang.update(0.004);
//state.renderer.render(state.scene, state.camera);
this.postprocessing.composer.render(0.1);
//console.log(state.postprocessing.composer);
this.controls.update();
},
},
};
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment