File size: 7,338 Bytes
a13f8e3
 
 
e3bf736
 
 
 
 
 
 
 
 
 
3338798
 
350fc0e
e3bf736
 
89d6b0e
 
e3bf736
 
3338798
 
 
 
 
e3bf736
 
 
 
363f653
 
 
 
 
 
 
 
 
e3bf736
a13f8e3
 
e3bf736
 
 
ed73eac
2a85e13
e3bf736
363f653
 
437d329
363f653
 
 
 
 
 
 
 
 
 
 
a0e0c36
89d6b0e
e3bf736
 
 
 
 
 
 
01caa4d
a0e0c36
 
 
05f2fc1
10f4346
e3bf736
10f4346
 
e3bf736
 
a0e0c36
e3bf736
 
 
 
 
a0e0c36
e3bf736
10f4346
 
 
 
 
 
e3bf736
 
 
a0e0c36
b9dc5a3
a0e0c36
 
 
 
 
 
b9dc5a3
e3bf736
 
363f653
3338798
36722fa
3338798
b9dc5a3
36722fa
9b34615
437d329
e3bf736
a0e0c36
e3bf736
 
363f653
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f146896
 
785e69f
363f653
 
 
 
 
e3bf736
 
 
a0e0c36
e3bf736
 
23b1214
d8cbec2
e3bf736
 
 
 
 
 
 
d040897
05f2fc1
a0e0c36
 
 
 
363f653
437d329
363f653
437d329
363f653
 
 
 
 
 
 
 
 
e3bf736
a13f8e3
3338798
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
<!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;
            margin: 0;
            padding: 0;

        }
        canvas {
            display: block;
            margin-top: 20px;
        }
        #scene-container {
            width: 100vw;
            height: 100vh;
            margin: 0;
            padding: 0;
            overflow: hidden;
        }
        #uploadForm {
            margin-top: 20px;
        }
        #settings {
            margin-top: 20px;
            display: flex;
            flex-direction: column;
            align-items: center;
        }
        #settings label {
            margin: 5px;
        }
    </style>
</head>
<body>
    <h1>画像のモザイク処理と3Dアニメーション</h1>
    <form id="uploadForm">
        <input type="file" id="imageInput" accept="image/*">
        <button type="button" onclick="processImage()">画像を処理</button><br>
        <button type="button" onclick="useExampleImage()">例の画像(Gの文字)を使用</button> <!-- 新しく追加したボタン -->
    </form>
    <div id="settings">
        <label>
            シーン背景色: <input type="color" id="bgColorPicker" value="#222222" onchange="updateSceneBackgroundColor()">
        </label>
        <label>
            カメラ X: <input type="range" id="cameraX" min="-500" max="500" value="-100" oninput="updateCameraPosition()">
        </label>
        <label>
            カメラ Y: <input type="range" id="cameraY" min="-500" max="500" value="-100" oninput="updateCameraPosition()">
        </label>
        <label>
            カメラ Z: <input type="range" id="cameraZ" min="-1000" max="1000" value="300" oninput="updateCameraPosition()">
        </label>
    </div>
    <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(imageSrc = null) {
            const fileInput = document.getElementById('imageInput');
            const file = imageSrc ? null : fileInput.files[0];
            
            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 = imageSrc || URL.createObjectURL(file);
        }

        function useExampleImage() {
            const exampleImagePath = 'ex.png'; // 例の画像のパス
            processImage(exampleImagePath);
        }

        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);
            updateCameraPosition(); // カメラ位置を初期設定
            
            renderer = new THREE.WebGLRenderer();
            renderer.setSize(document.getElementById('scene-container').clientWidth, document.getElementById('scene-container').clientHeight);
            document.getElementById('scene-container').innerHTML = ''; // 既存のcanvasを削除
            document.getElementById('scene-container').appendChild(renderer.domElement);

            updateSceneBackgroundColor(); // シーンの背景色を初期設定
            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];

                    const color = new THREE.Color(`rgb(${r},${g},${b})`);
                    const geometry = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize);
                    const material = new THREE.MeshBasicMaterial({
                        color: color,
                        transparent: true,
                        opacity: a / 255
                    });

                    const cube = new THREE.Mesh(geometry, material);

                    cube.position.set(
                        (x - canvas.width / 2) * cubeSize * 1.2 + (Math.random()-0.5) * 2200 - 100,
                        (canvas.height / 2 - y) * cubeSize * 1.2 + (Math.random()-0.5) * 2200 - 100,
                        (Math.random()-0.5) * 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();
        }

        function updateSceneBackgroundColor() {
            const color = document.getElementById('bgColorPicker').value;
            scene.background = new THREE.Color(color); // シーンの背景色を更新
        }

        function updateCameraPosition() {
            const x = parseFloat(document.getElementById('cameraX').value);
            const y = parseFloat(document.getElementById('cameraY').value);
            const z = parseFloat(document.getElementById('cameraZ').value);
            camera.position.set(x, y, z);
            camera.lookAt(new THREE.Vector3(0, 0, 0));
        }
    </script>
</body>
</html>