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>