JustPaste
HomeCategoriesAboutDonateContactTerms of UsePrivacy Policy
JustPaste

Free online notepad — write and share instantly

Navigate

  • Home
  • Timeline
  • Categories

Info

  • About
  • Donate
  • Contact

Legal

  • Terms of Use
  • Privacy Policy

© 2026 JustPaste.app. All rights reserved.

Made with ♥ by JustPaste

64846 | JustPaste.app
12 days ago9 views
💻Technology

64846

<!DOCTYPE html>
<html lang="fa">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>House 3D</title>

<style>
html,body{
    margin:0;
    width:100%;
    height:100%;
    overflow:hidden;
    background:#20262b;
}

body{
    font-family:Arial,sans-serif;
}

canvas{
    display:block;
    width:100%;
    height:100%;
}

#crosshair{
    position:fixed;
    left:50%;
    top:50%;
    width:4px;
    height:4px;
    transform:translate(-50%,-50%);
    background:#fff;
    border-radius:50%;
    box-shadow:0 0 5px #000;
    pointer-events:none;
}

#hud{
    position:fixed;
    left:16px;
    bottom:15px;
    color:rgba(255,255,255,.55);
    font-size:12px;
    text-shadow:0 2px 5px #000;
    pointer-events:none;
}
</style>
</head>

<body>

<canvas id="game"></canvas>

<div id="crosshair"></div>
<div id="hud">WASD • Shift • Space • V</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r160/three.min.js"></script>

<script>

/* =========================================================
   SAFE START
   هیچ صفحه شروعی وجود ندارد
========================================================= */

const canvas=document.getElementById("game");

let renderer;
let scene;
let camera;

try{

    renderer=new THREE.WebGLRenderer({
        canvas:canvas,
        antialias:true,
        powerPreference:"high-performance"
    });

    renderer.setSize(
        window.innerWidth,
        window.innerHeight,
        false
    );

    renderer.setPixelRatio(
        Math.min(window.devicePixelRatio,1.35)
    );

    renderer.shadowMap.enabled=true;
    renderer.shadowMap.type=THREE.PCFSoftShadowMap;

    renderer.outputColorSpace=THREE.SRGBColorSpace;
    renderer.toneMapping=THREE.ACESFilmicToneMapping;
    renderer.toneMappingExposure=1.15;

    scene=new THREE.Scene();

    scene.background=new THREE.Color(
        0x9bb4c5
    );

    scene.fog=new THREE.Fog(
        0x9bb4c5,
        45,
        150
    );

    camera=new THREE.PerspectiveCamera(
        72,
        innerWidth/innerHeight,
        .05,
        250
    );

}catch(e){

    /* اگر WebGL اصلاً در مرورگر موجود نباشد */
    canvas.style.background=
        "linear-gradient(#7895aa 0%,#a8b9bd 52%,#38452f 53%,#293525 100%)";

}


/* =========================================================
   MATERIALS
========================================================= */

if(renderer){

const M={

    grass:new THREE.MeshStandardMaterial({
        color:0x394a2d,
        roughness:1
    }),

    grass2:new THREE.MeshStandardMaterial({
        color:0x52663a,
        roughness:1
    }),

    road:new THREE.MeshStandardMaterial({
        color:0x202326,
        roughness:.95
    }),

    asphalt2:new THREE.MeshStandardMaterial({
        color:0x303438,
        roughness:.9
    }),

    concrete:new THREE.MeshStandardMaterial({
        color:0x777b79,
        roughness:.92
    }),

    wall:new THREE.MeshStandardMaterial({
        color:0xc8c0ae,
        roughness:.82
    }),

    wallDark:new THREE.MeshStandardMaterial({
        color:0x938c7d,
        roughness:.9
    }),

    brick:new THREE.MeshStandardMaterial({
        color:0x794c35,
        roughness:.9
    }),

    roof:new THREE.MeshStandardMaterial({
        color:0x303235,
        roughness:.86
    }),

    wood:new THREE.MeshStandardMaterial({
        color:0x62402a,
        roughness:.75
    }),

    woodLight:new THREE.MeshStandardMaterial({
        color:0x8b5d38,
        roughness:.7
    }),

    black:new THREE.MeshStandardMaterial({
        color:0x111416,
        roughness:.35,
        metalness:.65
    }),

    metal:new THREE.MeshStandardMaterial({
        color:0x777d80,
        roughness:.28,
        metalness:.8
    }),

    glass:new THREE.MeshPhysicalMaterial({
        color:0x8eb6c8,
        roughness:.08,
        metalness:.05,
        transparent:true,
        opacity:.42
    }),

    carpet:new THREE.MeshStandardMaterial({
        color:0x45433d,
        roughness:1
    }),

    screen:new THREE.MeshStandardMaterial({
        color:0x142c42,
        roughness:.2,
        metalness:.15
    }),

    sofa:new THREE.MeshStandardMaterial({
        color:0x454849,
        roughness:.95
    }),

    white:new THREE.MeshStandardMaterial({
        color:0xdad6cb,
        roughness:.8
    })

};


/* =========================================================
   LIGHT
========================================================= */

const hemi=new THREE.HemisphereLight(
    0xcfe4ff,
    0x303725,
    2.1
);

scene.add(hemi);


const sun=new THREE.DirectionalLight(
    0xffe5bd,
    3.8
);

sun.position.set(
    -45,
    60,
    30
);

sun.castShadow=true;

sun.shadow.mapSize.set(
    1536,
    1536
);

sun.shadow.camera.left=-75;
sun.shadow.camera.right=75;
sun.shadow.camera.top=75;
sun.shadow.camera.bottom=-75;

sun.shadow.camera.near=.1;
sun.shadow.camera.far=180;

sun.shadow.bias=-.0004;

scene.add(sun);


/* =========================================================
   HELPERS
========================================================= */

function box(
    x,y,z,
    sx,sy,sz,
    material,
    cast=true
){

    const o=new THREE.Mesh(
        new THREE.BoxGeometry(
            sx,sy,sz
        ),
        material
    );

    o.position.set(x,y,z);

    o.castShadow=cast;
    o.receiveShadow=true;

    scene.add(o);

    return o;
}


function cyl(
    x,y,z,
    r,h,
    material,
    segments=20
){

    const o=new THREE.Mesh(
        new THREE.CylinderGeometry(
            r,
            r*1.04,
            h,
            segments
        ),
        material
    );

    o.position.set(x,y,z);

    o.castShadow=true;
    o.receiveShadow=true;

    scene.add(o);

    return o;
}


function sphere(
    x,y,z,
    r,
    material
){

    const o=new THREE.Mesh(
        new THREE.SphereGeometry(
            r,
            20,
            16
        ),
        material
    );

    o.position.set(x,y,z);

    o.castShadow=true;
    o.receiveShadow=true;

    scene.add(o);

    return o;
}


/* =========================================================
   GROUND
========================================================= */

box(
    0,
    -.3,
    0,
    180,
    .6,
    180,
    M.grass
);


/* =========================================================
   ROAD
========================================================= */

box(
    0,
    .015,
    -28,
    180,
    .08,
    13,
    M.road,
    false
);

box(
    0,
    .07,
    -20.8,
    180,
    .14,
    2.5,
    M.concrete,
    false
);


/* road lines */

for(let x=-85;x<=85;x+=9){

    box(
        x,
        .075,
        -28,
        5,
        .035,
        .18,
        M.white,
        false
    );

}


/* =========================================================
   HOUSE FOUNDATION
========================================================= */

box(
    0,
    .35,
    0,
    28,
    .7,
    20,
    M.concrete
);


/* wooden floor */

box(
    0,
    .76,
    0,
    25,
    .18,
    17,
    M.wood
);


/* =========================================================
   HOUSE WALLS
========================================================= */

/* left */

box(
    -12.5,
    4.5,
    0,
    1,
    7.5,
    18,
    M.wall
);


/* right */

box(
    12.5,
    4.5,
    0,
    1,
    7.5,
    18,
    M.wall
);


/* back */

box(
    0,
    4.5,
    -8.5,
    24,
    7.5,
    1,
    M.wall
);


/* front wall pieces */

box(
    -9,
    4.5,
    8.5,
    7,
    7.5,
    1,
    M.wall
);

box(
    9,
    4.5,
    8.5,
    7,
    7.5,
    1,
    M.wall
);

box(
    0,
    7,
    8.5,
    11,
    2.5,
    1,
    M.wall
);


/* =========================================================
   ROOF
========================================================= */

const roof=new THREE.Mesh(
    new THREE.ConeGeometry(
        18,
        6,
        4
    ),
    M.roof
);

roof.position.set(
    0,
    10.8,
    0
);

roof.rotation.y=Math.PI/4;

roof.scale.z=.62;

roof.castShadow=true;
roof.receiveShadow=true;

scene.add(roof);


/* =========================================================
   DOOR
========================================================= */

box(
    0,
    3.7,
    8.0,
    3.4,
    5.9,
    .18,
    M.woodLight
);


/* door frame */

box(
    -1.85,
    3.7,
    7.88,
    .2,
    6.3,
    .3,
    M.white
);

box(
    1.85,
    3.7,
    7.88,
    .2,
    6.3,
    .3,
    M.white
);

box(
    0,
    6.8,
    7.88,
    4,
    .2,
    .3,
    M.white
);


/* handle */

sphere(
    .95,
    3.6,
    7.72,
    .12,
    M.metal
);


/* =========================================================
   WINDOWS
========================================================= */

function makeWindow(x,y,z){

    box(
        x,y,z,
        4.4,
        3.1,
        .12,
        M.glass,
        false
    );

    box(
        x-2.25,
        y,
        z-.12,
        .18,
        3.5,
        .25,
        M.white
    );

    box(
        x+2.25,
        y,
        z-.12,
        .18,
        3.5,
        .25,
        M.white
    );

    box(
        x,
        y+1.65,
        z-.12,
        4.6,
        .18,
        .25,
        M.white
    );

    box(
        x,
        y-1.65,
        z-.12,
        4.6,
        .18,
        .25,
        M.white
    );

    box(
        x,
        y,
        z-.14,
        .12,
        3.1,
        .25,
        M.white
    );

}

makeWindow(
    -6,
    4.5,
    7.92
);

makeWindow(
    6,
    4.5,
    7.92
);


/* =========================================================
   COMPUTER DESK
========================================================= */

const dx=-5;
const dz=-2;


box(
    dx,
    2.15,
    dz,
    7,
    .35,
    2.3,
    M.woodLight
);


/* desk legs */

for(const x of [
    dx-2.9,
    dx+2.9
]){

    box(
        x,
        1.15,
        dz-.8,
        .28,
        2.3,
        .28,
        M.darkWood||M.wood
    );

    box(
        x,
        1.15,
        dz+.8,
        .28,
        2.3,
        .28,
        M.darkWood||M.wood
    );

}


/* =========================================================
   MONITOR
========================================================= */

box(
    dx,
    3.65,
    dz,
    4.1,
    2.45,
    .28,
    M.black
);

box(
    dx,
    3.65,
    dz-.18,
    3.65,
    2,
    .035,
    M.screen,
    false
);


/* screen glow */

const monitorLight=new THREE.PointLight(
    0x5599cc,
    1.2,
    5
);

monitorLight.position.set(
    dx,
    3.6,
    dz+.1
);

scene.add(monitorLight);


/* stand */

box(
    dx,
    2.75,
    dz,
    .3,
    1.3,
    .3,
    M.metal
);

box(
    dx,
    2.35,
    dz,
    1.4,
    .12,
    .7,
    M.metal
);


/* =========================================================
   KEYBOARD
========================================================= */

box(
    dx,
    2.38,
    dz+1,
    3,
    .13,
    .85,
    M.black
);

for(let r=0;r<4;r++){

    for(let c=0;c<13;c++){

        box(
            dx-1.32+c*.22,
            2.46,
            dz+.73+r*.19,
            .14,
            .035,
            .11,
            M.white,
            false
        );

    }

}


/* mouse */

sphere(
    dx+2,
    2.45,
    dz+1,
    .24,
    M.black
);


/* =========================================================
   PC CASE
========================================================= */

box(
    dx+4.1,
    1.9,
    dz,
    1.6,
    3.5,
    2.3,
    M.black
);

box(
    dx+3.25,
    1.9,
    dz,
    .025,
    2.7,
    1.7,
    M.glass,
    false
);


/* =========================================================
   CHAIR
========================================================= */

box(
    dx,
    1.35,
    dz+3,
    2.3,
    .3,
    2.1,
    M.sofa
);

box(
    dx,
    2.6,
    dz+3.85,
    2.3,
    2.7,
    .3,
    M.sofa
);

cyl(
    dx,
    .7,
    dz+3,
    .14,
    1.3,
    M.metal
);


/* =========================================================
   SOFA
========================================================= */

box(
    5,
    1.25,
    -1,
    7,
    1,
    2.4,
    M.sofa
);

box(
    5,
    2.65,
    -2,
    7,
    2.8,
    .45,
    M.sofa
);

box(
    1.5,
    2,
    -1,
    .55,
    2,
    2.5,
    M.sofa
);

box(
    8.5,
    2,
    -1,
    .55,
    2,
    2.5,
    M.sofa
);


/* cushions */

for(let x=3;x<=7;x+=2){

    box(
        x,
        1.85,
        -1,
        1.5,
        .3,
        1.35,
        M.woodLight
    );

}


/* =========================================================
   TABLE
========================================================= */

cyl(
    5,
    1.25,
    3.1,
    2,
    .3,
    M.woodLight,
    32
);

cyl(
    5,
    .65,
    3.1,
    .18,
    1.3,
    M.metal
);


/* =========================================================
   TV
========================================================= */

box(
    5,
    3.8,
    -7.95,
    6.5,
    3.7,
    .3,
    M.black
);

box(
    5,
    3.8,
    -8.14,
    5.8,
    3,
    .04,
    M.screen,
    false
);


/* =========================================================
   CEILING LIGHTS
========================================================= */

function ceilingLight(x,z){

    const light=new THREE.PointLight(
        0xffd7a2,
        2.7,
        12
    );

    light.position.set(
        x,
        6.8,
        z
    );

    light.castShadow=true;

    scene.add(light);


    const fixture=new THREE.Mesh(
        new THREE.SphereGeometry(
            .3,
            16,
            12
        ),
        new THREE.MeshBasicMaterial({
            color:0xffe6ba
        })
    );

    fixture.position.set(
        x,
        6.7,
        z
    );

    scene.add(fixture);
}

ceilingLight(-6,3);
ceilingLight(6,3);


/* =========================================================
   OUTDOOR TREES
========================================================= */

function tree(x,z,s){

    s=s||1;

    cyl(
        x,
        2*s,
        z,
        .38*s,
        4*s,
        M.wood,
        14
    );

    const crown=new THREE.Mesh(
        new THREE.IcosahedronGeometry(
            2.6*s,
            1
        ),
        M.grass2
    );

    crown.position.set(
        x,
        5*s,
        z
    );

    crown.castShadow=true;
    crown.receiveShadow=true;

    scene.add(crown);

}


tree(-20,-3,1.3);
tree(-28,8,1.6);
tree(20,1,1.4);
tree(28,10,1.7);
tree(-30,-17,1.2);
tree(30,-17,1.4);
tree(-15,-32,1.4);
tree(16,-32,1.7);


/* =========================================================
   FENCE
========================================================= */

function fence(z){

    for(let x=-38;x<=38;x+=4){

        box(
            x,
            1.15,
            z,
            .16,
            2.3,
            .16,
            M.wood
        );

    }

    box(
        0,
        1.7,
        z,
        78,
        .18,
        .18,
        M.wood
    );

    box(
        0,
        .75,
        z,
        78,
        .18,
        .18,
        M.wood
    );
}

fence(-38);


/* =========================================================
   RANDOM ROCKS
========================================================= */

for(let i=0;i<45;i++){

    const x=(Math.random()-.5)*75;
    const z=(Math.random()-.5)*75;

    if(
        Math.abs(x)<16 &&
        Math.abs(z)<14
    ) continue;

    const r=.12+
        Math.random()*.35;

    const rock=new THREE.Mesh(
        new THREE.DodecahedronGeometry(
            r,
            0
        ),
        M.concrete
    );

    rock.position.set(
        x,
        r,
        z
    );

    rock.rotation.set(
        Math.random(),
        Math.random(),
        Math.random()
    );

    rock.castShadow=true;

    scene.add(rock);
}


/* =========================================================
   PLAYER
========================================================= */

const player={

    pos:new THREE.Vector3(
        0,
        1.7,
        18
    ),

    yaw:Math.PI,

    pitch:0,

    vy:0,

    grounded:true,

    third:false

};


/* =========================================================
   MOUSE
   کاملاً بدون کلیک
   بدون POINTER LOCK
========================================================= */

let mouseX=0;
let mouseY=0;
let hasMouse=false;

document.addEventListener(
    "mousemove",
    e=>{

        if(!hasMouse){

            mouseX=e.clientX;
            mouseY=e.clientY;

            hasMouse=true;

            return;
        }

        const dx=
            e.clientX-mouseX;

        const dy=
            e.clientY-mouseY;

        mouseX=e.clientX;
        mouseY=e.clientY;

        player.yaw-=dx*.002;

        player.pitch-=dy*.002;

        player.pitch=Math.max(
            -1.4,
            Math.min(
                1.4,
                player.pitch
            )
        );

    }
);


/* =========================================================
   KEYBOARD
========================================================= */

const keys={};

document.addEventListener(
    "keydown",
    e=>{

        keys[e.code]=true;

        if(e.code==="Space"){

            e.preventDefault();

            if(player.grounded){

                player.vy=6.2;

                player.grounded=false;

            }

        }

        if(e.code==="KeyV"){

            player.third=
                !player.third;

        }

    }
);

document.addEventListener(
    "keyup",
    e=>{
        keys[e.code]=false;
    }
);


/* =========================================================
   MOVEMENT
========================================================= */

const clock=new THREE.Clock();

function update(dt){

    let f=0;
    let s=0;

    if(keys.KeyW)f++;
    if(keys.KeyS)f--;

    if(keys.KeyD)s++;
    if(keys.KeyA)s--;

    const speed=
        keys.ShiftLeft||
        keys.ShiftRight
        ?8
        :4.5;


    if(f||s){

        const forward=
            new THREE.Vector3(
                Math.sin(player.yaw),
                0,
                Math.cos(player.yaw)
            );

        const right=
            new THREE.Vector3(
                Math.cos(player.yaw),
                0,
                -Math.sin(player.yaw)
            );

        const move=
            new THREE.Vector3();

        move.addScaledVector(
            forward,
            f
        );

        move.addScaledVector(
            right,
            s
        );

        move.normalize();

        player.pos.addScaledVector(
            move,
            speed*dt
        );

    }


    /* gravity */

    player.vy-=17*dt;

    player.pos.y+=
        player.vy*dt;


    if(player.pos.y<=1.7){

        player.pos.y=1.7;

        player.vy=0;

        player.grounded=true;

    }


    /* world */

    player.pos.x=
        THREE.MathUtils.clamp(
            player.pos.x,
            -70,
            70
        );

    player.pos.z=
        THREE.MathUtils.clamp(
            player.pos.z,
            -70,
            70
        );


    /* =====================================================
       CAMERA
    ===================================================== */

    if(!player.third){

        camera.position.copy(
            player.pos
        );

        const look=new THREE.Vector3(

            Math.sin(player.yaw)*
            Math.cos(player.pitch),

            Math.sin(player.pitch),

            Math.cos(player.yaw)*
            Math.cos(player.pitch)

        );

        camera.lookAt(
            player.pos.x+look.x,
            player.pos.y+look.y,
            player.pos.z+look.z
        );

    }else{

        const distance=7;

        camera.position.set(

            player.pos.x-
            Math.sin(player.yaw)*distance,

            player.pos.y+2.2,

            player.pos.z-
            Math.cos(player.yaw)*distance

        );

        camera.lookAt(
            player.pos.x,
            player.pos.y+1,
            player.pos.z
        );

    }

}


/* =========================================================
   RESIZE
=

⚠️Content was pasted as plain text and auto-formatted as a code block. Use the Code Block button in the editor for proper formatting.

← Back to timeline