LoginSignup
9
10

More than 5 years have passed since last update.

Three.jsでドラッグアンドドロップでテクスチャーを貼る

Last updated at Posted at 2013-02-01

Three.jsの投稿があったので自分も

画像ファイルJPEGやPNGとかをドロップするとトンネルの中にテクスチャが貼られます。

タイトルまんまのソース

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" /><title>トーラスのなかを進む テクスチャ版 - js do it</title>
<meta name="Description" content="jsdo.it - share JavaScript, HTML5 and CSS - " />
<meta name="Keywords"  content="JavaScript,HTML5,CSS" />
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">

<style type="text/css">body { background-color: #DDDDDD; font: 30px sans-serif; }</style></head>
<body>
<div id="dropImg">ここに画像をドロップ</div>
<script type="text/javascript" src="/lib/Three.js-r42/js"></script>

<script type="text/javascript">
window.onload=function(){

var renderer = new THREE.WebGLRenderer();
renderer.setSize( 450, 300 );
document.body.appendChild( renderer.domElement );

var scene = new THREE.Scene();

var camera = new THREE.Camera(
                75,     // Field of view
                450 / 300,  // Aspect ratio
                0.02,   // Near
                1000    // Far
            );
camera.position.set( 0, 5, 5.5 );
scene.addLight( new THREE.AmbientLight( 0x101010 ) );

var directionalLight = new THREE.DirectionalLight(  0xffffff );
                directionalLight.position.x = 0;
                directionalLight.position.y = 0;
                directionalLight.position.z = 1;
                directionalLight.position.normalize();
//scene.addLight( directionalLight );
var directionalLight2 = new THREE.DirectionalLight(  0x00ff00 );
                directionalLight2.position.x = 1;
                directionalLight2.position.y = 0;
                directionalLight2.position.z = 0;
                directionalLight2.position.normalize();
//scene.addLight( directionalLight2 );
var directionalLight3 = new THREE.DirectionalLight(  0x0000ff );
            directionalLight3.position.x = 0;
                directionalLight3.position.y = 1;
                directionalLight3.position.z = 0;
                directionalLight3.position.normalize();
            //  scene.addLight( directionalLight3 );

var ptlight = new THREE.PointLight( 0xFFFFFF );
ptlight.position.set( 0, 100, 0 );
scene.addLight( ptlight);

material=new THREE.MeshLambertMaterial( { color: 0xaaaaaa, shading: THREE.FlatShading } );
//material=new THREE.MeshBasicMaterial( { color:0x0afaaf, vertexColors:false, shading: THREE.FlatShading } );

object = new THREE.Mesh( MakeTorus(), material);
object.overdraw=true;
object.doubleSided = true;
object.flipSided=true;
//object.matrixAutoUpdate=false;
scene.addChild(object);

if ( !window.requestAnimationFrame ) {

    window.requestAnimationFrame = ( function() {

        return window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.oRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element ) {

            window.setTimeout( callback, 1000 / 60 );

        };

    } )();

}
animate();

function Cross( v1, v2 )
    {
        var vx = v1.y * v2.z - v1.z * v2.y;
        var vy = v1.z * v2.x - v1.x * v2.z;
        var vz = v1.x * v2.y - v1.y * v2.x;

        return new THREE.Vector3(vx,vy,vz);
}

// calculate Roman surface by u,v parameter.
function TorusSurface(u,v) {
    var a=1/3;
    var c = 1;
     var x = Math.cos(u)*(Math.cos(v)*a+c);
     var y = Math.sin(v)*a;
     var z = Math.sin(u)*(Math.cos(v)*a+c);
     //document.write(x +"," + y + ","+z +"\n");
     return new THREE.Vector3(x, y, z);
}

function animate() {
    requestAnimationFrame( animate );
    render();
}

function render() {
    var a=1/2;
    var c = 1;
    var time = new Date().getTime() * 0.001;

    camera.position.set( 1.1*Math.cos(time), 0.34*Math.sin(time/10),  1.1*Math.sin(time) );
    camera.target.position.set( 1.0*Math.cos(time+0.5), 0,  1.0*Math.sin(time+0.5) );
    //camera.target.position.set(0, 0.1, 0);
    ptlight.position.set(1.0*Math.cos(time+0.5), 0,  1.0*Math.sin(time+0.5) );
    renderer.render( scene, camera );
}
var dropArea = document.getElementById('dropImg');
var image = new Image();

// テクスチャ画像がドロップされた場合の処理
image.onload = function() {
    console.log('image.onload start');
    var canvas = document.createElement("canvas");
    canvas.width=image.width;
    canvas.height=image.height;
    var ctx = canvas.getContext("2d");
    ctx.drawImage(image,0,0,image.width,image.height,0,0,image.width,image.height);

    var texture = new THREE.Texture( canvas, new THREE.UVMapping(), THREE.ClampToEdgeWrapping, THREE.ClampToEdgeWrapping,
                   THREE.NearestFilter,THREE.NearestMipMapLinearFilter);
    texture.needsUpdate = true;
    var material1 = [
    new THREE.MeshLambertMaterial( { map: texture } ),
    new THREE.MeshBasicMaterial( { color: 0xffffff, wireframe: false, opacity: 0.1 } )
    ];
    scene.removeObject(object);

    object = new THREE.Mesh( MakeTorus(), material1 );
    object.overdraw=true;
    object.doubleSided = true;
    object.flipSided=true;

    scene.addObject(object);

};

//dropArea.addEventListener('dragenter', function(e) {
//  e.stopPropagation();
//}, false);

dropArea.addEventListener('dragleave', function(e) {
  e.preventDefault();
}, false);

dropArea.addEventListener('drop', function(e) {
        console.log('Drop start');
e.preventDefault();    
    var file = e.dataTransfer.files[0];
    if( !file.type.match(/image/)) {
        console.log("oops!");
        e.stopPropagation();
        return false;
    }

    var reader = new FileReader();
    reader.onload = function(e) {
        console.innerText = 'Reader onload start';  
        var fileContent = reader.result;
        image.src = fileContent;
        console.log('Reader onload end');
    };

    reader.readAsDataURL(file);
    //e.stopPropagation();
        console.log('Drop end');
}, false);

document.body.addEventListener('dragover', function(e) {
  e.preventDefault();
}, false);

function MakeTorus() {
    var geom = new THREE.Geometry();
    var ustep = 0.1;
    var vstep = 0.1;

    var pCount = 0;
    var geom = new THREE.Geometry();
    var vv,uu;

    for(var v =0; v < Math.PI*2; v+=vstep) {
    for(var u =0; u < 2*Math.PI; u+=ustep) {
        v1 = TorusSurface(u, v);
        v2 = TorusSurface(u+ustep, v);
        v3 = TorusSurface(u+ustep, v+vstep);
        v4 = TorusSurface(u, v+vstep);

        geom.vertices.push(new THREE.Vertex(v1));
        geom.vertices.push(new THREE.Vertex(v2));
        geom.vertices.push(new THREE.Vertex(v3));
        geom.vertices.push(new THREE.Vertex(v4));

        var nvx1 = v1.x - v2.x;
        var nvy1 = v1.y - v2.y;
        var nvz1 = v1.z - v2.z;

        var nvx2 = v4.x - v2.x;
        var nvy2 = v4.y - v2.y;
        var nvz2 = v4.z - v2.z;

        var faceVertical = Cross(
                    new THREE.Vector3(nvx1,nvy1,nvz1), 
                    new THREE.Vector3(nvx2,nvy2,nvz2)
            );

        var length = Math.sqrt( (faceVertical.x * faceVertical.x
                                + faceVertical.y * faceVertical.y
                            + faceVertical.z * faceVertical.z) );
        var faceNormal = new THREE.Vector3(-faceVertical.x / length, -faceVertical.y / length, -faceVertical.z / length );

            var face1 = new THREE.Face3( pCount, pCount + 2 , pCount + 1 );
        face1.normal = faceNormal;
        geom.faces.push(face1  );
        geom.faceVertexUvs[ 0 ].push( [
        new THREE.UV( (u/(2*Math.PI)), (v/(2*Math.PI)) ),
        new THREE.UV( ((u+ustep)/(2*Math.PI)), ((v+vstep)/(2*Math.PI)) ),
        new THREE.UV( ((u+ustep)/(2*Math.PI)), (v/(2*Math.PI)) )
        ] );

        var face2 = new THREE.Face3( pCount, pCount + 3 , pCount + 2 );
        face2.normal = faceNormal;
        geom.faces.push( face2 );
        geom.faceVertexUvs[ 0 ].push( [
        new THREE.UV( (u/(2*Math.PI)), (v/(2*Math.PI) )),
        new THREE.UV( (u/(2*Math.PI)),( (v+vstep)/(2*Math.PI)) ),
        new THREE.UV( ((u+ustep)/(2*Math.PI)), ((v+vstep)/(2*Math.PI) ))
        ] );

        pCount = pCount + 4;
     }
    }
    return geom;
}
};

</script>
</body>
</html>

お試しはこちら

http://jsdo.it/kjunichi/3t5w

関連記事

9
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
10