参考文档:CreateJS | A suite of JavaScript libraries and tools designed for working with HTML5
标准地图来源:自然资源部地图技术审查中心承办的标准地图服务
《南美洲地图 1:1750万 4开》 审图号:GS(2020)4394号
想要了解和下载更多关于 标准地图 的内容,欢迎访问中国地图出版集团官网和中国地图出版集团官方微博
🎴 效果演示
玻利维亚区域再闪烁😀
📑 概述需求
地图 是按照一定的法则,有选择地以二维或多维形式与手段在平面或球面上表示地球(或其它星球)若干现象的图形或图像,它具有严格的数学基础、符号系统、文字注记,并能用地图概括原则,科学地反映出自然和社会经济现象的分布特征及其相互关系。(引自百度百科)
简而言之,地图具有科学严谨的特性。而行政区划是图国家版图最主要的表现形式,不容出错。
地图数据一般是通过专门人员通过测绘相关技术得来
由于地图本身的特性
通常在出版使用的时候,最终会通过 GIS
或者 Illustrator
,以矢量图的形式展示
自然是一个复杂系统,而地图中也不会出现任何的规则图形
那么是不是可以获取地图中不规则矢量图形的数据,且在前端页面中绘制出来,用以显示呢?
答案是肯定的,本文就此问题进行简单的探索🔍
🔠 数据获取
此处是模拟实际的矢量地图数据
在 Illustrator
中,用钢笔工具绘勾绘出玻利维亚的边界线
将地图存储为 svg
文件
在 svg
中可以看到一个 polygon
标签,其中的 points
中的属性内容,即不规则矢量图形的点位数据
💻 代码分释
基于 Shape
类,封装 Irregular
类方法
(function () {
/**
* 定义非规则闭合图形的类
*/
function Irregular(points, center, fill, stroke) {
this.Shape_constructor()
this.points = points || '0,0 0,100,50,50'
this.fill = fill || 'rgb(255,255,255)'
this.stroke = stroke || 'rgb(0,0,0)'
this.center = center || { x: 0, y: 0 }
this.x = this.center.x
this.y = this.center.y
}
let p = createjs.extend(Irregular, createjs.Shape)
p.isVisible = function () { return true }
p.draw = function (ctx, ignoreCache) {
this.graphics.clear()
.f(this.fill).s(this.stroke)
this.points.split(' ').forEach((point, index) => {
let [mapX, mapY] = point.split(',')
let { x, y } = this.center
index == 0 ? this.graphics.mt(mapX - x, mapY - y) : this.graphics.lt(mapX - x, mapY - y)
})
this.Shape_draw(ctx, true)
}
createjs.Irregular = createjs.promote(Irregular, 'Shape')
})()
初始化舞台 & 加载数据
const init = () => {
stage = new createjs.Stage('examCanvas')
loader = new createjs.LoadQueue(false)
loader.addEventListener('complete', handleComplete)
loader.loadManifest(
[{
src: 'southa.jpg', id: 'map'
}],
true, '../_assets/img/'
)
}
构建底图 map
元素和不规则矢量图形 irr
元素
调用封装的 Irregular
方法,直接构建不规则矢量图形,其中 points
是从 Illustrator
导出的 svg
点数据
const handleComplete = () => {
// 构建地图层
map = new createjs.Bitmap(loader.getResult('map'))
// 构建不规则图形
irr = new createjs.Irregular(points,
{ x: 437, y: 200 },
'rgba(255,255,255,0.5)', 'rgba(0,0,0,1)')
stage.addChild(map, irr)
stage.update()
createjs.Ticker.timingMode = createjs.Ticker.RAF
createjs.Ticker.addEventListener('tick', tick)
}
设置 irr
填充透明度变化
const tick = (e) => {
// 随时间变化填充色的透明度
irr.fill = `rgba(255,255,255,${Math.abs(e.time % 3000 / 1500 - 1)})`
stage.update()
}
🐈 完整代码
🚀 写在最后
实际矢量图绘制还可以进一步探索,导出的 svg
可能不光有 ploygon
标签,或许还可能包括 path
或者其他矢量标签,后续如果有时间可以进一步研究。此处只是记录一种实现方式,如果有大佬有更好的实现模式,欢迎指导和交流。
码字不易,如果喜欢,不用三连,点个赞👍便是最大的鼓励
欢迎关注微信公众号 "书咖里的曼基康"