File size: 4,607 Bytes
a13f8e3
 
 
e3bf736
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a13f8e3
 
e3bf736
 
 
 
 
 
 
 
 
 
 
 
 
01caa4d
e3bf736
 
05f2fc1
e3bf736
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d040897
36722fa
 
 
 
9b34615
e3bf736
 
 
 
 
 
 
 
 
 
 
 
 
 
01caa4d
e3bf736
 
 
 
 
01caa4d
e3bf736
01caa4d
 
 
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 = 5; // 立方体のサイズ
        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() * 200 - 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>