|
|
|
import * as THREE from 'three'
|
|
|
|
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
|
|
|
|
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
|
|
|
|
import { RenderPixelatedPass } from 'three/addons/postprocessing/RenderPixelatedPass.js';
|
|
|
|
import { OutputPass } from 'three/addons/postprocessing/OutputPass.js';
|
|
|
|
|
|
|
|
let scene, camera, renderer
|
|
|
|
let aspect, frustumSize
|
|
|
|
let time = 0
|
|
|
|
let lastTime = 0
|
|
|
|
let controls
|
|
|
|
let mesh
|
|
|
|
let composer
|
|
|
|
let pixelSize = 8
|
|
|
|
let container_element = document.getElementById('container-index')
|
|
|
|
|
|
|
|
let cFrames = 0;
|
|
|
|
let isCapturing = false;
|
|
|
|
let frame_array = []
|
|
|
|
const totalCFrames = 1200; // Number of frames to capture
|
|
|
|
let captureFrames = false;
|
|
|
|
|
|
|
|
let containerW = container_element.offsetWidth
|
|
|
|
let containerH = container_element.offsetHeight
|
|
|
|
|
|
|
|
const texture = new THREE.TextureLoader().load("public/images/main-txt.png")
|
|
|
|
texture.minFilter = THREE.NearestFilter
|
|
|
|
texture.colorSpace = THREE.SRGBColorSpace;
|
|
|
|
texture.wrapS = THREE.RepeatWrapping;
|
|
|
|
texture.wrapT = THREE.RepeatWrapping;
|
|
|
|
|
|
|
|
|
|
|
|
function init(){
|
|
|
|
SetupRenderer()
|
|
|
|
scene = new THREE.Scene()
|
|
|
|
SetupCamera()
|
|
|
|
SetupControls()
|
|
|
|
|
|
|
|
composer = new EffectComposer( renderer );
|
|
|
|
if (window.innerWidth <= 1024)
|
|
|
|
{
|
|
|
|
pixelSize = 4;
|
|
|
|
}
|
|
|
|
const renderPixelatedPass = new RenderPixelatedPass( pixelSize, scene, camera );
|
|
|
|
renderPixelatedPass.normalEdgeStrength = 0;
|
|
|
|
renderPixelatedPass.depthEdgeStrength = 1;
|
|
|
|
renderPixelatedPass.pixelAlignedPanning = false;
|
|
|
|
composer.addPass( renderPixelatedPass );
|
|
|
|
|
|
|
|
const outputPass = new OutputPass();
|
|
|
|
composer.addPass( outputPass );
|
|
|
|
|
|
|
|
AddLights()
|
|
|
|
|
|
|
|
const geom = new THREE.BoxGeometry(1, 1, 1)
|
|
|
|
const mat = new THREE.MeshPhongMaterial({map: texture})
|
|
|
|
mesh = new THREE.Mesh(geom, mat)
|
|
|
|
scene.add(mesh)
|
|
|
|
animate()
|
|
|
|
}
|
|
|
|
|
|
|
|
function SetupRenderer(){
|
|
|
|
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
|
|
|
|
renderer.setClearColor(0xffffff, 0);
|
|
|
|
renderer.setSize(containerW, containerH)
|
|
|
|
document.getElementById('container-index').appendChild(renderer.domElement)
|
|
|
|
}
|
|
|
|
|
|
|
|
function SetupCamera(){
|
|
|
|
aspect = (containerW) / (containerH)
|
|
|
|
|
|
|
|
frustumSize = 1.75 / aspect
|
|
|
|
camera = new THREE.OrthographicCamera(
|
|
|
|
frustumSize * aspect / -2,
|
|
|
|
frustumSize * aspect / 2,
|
|
|
|
frustumSize / 2,
|
|
|
|
frustumSize / -2,
|
|
|
|
0.01,
|
|
|
|
5000
|
|
|
|
)
|
|
|
|
|
|
|
|
camera.position.x = 5
|
|
|
|
camera.position.set(0, 0, 20)
|
|
|
|
}
|
|
|
|
|
|
|
|
function SetupControls(){
|
|
|
|
controls = new OrbitControls(camera, renderer.domElement)
|
|
|
|
controls.enableRotate = false;
|
|
|
|
controls.enablePan = false
|
|
|
|
controls.zoomToCursor = false;
|
|
|
|
controls.mouseButtons = {
|
|
|
|
RIGHT: THREE.MOUSE.ROTATE,
|
|
|
|
MIDDLE: THREE.MOUSE.DOLLY,
|
|
|
|
LEFT: THREE.MOUSE.PAN
|
|
|
|
}
|
|
|
|
|
|
|
|
controls.update()
|
|
|
|
}
|
|
|
|
|
|
|
|
function AddLights() {
|
|
|
|
// Add Ambient Light
|
|
|
|
const ambientLight = new THREE.AmbientLight(0xffffff, 4); // Soft white light
|
|
|
|
scene.add(ambientLight);
|
|
|
|
|
|
|
|
// Add Directional Light
|
|
|
|
const directionalLight = new THREE.DirectionalLight(0xffffff, 0); // Soft white light
|
|
|
|
directionalLight.position.set(-5, 0, 5).normalize();
|
|
|
|
scene.add(directionalLight);
|
|
|
|
}
|
|
|
|
|
|
|
|
function animate(){
|
|
|
|
requestAnimationFrame(animate)
|
|
|
|
const deltaTime = (time - lastTime) / 1000
|
|
|
|
lastTime = time
|
|
|
|
//controls.update()
|
|
|
|
// Rotate the mesh on the x and z axes
|
|
|
|
mesh.rotation.x += 0.001
|
|
|
|
mesh.rotation.z += 0.001
|
|
|
|
mesh.rotation.y += 0.001
|
|
|
|
mesh.position.x = 0;
|
|
|
|
mesh.position.y = 0;
|
|
|
|
//texture.offset.x += 0.001;
|
|
|
|
composer.render()
|
|
|
|
//renderer.render(scene, camera)
|
|
|
|
if (captureFrames && cFrames < totalCFrames) {
|
|
|
|
captureFrame();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function getContainerDimensions(){
|
|
|
|
containerW = container_element.offsetWidth
|
|
|
|
containerH = container_element.offsetHeight
|
|
|
|
}
|
|
|
|
|
|
|
|
window.addEventListener('resize', () => {
|
|
|
|
getContainerDimensions()
|
|
|
|
aspect = (containerW) / (containerH)
|
|
|
|
camera.left = -frustumSize * aspect / 2
|
|
|
|
camera.right = frustumSize * aspect / 2
|
|
|
|
camera.top = frustumSize / 2
|
|
|
|
camera.bottom = -frustumSize / 2
|
|
|
|
camera.updateProjectionMatrix()
|
|
|
|
renderer.setPixelRatio(window.devicePixelRatio)
|
|
|
|
renderer.setSize(containerW, containerH)
|
|
|
|
})
|
|
|
|
|
|
|
|
function captureFrame() {
|
|
|
|
renderer.domElement.toDataURL('image/png').replace("image/png", "image/octet-stream");
|
|
|
|
let imgData = renderer.domElement.toDataURL("image/png");
|
|
|
|
frame_array.push(imgData);
|
|
|
|
cFrames++;
|
|
|
|
|
|
|
|
// If last frame, prepare the download
|
|
|
|
if (cFrames === totalCFrames) {
|
|
|
|
prepareDownload();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function prepareDownload() {
|
|
|
|
let zip = new JSZip();
|
|
|
|
console.log('zipping..')
|
|
|
|
frame_array.forEach((dataUrl, index) => {
|
|
|
|
let imgData = dataUrl.split(',')[1]; // Get base64 data part
|
|
|
|
zip.file(`frame_${index.toString().padStart(4, '0')}.png`, imgData, {base64: true});
|
|
|
|
});
|
|
|
|
console.log('zipped!')
|
|
|
|
zip.generateAsync({type: "blob"})
|
|
|
|
.then(function(content) {
|
|
|
|
const a = document.createElement("a");
|
|
|
|
a.href = URL.createObjectURL(content);
|
|
|
|
a.download = "frames.zip";
|
|
|
|
console.log('zip dl ready!')
|
|
|
|
a.click();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// Event listener for the spacebar key press
|
|
|
|
document.addEventListener('keydown', (event) => {
|
|
|
|
if (event.code === 'Space') { // Check if spacebar is pressed
|
|
|
|
isCapturing = !isCapturing; // Toggle capturing
|
|
|
|
|
|
|
|
if (isCapturing) {
|
|
|
|
cFrames = 0; // Reset frame counter
|
|
|
|
captureFrames = true
|
|
|
|
console.log('Capture started...');
|
|
|
|
} else {
|
|
|
|
captureFrames = false
|
|
|
|
console.log('Capture paused...');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
init()
|
|
|
|
|