javascript — Интегрируйте динамические изображения с HTML5 WebGL 360 градусов панорамы просмотра с Three.js в Codeigniter

Панорама 360 зрителей найдено ВОТ а также ВОТ просты в использовании, если просто скопировать и вставить код, доступный в их документации, и разместить 360 изображений рядом с индексным файлом и открыть его в браузере. Однако есть ли способ динамически выводить изображения из базы данных и отображать 360 изображений в виде, как это (ссылка на сайт)
введите описание изображения здесь

Код, указанный в файле Panorama Viewer, получает изображения в массиве Panorama следующим образом.

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

Что если нам нужно отобразить только одно изображение? Кто-нибудь пытался динамически выводить изображения из базы данных и отображал представление с 360-зрителем в нем? Я видел неотвеченную тему Вот но никто не ответил на этот вопрос.

0

Решение

Для многих разработчиков Codeigniter и тех, кто занимается разработкой веб-сайтов по недвижимости, они либо хотели, либо пытались, но не смогли интегрировать программу просмотра изображений 360 на своих веб-сайтах. Вот упражнение, которое я сделал и усвоил до сих пор.

Как это устроено?

  1. Загрузить изображение 360
  2. Получить 360 изображений из базы данных
  3. Показать / сделать вид

То, что нам нужно?

  • Функция в контроллере для загрузки 360 изображений
  • Функция в модели для сохранения и получения списка из 360 изображений
  • Функция для вызова видов для отображения изображений.
  • Страница разметки для отображения изображения 360, в котором есть весь JavaScript.

Это мой взгляд на загрузку 360 изображений
Это мой взгляд на загрузку 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');
}

}

Выше моя функция контроллера, которая загружает изображение 360 и сохраняет имя в базе данных. Ничего особенного, я не использую библиотеку загрузки CI

Схема БД

Это моя таблица базы данных для хранения 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');
}

}

Выше находится функция контроллера, которая получает все данные из моделей и вызывает представление для отображения страницы. Вы можете увидеть в функции контроллера следующие строки

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

получить список из 360 изображений от модели. Теперь в подробном представлении свойства я снова обращаюсь к представлению, которое фактически отображает изображение 360 в < iframe> и отправка имени изображения на URL, который отображает изображение 360.

<?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 }
}?>

У меня есть другой контроллер load360 с функцией showImage, которая получает имя изображения в качестве параметра и вызывает представление, которое отображает изображение 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>

И Работа Готово. Вы можете увидеть, как представления отображаются по следующим ссылкам

Двойные 360 изображений

Single 360 ​​Image

2

Другие решения

Других решений пока нет …