您现在的位置是:主页 > news > 京东企业集团网站建设方案/百度识图查另一半情头

京东企业集团网站建设方案/百度识图查另一半情头

admin2025/5/2 16:46:42news

简介京东企业集团网站建设方案,百度识图查另一半情头,有没有可以在线做化学实验的网站,招聘做网站专业人员本文由WRLD 3D赞助。 感谢您支持使SitePoint成为可能的合作伙伴。 以下活动在圣诞节前夕的7:00 am至8:00 am之间进行。 事件是实时发生的。 对于我们所有的数据收集功能,在可视化我们所居住的3D世界中的数据时,我们仍然抱有希望。我们盯着2D图表和日志条…

京东企业集团网站建设方案,百度识图查另一半情头,有没有可以在线做化学实验的网站,招聘做网站专业人员本文由WRLD 3D赞助。 感谢您支持使SitePoint成为可能的合作伙伴。 以下活动在圣诞节前夕的7:00 am至8:00 am之间进行。 事件是实时发生的。 对于我们所有的数据收集功能,在可视化我们所居住的3D世界中的数据时,我们仍然抱有希望。我们盯着2D图表和日志条…

本文由WRLD 3D赞助。 感谢您支持使SitePoint成为可能的合作伙伴。

以下活动在圣诞节前夕的7:00 am至8:00 am之间进行。 事件是实时发生的。

对于我们所有的数据收集功能,在可视化我们所居住的3D世界中的数据时,我们仍然抱有希望。我们盯着2D图表和日志条目,但是我们从世界中拔出的许多数据都具有意义在3D环境中。 并且,当将数据重新应用到3D模型中时,可视化该数据可能会很有用。

这是增强现实寻求解决的问题。 与虚拟现实的虚构环境相比,增强现实可以帮助我们解决许多现实问题。 通过应用数据,否则我们将通过2D媒体将其消耗到我们周围的现实世界中。 映射是增强现实的孩子中的长子。

当WRLD与我们联系时,写他们的平台时,我立即被他们平台的图形和性能所吸引。 但是,我越是使用他们的平台; 我对API的实用性和映射数据的保真度更加着迷。

我们将发布一系列教程,以演示如何使用该平台将信息带入适用的世界。 每个教程的主题均根据受欢迎的电视节目而定。 您可能已经猜到,第一个大约是24

在本教程中,我们将学习如何开始使用WRLD平台。 我们将按照文档示例来呈现最简单的地图。 然后,我们将创建一个本地环境来编译代码。 并开始讲一个故事。

我们将讨论以下主题:

  • 根据地点名称渲染地图
  • 遍历地图,了解一系列事件
  • 突出建筑物并在每个建筑物上设计活动
  • 使用HTML5音频API播放声音文件
  • 更改天气状况和一天中的时间

可以在Github上找到本教程的代码。 它已经过现代版本或Firefox,Node和macOS的测试。

入门

最简单的入门方法是遵循文档中的第一个示例。 在此之前,我们需要一个帐户。 转到https://www.wrld3d.com ,然后单击“注册”。

WRLD主页

登录后,单击“开发人员”和“访问API密钥”。

WRLD访问API密钥屏幕

为您的应用程序创建一个新的API密钥。 您可以调用任何名称,但是稍后需要复制生成的密钥…

WRLD密钥

对于第一个示例,我们可以从官方文档站点获得代码。 我将其放在CodePen中,并用纽约的坐标替换了坐标:

WRLD.js基于Leaflet.js ,这使以前做过一些基于地图的工作的任何人都熟悉。 这也意味着地图具有移动友好性和交互性。

使用鼠标左键单击并拖动以在地图上平移。 用鼠标右键单击并拖动以旋转地图。 单击并拖动,用鼠标中键更改视角。 滚动鼠标滚轮将影响缩放。 该地图还可以在触摸设备上进行控制。

免费学习PHP!

全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。

原价$ 11.95 您的完全免费

除了包括Javascript SDK和样式表之外; 我们只需要大约5行格式化代码即可绘制出精美的纽约地图! 第一个参数map是WRLD将地图渲染到的元素的ID。 第二个是我们生成的API密钥。 第三个是配置对象。 该对象包含地图中心的坐标,以及可选的缩放级别。

建立构建链

CodePen非常适合进行快速演示。 但是我们需要更强大,更美观的东西。 让我们设置一些简单的东西,它将所有现代Javascript编译成大多数浏览器可以理解的版本。

ParcelJS是最近宣布的; 作为快速的零配置Web捆绑器。 让我们测试一下。 首先,我们需要通过NPM将Parcel安装为全局应用程序:

npm install -g parcel-bundler

接下来,我们可以为项目创建一些文件。 我们需要一个Javascript文件,一个CSS文件和一个HTML入口点文件:

const Wrld = require("wrld.js")
const map = Wrld.map("map", "[your API key here]", {
center: [40.73061, -73.935242],
zoom: 16,
})

这是来自tutorial/app.js

@import "https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.1/leaflet.css";
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
#map {
width: 100%;
height: 100%;
background-color: #000000;
}

这是来自tutorial/app.css

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="./app.css" />
<title>Getting started with WRLD</title>
</head>
<body>
<div id="map"></div>
<script src="./app.js"></script>
</body>
</html>

这是来自tutorial/index.html

注意app.js如何要求wrld.js吗? 我们需要安装WRLD Javascript SDK:

npm init -y
npm install --save wrld.js

然后,我们可以开始使用Parcel构建和运行本地文件:

parcel index.html

这将启动本地开发服务器,并捆绑JS和CSS文件。 该过程如下所示:

包裹包裹

打开浏览器中显示的URL,您应该再次看到纽约地图。 当我们更改JS和CSS文件时,这些文件将自动重新编译并重新加载到浏览器中。 包裹似乎确实符合其要求。

而且,这正是我们所需要的—省力的构建链,使我们能够专注于使用WRLD完成工作!

包裹仍然很新。 您可能难以满足高度定制的工作流程或构建要求; 并且文档仍然可以解释这些情况下的处理方法。 不过,我认为这个简单的构建链将满足我们的需求,Parcel在这里已兑现了诺言。

将名称转换为坐标

有时,我们知道我们要考虑的位置的确切坐标。 有时我们只知道地点的名称。 让我们快速回避,看看当我们只知道它的名字时如何发现该位置的坐标。

这是WRLD平台上尚不可用的少数服务之一。 因此,让我们使用Google API进行计算。 我们需要另一个API密钥,因此请转到https://developers.google.com/maps/documentation/geocoding/get-api-key并单击“获取密钥”:

写谷歌密钥

接下来,我们可以使用Google Geocoding服务,通过稍微更改Javascript来查找地址的坐标:

const Wrld = require("wrld.js")
const keys = {
wrld: "[your WRLD API key]",
google: "[your Google API key]",
}
window.addEventListener("load", async () => {
const address = encodeURIComponent("empire state building, new york")
const endpoint = "https://maps.googleapis.com/maps/api/geocode/json?"
+ "key=" + keys.google + "&address=" + address
// console.log(endpoint)
const response = await fetch(endpoint)
const lookup = await response.json()
// console.log(lookup)
const { lat, lng } = lookup.results[0].geometry.location
const map = Wrld.map("map", keys.wrld, {
center: [lat, lng],
zoom: 12,
})
})

这是来自tutorial/app.js

我已经将键重构为一个对象。 我们甚至可以将它们移到环境变量文件中,并从Git中排除该文件。 这样,密钥可能有用但对公众隐藏。 我还将代码移动到异步短箭头函数中,以便可以使用asyncawait ; 这样一来,一旦加载文档,它就会发生。

接下来,我们可以定义一个要查找的地址。 最好对地址进行编码,以便可以将其用作查询字符串参数。 我们可以将其与Google API密钥一起馈入地理编码API端点,以获取结果。

继续并取消注释控制台日志语句,这样您就可以看到编码后的URI的样子,以及Google返回给我们的结果。 我们从Google获得了相当详细的结果,但是我们想要的位在results[0].geometry.location 。 使用对象解构,我们可以仅提取该对象的latlng键。

最后,我们可以将其输入到map函数中,地图将渲染帝国大厦。 就像我说的,我们经常已经知道地图中心的坐标。 但是,当我们不这样做时:此服务和代码将帮助我们找到它们。

在地图上移动

让我们开始进行沉浸式地图体验。 我们希望带某人进行一系列事件,然后将地图移至每个新事件,以便我们向他们讲述一个故事。 将故事内容与故事机制分开的一种好方法是创建一个单独的“数据” JavaScript导入:

module.exports = [
{
// start at Empire State Building
lat: 40.7484405,
lng: -73.98566439999999,
seconds: 15,
image: ".jack-1",
text: "What a lovely day...<phone rings>",
},
{
// stay in the same place but update story
lat: 40.7484405,
lng: -73.98566439999999,
seconds: 15,
image: ".chloe-1",
text: "Jack, we have a problem...",
},
// ...more events
]

这是来自tutorial/story.js

我们可以将故事分为地图事件。 每个事件甚至都有latlng ,尽管某些事件可能在先前的位置发生。 对于每个事件,我们都会显示某人讲话的图片以及他们在说什么。 几秒钟后,我们会将相机移至新位置和/或扬声器。

我们可以将该文件导入到主要的Javascript文件中,并更改地图以显示第一个故事事件。 我们甚至可以突出显示事件发生的建筑物:

const story = require("./story")
window.addEventListener("load", async () => {
// ...old code commented out here
const { lat, lng } = story[0]
const map = Wrld.map("map", keys.wrld, {
center: [lat, lng],
zoom: 15,
})
map.on("initialstreamingcomplete", () => {
Wrld.buildings
.buildingHighlight(
Wrld.buildings
.buildingHighlightOptions()
.highlightBuildingAtLocation([lat, lng])
.color([125, 255, 125, 128]),
)
.addTo(map)
})
})

这是来自tutorial/app.js

该代码演示了初始地图渲染/流式处理完成后如何突出显示建筑物。 Wrld.buildings.buildingHighlightOptions创建一个模板选项对象,向其中添加突出显示的位置和颜色。 我们将此选项对象传递给Wrld.buildings.buildingHighlight以创建高光,并将其添加到地图。 颜色数组是RGBA值,这意味着第四个整数是不透明度值( 128约为255限制的一半,或50%透明)。

这不是突出建筑物的唯一方法。 我们还可以使用射线投射来选择建筑物,但这比我们这里需要的要先进。 您可以在https://wrld3d.com/wrld.js/latest/docs/api/L.Wrld.buildings.BuildingHighlightOptions中找到有关它的文档。

实际上,当我们这样做时; 我们可以将建筑物的亮点抽象为可重用的功能。 我们甚至可以为每个事件添加特定的突出显示颜色,并在每次添加新事件时删除以前的建筑物突出显示:

const { lat, lng, color } = story[0]
const map = Wrld.map("map", keys.wrld, {
center: [lat, lng],
zoom: 15,
})
map.on("initialstreamingcomplete", () => {
highlightBuildingAt(lat, lng, color)
})
let highlight = null
const highlightBuildingAt = (lat, lng, color) => {
if (highlight) {
highlight.remove()
}
highlight = Wrld.buildings
.buildingHighlight(
Wrld.buildings
.buildingHighlightOptions()
.highlightBuildingAtLocation([lat, lng])
.color(color),
)
.addTo(map)
}

这是来自tutorial/app.js

这样,Jack和Chloe可以拥有自己的突出显示颜色,以在说话时显示出来。 删除建筑物高光比添加高光更容易。 我们只需要保存对我们创建的突出显示的引用,并在其上调用remove方法。

移动地图

好的,现在我们需要将地图移至每个新事件。 我们将突出显示每个事件的建筑物,因此我们知道我们正在查看哪个事件:

const { lat, lng, zoom, color, seconds } = story[0]
const map = Wrld.map("map", keys.wrld, {
center: [lat, lng],
zoom,
})
map.on("initialstreamingcomplete", () => {
highlightBuildingAt(lat, lng, color)
if (story.length > 1) {
setTimeout(() => showNextEvent(1), seconds * 1000)
}
})
let highlight = null
const highlightBuildingAt = (lat, lng, color) => {
if (highlight) {
highlight.remove()
}
highlight = Wrld.buildings
.buildingHighlight(
Wrld.buildings
.buildingHighlightOptions()
.highlightBuildingAtLocation([lat, lng])
.color(color),
)
.addTo(map)
}
const showNextEvent = index => {
const { lat, lng, zoom, degrees, color, seconds } = story[index]
map.setView([lat, lng], zoom, {
headingDegrees: degrees,
animate: true,
durationSeconds: 2.5,
})
setTimeout(() => {
highlightBuildingAt(lat, lng, color)
if (story.length > index + 1) {
setTimeout(() => showNextEvent(index + 1), seconds * 1000)
}
}, 2.5 * 1000)
}

这是来自tutorial/app.js

这里有很多事情,所以让我们分解一下:

  1. 我们向每个事件添加了zoom属性。 这意味着我们可以对事件之间的缩放级别进行动画处理,从而使故事更具动感。 除了第一个事件外,我们还为所有事件添加了一个degrees属性。 我们可以修改第一个事件的摄影机方向,但默认情况下(360度)我觉得很好。 在事件中添加度数可以使标题动画与缩放动画大致相同。
  2. 如果存在多个事件(可以放心地假设这样做,但是无论如何我都添加了检查),那么我们将使用第一个事件的seconds属性来延迟向事件2的过渡。 我们创建一个showNextEvent函数,其硬编码索引值为1
  3. showNextEvent ,我们使用setView方法对摄像机的位置,缩放和航向进行动画处理。 动画将花费2.5秒,因此我们将超时设置为该时间。 在超时回调函数中,我们突出显示新建筑物(以便突出显示仅在摄像机完成移动之后发生)并排队下一个事件。

随时添加更多事件和/或完全更改故事。 自己制作,玩得开心!

添加音频

我们的故事有点安静。 我们需要一些悬念的背景音乐才能进入该区域。 前往Epidemic Sound之类的网站,并为您的故事找到一些可疑的音乐曲目。 我已经下载了一些文件,并将它们放在了tutorial/tracks文件夹中。

现在,让我们创建一个不可见的音频播放器,并使其随机播放曲目。 为此,我们需要一个曲目列表:

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="./app.css" />
<title>Getting started with WRLD</title>
</head>
<body>
<div id="map"></div>
<audio class="track-1" src="./tracks/track-1.mp3" />
<audio class="track-2" src="./tracks/track-2.mp3" />
<audio class="track-3" src="./tracks/track-3.mp3" />
<audio class="track-4" src="./tracks/track-4.mp3" />
<audio class="track-5" src="./tracks/track-5.mp3" />
<audio class="track-6" src="./tracks/track-6.mp3" />
<audio class="track-7" src="./tracks/track-7.mp3" />
<audio class="track-8" src="./tracks/track-8.mp3" />
<audio class="track-9" src="./tracks/track-9.mp3" />
<audio class="track-10" src="./tracks/track-10.mp3" />
<script src="./app.js"></script>
</body>
</html>

这是来自tutorial/index.html

Parcel正在监视index.html并将所有静态文件引用重写为其复制到dist文件夹中的文件。 如果我们在此HTML文件中创建HTML4 audio标签,Parcel会将这些文件复制到列表文件夹,然后通过开发服务器提供这些文件。 我们不必以这种方式做事,但是随着我们的开发,它对于测试来说更加简单。

一种替代方法是从Internet上的某个地方引用这些文件。 另一个可能是不使用开发服务器。

module.exports = [
".track-1",
".track-2",
".track-3",
".track-4",
".track-5",
".track-6",
".track-7",
".track-8",
".track-9",
".track-10",
]

这是来自tutorial/tracks.js

我们可以使用此列表查找与要播放的每个*.mp3文件链接HTML元素。 我们将在主要的JS文件中使用此列表:

const nextTrack = () => {
const index = Math.floor(Math.random() * tracks.length)
const audio = new Audio(document.querySelector(tracks[index]).src)
audio.addEventListener("ended", () => nextTrack())
audio.play()
}
nextTrack()

这是来自tutorial/app.js

我们想随机播放曲目,因此我们找到一个随机索引。 然后,获取与该索引匹配的audio元素,并使用其src属性值创建一个新的Audio对象。 曲目播放完毕后,我们再次调用nextTrack函数(因此,下一个随机曲目将开始循环播放)并开始随机选择的曲目。

不幸的是,我无法在Github存储库中包含正在使用的曲目。 首先,它们将极大地增加仓库的规模。 其次,我有权将其用于YouTube作品,但不得出于任何其他原因进行分发。 如果要获取我使用过的曲目,可以在“ 流行声音”搜索结果页面上找到它们。

为活动添加信息卡

我之前提到过; WRLD.js基于LeafletJS。 这很棒,因为在处理WRLD映射时,我们可以做Leaflet允许的所有事情。 实际上,我们可以使用Leaflet弹出窗口来叙述故事事件。 Leaflet弹出窗口如下所示:

L.popup()
.setLatLng(latlng)
.setContent("I am a popup!")
.openOn(map)

我们将在弹出窗口中嵌入每个事件的图像和文本。 如果我们可以将弹出窗口相对于建筑物的高度定位,那也很酷。 不是在顶部,而是……说……沿着建筑物的一半。 我们可以这样使用:

let popup = null
const showPopup = (lat, lng, image, text, elevation) => {
const src = document.querySelector(image).src
const element1 = "<img class='image' src='" + src + "' />"
const element2 = "<span class='text'>" + text + "</span>"
const element3 = "<div class='popup'>" + element1 + element2 + "</div>"
popup = L.popup({
closeButton: false,
autoPanPaddingTopLeft: 100,
elevation: Math.max(20, elevation / 2),
})
.setLatLng(L.latLng(lat, lng))
.setContent(element3)
.openOn(map)
}

这是来自tutorial/app.js

L.popup接受一个options对象。 我们设置的选项是:

  1. 我们想要隐藏通常在Leaflet弹出窗口上显示的关闭按钮。
  2. 当摄像机完成平移以显示弹出窗口时,我们希望摄像机在屏幕的顶部/左侧之间留出足够的空间。
  3. 我们希望弹出窗口距离地面至少20米,并且最多为建筑物其他高度的一半。

我们还在构造一个HTML字符串。 它将事件的图像和文本放在.popup元素内。 我们可以对这些元素使用以下样式:

.hidden {
display: none;
}
.image {
display: flex;
width: auto;
height: 100px;
}
.text {
display: flex;
padding-left: 10px;
font-size: 16px;
}
.popup {
display: flex;
flex-direction: row;
align-items: flex-start;
}

这是来自tutorial/app.css

.popup是Flexbox容器元素。 我们应用于它的flex样式是,子级应该连续显示,并且它们应该与容器的顶部对齐。 有很多很棒的Flexbox指南。 看看Flexbox Zombies ,这是一种有趣的学习方式……

请注意,我们还为index.html的图像定义了.hidden样式。 我们不希望它们显示-它们在那里,因此Parcel将正确复制和引用它们。

问题是:我们如何获得每座建筑物的标高? 我们可以听取建筑信息事件,并从那里算出海拔。 不幸的是,没有突出显示此方法的方法,因此我们必须陷入“全局”事件并偷偷地添加/删除侦听器:

let elevation = 0
const waitForElevation = onElevation => {
const listener = event => {
map.buildings.off("buildinginformationreceived", listener)
const information = event.buildingHighlight.getBuildingInformation()
if (!information) {
onElevation(0)
} else {
const dimensions = information.getBuildingDimensions()
const ground = dimensions.getBaseAltitude()
const elevation = dimensions.getTopAltitude() - ground
onElevation(elevation)
}
}
map.buildings.on("buildinginformationreceived", listener)
}

这是来自tutorial/app.js

waitForElevation创建并将侦听器功能添加到buildinginformationreceived地图事件。 触发侦听器的那一刻,它会自行删除。 这样,我们可以触发每个事件:添加侦听器→突出显示建筑物→调用侦听器→删除侦听器。

收到的buildinginformationreceived会接收一个事件,该事件具有getBuildingInformation方法。 如果建筑物有任何信息,我们将获取地面海拔高度并据此计算出海拔高度。 如果不是,我们调用onElevation函数参数。 因此, onElevation会以0或更大的整数来调用。

所有剩下要做的就是一个加onElevation回调到每个highlightBuildingAt通话; 并在该函数内调用waitForElevation

map.on("initialstreamingcomplete", () => {
highlightBuildingAt(
lat, lng, color,
elevation => showPopup(lat, lng, image, text, elevation)
)
if (story.length > 1) {
setTimeout(() => showNextEvent(1), seconds * 1000)
}
})
let highlight = null
const highlightBuildingAt = (lat, lng, color, onElevation) => {
waitForElevation(onElevation)
// ...rest of highlightBuildingAt
}
const showNextEvent = index => {
// ...rest of showNextEvent
setTimeout(() => {
highlightBuildingAt(
lat, lng, color,
elevation => showPopup(lat, lng, image, text, elevation)
)
if (story.length > index + 1) {
setTimeout(() => showNextEvent(index + 1), seconds * 1000)
}
}, 2.5 * 1000)
}

这是来自tutorial/app.js

改变天气和一天中的时间

杰克的故事在冬天播出。 但是地图晴朗而明亮。 让我们将天气更改为与季节保持一致:

map.themes.setWeather(Wrld.themes.weather.Snowy)

这是来自tutorial/app.js

改变天气很容易。 在这里,我们正在下雪; 但是我们可以做到以下任何一种:

  • Wrld.themes.weather.Clear
  • Wrld.themes.weather.Overcast
  • Wrld.themes.weather.Foggy
  • Wrld.themes.weather.Rainy
  • Wrld.themes.weather.Snowy

同样,我们希望使时间流逝更加现实。 每24集应该在1小时内发生一次。 如果我们可以将每个位置相隔1小时,那就太好了,但我们只有以下时间可以配合使用:

  • Wrld.themes.time.Dawn
  • Wrld.themes.time.Day
  • Wrld.themes.time.Dusk
  • Wrld.themes.time.Night

让我们根据每个事件更改一天中的时间:

const { lat, lng, zoom, color, seconds, image, text, time } = story[0]
const map = Wrld.map("map", keys.wrld, {
center: [lat, lng],
zoom,
})
if (time) {
map.themes.setTime(time)
}
// ...later
const showNextEvent = index => {
const {
lat, lng, zoom, degrees, color, seconds, image, text, time
} = story[index]
map.setView(...)
setTimeout(() => {
if (time) {
map.themes.setTime(time)
}
highlightBuildingAt(...)
if (story.length > index + 1) {
setTimeout(...)
}
}, 2.5 * 1000)
}

这是来自tutorial/app.js

摘要

今天完成了。 希望您以后能像我把它们放在一起一样开心。 花一些时间修饰你的故事; 添加新角色,新音乐以及您认为可以使您的故事精彩的任何内容。 我们很乐意看到您的想法。

这是最终产品的视频。 我将为此添加更多事件,但是我为我们的管理感到骄傲:

下次,我们将学习有关WRLD平台允许的演示,动画和自动化的更多信息。 实际上,我们将使用WRLD创建有用的,可出售的移动友好型应用程序。 下次见!

翻译自: https://www.sitepoint.com/building-dynamic-3d-maps/