-
-
Save stillefront/f5ee6ef7767884d50d66d9190d23a543 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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