threejs 全景区加可点击标注

2023-11-16

<template>

    <div class="test-wrapper" id="container">

        <el-dialog :visible.sync="dialogVisible">

            {{pointName}}

        </el-dialog>

    </div>

</template>

 

<script>

import * as THREE from "three";

 

import qjt from "@/assets/threejs/p2.png";

import Icon from "@/assets/threejs/test1.png";

 

var OrbitControls = require('three-orbit-controls')(THREE)

 

var camera, scene, renderer,controls;

var cameraOrtho, sceneOrtho;

var _sprites = [];

var _lables = [];

var clickableObjects = [];

var _pRadius = 100;

var _raycaster;

var _mouse = new THREE.Vector2();

var containerWidth, containerHeight;

 

export default {

    name: "test",

    data() {

        return {

            pointList:[

                {

                    id:1,

                    name:'aaa',

                    lon:120,

                    lat:0,

                },

                {

                    id:2,

                    name:'bbbb',

                    lon:120,

                    lat:10,

                }

            ],

            rotateSpeed:1,

            pointName:'',

            dialogVisible:false,

        };

    },

    mounted() {

        this.$nextTick(() => {

            this.init();

            this.animate();

        })

       

    },

    methods: {

        init() {

 

            

            let container = document.getElementById('container');

 

            containerWidth = container.clientWidth;

            containerHeight = container.clientHeight;

 

            scene = new THREE.Scene();

            camera = new THREE.PerspectiveCamera(

                75,

                containerWidth / containerHeight,

                0.1,

                1000

            );

 

            var width = containerWidth;

            var height = containerHeight;

            cameraOrtho = new THREE.OrthographicCamera(

                -width / 2,

                width / 2,

                height / 2,

                -height / 2,

                1,

                10

            );

            cameraOrtho.position.z = 10;

 

            sceneOrtho = new THREE.Scene();


 

            var geometry = new THREE.SphereBufferGeometry(100, 60, 40);

            geometry.scale(-1, 1, 1);

 

            var texture = new THREE.TextureLoader().load(qjt);

            var material = new THREE.MeshBasicMaterial({ map: texture });

 

            let mesh = new THREE.Mesh(geometry, material);

 

            scene.add(mesh);

 

            camera.position.z = 50;

 

            renderer = new THREE.WebGLRenderer();

            renderer.setSize(containerWidth, containerHeight);

            renderer.autoClear = false;

            container.appendChild(renderer.domElement);

 

            controls = new OrbitControls(camera, renderer.domElement);

            controls.enablePan = false;

            controls.maxDistance = 100;

            controls.autoRotate = true;

            controls.autoRotateSpeed = this.rotateSpeed;

 

            this.loadPoint();

 

            _raycaster = new THREE.Raycaster();

 

            document.addEventListener("mousedown", this.onMouseDown, false);


 

        },

        animate() {

            requestAnimationFrame(this.animate);

            this.update();

            

        },

        update(){

            controls.update();

            this.renderSprites();

            renderer.render(scene, camera);

            renderer.render(sceneOrtho, cameraOrtho);

        },

        loadPoint(){

            this.pointList.forEach(item => {

                _sprites.push(this.createSprite(item));

            })

        },

        createSprite(item) {

            var textureLoader = new THREE.TextureLoader();

            var ballMaterial = new THREE.SpriteMaterial({

                map: textureLoader.load(Icon)

            });

            var sp1 = {

                lon: item.lon,

                lat: item.lat,

                name: item.name,

                sprite: new THREE.Sprite(ballMaterial)

            };

            sp1.sprite.scale.set(1, 1, 1);

            sp1.sprite.position.set(0, 0, 0);

            sp1.sprite.name = item.name;

            sceneOrtho.add(sp1.sprite);

            clickableObjects.push(sp1.sprite);

            return sp1;

        },

        geoPosition2World(lon, lat) {

            lat = Math.max(-85, Math.min(85, lat));

            var phi = THREE.Math.degToRad(90 - lat);

            var theta = THREE.Math.degToRad(lon);

 

            var result = {

                x: _pRadius * Math.sin(phi) * Math.cos(theta),

                y: _pRadius * Math.cos(phi),

                z: _pRadius * Math.sin(phi) * Math.sin(theta)

            };

            return new THREE.Vector3(result.x, result.y, result.z);

        },

        worldPostion2Screen(world_vector, camera) {

            var vector = world_vector.clone();

            vector.project(camera);

            var result = {

                x: Math.round((vector.x + 1) * containerWidth / 2 - containerWidth / 2),

                y: Math.round(containerHeight / 2 - (-vector.y + 1) * containerHeight / 2),

                z: 0

            };

            return new THREE.Vector3(result.x, result.y, result.z);

        },

        renderSprites(){

            for (var i = 0; i < _sprites.length; i++) {

                var wp = this.geoPosition2World(_sprites[i].lon, _sprites[i].lat);

                var sp = this.worldPostion2Screen(wp, camera);

                var test = wp.clone();

                test.project(camera);

                if (test.x > -1 && test.x < 1 && test.y > -1 && test.y < 1 && test.z > -1 && test.z < 1) {

                    _sprites[i].sprite.scale.set(24, 24, 1.0);

                    _sprites[i].sprite.position.set(sp.x, sp.y, 1);

                } else {

                    _sprites[i].sprite.scale.set(1.0, 1.0, 1.0);

                    _sprites[i].sprite.position.set(0, 0, 0);

                }

            }

        },

        onMouseDown(event){

            controls.autoRotateSpeed = 0;

            _mouse.x = event.clientX / containerWidth * 2 - 1;

            _mouse.y = -(event.clientY / containerHeight) * 2 + 1;

            _raycaster.setFromCamera(_mouse, cameraOrtho);

            var intersects = _raycaster.intersectObjects(clickableObjects);

            if(intersects != null && intersects.length > 0){

                this.pointName = intersects[0].object.name;

                this.dialogVisible = true;

            }else{

                this.dialogVisible = false;

            }

        }

    }

};

</script>

 

<style lang="less" scoped>

.test-wrapper {

    height: 100vh;

}

</style>

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

threejs 全景区加可点击标注 的相关文章

  • Spark on Kubernetes 与 Spark on Yarn 不完全对比分析

    前言 Apache Spark 是目前应用最广泛的大数据分析计算工具之一 它擅长于批处理和实时流处理 并支持机器学习 人工智能 自然语言处理和数据分析应用 随着 Spark 越来越受欢迎 使用量越来越大 狭义上的 Hadoop MR 技术栈
  • (转)提高网站速度的最佳实践

    原文来自 http www space007 com post 129 html 相信互联网已经越来越成为人们生活中不可或缺的一部分 ajax flex等等富客户端的应用使得人们越加 幸福 地体验着许多原先只能在C S实现的功能 比如Goo
  • 【blender建模功能】06 多边形建形工具

    blender 06 多边形建形工具全解 全参数 拓展对齐与自动合并 拓扑使用演示 1 使用方式 1 1 顶点预捕捉 1 2 创建面 1 3 边界边预捕捉 2 实用 2 1 位置对齐与自动合并技巧 2 2 边界边与顶点延伸面 2 3 快速点
  • 【重要!】一文理解指针作为函数参数传递!看完不懂你打我

    先说最重要的结论 当指针作为参数传入函数时 是值传递而非引用传递 其次 不要把指针在定义时和使用时搞混 定义时 值 p p p int p 变量 int变量 int p 一重指针 int变量的地址 int变量 int p 二重指针 int变
  • Realtime Multi-Person 2D Pose Estimation using Part Affinity Fields解读

    摘要 我们的方法 能够有效的检测一个图像中的多人 通过Part Affinity Fields来学习身体的各部分及关联性 利用全局纹理信息 自下而上的方法 达到实时性和高精度 通过两个分支来学习到部位的位置和关联性 引言 一张图中的多人po
  • OceanBase能取代Oracle吗

    推荐两篇文章 1 http www ha97 com 5766 html 2 http www sohu com a 152030438 151779
  • Python3 juypterlab pyecharts 柱状图/条形图制作

    1 打开虚拟机 确保虚拟机中的mysql正常连接 2 数据准备 Navicat Premium正常连接虚拟机中的mysq 创建名为follow的数据库 再通过excel导入准备好的数据 3 Navicat Premium中查询评分9 0分以
  • 解析创客教育的实践进程

    算力已经成为数字时代的核心生产力 是拉动数字经济向前发展的新动能 对于AI算力的投入 也将加快人工智能这一重要的数字化技术与实体经济的融合 赋能传统产业转型升级 催生新产业新业务新模式 为我国数字经济做强做优做大做出应有的贡献 在孩子的学习
  • OpenHarmony鸿蒙系统源码编译

    学习资源 鸿蒙官网 https device harmonyos com cn home 开源代码仓库地址 https openharmony gitee com 源码获取 参考 https device harmonyos com cn
  • Unate function & Positive unate & Negtive unate

    Unate function Unateness gt Positive unate and negtive unate
  • python变量的引用赋值及深浅拷贝

    python变量的引用赋值及深浅拷贝 1 python的变量 1 1 可变数据类型 1 2 不可变数据类型 2 深浅拷贝 2 1 内存地址以及实际存储数据之间的关系 2 2 若拷贝对象是可变数据类型 2 3 若拷贝对象是不可变数据类型 1
  • MyBatis3入门

    这里对mybatis的入门介绍以官方最新MyBatis3 4 1为准 具体文档及jar包请访问 https github com mybatis mybatis 3 releases 以前经常都在使用mybatis 但通常都是和Spring
  • MFC 启用和禁用控件

    启用和禁用控件可以调用CWnd EnableWindow 函数 BOOL EnableWindow BOOL bEnable TRUE 判断控件是否可用可以调用 CWnd IsWindowEnable函数 BOOL IsWindowEnab
  • Oracle VM VirtualBOX下克隆虚拟机镜像

    Oracle VM VirtualBOX下克隆虚拟机镜像 Windows环境下在Oracle VM VirtualBOX下克隆虚拟机镜像 1 通过命令操作 VBoxManage exe clonevdi F mysqlvm mysqledi
  • 二叉树的深度优先遍历和广度优先遍历js代码实现

    a 树的深度优先搜索和广度优先搜索 其实没了解过的时候 看见树就头晕 之后去搜了下 发现也不是什么困难的事情 其实树的深度优先搜索指的是不按照层级的规律去便利 像前序便利 中序后序便利都是属于深度便利的方式 树的广度便利就是按照层级关系 一
  • js 解构赋值

    取对象里的code以及value值 对象结构 var data code 1 message Hello World 常规取值做法 var code data code var message data message 用解构就方便简洁许多
  • sqlserver 联表查询、子查询、窗口函数、聚合函数等概念与例子

    with cte as的用法 查询的一个有用工具 允许创建临时命名结果集 可在查询中多次引用相同的子查询结果 可以提高查询的可读性和维护性 WITH cte name column1 column2 AS 这里是子查询 SELECT col
  • 静态白盒测试-code review

    一 静态白盒测试概述 首先区分软件测试的几个术语 白盒测试 黑盒测试 静态测试 动态测试 白盒测试 也称为透明测试 clear box testing 白盒测试针对逻辑结构进行检查 它允许我们看到程序的内部结构 黑盒测试 black box
  • 图片重叠,转换

随机推荐

  • Unity射线检测失效原因(逐步完善)

    完整用法 1 确保被检测物体拥有 层的设置 public LayerMask m layerMask 别忘记给敌人设置层和在脚本中选择层 2 确保被检测物体拥有 collider且其厚度不为0
  • Unity缺少System.IO.Ports

    问题 我需要使用串口相关的类库 但是引用不到 怎么解决的 PlayerSetting 界面把 Api Compatibility Level 切换为 NET 4 x 然后就好了
  • python并发编程之多线程

    多线程 多线程的作用 也是用于提高程序的效率 多进程 1 核心是多道技术 把内存分成 几块 2 通过 本质上就是切换 加 保存状态 3 当程序 IO 操作较多 可以提高程序效率 多线程什么是多线程 程序的执行线路 相当于与一条流水线 其包含
  • 计算机物联网论文范文大全,精选物联网的毕业论文范文.doc

    精选物联网的毕业论文范文 基于单片机的嵌入式以太网控制终端设计摘要 基于单片机技术的以太网终端广泛应用在各个领域 本文基于建荣AX20XX PHY的解决方案 实现ARP请求 以及ping命令 同时 本文详细介绍以太网接口的硬件设计和通信电路
  • 数学建模之方差分析基础--单因素,双因素方差分析与matlab实现

    前言 由于方差分析的原理基本在所有概率论与数理统计的书中都可以找到 那么这里就直接以图片的形式呈现了 关于方差齐次性检验以后会补充 知识基础 假设检验 今天刚刚学了数据结构 发现自己以前写的数组的基础操作水平极低 真是惭愧 简介 方差分析
  • 贝叶斯网络结构学习方法简介

    题目 贝叶斯网络结构学习方法简介 贝叶斯网络 Bayesiannetwork BN 结构学习就是从给定的数据集中学出贝叶斯网络结构 即各节点之间的依赖关系 只有确定了结构才能继续学得网络参数 即表示各节点之间依赖强弱的条件概率 对于普通人来
  • 计算机致命命令,[注意]13 个致命的Linux 命令

    本文收集所有你不能在 Linux 下执行的命令 执行任何下列命令 之一 会让你丢失数据或造成数据损坏 冻结或挂起你运行中的 Linux 系统 千万不要在 Linux 文本界面运行下列命令 NEVER RUN THE FOLLOWING CO
  • 获取单选框值

    function getRadioVal nameVal var inputs document getElementsByName nameVal var checkVal for var i 0 len inputs length i
  • 海思3559:uboot顶层Makefile分析

    顶层Makefile的内容主要结构为 确定版本号及主机信息 实现静默编译功能 设置各种路径 设置编译工具链 设置规则 设置与cpu相关的伪目标 需要注意的是 结构顺序并不代表代码执行顺序 1 确定版本号及主机信息 VERSION 2016
  • 群辉 Synology NAS Docker 安装 RustDesk-server 自建服务器只要一个容器

    from https blog zhjh top archives M8nBI5tjcxQe31DhiXqxy 简介 之前按照网上的教程 rustdesk server 需要安装两个容器 最近想升级下版本 发现有一个新镜像 rustdesk
  • 零基础学Python 爬虫-笔记

    零基础学Python 爬虫 Tony老师 普门教育 python 兼容 3 8 5 pycharm 付费 免费 写项目有区别 破解版2019 代码提示 爬虫 概念 科技 智能化 互联网 数据时代 智能家居 爬虫 批量的采集数据 网络 cpo
  • 关于Spring 的IoC和AOP的面试题,快看看你都能答上来哪些

    推荐 前些天发现了一个巨牛的人工智能学习网站 通俗易懂 风趣幽默 忍不住分享一下给大家 点击跳转到网站 博客首页 派 大 星 欢迎关注 点赞 收藏 留言 本文由派大星原创编撰 系列专栏 迎战面试 本系列分享自己准备面试的过程和一些经典的面试
  • 从0开始实现简易版vue2

    文章目录 前言 原理 思路分析 实现Observer 实现Watcher 实现Compile 前言 Vue js的双向绑定原理是其最重要的特性之一 它使得数据模型和DOM之间的同步变得非常简单和高效 先上个成果图来吸引各位 new Simp
  • MySQL B+树索引

    MySQL B 树索引B 树是MySQL中最常用的索引结构 它是B树的变种 区别在于B 树的非叶子节点不保存数据 只保存节点指针 这使得B 树层次更少 查询效率更高 B 树的特点 1 非叶子节点不保存数据 只有叶子节点保存实际数据 这使树更
  • hive DEBUG

    输出 DEBUG 日志 使用以下参数 hive hiveconf hive root logger DEBUG console 远程调试 hive cli hive debug 此命令监听 8000 端口 可以使用远程调试连接此 jvm 远
  • win10系统 Mysql初始化报错:[ERROR] --initialize specified but the data directory has files in it. Aborting

    解决方法 1 删除以前安装的Mysql文件夹 data文件夹保存自己创建使用过的表单 可以数据迁移到其他mysql版本 2 查看自己是否已经初始化 如果当前安装版本的Mysql文件夹根目录是否存在data文件夹 如果存在 则已经初始化 可以
  • DSS部署-3、创建hadoop用户

    文章目录 第三部分 创建hadoop用户 第三部分 创建hadoop用户 1 创建一个名字为hadoop的普通用户 root bigdata senior01 useradd hadoop root bigdata senior01 pas
  • IDEA-常用配置

    一 Appearance Behavior 1 1 设置主题 1 2 设置窗体及菜单的字体及大小 二 Editor General 2 1 设置自动导包的功能 Add unambiguous imports on the fly 自动导入不
  • 提升前端开发效率:基于vue的van-radio-group组件封装指南

    前言 vant 作为一款流行的 ui 框架 其中 van radio group 组件是一个常用的单选框组件 但有时我们需要根据项目需求进行定制化封装 本文将介绍如何基于 vue 框架封装 van radio group 组件 让我们一起来
  • threejs 全景区加可点击标注