使用HTML5 WebGL 360度全景查看器将动态图像与Codeigniter中的Three.js集成

时间:2017-02-27 11:51:47

标签: javascript php html5 codeigniter 360-panorama-viewer

如果您只是复制并粘贴其文档中提供的代码并将360图像放在索引文件旁边并将其打开,则找到的Panorama 360查看器HEREHERE很容易使用浏览器。但有没有办法动态地从数据库中提取图像并在视图中渲染360图像(linkenter image description here

全景查看器文件中给出的代码可以像这样获取全景数组中的图像

var panoramasArray = ["01.jpg","02.jpg","03.jpg","04.jpg","05.jpg","06.jpg"];
var panoramaNumber = Math.floor(Math.random()*panoramasArray.length);

如果我们只需显示一张图片怎么办?有没有人试图从数据库中动态引入图像并使用360查看器呈现视图?我看到了一个未答复的帖子here,但没有人回答这个问题。

1 个答案:

答案 0 :(得分:2)

对于许多Codeigniter开发人员和那些一直在开发房地产网站的人来说,要么想要尝试但未能将360图像查看器集成到他们的网站中。这是迄今为止我所做和所学的练习。

如何运作?

  1. 上传360图片
  2. 从数据库中获取360图像
  3. 显示/渲染视图
  4. 我们需要什么?

    • 控制器中用于上传360张图像的功能
    • 模型中用于保存和获取360图像列表的功能
    • 调用视图以显示图像的功能。
    • 显示360图像的标记页面,其中包含所有JavaScript。

    This is my view to upload 360 Image 这是我上传360图像的视图,这只是一个带有文件输入字段的表单。

    public function upload_360_images()
    {
        if($this->session->userdata['id'] && $this->session->userdata['type']=='user')
        {
            if($_FILES)
            {
                if(isset($_FILES['files'])){
                    $data['errors']= array();
                    $extensions = array("jpeg","jpg","png");
    
                    foreach($_FILES['files']['tmp_name'] as $key => $tmp_name ){
    
                        $file_name = $key.$_FILES['files']['name'][$key];
                        $file_size =$_FILES['files']['size'][$key];
                        $file_tmp =$_FILES['files']['tmp_name'][$key];
                        $file_type=$_FILES['files']['type'][$key];
                        /*$file_ext=explode('.',$_FILES['image']['name'][$key]) ;
                        $file_ext=end($file_ext);*/
                        $i=1;
                        if($file_size > 7097152){
                            $data['errors'][$i]='File '.$i.' size must be less than 7 MB';
                            $i++;
                        }
    
                        $desired_dir="uploads";
                        if(empty($data['errors'])==true){
                            if(is_dir($desired_dir)==false){
                                mkdir("$desired_dir", 0700);        // Create directory if it does not exist
                            }
                            if(is_dir("$desired_dir/".$file_name)==false){
                                move_uploaded_file($file_tmp,"uploads/".$file_name);
                                $this->post_model->add360Image('property_360_images',$file_name,$this->uri->segment(3));
                            }else{                                  //rename the file if another one exist
                                $new_dir="uploads/".$file_name.time();
                                rename($file_tmp,$new_dir) ;
                            }
    
                        }else{
                            $data['contact']=$this->admin_model->getContactDetails();
                            $data['images']=$this->post_model->getProperty360Images($this->uri->segment(3));
                            $data['title']='My Profile Image';
                            $this->load->view('site/static/head',$data);
                            $this->load->view('site/static/header');
                            $this->load->view('site/content/upload_360_images');
                            $this->load->view('site/static/footer');
                            $this->load->view('site/static/footer_links');
                        }
                    }
                    if(empty($data['errors']))
                    {
                        redirect(base_url().'dashboard');
                    }
                    else
                    {
                        $data['contact']=$this->admin_model->getContactDetails();
                        $data['images']=$this->post_model->getProperty360Images($this->uri->segment(3));
                        $data['title']='My Profile Image';
                        $this->load->view('site/static/head',$data);
                        $this->load->view('site/static/header');
                        $this->load->view('site/content/upload_360_images');
                        $this->load->view('site/static/footer');
                        $this->load->view('site/static/footer_links');
                    }
                }
    
            }
            else
            {
                $data['contact']=$this->admin_model->getContactDetails();
                $data['images']=$this->post_model->getProperty360Images($this->uri->segment(3));
                $data['title']='My Profile Image';
                $this->load->view('site/static/head',$data);
                $this->load->view('site/static/header');
                $this->load->view('site/content/upload_360_images');
                $this->load->view('site/static/footer');
                $this->load->view('site/static/footer_links');
            }
    
        }
        else
        {
            redirect(base_url().'user/login');
        }
    
    }
    

    上面是我的Controller功能,它上传360 Image并将名称保存在数据库中。没什么好看的,我没有使用CI上传库

    DB Schema

    这是我的数据库表,用于存储360图像名称

    public function property_detail()
    {
    
        $id=$this->uri->segment(3);
        $this->property_model->incPageViewById($id);
        $data['contact']=$this->admin_model->getContactDetails();
        $data['section_fields']=$this->admin_model->getSectionFields('property_sections');
        $data['property']=$this->property_model->getPropertyById($id);
        // Get 360 Images list of this property based on ID
        $data['images360']=$this->post_model->getProperty360Images($id);
        $data['profile']=$this->property_model->getFieldsById($id);
        $data['types']=$this->admin_model->getAll('property_types');
    
        $data['similar']=$this->property_model->getSimilarPropertiesById($data['property'][0]['posted_by']);
        $data['popular']=$this->property_model->getAllProperties(0,0);
        if($this->isLoggedIn())
        {
            $data['favorites']=$this->property_model->getMyFavorites($this->session->userdata['id']);
            $data['is_favorite']=$this->property_model->isFavorite($id,$this->session->userdata['id']);
        }
    
        $data['posted_by']=$this->property_model->getPostedByDetails($id);
        $data['comments']=$this->property_model->getCommentsById($id);
        if($_POST)
        {
            $config=array(
                array(
                    'field'     => 'name',
                    'label'     => 'Name',
                    'rules'     => 'trim|required',
                ),
                array(
                    'field'     => 'email',
                    'label'     => 'Email',
                    'rules'     => 'trim|required',
                ),
                array(
                    'field'     => 'comment',
                    'label'     => 'Comment',
                    'rules'     => 'trim|required',
                )
            );
            $this->form_validation->set_rules($config);
            if($this->form_validation->run()==false)
            {
                $data['errors']=validation_errors();
                $data['title']=$data['property'][0]['title'];
                $this->load->view('site/static/head',$data);
                $this->load->view('site/static/header');
                $this->load->view('site/content/property_detail');
                $this->load->view('site/static/footer');
                $this->load->view('site/static/footer_links');
            }
            else
            {
                $this->property_model->addComment($_POST,$id);
                $data['success']='Comment posted successfully';
                $data['comments']=$this->property_model->getCommentsById($id);
                $data['title']=$data['property'][0]['title'];
                $this->load->view('site/static/head',$data);
                $this->load->view('site/static/header');
                $this->load->view('site/content/property_detail');
                $this->load->view('site/static/footer');
                $this->load->view('site/static/footer_links');
            }
        }
        else
        {
            $data['title']=$data['property'][0]['title'];
            $this->load->view('site/static/head',$data);
            $this->load->view('site/static/header');
            $this->load->view('site/content/property_detail');
            $this->load->view('site/static/footer');
            $this->load->view('site/static/footer_links');
        }
    
    }
    

    上面是Controller Function,它从Models中获取所有数据并调用视图来呈现页面。您可以在控制器功能中看到以下行

    // Get 360 Images list of this property based on ID
    $data['images360']=$this->post_model->getProperty360Images($id);
    

    从模型中获取360张图片的列表。现在在属性详细信息视图中,我再次调用实际在<中显示360图像的视图。 iframe>并将图像名称发送到显示360图像的URL。

    <?php if(count($images360)>0){
     ?><h3>360 View</h3><?php
     for($i=0;$i<count($images360);$i++){?>
        <iframe src = "https://duperty.com/realestate/load360/showImage/<?php echo $images360[$i]['image']?>" width = "100%" height = "540" frameborder = "0" scrolling = "no"></iframe>
        <?php }
      }?>
    

    我有另一个带有showImage函数的控制器load360,它接收Image name作为参数并调用显示360图像的视图

    class Load360 extends CI_Controller {
    function __construct()
    {
        parent::__construct();
    }
    
    public function showImage()
    {
        header("cache-Control: no-store, no-cache, must-revalidate");
        header("cache-Control: post-check=0, pre-check=0", false);
        header("Pragma: no-cache");
        header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
    
        $data['image']=$this->uri->segment(3);
        //echo $data['image'];exit;
        $this->load->view('site/content/show360',$data);
    }
    

    }

    在我在这里调用的show360视图中,我只是回显图像变量和图像路径。

       <html>
       <head>
         <style>
         body{
            margin: 0;
        }
    
           canvas {
            height: 100%;
            width: 100%;
            }
           </style>
         <script src="//cdnjs.cloudflare.com/ajax/libs/three.js/r69/three.min.js"></script>
    
          </head>
          <body>
    
         <script>
    
            var manualControl = false;
            var longitude = 0;
            var latitude = 0;
            var savedX;
            var savedY;
            var savedLongitude;
            var savedLatitude;
    
            // panoramas background
            var panoramasArray = ["<?php echo base_url().'uploads/'.$image;?>"];
            var panoramaNumber = Math.floor(Math.random()*panoramasArray.length);
    
            // setting up the renderer
            renderer = new THREE.WebGLRenderer();
            renderer.setSize(window.innerWidth, window.innerHeight);
            document.body.appendChild(renderer.domElement);
    
            // creating a new scene
            var scene = new THREE.Scene();
    
            // adding a camera
            //var camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 0.5, 500);
            var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000);
            camera.target = new THREE.Vector3(0, 0, 0);
    
            // creation of a big sphere geometry
            var sphere = new THREE.SphereGeometry(100, 100, 40);
            sphere.applyMatrix(new THREE.Matrix4().makeScale(-1, 1, 1));
    
            // creation of the sphere material
            var sphereMaterial = new THREE.MeshBasicMaterial();
            sphereMaterial.map = THREE.ImageUtils.loadTexture(panoramasArray[panoramaNumber])
    
            // geometry + material = mesh (actual object)
            var sphereMesh = new THREE.Mesh(sphere, sphereMaterial);
            scene.add(sphereMesh);
    
            // listeners
            document.addEventListener("mousedown", onDocumentMouseDown, false);
            document.addEventListener("mousemove", onDocumentMouseMove, false);
            document.addEventListener("mouseup", onDocumentMouseUp, false);
    
            render();
    
            function render(){
    
                requestAnimationFrame(render);
    
                if(!manualControl){
                    longitude += 0.1;
                }
    
                // limiting latitude from -85 to 85 (cannot point to the sky or under your feet)
                latitude = Math.max(-85, Math.min(85, latitude));
    
                // moving the camera according to current latitude (vertical movement) and longitude (horizontal movement)
                camera.target.x = 500 * Math.sin(THREE.Math.degToRad(90 - latitude)) * Math.cos(THREE.Math.degToRad(longitude));
                camera.target.y = 500 * Math.cos(THREE.Math.degToRad(90 - latitude));
                camera.target.z = 500 * Math.sin(THREE.Math.degToRad(90 - latitude)) * Math.sin(THREE.Math.degToRad(longitude));
                camera.lookAt(camera.target);
    
                // calling again render function
                renderer.render(scene, camera);
    
            }
    
            // when the mouse is pressed, we switch to manual control and save current coordinates
            function onDocumentMouseDown(event){
    
                event.preventDefault();
    
                manualControl = true;
    
                savedX = event.clientX;
                savedY = event.clientY;
    
                savedLongitude = longitude;
                savedLatitude = latitude;
    
            }
    
            // when the mouse moves, if in manual contro we adjust coordinates
            function onDocumentMouseMove(event){
    
                if(manualControl){
                    longitude = (savedX - event.clientX) * 0.1 + savedLongitude;
                    latitude = (event.clientY - savedY) * 0.1 + savedLatitude;
                }
    
            }
    
            // when the mouse is released, we turn manual control off
            function onDocumentMouseUp(event){
    
                manualControl = false;
    
            }
    
            // pressing a key (actually releasing it) changes the texture map
            document.onkeyup = function(event){
    
                panoramaNumber = (panoramaNumber + 1) % panoramasArray.length
                sphereMaterial.map = THREE.ImageUtils.loadTexture(panoramasArray[panoramaNumber])
    
            }
    
        </script>
    
     </body>
     </html>
    

    和乔布斯完成。您可以在以下链接中查看视图的呈现方式

    Double 360 Images

    Single 360 Image