Maison  >  Article  >  interface Web  >  Exemple de développement HTML5 - Panorama 3D (démo du panorama ThreeJs) explication détaillée (image)

Exemple de développement HTML5 - Panorama 3D (démo du panorama ThreeJs) explication détaillée (image)

黄舟
黄舟original
2018-05-18 10:29:0536951parcourir

Avant-propos

Dans l'environnement panoramique H5 actuel sur le marché, il existe de nombreuses façons d'obtenir des vues panoramiques. Vous pouvez utiliser CSS3 pour le construire directement ou utiliser une bibliothèque basée sur threeJ pour y parvenir. de nombreuses autres méthodes de production.Utilisation du logiciel Panorama
Ce tutoriel convient aux lions d'ingénierie qui n'ont pas développé de panorama 3D

Si vous pensez que le contenu est trop ennuyeux, vous pouvez passer directement à la fin

Téléchargez le code

Théorie

Je n'entrerai pas dans les détails des théories pertinentes utilisées dans l'ensemble du panorama 3D. Parlons un peu des théories pertinentes utilisées dans ce cas<.>

Je pense que les programmeurs accorderont plus d'attention au contenu de l'implémentation du code

La démo expliquée cette fois consiste à utiliser css3DRender pour créer une scène panoramique cubique

Imaginez, tout ce dont nous avons besoin à faire est de construire une boîte cubique

Et puis de mettre l'objectif sur ce qui suit. Chaque face de la boîte cubique

est attachée à une face de notre scène, donc lorsque la caméra tourne, que vous voyez, c'est la vue panoramique de la scène


Exemple de développement HTML5 - Panorama 3D (démo du panorama ThreeJs) explication détaillée (image)

Trucs théoriques détaillés Parlons-en plus tard, cette fois, faisons d'abord une démo simple

Analyse de la démo

Ce tutoriel utilise deux bibliothèques :

threeJS et CSS3DRender.js basés sur celui-ci

Le code est extrait de l'exemple sur le site officiel et a fait quelques ajustements.

<!DOCTYPE html>
<html>
<head>
    <title>three.js css3d - panorama</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <style>
        body {
            background-color: #000000;
            margin: 0;
            cursor: move;
            overflow: hidden;
        }
        .surface { width: 1026px; height: 1026px; background-size: cover; position: absolute; }
        .surface .bg { position: absolute; width: 1026px; height: 1026px; }
    </style>
</head>
<body>
<p>
    <p id="surface_0" class="surface">
        <img class="bg" src="images/posx.jpg" alt="">
    </p>
    <p id="surface_1" class="surface">
        <img class="bg" src="images/negx.jpg" alt="">
    </p>
    <p id="surface_2" class="surface">
        <img class="bg" src="images/posy.jpg" alt="">
    </p>
    <p id="surface_3" class="surface">
        <img class="bg" src="images/negy.jpg" alt="">
    </p>
    <p id="surface_4" class="surface">
        <img class="bg" src="images/posz.jpg" alt="">
    </p>
    <p id="surface_5" class="surface">
        <img class="bg" src="images/negz.jpg" alt="">
    </p>
</p>
<script src="js/three.min.js"></script>
<script src="js/CSS3DRenderer.min.js"></script>
<script src="js/index.js"></script>
</body>
</html>
Il n'y a rien de spécial ici en html. Tout d'abord, mettez chaque côté et utilisez p pour mettre l'image de chaque côté.

La raison pour laquelle nous n'utilisons pas la démo du site officiel est que le site officiel crée une image et l'insère dans la page. Il n'est pas pratique pour nous d'ajouter des éléments à chaque visage

D'abord. définissez les six faces. , si vous souhaitez ajouter des éléments interactifs à chaque surface, ajoutez simplement dom directement au html

Au total, 3 js sont introduits, à l'exception de l'index, les deux autres sont des js compressés, pas besoin de s'en soucier, jetez un oeil à l'implémentation d'index.js

camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 1000 );

scene = new THREE.Scene();
Ensuite il est évident que ces deux lignes de code créent littéralement une caméra et créent une scène.

Voici une brève explication de ces deux classes

PerspectiveCamera

Ce qui suit est l'explication du site officiel


Exemple de développement HTML5 - Panorama 3D (démo du panorama ThreeJs) explication détaillée (image) Le sens général :
Il s'agit d'un mode de projection qui imite l'œil humain, c'est le mode de projection le plus couramment utilisé pour le rendu de scènes 3D.
En bref, cette classe est une nouvelle lentille
Ci-dessous l'exemple de code

Exemple de développement HTML5 - Panorama 3D (démo du panorama ThreeJs) explication détaillée (image)

Le constructeur de cette classe accepte quatre paramètres


Exemple de développement HTML5 - Panorama 3D (démo du panorama ThreeJs) explication détaillée (image)

Alors, quels sont exactement ces quatre paramètres ?


Exemple de développement HTML5 - Panorama 3D (démo du panorama ThreeJs) explication détaillée (image)

représentent respectivement l'angle de l'objectif, le rapport hauteur/largeur, la distance focale minimale et la distance focale la plus éloignée


Scène

Ensuite, utilisez la classe de scène scène de création

La description officielle suivante



Exemple de développement HTML5 - Panorama 3D (démo du panorama ThreeJs) explication détaillée (image)Cette chose crée une scène Cette scène vous permet de créer une certaine chose et une certaine position via une scène de rendu à trois Js

Après avoir connu la scène et la caméra, nous devons mettre le cube mentionné précédemment

dans la scène. Tout d'abord, définir les données des six faces, la position de chaque face et l'angle de rotation de la rotation 3D.

Les trois paramètres de position correspondent respectivement aux positions des axes x, y et z

Comme la largeur du visage que j'ai sélectionné est de 1024px

, la position est basée sur le plus ou le moins 1024/2 du point central

Les trois paramètres de rotation, les décibels, correspondent à l'angle de rotation de l'axe xyz

Math.PI/2 représente 90 degrés


CSS3DObject
var sides = [
    {
        position: [ -512, 0, 0 ],//位置
        rotation: [ 0, Math.PI / 2, 0 ]//角度
    },
    {
        position: [ 512, 0, 0 ],
        rotation: [ 0, -Math.PI / 2, 0 ]
    },
    {
        position: [ 0,  512, 0 ],
        rotation: [ Math.PI / 2, 0, Math.PI ]
    },
    {
        position: [ 0, -512, 0 ],
        rotation: [ - Math.PI / 2, 0, Math.PI ]
    },
    {
        position: [ 0, 0,  512 ],
        rotation: [ 0, Math.PI, 0 ]
    },
    {
        position: [ 0, 0, -512 ],
        rotation: [ 0, 0, 0 ]
    }
];

/**
 * 根据六个面的信息,new出六个对象放入场景中
 */
for ( var i = 0; i < sides.length; i ++ ) {

    var side = sides[ i ];

    var element = document.getElementById("surface_"+i);
    element.width = 1026; // 2 pixels extra to close the gap.多余的2像素用于闭合正方体

    var object = new THREE.CSS3DObject( element );
    object.position.fromArray( side.position );
    object.rotation.fromArray( side.rotation );
    scene.add( object );

}

Ensuite, il y a une nouvelle classe ici CSS3DObject

Cependant, cette classe n'appartient pas à la classe officielle, mais à la classe de la bibliothèque 3DRender que nous avons référencée


Il n'y a pas de documentation. Regardons le code

et nous pouvons voir qu'il s'agit d'un héritage pour la classe THREE.Object3D
THREE.CSS3DObject = function (element) {
    THREE.Object3D.call(this);
    this.element = element;
    this.element.style.position = &#39;absolute&#39;;
    this.addEventListener(&#39;removed&#39;, function (event) {
        if (this.element.parentNode !== null) {
            this.element.parentNode.removeChild(this.element);
            for (var i = 0, l = this.children.length; i < l; i++) {
                this.children[i].dispatchEvent(event)
            }
        }
    })
}
;
THREE.CSS3DObject.prototype = Object.create(THREE.Object3D.prototype);
, changez la position de l'élément entrant en positionnement absolu, puis ajoutez un événement. lorsqu'il est retiré.

Rien de spécial n'est défini, alors vérifions la classe officielle Object3D

Object3D

Cette classe est une classe de base qui définit des objets, parmi lesquels L'objet de nouveau contient les deux attributs suivants Exemple de développement HTML5 - Panorama 3D (démo du panorama ThreeJs) explication détaillée (image)

qui représentent respectivement la position et l'angle de rotation de l'objet.
.position

The object&#39;s local position.

.rotation

Object&#39;s local rotation (see Euler angles), in radians.
Ensuite, la boucle for consiste à définir six objets et à les ajouter à la scène

D'accord, continuons

CSS3DRenderer
renderer = new THREE.CSS3DRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

C'est la classe de la bibliothèque que nous avons référencée

Ceci La fonction principale de la classe est de la restituer en fonction de la scène et des informations relatives à l'objectif en trois

en utilisant des éléments dom et des attributs css3D

Ici, nous créons simplement une nouvelle classe et définissons la largeur et la hauteur

mais CSS3DRender n'a pas commencé à rendre la page ici


La liaison d'événement ici ne sera pas discutée en détail
document.addEventListener( &#39;mousedown&#39;, onDocumentMouseDown, false );
document.addEventListener( &#39;wheel&#39;, onDocumentMouseWheel, false );

document.addEventListener( &#39;touchstart&#39;, onDocumentTouchStart, false );
document.addEventListener( &#39;touchmove&#39;, onDocumentTouchMove, false );

window.addEventListener( &#39;resize&#39;, onWindowResize, false );
Ensuite, analysons le code de rendu


animate();
requestAnimationFrame( animate );
function animate() {

    requestAnimationFrame( animate );

    // lat +=  0.1;
    lat = Math.max( - 85, Math.min( 85, lat ) );
    phi = THREE.Math.degToRad( 90 - lat );
    theta = THREE.Math.degToRad( lon );

    target.x = Math.sin( phi ) * Math.cos( theta );
    target.y = Math.cos( phi );
    target.z = Math.sin( phi ) * Math.sin( theta );

    camera.lookAt( target );
    /**
     * 通过传入的scene和camera
     * 获取其中object在创建时候传入的element信息
     * 以及后面定义的包括位置,角度等信息
     * 根据场景中的obj创建dom元素
     * 插入render本身自己创建的场景p中
     * 达到渲染场景的效果
     */
    renderer.render( scene, camera );

}
Cette méthode peut déclencher la méthode d'animation en fonction de la fréquence d'images.


Ce code ajuste la position de l'objectif de la caméra en fonction de valeurs d'attribut prêtes à l'emploi (mises à jour en temps réel par glissement du doigt ou par glissement de la souris)
lat = Math.max( - 85, Math.min( 85, lat ) );
    phi = THREE.Math.degToRad( 90 - lat );
    theta = THREE.Math.degToRad( lon );

    target.x = Math.sin( phi ) * Math.cos( theta );
    target.y = Math.cos( phi );
    target.z = Math.sin( phi ) * Math.sin( theta );

    camera.lookAt( target );
renderer.render( scene, camera );

然后渲染........
因为render里面的代码比较多,这里就不贴代码了,大概总结一下render做的事情就是
首先render自己创建一个作为场景的p

通过传入的scene和camera

获取其中object在创建时候传入的element信息
以及后面定义的包括位置,角度等信息

根据场景中的obj创建dom元素(就是通过dom实现本应在canvas里的东西)

插入render本身自己创建的场景p中

当镜头方向变了,获取到的参数就变了,通过传入的对象身上带有的变化的参数改变页面上dom元素的位置。

达到渲染场景的效果

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn