File size: 5,180 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
 
e3ca868
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e3bf736
e3ca868
 
 
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
143
144
145
146
<!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なら透明なキューブを作成
            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 // 透明度を設定(0で完全透明、255で不透明)
            });

            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>