File size: 4,610 Bytes
a13f8e3 e3bf736 a13f8e3 e3bf736 01caa4d 712aea5 e3bf736 05f2fc1 e3bf736 d040897 36722fa 9b34615 e3bf736 143af1b e3bf736 01caa4d e3bf736 01caa4d 051bc00 e3bf736 36722fa e3bf736 23b1214 d8cbec2 e3bf736 d040897 05f2fc1 e3bf736 a13f8e3 01caa4d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>画像モザイク&3Dアニメーション</title>
<style>
body {
display: flex;
flex-direction: column;
align-items: center;
background-color: #222;
color: #fff;
font-family: Arial, sans-serif;
}
canvas {
display: block;
margin-top: 20px;
}
#scene-container {
width: 80vw;
height: 80vh;
}
#uploadForm {
margin-top: 20px;
}
</style>
</head>
<body>
<h1>画像のモザイク処理と3Dアニメーション</h1>
<form id="uploadForm">
<input type="file" id="imageInput" accept="image/*">
<button type="button" onclick="processImage()">画像を処理</button>
</form>
<canvas id="canvas" style="display: none;"></canvas>
<div id="scene-container"></div>
<!-- Three.js ライブラリ -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
let scene, camera, renderer;
const cubeSize = 6; // 立方体のサイズ
let cubes = []; // 立方体を格納する配列
function processImage() {
const fileInput = document.getElementById('imageInput');
const file = fileInput.files[0];
if (!file) return;
const img = new Image();
img.onload = () => {
const scale = 0.1; // モザイクの縮小スケール
canvas.width = img.width * scale;
canvas.height = img.height * scale;
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
create3DScene();
};
img.src = URL.createObjectURL(file);
}
function create3DScene() {
// Three.jsの基本設定
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.getElementById('scene-container').appendChild(renderer.domElement);
createCubesFromImage();
animate(); // アニメーション開始
}
function createCubesFromImage() {
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
for (let y = 0; y < canvas.height; y++) {
for (let x = 0; x < canvas.width; x++) {
const index = (y * canvas.width + x) * 4;
const r = imageData[index];
const g = imageData[index + 1];
const b = imageData[index + 2];
const color = new THREE.Color(`rgb(${r},${g},${b})`);
const geometry = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize);
const material = new THREE.MeshBasicMaterial({ color: color });
const cube = new THREE.Mesh(geometry, material);
// x座標はそのままに、y座標のみ反転させる
cube.position.set(
(x - canvas.width / 2) * cubeSize * 1.2, // x座標をそのまま使用
(canvas.height / 2 - y) * cubeSize * 1.2, // y座標を反転
Math.random() * 2200 - 100 // 初期位置のばらつきを与える
);
scene.add(cube);
cubes.push(cube);
}
}
}
function animate() {
requestAnimationFrame(animate);
// 各立方体をターゲット位置へ移動させる
cubes.forEach((cube, index) => {
const targetX = ((index % canvas.width) - canvas.width / 2) * cubeSize * 1.2;
const targetY = ((canvas.height / 2) - Math.floor(index / canvas.width)) * cubeSize * 1.2;
const targetZ = 0;
cube.position.x += (targetX - cube.position.x) * 0.05;
cube.position.y += (targetY - cube.position.y) * 0.05;
cube.position.z += (targetZ - cube.position.z) * 0.05;
});
renderer.render(scene, camera);
}
</script>
</body>
</html> |