File size: 5,359 Bytes
a13f8e3
 
 
e3bf736
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a13f8e3
 
e3bf736
 
 
 
 
a0e0c36
e3bf736
 
 
 
 
 
 
 
01caa4d
a0e0c36
 
 
05f2fc1
e3bf736
 
 
 
 
 
 
a0e0c36
e3bf736
 
 
 
 
a0e0c36
e3bf736
 
 
 
 
a0e0c36
b9dc5a3
a0e0c36
 
 
 
 
 
b9dc5a3
e3bf736
 
a0e0c36
ceadab9
36722fa
 
b9dc5a3
36722fa
9b34615
e3bf736
a0e0c36
e3bf736
 
 
 
 
 
 
 
 
 
 
b9dc5a3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e3bf736
 
 
 
 
a0e0c36
e3bf736
 
23b1214
d8cbec2
e3bf736
 
 
 
 
 
 
d040897
05f2fc1
a0e0c36
 
b9dc5a3
a0e0c36
 
e3bf736
a13f8e3
a0e0c36
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<!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>
    <button id="replayButton" style="margin-top: 10px; display: none;" onclick="replayAnimation()">もう一度再生</button>
    <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 = 8;
        let cubes = [];
        let animationFrameId;

        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();
                document.getElementById('replayButton').style.display = 'block';
            };
            img.src = URL.createObjectURL(file);
        }

        function create3DScene() {
            if (renderer) {
                // 既存のシーンをクリア
                cancelAnimationFrame(animationFrameId);
                cubes.forEach(cube => scene.remove(cube));
                cubes = [];
                renderer.dispose();
            }

            // Three.jsの基本設定
            scene = new THREE.Scene();
            camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
            camera.position.set(300, 300, 300);
            camera.lookAt(new THREE.Vector3(0, 0, 0));
            renderer = new THREE.WebGLRenderer();
            renderer.setSize(window.innerWidth, window.innerHeight);
            document.getElementById('scene-container').innerHTML = ''; // 既存のcanvasを削除
            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 a = imageData[index + 3];  // アルファチャネル(透明度)

                    // アルファ値が0より大きい(透明でない)場合のみキューブを作成
                    if (a > 0) {
                        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);

                        cube.position.set(
                            (x - canvas.width / 2) * cubeSize * 1.2,
                            (canvas.height / 2 - y) * cubeSize * 1.2,
                            Math.random() * 2200 - 100
                        );
                        scene.add(cube);
                        cubes.push(cube);
                    }
                }
            }
        }

        function animate() {
            animationFrameId = 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);
        }

        function replayAnimation() {
            // アニメーションの再生をリセット
            create3DScene();
        }
    </script>
</body>
</html>