3d-cube / index.html
soiz's picture
Update index.html
a13f8e3 verified
raw
history blame
3.61 kB
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>モザイク画像の3D変換</title>
<style>
body { margin: 0; overflow: hidden; }
canvas { display: block; }
#upload { position: fixed; top: 10px; left: 10px; z-index: 10; }
</style>
</head>
<body>
<input type="file" id="upload" accept="image/*" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>
// 基本的なThree.jsのセットアップ
let scene, camera, renderer, controls;
const cubes = [];
const pixelSize = 5; // ピクセル1つあたりの立方体サイズ
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 300;
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
animate();
}
function animate() {
requestAnimationFrame(animate);
cubes.forEach(cube => {
// 各立方体が中心に集まるように位置を調整
cube.position.x += (0 - cube.position.x) * 0.02;
cube.position.y += (0 - cube.position.y) * 0.02;
cube.position.z += (0 - cube.position.z) * 0.02;
});
camera.rotation.y += 0.01; // カメラの回転
renderer.render(scene, camera);
}
// モザイク画像を生成する関数
function createMosaicImage(image) {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const width = 50; // モザイクの幅
const height = 50; // モザイクの高さ
canvas.width = width;
canvas.height = height;
// 画像を縮小してモザイク化
ctx.drawImage(image, 0, 0, width, height);
const imageData = ctx.getImageData(0, 0, width, height).data;
// 各ピクセルから立方体を作成
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
const i = (y * width + x) * 4;
const r = imageData[i];
const g = imageData[i + 1];
const b = imageData[i + 2];
const color = new THREE.Color(`rgb(${r},${g},${b})`);
const geometry = new THREE.BoxGeometry(pixelSize, pixelSize, pixelSize);
const material = new THREE.MeshBasicMaterial({ color });
const cube = new THREE.Mesh(geometry, material);
// 初期位置をランダムに設定
cube.position.x = Math.random() * 600 - 300;
cube.position.y = Math.random() * 600 - 300;
cube.position.z = Math.random() * 600 - 300;
// 各ピクセルの位置に立方体を配置
const targetX = (x - width / 2) * pixelSize;
const targetY = (y - height / 2) * pixelSize;
cube.userData = { targetX, targetY, targetZ: 0 };
cubes.push(cube);
scene.add(cube);
}
}
}
// ファイル選択時のイベントリスナー
document.getElementById("upload").addEventListener("change", (event) => {
const file = event.target.files[0];
const reader = new FileReader();
reader.onload = (e) => {
const image = new Image();
image.onload = () => createMosaicImage(image);
image.src = e.target.result;
};
reader.readAsDataURL(file);
});
// 初期化
init();
</script>
</body>
</html>