建站资讯

使用 Cufon渲染网页字体(网页嵌入特殊字体解决方

2012-09-18 23:57:15

浏览:

这是一篇关于 Cufon 技术的小文章。什么是 Cufon 呢?简单的说,Cufon 是一个用来替代 sIFR 框架,实现在网页中对文字字体进行渲染功能的纯 JavaScript 开源类库。 为什么要使用 Cufon 那么为

这是一篇关于 Cufon 技术的小文章。什么是 Cufon 呢?简单的说,Cufon 是一个用来替代 sIFR 框架,实现在网页中对文字字体进行渲染功能的纯 JavaScript 开源类库。

为什么要使用 Cufon

那么为什么要使用 Cufon 呢?这要从 Web 开发人员,所经常面对的一种“冲突”,即“字体(Font Family)冲突”开始讲起。

通常的这一冲突总是爆发于 Web 页面的设计者(Designer)和开发者(Coder)之间。在很多场合下,Web 页面的设计者都会倾向于在他们的页面设计稿中,为文字附加使用一些“特殊”的字体和特效,以此来展示他们卓越的设计能力。

如下图 1 所示,是某设计者为公司 A 所设计的一个公司简介页面(部分)。在其中为了突出公司的“亲和力”,设计者使用了一种名为 Baroque Script 的手写字体。


图 1. 设计者为网站所设计的公司简介效果图(部分)
图 1. 设计者为网站所设计的公司简介效果图(部分)
 

无疑的这一设计将会让开发人员“抓狂”。因为与此同时,A 公司雇主明确的告诉了开发人员,公司简介的内容需要可以通过后台管理程序进行修改,并实时的显示到相应的页面上。

这也就意味着,即使开发人员可以如下代码所示通过编写脚本,来实时输出公司简介的内容,并指定这一内容使用“Baroque Script”字体进行显示,也是无法“完美”的实现设计初衷的。


清单 1. 无效的 font-family 字体指定
 

				
  
……
 


因为在大部分的浏览器上,并不会安装有 Baroque Script 字体。因此在这些浏览器上系统会主动“忽略”掉代码中关于 font-family 的说明,转而使用缺省字体进行输出,如下图 2 所示。


图 2. 在没有安装 Baroque Script 字体浏览器上的公司简介输出效果
图 2. 在没有安装 Baroque Script 字体浏览器上的公司简介输出效果
 

当然随着 Web 标准的发展,关于这一问题现在也已经有了一个“官方”的解决方案,那就是通过 CSS3 标准下的 @font-face 属性来指定和引入非缺省字体,如下代码所示。


清单 2. 通过 @font-face 引入外部字体
 

				
……
 @font-face { 
  font-family: "Baroque Script"; 
 src: url('BaroqueScript.ttf') 
 } 
……

完整的实现则可以参考范例 1.htm。显然的,这一解决方案会成为今后在此类问题上一个主流的处理方法。但是不幸的是,截止到目前为止其却并没有获得很多浏览器,尤其是 IE 系列浏览器的完整支持。而与之相较本文所将介绍的 Cufon 方案,目前在“普适性”上较 @font-face 方案则是要广泛许多,下表 1 则给出了二者在浏览器支持方面的一个比较,以供读者参考。


表 1. Cufon 和 @font-face 方案普适性比较一览表
 

  所支持浏览器
Cufon IE(≥ 5) Firefox(≥ 1.5)Opera(≥ 9.5)Safari(≥ 3)Google Chrome(≥ 1.0)
@font-face IE(≥ 4,仅支持 OpenType)Firefox(≥ 3.5) Opera(≥ 10.0) Safari(≥ 3.1)

那么面对这一冲突,Cufon 究竟是如何解决非缺省字体显示的问题的呢?


初涉 Cufon

引入 Cufon

作为一种基于 JavaScript 的网页字体引入方案, Cufon 的核心功能是通过一个名为“cufon-yui.js”的 JavaScript 类库,提供给开发人员的。因此使用 Cufon 技术的第一步,当然就是在 Web 页面中引入这一类库,如下代码所示。


清单 3. 引入 Cufon 核心库
 

				
  

创建并引入字体文件

这是使用 Cufon 技术的另一个关键所在。显然的对于初次接触 Cufon 技术的读者而言,这并不是一个容易理解的概念,那么什么是 Cufon 字体文件呢?

简言之 Cufon 字体文件,就是按照 Cufon 所提出的字体描述标准,创建形成的一种字体文件。

而和其他字体创建标准如 TrueType、OpenType 等不同的是,按照 Cufon 标准所形成的这一文件本身,就是一个标准的 JavaScript 脚本文件,这也就意味着其也可以通过

为标记附加 Cufon 转换

在完成了上述的两项准备工作后,事实上使用 Cufon 类库来实现对字体的渲染是非常简单的,这仅仅牵涉到了 Cufon 类库所提供的一个核心方法,即 Cufon.replace 方法,如下代码所示。


清单 5. 使用 Cufon.replace 方法对标记字体进行渲染
 

				
  

其中参数值“p”表示,在本例中 Cufon 将对整个 Web 页面下所有

标记对象下的文本,实施字体渲染处理。

当然在更多的应用场合,我们可能还会需要对某一特定标记,进行字体的渲染。在这方面 Cufon.replace 方法也给予了较好的支持。下表 2 给出了方法所支持标记符写作规则及对应意义,以供读者根据实际情况进行选用。从中读者也不难发现,这一规范和 CSS 下选择符的书写语法是非常接近的。


表 2. Cufon.replace 方法选择符参数值语法规范(部分)
 

语法 说明
value 渲染所有以 value 为名称的标记下文本
#value 渲染以 value 为标记的 id 属性值的标记下文本
.value 渲染所有 class 属性值为 value 的标记下文本
选择符联合 可以使用的联合符有空格(“ ”),大于号(“>”)等,相关含义则可参考 CSS 选择符联合的相关说明

至此这一简单的应用便开发完成了。完整的源代码读者可以参考范例 2.htm。将其部署到对应 Web 目录下,并在浏览器中进行查看,笔者相信读者是会得到如图 1 所示的显示效果的。


深入了解 Cufon API

当然真实的应用,并不会总如范例 2.htm 那么简单,为了更好的适应各种网页字体渲染的要求,Cufon 框架也提供了各种方法来辅助开发者实现其目标。下面笔者就择其一二,向读者进行一个简单的介绍。

CSS 增强

通过范例 2.htm 读者可以看到,Cufon 不仅能够针对标记文字进行字体的渲染,而且更为重要的是,这种渲染显然还参考了标记所对应的 CSS 风格 font-size,这对于实际的 Web 应用开发当然是非常重要的,也是 Cufon 技术的一个“特色”所在。

而与此同时,为了可以更为精确的控制在进行字体渲染时所使用的字体风格,Cufon 还提供了“配置项(Option)”这一概念,来帮助开发者直接在 Cufon 方法中指定相应字体风格值,如下表 3 所示。


表 3. Cufon 常用配置项和 CSS 风格名称对照表
 

Cufon 配置项 对应 CSS 风格 备注
color color  
fontSize font-size 在 Cufon 配置项下使用时,仅允许使用 px 作为风格的单位
fontStyle font-style  
fontWeight font-weight  
fontStretch font-stretch CSS3 风格,仅允许通过 cufon 配置项进行使用,如果在 CSS 文件中指定,则会被部分浏览器视为无效而忽略
letterSpacing letter-spacing  
textTransform text-transform  

而在 Cufon 中设定相关字体渲染配置项值的方法,则主要有以下两个。

  1. 通过 Cufon.set 方法设定相关配置项。

    Cufon 类库提供有专门的 Cufon.set 方法,可用于指定当前所使用的配置项值,其语法规范可以如下代码所示。



    清单 6. Cufon.set 语法规范
    				
     Cufon.set("配置项名称", 配置项值 ) 
    

    举例而言,针对范例 2.htm,如果我们希望在显示时相关文字的颜色为红色,那么我们就可以在调用 Cufon.replace 方法之前,通过 Cufon.set 首先对 color 配置项进行设置,如下代码所示,完整的实现则可以参考范例 3.htm。



    清单 7. 使用 Cufon.set 改变所渲染文字的颜色
    				
     Cufon.set("color", "#FF0000"); 
    ……
     

    This is the company's introduction


    同时通过这一范例读者也可以了解到,显然的,在优先级上通过 Cufon.set 方法所设置的字体显示风格,是要高于使用 CSS 所设定的相应风格的。

  2. 在 Cufon.replace 方法中,直接设定相关的配置项值。

    这也是非常简单的。如下代码所示是关于 Cufon.replace 方法的一个完整描述,从中读者可以看到,事实上在 Cufon.replace 方法内,配置项及其对应值可以通过一个 JSON 模式的 JavaScript 对象来提供,对此笔者就不再通过实例进行演示了。

    而显然的在优先级上,由于其较 Cufon.set 方法更为接近所处理的标记实体,因此,在 Cufon.replace 方法中所指定的显示风格,将具有最高的处理优先级别,这也是毋庸置疑的。



    清单 8. 完整的 Cufon.relace 语法规范
    				
     Cufon.replace("选择符", {"配置项 1" : 值 , "配置项 2": 值 , …… }); 
    

处理多种字体

关于缺省渲染字体

如果不通过 fontFamily 配置,进行指定,那么,cufon 将使用在顺序上,最后引入到系统的那个 cufon 字体文件所对应的字体,来对相关标记进行渲染。

这是 Cufon 应用的另一大特色。在同一个页面中,Cufon 可以为不同的标记对象,提供不同的字体渲染效果,这对于实际的 Web 应用而言,当然是非常常见的一个需求。

而 Cufon 对此功能的支持则仍然是通过配置项来完成的。在 Cufon 中开发着可以通过指定配置项“fontFamily”,来确定对应标记对象所需要使用的字体。

比如在范例 4.htm 中,除前例所使用的 Baroque Script 字体外,笔者还引入了另一个由 TrueType 字体 Whiteboard Modern Demo 所形成的 Cufon 字体文件 Modern_Demo_font.js,并分别用这两种字体,渲染了文档中 id 属性值为“id1”和“id2”的两个标记,如下代码所示。


清单 9. 使用不同的字体渲染标记
 

				
 Cufon.replace("#id1", {fontFamily : "Baroque Script"}); 
 Cufon.replace("#id2", {fontFamily : "Whiteboard Modern Demo"}); 

其产生的效果则可如下图 3 所示。


图 3. 在同一 Web 页面中使用多种字体进行渲染
图 3. 在同一 Web 页面中使用多种字体进行渲染
 

细心的读者可能会从上图 3 中发现有这样一个问题,即在范例 4.htm 中,

标记的文本应该是“It is a ID 2”,而并非如图所示的“It is a ID”,为什么会发生这样的情况呢?

要解释清楚这一问题其实并不困难,这牵涉到了 Cufon 在处理字符问题上的一个策略,即 Cufon 会“忽略”掉不存在于其字体文件中的字符。

比如在 Whiteboard Modern Demo 字体中,并没有包含针对字符“2”的书写方法,因此自然的当 Cufon 在使用这一字体显示字符时,如果遇到需要输出“2”的情形,其就会主动的将其“忽略”处理,这也就是为什么运行范例 4.htm,会出现如图 3 所示情形的原因所在。

而除此之外,Cufon 在处理字体问题时,还有另外的几项重要的策略和原则,在此一并列出,以供读者使用时参考。

  • 首先,如果不指明所需要使用的字体,那么在使用 Cufon.replace 方法,对字体进行渲染时,系统将缺省使用最后引入的字体。
  • 其次,Cufon 仅能够且仅允许处理使用 Cufon 字体文件描述的字体。

换言之,即使某一字体是所有系统中都携带的,但只要其没有通过 Cufon 所要求的方式进行引入,那么这种字体就不能在 Cufon 中使用,否则的话,Cufon 会因为引发错误而终止所有相关 JavaScript 脚本的执行。文后的 5.htm 给出了在这方面的一个范例,以供读者参考。

  • 最后,使用 Cufon 渲染的标记将会覆盖对应标记下所有子标记的 font-family 属性,如范例 6.htm 所示。显然的这是符合在先前我们所提出的风格优先级原则的。

Cufon 实现原理初探及应用

通过上文的介绍和演示,读者对于 Cufon 所展现出来的魔力以及在应用中的相关注意事项,应该是有了一个大致的了解了。那么 Cufon 是如何实现这一魔法的呢?

事实上如果读者所使用的浏览器恰好 Firefox 的话,那么当运行前述 Cufon 范例时,浏览器的表现其实是会“泄露”Cufon 的秘密所在的。如下图 4 所示,在 Firefox 浏览器上,如果读者使用鼠标右键,单击经 Cufon 渲染的文字,就可以发现这些文字,现在“竟然”已经可以按照图片模式进行查看和存储了。


图 4. 在 Firefox 下将 Cufon 渲染文字存储为图片
图 4. 在 Firefox 下将 Cufon 渲染文字存储为图片
 

这无疑暗示了,Cufon 技术的实现策略其实就是以一定标准,在网页相关位置上“画”出了所需要显示的文字字符,并同时替换原先区域所需要显示的文字。

而这自然就牵涉到了一个非常重要的问题,即如何“直接”在网页上实现“作画”呢?总体来看目前业界比较成熟的方案,有以下 三种

  • 使用 Java Applet 进行绘画。
  • 通过 ActionScript 语言在 Flash 内进行绘画。
  • 借助于浏览器所推出的专有页面绘画方案,如 VML、Canvas 和 SVG 等,来进行页面的绘画。通常的,这些方案又都和浏览器 DOM 对象以及 JavaScript 语言紧密相关。

Cufon 使用的正是上述第三种解决方案。当然囿于篇幅所限,笔者是无法向读者尽述 Cufon 使用这一方案,实现字体渲染的种种细节的。在此笔者则将通过另外一个实例,即构建统一的 Web 统计图表引擎实例,来帮助读者了解 Cufon 框架背后所隐藏的这一技术要点。在笔者看来,虽然这两个应用在目标上大相径庭,但其所采用的基本策略和方法则是非常类似的。

准备描述规范

和 Cufon 的设计者在开发之初,为 Cufon 准备 Cufon 字体文件描述规范类似,我们开发 Web 统计图表引擎的第一步,也为 Web 统计图表准备相应的描述规范。以二维饼图为例,这一规范可能会被表述为如下所示的形式。

  • 首先,每一个饼图将被描述为一个 JavaScript 数组,数组的每一个元素则代表了饼图中的一个扇区。
  • 其次,数组的每一个元素将被组织为一个 JSON 对象。而在这一对象中将包含有两个基本的属性,即“color”属性和“percent”属性,前者指明了对应扇区所使用的渲染色,后者则表示扇区在整个饼图中所占的百分比。

而根据这一规范所形成的一个饼图描述范例,则可如下代码所示。


清单 10. 饼图描述实例
 

				
 var pie = [ 
  {"color" : "red", "percent" : 20}, 
  {"color" : "green", "percent" : 40}, 
  {"color" : "blue", "percent" : 40} 
 ]; 

至于其他的统计图表,当然也是可以如上所述整理形成相关的描述规范的,这部分工作将作为一个练习,供有兴趣的读者补充完成并实现,在此笔者就不多加赘述了。

提供绘制接口

在制定了相关图表的绘制规范后,下面要做的则是和 Cufon 一样,向其他开发人员提供统计图表绘制的方法,以帮助他们在实际应用中实现相关图像的绘制。

在此我们不妨将整个绘制接口对象命名为 StatisticalGraph,绘制方法命名为 draw,如下代码所示。


清单 11. 接口对象声明
 

				
 var StatisticalGraph = (function(){ 
 this.draw = function(data, type, dest, options){ 
……
 }; 
  ……
  return this; 
 })(); 

其中,相关参数的基本含义可如下表 4 所示。


表 4. StatisticalGraph.draw 方法参数说明
 

参数 说明
data 需要进行描绘的数据
type 描绘类型说明,比如“pie”表示需要将数据描绘为饼图
dest 指向 Web 页面中的一个标记对象,针对图形的描绘,将在这一标记下进行
options 为一 JSON 对象,指明了在绘画统计图过程中的相关配置项及其值

使用 Canvas 绘制统计图

在规定了整个应用接口后,我们就将使用 VML、Canvas、SVG 等 Web 页面图形绘画方案,来实现统计图表的绘画了。在此之前则不妨来首先了解一下,这些方案在浏览器应用环境上的差别,如下表 5 所示。


表 5. 浏览器 Web 页面绘图方案支持情况一览表
 

  IE Firefox Opera Safari GoogleChrome
VML 5.0 以上支持 不支持 不支持 不支持 不支持
Canvas 不支持 1.5 以上支持 9.5 以上支持 3.0 以上支持 1.0 以上支持
SVG 不直接支持 部分支持 完全支持 不直接支持 不直接支持

显然的对于统计图表的绘画应用而言,使用 VML+Canvas 联合的方案是一个具有最大普适性的策略,而这事实上也正是 Cufon 所采用的图形绘画的解决方案。

仍然以饼图绘制为例。由这一策略出发,读者是不难理解如下代码所示的绘制基本业务逻辑的。


清单 12. 饼图绘画接口
 

				
……
 case "pie": 
  return (isIE)?_drawVMLPie(data, dest, options):_drawCanvasPie(data, dest, options); 
 break; 
……

那么如何来实现代码中所给出的两个绘制接口 _drawVMLPie 和 _drawCanvasPie 呢?在此,我们则不妨从 _drawCanvasPie 的一些实现细节开始起,来逐步的了解在这一过程中,所普遍适用的一些开发原则和技巧。

了解 Canvas

首先需要简单的介绍一下 Canvas 本身,这实际上是一个由 HTML 5 标准所正式支持的 HTML 标记。因此,对于支持 Canvas 标记的浏览器而言,使用 Canvas 标记和使用其他传统 HTML 标记是没有任何不同的。

而在 HTML 5 中,一个 Canvas 标记所代表的就是一个独立的绘画区间。而一般的我们则将这一绘画区间称之为“画布”。

确立坐标系

显然的对于所有绘图而言,在画布上确立坐标系,都应该是整个绘图工作的第一步,Canvas 自然也不例外。而与传统意义上的二维平面坐标系不同,Canvas 坐标系的纵轴方向是自上而下的,缺省则将使用画布的左上角置为整个坐标系的(0,0)原点。

据此并根据前述说明,读者是不难完成如下代码所示的 Canvas 画布创建代码的,在此 Options 配置项“width”和“height”所代表的,则分别是整个画布的宽度和高度。


清单 13. 创建 Canvas 绘画区域
 

				
 var canvas = document.createElement('canvas'); 
 canvas.width = (options['width'])?options['width']:100; 
 canvas.height = (options['height'])?options['height']:100; 
 dest.appendChild(canvas); 

创建画笔对象

在创建了 Canvas 对象后,我们并不能直接在 Canvas 画布上进心绘画,而是需要通过创建一个一个画笔对象,才能够实现在 Canvas 画布上的绘画。这一画笔对象的创建方法也非常简单,如下代码所示,其中,“2d”表明在此处将使用二维平面模式进行绘画。


清单 14. 创建画笔
 

				
 var brash = canvas.getContext('2d'); 

绘画并填充扇形区域

那么,我们又该如何使用画笔对象,进行统计图表如饼图的绘画呢?从几何学角度来讲每个饼图其实都是由若干个扇形所组成的,所以饼图绘画的核心,其实也就在于每一个扇形的作画上。而对于 Canvas 而言以下两点则是需要读者特别了解的。

  • 首先,Canvas 提供了点、线(包括弧线),以及闭合直线图形、圆(包括椭圆)的绘制方法,但对于其他非规则图形,如扇形等,Canvas 并没提供直接支持。
  • 其次,Canvas 允许对任意一个闭合区间,使用颜色进行填充和边界绘制。

当然,结合一定的数学知识,尤其是三角函数知识,笔者相信这一问题其实并不难解决。为方便起见,笔者在此将通过代码注解的方式,向读者来介绍在这一过程中的一些关键所在,以供读者参考。

清单 15. 绘画并填充扇形

 

var dot_x = canvas.width / 2 ; // 设定圆心位置的 x 坐标,置于整个画布的中央,下同
var dot_y = canvas.height/ 2 ; // 设定圆心位置的y坐标			
 // 设定半径,在此,去掉 20 的目的,是为了使得整个饼图,可以比画布看上去小些
 var radius = (Math.min(canvas.width,canvas.height) - 20)/2; 
 var startAngel = 0; // 起始角度
 var start_x = dot_x + radius; var start_y = dot_y; // 设定起始扇形底边所在远端坐标
 for(i=0; i
			

完整的代码实现读者可以参阅范例 7.htm,代码的运行效果,则可如下图 5 所示。


图 5. 使用统计图引擎绘画饼图
图 5. 使用统计图引擎绘画饼图
 

至此 Canvas 下的饼图显示引擎就已基本开发完成了。当然根据应用的需要,我们还可以继续扩展这一引擎,比如在范例 8.htm 中,笔者就在现有引擎基础上,增加了两个扇形区域数据描述属性 offset_x 和 offset_y 属性,来分别表示该扇形区域的水平和垂直偏移量,而应用这一新引擎所产生的执行效果,则可如下图 6 所示。显然的对于某些需要突出显示某个区域的饼图统计图表而言,这将是很好的一种表达方式。


图 6. Firefox 下增加了偏移量控制的饼图
图 6. Firefox 下增加了偏移量控制的饼图
 

使用 VML 绘制统计图

在了解了 Canvas 下绘制统计图的主要方法和技巧后,再去理解同样的功能在 VML 下的实现,显然将要顺畅许多。有鉴于此,我在此就不对其实现细节和流程进行说明了,而仅将就这一开发中的几个关键开发点略作提示,以供读者参考。

  • VML 是一种基于 XML 的绘画标记语言。这是 VML 和 Canvas 最大的不同之处。

在 VML 规范下,任意的一个普通 HTML 标记,都可以视为 VML 下的一个独立的 “画布”而存在,而 VML 语言则相当于是 Canvas 的画笔对象,可以为这一画布提供各种各样的绘画方式。比如,我们可以使用 标记来实现从坐标(0,0)到(100,0)的直线段的绘画,如下代码所示。


清单 16. VML 基本应用范例
 

				
 


因此,在 VML 下动态创建图形的过程,其实也就是动态创建 VML 语言标记并将其附加到画布(即某一标记)下的过程,这二者是完全一致的。

  • behavior 风格的使用。

这是 VML 应用另外一个与众不同之处。在 VML 的规范中,开发者如果希望使用 VML 技术来进行页面的绘画,则不仅仅需要如一般 XML 语言一样,在 Web 文档中引入这一语言的名称空间(VML 的名称空间为“urn:schemas-microsoft-com:vml”),还需要确保所有 VML 标记,具有值为“url(#default#VML)”的 behavior 风格。否则的话,IE 浏览器是不会对其进行解析和处理的。这也正是读者可以在大部分 VML 应用中,看到有类似如下代码所示的 CSS 风格说明的原因所在。


清单 17. 需要为标记增加 behavior 风格,才能为 IE 解析
 

				
  

其余的开发技巧,应该说就和 Canvas 对象无异了,读者可参阅范例 7.htm 进行了解,在此笔者就不多赘述了。而在饼图引擎的基础上,笔者相信,读者也是一定可以完成其他统计图表的引擎开发工作的。

至此,关于 Cufon 及其基本实现原理便已经向读者介绍完毕了。而显然的由于 Cufon 引擎的实现原理,就是将文字描述转化为图形,那么在相关算法的支持下,我们是一定能够在 Cufon 的基础上,实现关于文字的更为丰富的渲染的。而事实上 Cufon 也已经开始了这方面的工作。比如利用现有的 Cufon 类库,开发者就可以通过为 Cufon.replace 方法,配置一个特殊的 color 配置项值“-linear-gradient( 颜色 1, 颜色 2, … , 颜色 n)”,来实现文字的颜色从颜色 1 到颜色 n 的渐变。笔者相信,随着 Cufon 的不断发展,类似这样的渲染实现是会越来越多的,而笔者也欢迎对此有兴趣的读者,来我一起来进行有关的研究和探讨。


 


下载

 

描述 名字 大小 下载方法
实例代码 src.zip 140KB HTTP 

 

作者: admin
使用 Cufon渲染网页字体(网页嵌入特殊字体解决方
这是一篇关于 Cufon 技术的小文章。什么是 Cufon 呢?简单的说,Cufon 是一个用来替代 sIFR 框架,实现在网页中对文字字体进行渲染功能的纯 JavaScript 开源类库。 为什么要使用 Cufon 那么为
长按图片保存/分享

深圳网站建设公司

启邦互动,深圳网站建设公司,致力于帮助深圳企业提供公司网站建设,手机网站建设,外贸网站建设,电商网站建设,学校网站建设

网站建设资讯

联系方式

深圳市龙华区大和路翠湖商务中心0210

Call us : + 137 2425 9054

Email us : service@sz-qibang.com

在线咨询

您好,请点击在线客服进行在线沟通!

联系方式
热线电话
400-12346578
上班时间
周一到周五
E-mail地址
123456@qq.com
扫一扫二维码
二维码
添加微信好友,详细了解产品
使用企业微信
“扫一扫”加入群聊
复制成功
添加微信好友,详细了解产品
我知道了