maps-api-v3_利用Google Maps API发挥创意

maps-api-v3

您已经设计了一个闪亮的新网站; 仔细选择颜色,版式和照片,以完美反映公司的品牌形象。 然后您的客户要求您添加地图。 当然,您可以使用地图构建“向导”,例如每个Google帐户随附的地图。 但是,让我们面对现实吧,它们的功能是有限的,而且看起来很普通!

另一方面,Google Maps API使您可以自由创建完全自定义的地图,从而可以完成各种有趣的事情。 朴次茅斯历史地图是我最近使用此API构建的网站。

本系列教程将向您展示如何使用Google Maps API创建自定义地图。 这将涉及到使用JavaScript弄脏双手,但这是值得的。

这些教程将涵盖各种内容。 仅举几例:自定义地图颜色,菜单和标记; 通过将您自己的地图设计(例如汉拉德地图)叠加到可缩放的Google地图上,使其栩栩如生; 链接到Flickr API; 图像优化; 响应式设计; 代码优化和验证。 或者,换句话说,当您完成工作时,不仅可以创建精美的地图,还可以查看与构建任何网站相关的许多内容。

情境

这些教程使用了一家英国公司推广音乐节的场景。 上面的“最终产品”图片显示了我们的目标。 看一下演示。

注意:在此示例中,仅Glastonbury标记是“活动的”。

在开始之前,您可能想要下载与本教程相关的文件 。 我为每个活动都提供了一个单独的html文件。


反正什么是API?

API或应用程序编程接口是一种表达公司(例如Facebook,Twitter,You Tube,Google)发布的一组命令(例如功能)的奇特方法。 想法是,您可以使用这些命令来创建其内容的高度自定义版本。 例如,对于Google Maps API,“内容”是地图,而对于Flickr API,“内容”是照片。

当人们谈论“混搭”时,它们意味着他们已经使用了两家或两家以上公司的API来组合内容,例如使来自Flickr的图片出现在Google地图上。 这些API实际上有成千上万种。 请看一下可编程Web以获得更多信息。

我们将在以后的教程中介绍Flickr API,但首先我们将重点关注Google Maps API。 这将使您能够做各种事情,包括自定义颜色,地图标记,弹出框样式,细节级别和缩放级别。 更不用说实际上使地图做一些很酷的事情,例如显示实时数据,对标记进行分组,规划路线,绘制自定义覆盖图,动态显示数据....列表无止境!


Google Maps入门

冒个风险,要开始使用,您需要一个Google帐户。 如果您目前还没有,请前往Google并注册。

有了您的Google帐户,您现在可以冒险进入Google Maps API页面 。 收藏此页; 您会变得非常熟悉。 主要领域是:

  • 开发人员指南:代码片段,向您展示如何使用API​​函数执行某些操作。
  • API参考:API中所有功能的完整参考列表。 将此用作使用API​​可以执行的“购物清单”。 (但是请记住,还有其他库可以让您做更多的事情。稍后我们将介绍这些内容)。

在继续之前,您还需要一个API密钥(由字母和数字组成的长序列,对您来说是唯一的)。 在此处获取您的API密钥。


创建第一个地图

好的,您准备开始构建。

要使提供的地图生效,请用您自己的API密钥替换显示为“ YOUR_API_KEY_GOES_HERE”的位置。 您的地图应类似于上面显示的地图。

该代码的基本原理是,它创建了一个div(称为festival-map ),JavaScript将其加载到该div中。 我在代码中添加了注释,以解释其工作原理,但是值得重点介绍一下。

该代码首先使用Doctype声明<!DOCTYPE html>将您的应用程序声明为HTML5。

然后为地图设置样式。 <style type="text/css"></style>标记之间的位。 您可以根据要放置地图的位置来调整#festival-map ID上的样式。 如果要“全屏”地图,则将宽度和高度设置为100%,并删除边距。

然后,跳过JavaScript片刻,body标记之间的代码会建立一个空的html对象,即一个div( festival-map )来保存地图。 这是一种“占位符”,JavaScript会将地图加载到其中。

<div id="festival-map"></div>

确定-现在查看JavaScript-该代码首先连接到您的Google Maps API密钥。

<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY_GOES_HERE&sensor=true"></script>

然后,它将启动到创建地图JavaScript中。 快速提醒:JavaScript函数(例如loadFestivalMap )是一组命令,它们仅在被其他代码调用时才运行。 这可能看起来很复杂,但实际上只在做一些事情-

  • 设置了地图的配置选项( festivalMapOptions )(例如,纬度,经度,缩放级别等),并创建了一个空JavaScript变量( festivalMap ),不久该地图将被分配给该JavaScript变量。 (提示: itouchmap是一个方便的站点,可用于查找任何位置的纬度和经度坐标。)
  • 然后,以下行触发loadFestivalMap函数运行: google.maps.event.addDomListener(window, 'load', loadFestivalMap);
  • 此函数创建地图,并将其分配给为其创建JavaScript变量(即festivalMap )。 在执行此操作时,它还将应用配置选项,并将地图加载到为保存该festival-map创建的festival-map div中。
  • 最后, loadMapMarkers功能被触发到由的最后一行运行loadFestivalMap功能。

如果这没有任何意义,请仔细阅读完整版代码中的注释, 进一步解释它们。


图片作为地图标记

到现在为止,您应该已经建立了一个地图并正在运行,并且幸运的是,您还没有对JavaScript感到困惑! 假设一切都很好,我们就可以开始使地图看起来更有趣了。

使用您自己的图像作为地图标记很容易。 与您为地图本身设置属性选项的方式类似(例如center, zoom如上所述, center, zoom等),您还可以更改地图标记的属性。 要将其他图像用作地图标记,您只需设置地图标记的icon属性。 (如果您感兴趣,则Google Maps API-标记部分列出了您可以使用的所有地图标记属性,方法和事件)。

通常,地图标记是.png,因为它们使您可以具有透明背景的不规则形状。

我们还需要为每个标记设置“可点击”区域,以确保.png的“图像”位可点击,而透明位则不可。 如果标记重叠,这真的很重要。

首先,创建地图图标图像( markerIconGlastonbury ),然后创建地图图标形状( markerShapeGlastonbury ),最后将它们链接到地图标记( markerGlastonbury )。

//Setting the position of the Glastonbury map marker.
var markerPositionGlastonbury = new google.maps.LatLng(51.159803, -2.585585);

//Setting the icon to be used with the Glastonbury map marker.
var markerIconGlastonbury = {
 url: 'icons/icon_glas_uk.png',
 //The size image file.
 size: new google.maps.Size(225, 120),
 //The point on the image to measure the anchor from. 0, 0 is the top left.
 origin: new google.maps.Point(0, 0),
 //The x y coordinates of the anchor point on the marker. e.g. If your map marker was a drawing pin then the anchor would be the tip of the pin.
 anchor: new google.maps.Point(189, 116)
};

//Setting the shape to be used with the Glastonbury map marker.
var markerShapeGlastonbury = {
 coord: [12,4,216,22,212,74,157,70,184,111,125,67,6,56],
 type: 'poly'
};

//Creating the Glastonbury map marker.
markerGlastonbury = new google.maps.Marker({
 //uses the position set above.
 position: markerPositionGlastonbury,
 //adds the marker to the map.
 map: festivalMap,
 title: 'Glastonbury Festival',
 //assigns the icon image set above to the marker.
 icon: markerIconGlastonbury,
 //assigns the icon shape set above to the marker.
 shape: markerShapeGlastonbury,
 //sets the z-index of the map marker.
 zIndex:102
});

您可以从本页顶部下载完整的html文件,或查看实时版本 。 目前,我只添加了一个地图标记…显然,我会在不久后添加更多标记!

提示:要获取地图图标的形状坐标,我将图标图像插入Dreamweaver中的一个临时网页,然后使用“多边形热点”工具获取坐标,然后将这些坐标复制回我的主地图页面。

关于Z索引的快速说明

元素(例如地图标记)可以同时具有x,y和z坐标。 Z索引是深度。 它决定了元素如何“堆叠”在彼此之上,以及如何重叠。

如果元素的x和y坐标相同,则具有较高z索引的元素将显示在具有较低z索引的元素的顶部。 (Z索引仅适用于定位的元素,例如相对,固定或绝对)。

到目前为止,地图看起来还可以,因为默认情况下,Google Maps API会为屏幕下方显示的元素提供更高的z索引,因此它们会出现在屏幕上方稍稍上方的项目上方。 例如,怀特岛(Isle of Wight)图标位于格拉斯顿伯里(Glastonbury)和雷丁音乐节(Reading Festival)图标的顶部(请参见下图)。

在本教程的后面,我们将介绍如何更改z索引来操纵地图标记的显示方式。


更改颜色和细节级别

尽管该地图已开始成形,但默认地图与我要实现的总体效果并不完全匹配。 幸运的是,使用API的“样式”选项来自定义地图外观非常简单。

在这一点上,我还应该说我只是参加了一些音乐节来说明这个例子。 这有点随机,我的选择并不能反映我对任何节日的支持或反对意见!

第1步

使用JSON向导来锻炼您希望地图的外观。 您可以更改几乎所有内容的颜色,添加和删除细节,分别设置颜色填充和几何形状等。值得花一些时间来习惯它的工作方式。 (如果您想知道, JSON只是一种格式化信息的方式,因此计算机可以读取它。)

第2步

当您对JSON向导预览中显示的样式感到满意时,请单击Show JSON按钮并复制代码。

第三步

返回到html文档,在打开JavaScript标记之后添加一个变量来保存此信息,然后粘贴代码。

//First, we read in the data describing style.
var style_festival = [
 {
 "featureType": "administrative",
 "stylers": [
 { "visibility": "off" }
 ]
 },{
 "featureType": "poi",
 "stylers": [
 { "visibility": "off" }
 ]
 },{
 "featureType": "transit",
 "stylers": [
 { "visibility": "off" }
 ]
 },{
 "featureType": "road",
 "stylers": [
 { "visibility": "off" }
 ]
 },{
 "featureType": "landscape",
 "stylers": [
 { "color": "#FFE200" }
 ]
 },{
 "featureType": "water",
 "stylers": [
 { "visibility": "on" },
 { "color": "#4f92c6" }
 ]
 }
];

第4步

您需要获取地图,才能将刚刚添加的信息视为地图样式。 使用StyledMapType可以做到这一点。

//Then we use this data to create the styles.
var styled_festival = new google.maps.StyledMapType(style_festival, {name: "Festival style"});

第5步

最后,您需要将新样式分配给地图以“激活”样式。

festivalMap.mapTypes.set('map_styles_festival', styled_festival);
festivalMap.setMapTypeId('map_styles_festival');

请使用本教程开始处的链接下载到目前为止的地图代码副本,或查看本部分教程实时演示 。 我实际上添加了两种样式。 一个会立即被激活,另一个将在缩放地图以提供更多细节时被激活。 (这将在下面进一步解释。)

这时我也忍不住要添加背景:)看一下body CSS选择器,看看我是怎么做到的。


弹出框和动态缩放

好的,现在该让地图实际做些事情了! 您可以使用内置的信息窗口叠加 ,但他们并不看起来棒极了 ,他们不能轻易进行定制。 因此,我们将使用信息框库。

第1步

下载Infobox库的副本。 解压缩,并将其存储在靠近地图的文件夹中。 然后在您的html文件顶部附近添加此行。

<script src="infobox/infobox.js" type="text/javascript"></script>

第2步

为每个地图标记添加z索引,以使靠近屏幕底部的z索引显示在上方的z索引的上方。 (即标记离屏幕底部越近,其z索引应该越高。)稍后将显示所有有关您为什么这样做的标记! 例如 -

//Creating the Glastonbury map marker.
markerGlastonbury = new google.maps.Marker({
 //uses the position set above.
 position: markerPositionGlastonbury,
 //adds the marker to the map.
 map: festivalMap,
 title: 'Glastonbury Festival',
 //assigns the icon image set above to the marker.
 icon: markerIconGlastonbury,
 //assigns the icon shape set above to the marker.
 shape: markerShapeGlastonbury,
 //sets the z-index of the map marker.
 zIndex:107
});

第三步

在每个地图标记之后添加以下代码。 请通读代码中的注释以查看其作用。

//Creates the information to go in the pop-up info box.
var boxTextGlastonbury = document.createElement("div");
boxTextGlastonbury.style.cssText = pop_up_info;
boxTextGlastonbury.innerHTML = '<span class="pop_up_box_text"><img src="content/glastonbury.jpg" width="400" height="285" border="0" /></span>';

//Sets up the configuration options of the pop-up info box.
var infoboxOptionsGlastonbury = {
 content: boxTextGlastonbury
 ,disableAutoPan: false
 ,maxWidth: 0
 ,pixelOffset: new google.maps.Size(-241, 0)
 ,zIndex: null
 ,boxStyle: {
 background: "url('infobox/pop_up_box_top_arrow.png') no-repeat"
 ,opacity: 1
 ,width: "430px"
 }
 ,closeBoxMargin: "10px 2px 2px 2px"
 ,closeBoxURL: "icons/button_close.png"
 ,infoBoxClearance: new google.maps.Size(1, 1)
 ,isHidden: false
 ,pane: "floatPane"
 ,enableEventPropagation: false
};

//Creates the pop-up infobox for Glastonbury, adding the configuration options set above.
infoboxGlastonbury = new InfoBox(infoboxOptionsGlastonbury);

//Add an 'event listener' to the Glastonbury map marker to listen out for when it is clicked.
google.maps.event.addListener(markerGlastonbury, "click", function (e) {
 //Open the Glastonbury info box.
 infoboxGlastonbury.open(festivalMap, this);
 //Changes the z-index property of the marker to make the marker appear on top of other markers.
 this.setZIndex(google.maps.Marker.MAX_ZINDEX + 1);
 //Zooms the map.
 setZoomWhenMarkerClicked();
 //Sets the Glastonbury marker to be the center of the map.
 festivalMap.setCenter(markerGlastonbury.getPosition());
});

第4步

在上面的代码中,您调用了setZoomWhenMarkerClicked函数。 当有人单击标记时,这将放大地图。 但是在您创建此功能之前,绝不会发生很多事情! 这是您需要创建的功能-

function setZoomWhenMarkerClicked(){
var currentZoom = festivalMap.getZoom();
 if (currentZoom < 7){
 festivalMap.setZoom(7);
 }
}

第5步

随着地图放大,您可能希望在地图上显示更多细节。 通过添加事件侦听器并使用getZoom方法连续检查缩放是否已完成,可以完成此操作。 如果已增加(级别6以上),则setMapTypeId方法用于设置上面定义的第二种(更详细的)样式。

//Continuously listens out for when the zoom level changes. This includs when the map zooms when a marker is clicked.
google.maps.event.addListener(festivalMap, "zoom_changed", function() {
 var newZoom = festivalMap.getZoom();
 //If the map is zoomed in, the switch to the style that shows the higher level of detail.
 if (newZoom > 6){
 festivalMap.setMapTypeId('map_styles_festival_zoomed');
 }
 //Otherwise the map must be zoomed out, so use the style with the lower level of detail.
 else {
 festivalMap.setMapTypeId('map_styles_festival');
 }

});

第6步

使用CSS为信息框设置样式,使其看起来更漂亮。

//Variable containing the style for the pop-up infobox.
var pop_up_info = "border: 0px solid black; background-color: #ffffff; padding:15px; margin-top: 8px; border-radius:10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; box-shadow: 1px 1px #888;";

步骤7

打开信息框后,地图标记将显示在最前面。 但是,如果关闭信息框,然后将地图缩小到原始位置,则标记将保留在前面。 这看起来很奇怪。

在步骤1中,为每个标记设置z-index。 您现在可以使用它来解决此问题。 您需要创建一个将z-index重置为其原始值的函数(即resetZindexes) ,然后向resetZindexes();)添加对该函数的调用(即resetZindexes();)以触​​发该函数在信息框运行时运行窗口关闭。

转到此页面顶部的链接,以获取到目前为止该站点代码的副本,或者查看此站点的实时版本 。 我只添加了Glastonbury的弹出窗口。 随意自己添加其他人!


定制横幅和导航

我们几乎可以自定义地图的外观了,但是在每天称呼它之前,我们应该添加一些导航控件。

Google地图有12个区域 ,您可以在其中添加地图控件,横幅等。您可以完全自定义这些区域,添加所需的任何html等。

我们将在地图的右侧添加自定义横幅和导航。

第1步

首先,首先定义一个函数来创建菜单。 此代码提取相当长……

//Function that creates the control panel area, ie. the map title and the 2 buttons just beneath it.
function createControlPanel (controlPanelDiv){
 controlPanelDiv.style.padding = '0px';
 controlUI = document.createElement('div');
 controlUI.style.border='0px solid white';
 controlUI.style.margin='10px';
 controlUI.style.paddingTop='11px';
 controlUI.style.paddingBottom='5px';
 controlUI.style.paddingLeft='0px';
 controlUI.style.paddingRight='0px';
 controlUI.style.width='245px';
 controlUI.style.height='419px';
 controlPanelDiv.appendChild(controlUI);

 //Map title
 titleBar = document.createElement('div');
 titleBar.style.backgroundColor = '#89CBED';
 titleBar.style.height='255px';
 titleBar.style.width='245px';
 titleBar.style.marginTop='0px';
 titleBar.style.marginBottom='0px';
 titleBar.style.marginLeft='0px';
 titleBar.style.marginRight='0px';
 titleBar.style.paddingTop='6px';
 titleBar.style.paddingBottom='2px';
 titleBar.style.paddingLeft='0px';
 titleBar.style.paddingRight='0px';
 titleBar.style.borderTopLeftRadius='5px';
 titleBar.style.borderTopRightRadius='5px';
 titleBar.style.borderBottomLeftRadius='0px';
 titleBar.style.borderBottomLeftRadius='0px';
 titleBar.style.cssFloat='left';
 titleBar.innerHTML = '<div align="center"><img src="icons/map_title.png" width="230" height="252" border="0"/></div>';
 controlUI.appendChild(titleBar);

 yellowStripe = document.createElement('div');
 yellowStripe.style.backgroundColor = '#FFFF00';
 yellowStripe.style.height='2px';
 yellowStripe.style.width='245px';
 yellowStripe.style.marginTop='3px';
 yellowStripe.style.marginBottom='3px';
 yellowStripe.style.marginLeft='0px';
 yellowStripe.style.marginRight='0px';
 yellowStripe.style.paddingTop='0px';
 yellowStripe.style.paddingBottom='0px';
 yellowStripe.style.paddingLeft='0px';
 yellowStripe.style.paddingRight='0px';
 yellowStripe.style.cssFloat='left';
 yellowStripe.style.fontFamily='Georgia, serif';
 yellowStripe.style.fontSize='14px';
 controlUI.appendChild(yellowStripe);

 //'Smaller' events button.
 smallEvents = document.createElement('div');
 smallEvents.style.height='108px';
 smallEvents.style.width='129px';
 smallEvents.style.marginTop='0px';
 smallEvents.style.marginBottom='0px';
 smallEvents.style.marginLeft='0px';
 smallEvents.style.marginRight='0px';
 smallEvents.style.paddingTop='0px';
 smallEvents.style.paddingBottom='2px';
 smallEvents.style.paddingLeft='0px';
 smallEvents.style.paddingRight='0px';
 smallEvents.style.cssFloat='left';
 smallEvents.innerHTML = '<div align="center" onClick="handelRequests(\'small_events\')" OnMouseOver="this.style.cursor=\'pointer\';" OnMouseOut="this.style.cursor=\'default\';"><img src="icons/button_small_event.png" width="128" height="107" border="0"/></div>';
 controlUI.appendChild(smallEvents);

 //Umbrella button
 brolly = document.createElement('div');
 brolly.style.height='149px';
 brolly.style.width='94px';
 brolly.style.marginTop='0px';
 brolly.style.marginBottom='0px';
 brolly.style.marginLeft='0px';
 brolly.style.marginRight='0px';
 brolly.style.paddingTop='0px';
 brolly.style.paddingBottom='2px';
 brolly.style.paddingLeft='0px';
 brolly.style.paddingRight='0px';
 brolly.style.cssFloat='left';
 brolly.innerHTML = '<div align="center" onClick="handelRequests(\'rainfall\')" OnMouseOver="this.style.cursor=\'pointer\';" OnMouseOut="this.style.cursor=\'default\';"><img src="icons/button_brolly.png" width="93" height="148" border="0"/></div>';
 controlUI.appendChild(brolly);

}

关于样式的快速说明:上面的代码使用元素的style属性来使用JavaScript定义其样式。 要将CSS属性转换为其JavaScript表示法,只需记住没有连字符的属性保持不变,而将具有连字符的属性转换为camelCase ,例如background-image变为backgroundImage。 例外是float ,它变成cssFloat

第2步

然后,创建一个div来保存菜单,然后通过调用您在步骤1中刚刚创建的函数将菜单添加到该div中。

//Create control panel (ie. site title and 2 buttons) which appears on the right-hand side.
var controlPanelDiv = document.createElement('div');
var festivalMapControlPanel = new createControlPanel(controlPanelDiv, festivalMap);

第三步

然后设置地图的controls属性,以将菜单添加到相关位置,在本例中为RIGHT_TOP

//Add the control panel and reset button (created previously) to the map.
festivalMap.controls[google.maps.ControlPosition.RIGHT_TOP].push(controlPanelDiv);

第4步

到现在,您应该拥有一些看起来像自定义菜单的内容,该菜单显示在地图的右侧。 所以剩下要做的就是让您的菜单做某事...

在接下来的教程中,我们将使用“较小事件”按钮显示Flickr的照片,并使用“雨伞”按钮显示草绘的降雨图叠加层。 (我知道这是陈词滥调,但夏季确实有很多降雨!)

因此,为了使本教程发挥作用,我重复了上述步骤,还向RIGHT_BOTTOM区域添加了一个Reset按钮。 这包括在“重置”按钮周围包装代码以调用handelRequests函数。

//Function that creates the 'Reser map' button.
function createResetButton (resetButtonDiv){
 resetButtonDiv.style.padding = '0px';
 controlUI2 = document.createElement('div');
 controlUI2.style.backgroundColor = '#ffffff';
 controlUI2.style.borderRadius='5px';
 controlUI2.style.margin='10px';
 controlUI2.style.paddingTop='2px';
 controlUI2.style.paddingBottom='2px';
 controlUI2.style.paddingLeft='2px';
 controlUI2.style.paddingRight='5px';
 controlUI2.style.textAlign='center';
 controlUI2.style.width='148px';
 controlUI2.style.height='31px';
 controlUI2.innerHTML = '<div onClick="handelRequests(\'reset\')" OnMouseOver="this.style.cursor=\'pointer\';" OnMouseOut="this.style.cursor=\'default\';" ><img src="icons/button_reset.png" width="148" height="31" border="0"/></div>';
 resetButtonDiv.appendChild(controlUI2);
}

第5步

handelRequests函数可以做一些事情-查看代码中的注释。

//Function that is called when either the 'smaller events', unbrella or the 'reset map' buttons are clicked.
function handelRequests (buttonPressed) {
if (buttonPressed === "reset"){
 //Resets the zoom, map position and marker z-indexes back to their orignal position. Also closes all infoboxes currently open.
 festivalMap.setZoom(festivalMapZoom);
 festivalMap.setCenter(festivalMapCenter);
 resetZindexes();
 //This is a function I've created that closes any info boxes that are open.
 closeAllInfoboxes();
}
else if (buttonPressed === "small_events"){
 alert("This button will do something useful in a later tutorial!");
}
else if (buttonPressed === "rainfall"){
 alert("This button will do something useful in a later tutorial!");
}
}

您可以从此页面顶部获得该教程本部分的html文件的完整副本,或查看实时示例 。 在此示例中,仅Glastonbury地图标记处于活动状态。


接下来是什么?

本教程就是这样! 希望您现在可以进行一些工作,与本页面顶部的图片大致相似。 如果出现问题,请浏览GitHub上的可下载文件 。 我已将代码包含在本教程每个部分的单独文件中,因此您应该能够找出所有错误所在。

下一个教程将探讨如何使用Google maps API将自己的地图(例如汉诺德或历史地图)栩栩如生,使其可缩放和交互。


图片积分

本教程中使用的照片均已根据知识共享许可发布。

翻译自: https://webdesign.tutsplus.com/tutorials/getting-creative-with-the-google-maps-api--webdesign-13380

maps-api-v3

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值