使用three.js写全景图,使用sprite类canvas,结合射线,点击跳转指定全景图【转】
https://blog.csdn.net/WDCCSDN/article/details/81214804
话不多说上代码:
1、html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
html, body {
margin: 0;
height: 100%;
}
canvas {
display: block;
}
</style>
</head>
<body onload="draw();">
</body>
<script src="js/three.js"></script>
<script src="js/panorama.js"></script>
</html>
2、js
var key=4;
var renderer;
var camera;
var scene;
var light;
var stats;
var isUserInteracting = false,lon = 90,lat = 0,phi = 0, theta = 0,target = new THREE.Vector3();
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2(); //鼠标位置
var mesh,texture=[],go_room=[];
texture[0] = THREE.ImageUtils.loadTexture("images/1.jpg",null,function(t){});
texture[1] = THREE.ImageUtils.loadTexture("images/2.jpg",null,function(t){});
texture[2] = THREE.ImageUtils.loadTexture("images/3.jpg",null,function(t){});
texture[3] = THREE.ImageUtils.loadTexture("images/4.jpg",null,function(t){});
texture[4] = THREE.ImageUtils.loadTexture("images/5.jpg",null,function(t){});
texture[5] = THREE.ImageUtils.loadTexture("images/6.jpg",null,function(t){});
function initRender() {
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
function initCamera() {
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 11000);
camera.target = new THREE.Vector3( 0, 0, 0 );
}
function initScene() {
scene = new THREE.Scene();
}
function initLight() {
}
function initModel() {
//声明一个球体
var geometry = new THREE.SphereGeometry( 500, 60, 40 );
// 反转X轴上的几何图形,使所有的面点向内。
geometry.scale( -1, 1, 1 );
//声明球体纹理
if(texture[key-1]==undefined){
texture[key-1]=THREE.ImageUtils.loadTexture("images/"+key+".jpg",null,function(t){});
}
var material = new THREE.MeshBasicMaterial({map:texture[key-1]});
mesh = new THREE.Mesh( geometry,material );
scene.add( mesh );
initpos();
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove( event ) {
if ( isUserInteracting === true ) {
lon = ( onPointerDownPointerX - event.clientX ) * 0.1 + onPointerDownLon;
lat = ( event.clientY - onPointerDownPointerY ) * 0.1 + onPointerDownLat;
}
}
function onDocumentMouseUp( event ) {
isUserInteracting = false;
}
function onDocumentMouseDown( event ) {
//通过鼠标点击的位置计算出raycaster所需要的点的位置,以屏幕中心为原点,值的范围为-1到1.
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
// 通过鼠标点的位置和当前相机的矩阵计算出raycaster
raycaster.setFromCamera( mouse, camera );
// 获取raycaster直线和所有模型相交的数组集合
var intersects = raycaster.intersectObjects(go_room);
console.log(intersects);
if(intersects.length ==1){
switch (intersects[0].object.name){
case "room1":
changeScene(1);
break;
case "room2":
changeScene(2);
break;
case "room3":
changeScene(3);
break;
case "room4":
changeScene(4);
break;
case "room5":
changeScene(5);
break;
case "room6":
changeScene(6);
break;
}
}else{
event.preventDefault();
isUserInteracting = true;
onPointerDownPointerX = event.clientX;
onPointerDownPointerY = event.clientY;
onPointerDownLon = lon;
onPointerDownLat = lat;
}
}
function onDocumentMouseWheel( event ) {
var fov = camera.fov + event.deltaY * 0.05;
camera.fov = THREE.Math.clamp( fov, 10, 75 );
camera.updateProjectionMatrix();
}
function onDocumentTouchStart( event ) {
if ( event.touches.length == 1 ) {
event.preventDefault();
onPointerDownPointerX = event.touches[ 0 ].pageX;
onPointerDownPointerY = event.touches[ 0 ].pageY;
onPointerDownLon = lon;
onPointerDownLat = lat;
}
}
function onDocumentTouchMove( event ) {
if ( event.touches.length == 1 ) {
event.preventDefault();
lon = ( onPointerDownPointerX - event.touches[0].pageX ) * 0.1 + onPointerDownLon;
lat = ( event.touches[0].pageY - onPointerDownPointerY ) * 0.1 + onPointerDownLat;
}
}
function animate() {
update();
requestAnimationFrame( animate );
}
function update() {
if ( isUserInteracting === false ) {
lon += 0.1;
}
lat = Math.max( - 85, Math.min( 85, lat ) );
phi = THREE.Math.degToRad( 90 - lat );
theta = THREE.Math.degToRad( lon );
target.x = 500 * Math.sin( phi ) * Math.cos( theta );
target.y = 500 * Math.cos( phi );
target.z = 500 * Math.sin( phi ) * Math.sin( theta );
camera.lookAt( target );
renderer.render( scene, camera );
}
function draw() {
initRender();
initScene();
initCamera();
initLight();
initModel();
animate();
}
function changeScene(index){
key=index;
var material = mesh.material;
if(texture[key-1]==undefined){
texture[key-1]=THREE.ImageUtils.loadTexture("images/"+key+".jpg",null,function(t){});
}
material.map = texture[key-1];
material.map.needsUpdate = true;
throwDir(key);
}
function throwDir(key){
switch (key){
case 1:
for(var i=0;i<6;i++){
if(i==3){
go_room[i].position.set(3.5,0,-0.3);
}else{
go_room[i].position.set(100,100,100);
}
scene.add(go_room[i]);
}
break;
case 2:
for(var i=0;i<6;i++){
if(i==3){
go_room[i].position.set(3.5,0,-0.5);
}else{
go_room[i].position.set(100,100,100);
}
scene.add(go_room[i]);
}
break;
case 3:
for(var i=0;i<6;i++){
if(i==3){
go_room[i].position.set(3,0,1);
}else{
go_room[i].position.set(100,100,100);
}
scene.add(go_room[i]);
}
break;
case 4:
go_room[0].position.set(-2.5,-0.2,-0.6);
scene.add(go_room[0]);
go_room[1].position.set(-3.8,0.3,-0.3);
scene.add(go_room[1]);
go_room[2].position.set(-3.8,0.3,0.3);
scene.add(go_room[2]);
go_room[3].position.set(-3,100,-0.6);
scene.add(go_room[3]);
go_room[4].position.set(-2.5,-0.2,0.6);
scene.add(go_room[4]);
go_room[5].position.set(-1.7,0,3);
scene.add(go_room[5]);
break;
case 5:
for(var i=0;i<6;i++){
if(i==3){
go_room[i].position.set(0.5,0,-2);
}else{
go_room[i].position.set(100,100,100);
}
scene.add(go_room[i]);
}
break;
case 6:
for(var i=0;i<6;i++){
if(i==3){
go_room[i].position.set(-0.3,0,2);
}else{
go_room[i].position.set(100,100,100);
}
scene.add(go_room[i]);
}
break;
}
}
function initpos(){
go_room[0] = makeTextSprite( " ","☝卧室1",{
"fontsize":20
});
go_room[0].name="room1";
go_room[0].position.set(-2.5,-0.2,-0.6);
scene.add(go_room[0]);
go_room[1] = makeTextSprite( " ","☝卧室2",{
"fontsize":20
});
go_room[1].name="room2";
go_room[1].position.set(-3.8,0.3,-0.3);
scene.add(go_room[1]);
go_room[2] = makeTextSprite( " ","☝卧室3",{
"fontsize":20
});
go_room[2].name="room3";
go_room[2].position.set(-3.8,0.3,0.3);
scene.add(go_room[2]);
go_room[3] = makeTextSprite( " ","☝客厅",{
"fontsize":20
});
go_room[3].name="room4";
go_room[3].position.set(-3,100,-0.6);
scene.add(go_room[3]);
go_room[4] = makeTextSprite( " ","☝卫生间",{
"fontsize":20
});
go_room[4].name="room5";
go_room[4].position.set(-2.5,-0.2,0.6);
scene.add(go_room[4]);
go_room[5] = makeTextSprite( " ","☝厨房",{
"fontsize":12
});
go_room[5].name="room6";
go_room[5].position.set(-1.7,0,3);
scene.add(go_room[5]);
}
window.addEventListener( 'resize', onWindowResize, false );
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'mouseup', onDocumentMouseUp, false );
document.addEventListener( 'wheel', onDocumentMouseWheel, false );
document.addEventListener( 'touchstart', onDocumentTouchStart, false );
document.addEventListener( 'touchmove', onDocumentTouchMove, false );
document.addEventListener( 'touchend', onDocumentMouseDown, false );
function makeTextSprite( message,message_zw, parameters){
if ( parameters === undefined ) parameters = {};
var fontface = parameters.hasOwnProperty("fontface") ?
parameters["fontface"] : "Arial";
var fontsize = parameters.hasOwnProperty("fontsize") ?
parameters["fontsize"] : 30;
var borderThickness = parameters.hasOwnProperty("borderThickness") ?
parameters["borderThickness"] : 4;
var borderColor = parameters.hasOwnProperty("borderColor") ?
parameters["borderColor"] : { r:0, g:0, b:0, a:1.0 };
var backgroundColor = parameters.hasOwnProperty("backgroundColor") ?
parameters["backgroundColor"] : { r:0, g:0, b:0, a:1.0 };
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
context.font = "Bold " + fontsize + "px " + fontface;
var metrics = context.measureText( message );
var textWidth = metrics.width;
context.fillStyle = "rgba(" + backgroundColor.r + "," + backgroundColor.g + ","
+ backgroundColor.b + "," + backgroundColor.a + ")";
context.strokeStyle = "rgba(" + borderColor.r + "," + borderColor.g + ","
+ borderColor.b + "," + borderColor.a + ")";
context.lineWidth = borderThickness;
context.fillStyle = "#ff0000";
context.fillText( message, borderThickness, fontsize + borderThickness);
context.font = 40 + "px " + fontface;
context.fillText( message_zw, borderThickness, fontsize + borderThickness+40);
var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
var spriteMaterial = new THREE.SpriteMaterial(
{ map: texture, useScreenCoordinates: false} );
var sprite = new THREE.Sprite( spriteMaterial );
sprite.scale.set(0.5,0.5,0.5);
return sprite;
}
个人服务器,一兆带宽,全景图比较大,下载慢,需要等一会
查看地址:http://47.104.152.68/panorama/changeqjt.html
或者访问:http://www.lianjiakeji.com/
各位有没有啥处理图片的好方式尽量压缩图片,因为我的全景图平均每张有一兆大小,访问比较慢
使用three.js写全景图,使用sprite类canvas,结合射线,点击跳转指定全景图【转】的更多相关文章
- Make Things Move -- Javascript html5版(二)实现最基本的Sprite类和stage管理对象
现在这几篇写的都是比较基础的东西,有过相应开发经验的朋友可直接忽略啦. 计算机模拟的动画都是由很多静态的一连串影像(sprite)在一定帧率(fps)内逐帧播放出来的. 对于js来说,我们可以用提供的 ...
- 分享:计算机图形学期末作业!!利用WebGL的第三方库three.js写一个简单的网页版“我的世界小游戏”
这几天一直在忙着期末考试,所以一直没有更新我的博客,今天刚把我的期末作业完成了,心情澎湃,所以晚上不管怎么样,我也要写一篇博客纪念一下我上课都没有听,还是通过强大的度娘完成了我的作业的经历.(当然作业 ...
- js深入研究之Person类案例
<script type="text/javascript"> /* 定义一个Person类 */ function Person(name, age) { this. ...
- 原生JS动态添加和删除类
原生JS动态添加和删除类 由于需要, 给按钮组监听点击事件(要求用事件委托),当有一个按钮被点击时,相应的给该按钮添加一个类(激活类),其他没有点击的按钮就要移出该类 添加和和删除类有三种方法 首先等 ...
- js写插件教程深入
原文地址:https://github.com/lianxiaozhuang/blog 转载请注明出处 js 写插件教程深入 1.介绍具有安全作用域的构造函数 function Fn(name){ t ...
- js面向对象设计之class类
class 相对 function 是后出来的,既然 class 出来了,显然是为了解决 function 在处理面向对象设计中的缺陷而来.下面通过对比,来看看 class 作为 ES6 中的重大升级 ...
- 前端与编译原理——用JS写一个JS解释器
说起编译原理,印象往往只停留在本科时那些枯燥的课程和晦涩的概念.作为前端开发者,编译原理似乎离我们很远,对它的理解很可能仅仅局限于"抽象语法树(AST)".但这仅仅是个开头而已.编 ...
- 使用JS写一个计算器
先上效果图: 简单的加减乘除功能还是有的,所以我们就考虑怎么来实现这个功能. 根据预期效果,可以确定页面中的布局要用到table tr td. 所以先放上页面布局,table的边框宽度border,c ...
- Node.js写文件的三种方法
Node.js写文件的三种方式: 1.通过管道流写文件 采用管道传输二进制流,可以实现自动管理流,可写流不必当心可读流流的过快而崩溃,适合大小文件传输(推荐) var readStream = fs. ...
随机推荐
- 5个php实例,细致说明传值与传引用的区别
传值:是把实参的值赋值给行参 ,那么对行参的修改,不会影响实参的值 传引用 :真正的以地址的方式传递参数传递以后,行参和实参都是同一个对象,只是他们名字不同而已对行参的修改将影响实参的值 说明: 传值 ...
- LeetCode(41):缺失的第一个正数
Hard! 题目描述: 给定一个未排序的整数数组,找出其中没有出现的最小的正整数. 示例 1: 输入: [1,2,0] 输出: 3 示例 2: 输入: [3,4,-1,1] 输出: 2 示例 3: 输 ...
- 【mysql】autocommit=0后,commit, rollback无效
之前在[mysql]MySQLdb中的事务处理中用autocommit和commit()以及rollback()实现了事务处理. 但后来,用同样的代码在另一个数据库中运行却失败了.找了一个下午的原因. ...
- noip 2017 时间复杂度
自认为是少有的复杂的代码 这题思想很简单,就是大模拟 对于for循环,一行读入4个字符串,然后分类讨论: ①:如果是一个正常的O(n),那么累计n的指数加1 ②:如果是一个常数级别的,那么继续循环,但 ...
- HDU1850 尼姆博弈求可行方案数目
尼姆博弈(Nimm's Game) 题型 尼姆博弈模型,大致上是这样的: 有3堆各若干个物品,两个人轮流从某一堆取任意多的物品,规定每次至少取1个,多者不限,最后取光者得胜. 分析 1.首先自己想一下 ...
- Windows C#入门环境搭建
Windows C#入门环境搭建 1. 安装Microsoft .NET Framework目录: C:\Windows\Microsoft.NET\Framework,查看已经安装的版本. 如果未安 ...
- Asp.Net构架(Http请求处理流程)、(Http Handler 介绍)、(HttpModule 介绍)
Asp.Net构架(Http请求处理流程) Http请求处理流程概述 对于普通访问者来说,这就像每天太阳东边升起西边落下一样是理所当然的:对于很多程序员来说,认为这个与己无关,不过是系统管理员或者网管 ...
- 【Java】 剑指offer(21) 调整数组顺序使奇数位于偶数前面
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇 ...
- js时间戳转换时间、距当前时间
// 1.时间戳转化成时间格式 function getTime(times) { return new Date(parseInt(times) * 1000).toLocaleString().r ...
- [漏洞案例]thinkcmf 2.x从sql注入到getshell实战
0X00 前言 这个案例是某项目的漏洞,涉及敏感的地方将会打码. 很久没更新博客了,放一篇上来除除草,新的一年会有所转变,以后会有更多领域的研究. 下面是正文 0X01 正文 某厂商某个网站用的是th ...