cesium-examples/map/2d/build/arcgis-map-branchRiver.js

541 lines
18 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.BranchRiver = factory());
}(this, (function () { 'use strict';
var tool = {
merge: function merge(settings, defaults) {
Object.keys(settings).forEach(function (key) {
defaults[key] = settings[key];
});
},
//计算两点间距离
getDistance: function getDistance(p1, p2) {
return Math.sqrt((p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]));
},
//判断点是否在线段上
containStroke: function containStroke(x0, y0, x1, y1, lineWidth, x, y) {
if (lineWidth === 0) {
return false;
}
var _l = lineWidth;
var _a = 0;
var _b = x0;
// Quick reject
if (y > y0 + _l && y > y1 + _l || y < y0 - _l && y < y1 - _l || x > x0 + _l && x > x1 + _l || x < x0 - _l && x < x1 - _l) {
return false;
}
if (x0 !== x1) {
_a = (y0 - y1) / (x0 - x1);
_b = (x0 * y1 - x1 * y0) / (x0 - x1);
} else {
return Math.abs(x - x0) <= _l / 2;
}
var tmp = _a * x - y + _b;
var _s = tmp * tmp / (_a * _a + 1);
return _s <= _l / 2 * _l / 2;
}
};
var resolutionScale = function (context) {
var devicePixelRatio = window.devicePixelRatio || 1;
context.canvas.width = context.canvas.width * devicePixelRatio;
context.canvas.height = context.canvas.height * devicePixelRatio;
context.canvas.style.width = context.canvas.width / devicePixelRatio + 'px';
context.canvas.style.height = context.canvas.height / devicePixelRatio + 'px';
context.scale(devicePixelRatio, devicePixelRatio);
};
var global = typeof window === 'undefined' ? {} : window;
var requestAnimationFrame = global.requestAnimationFrame || global.mozRequestAnimationFrame || global.webkitRequestAnimationFrame || global.msRequestAnimationFrame || function (callback) {
return global.setTimeout(callback, 1000 / 60);
};
var cancelAnimationFrame = global.cancelAnimationFrame || global.mozCancelAnimationFrame || global.webkitCancelAnimationFrame || global.msCancelAnimationFrame || function (id) {
clearTimeout(id);
};
var img1 = document.createElement('img');
var img2 = document.createElement('img');
var img3 = document.createElement('img');
img1.src = 'images/1.png';
img2.src = 'images/2.png';
img3.src = 'images/3.png';
var BranchRiver = function BranchRiver(map, userOptions) {
var self = this;
self.map = map;
//默认参数
var options = {
type: 'point',
isShowBaseLine: 'true',
grap: 10,
isShowTail: true, //是否显示粒子尾巴效果
lineWidth: 0.5, //线条宽度
lineStyle: '#C82800', //线条颜色
tailOpacity: 0.88, //尾巴动画透明度
animateLineWidth: 1, //动画线条宽度
renderLineWidth: [4, 3, 2, 1], //尾巴动画线条宽度
animateLineStyle: '#ffff00', //动画线条颜色
colors: ["#b5c334", "#59c4e6", "#edafda", "#93b7e3", "#a5e7f0", "#cbb0e3"]
};
self.init(userOptions, options);
//全局变量
var baseCtx = self.baseCtx = self.options.canvas.getContext("2d");
var animateCtx = self.animateCtx = self.options.animateCanvas.getContext("2d");
var topCtx = self.topCtx = self.options.topCanvas.getContext("2d");
baseCtx.lineWidth = options.lineWidth;
};
BranchRiver.prototype.init = function (setting, defaults) {
//合并参数
tool.merge(setting, defaults);
this.options = defaults;
};
BranchRiver.prototype.render = function () {
var self = this;
var baseCtx = self.baseCtx;
if (!baseCtx) {
return;
}
var roadLines = self.roadLines;
roadLines.forEach(function (line) {
//line.drawPath(baseCtx, self.map, self.options);
});
};
BranchRiver.prototype.animate = function () {
var self = this;
var animateCtx = self.animateCtx;
if (!animateCtx) {
return;
}
if (self.options.isShowTail) {
animateCtx.fillStyle = "rgba(0,0,0," + self.options.tailOpacity + ")";
var prev = animateCtx.globalCompositeOperation;
animateCtx.globalCompositeOperation = "destination-in";
animateCtx.fillRect(0, 0, self.map.width, self.map.height);
animateCtx.globalCompositeOperation = prev;
} else {
animateCtx.clearRect(0, 0, self.map.width, self.map.height);
}
//首先加载grade=0||grade=1,0&1——2——3
if (self.runlines && self.runlines.length === 0) {
self.runlines = self.roadLines.filter(function (item, index, array) {
return item.type == 0;
});
} else if (self.runlines.length < self.roadLines.length) {
self.runlines.forEach(function (runline) {
var type = runline.type;
var lastPointLng = runline.currentpoint.x;
var childLines = self.roadLines.filter(function (value) {
return value.type == type + 1;
});
childLines.forEach(function (childline) {
if (childline.points[0].x == lastPointLng) {
self.runlines.push(childline);
}
});
});
}
var roadLines = self.runlines;
switch (self.options.type) {
case 'point':
roadLines.forEach(function (line, index, arr) {
line.draw(animateCtx, self.map, self.options, self.topCtx);
});
break;
case 'arrow':
roadLines.forEach(function (line, index, arr) {
line.drawArrow(animateCtx, self.map, self.options);
});
break;
case 'circle':
roadLines.forEach(function (line, index, arr) {
line.drawCircle(animateCtx, self.map, self.options);
});
break;
}
};
BranchRiver.prototype.adjustSize = function () {
var width = this.map.width;
var height = this.map.height;
this.baseCtx.canvas.width = width;
this.baseCtx.canvas.height = height;
this.animateCtx.canvas.width = width;
this.animateCtx.canvas.height = height;
this.topCtx.canvas.width = width;
this.topCtx.canvas.height = height;
resolutionScale(this.baseCtx);
resolutionScale(this.animateCtx);
resolutionScale(this.topCtx);
};
BranchRiver.prototype.start = function () {
var self = this;
self.stop();
self.adjustSize();
self.addLine();
if (self.options.isShowBaseLine) {
self.render();
}
// (function drawFrame() {
// self.timer = setTimeout(function () {
// if (self.animationId) {
// cancelAnimationFrame(self.animationId);
// }
// self.animationId = requestAnimationFrame(drawFrame);
// self.animate();
// }, 60);
// })();
(function drawFrame() {
if (self.animationId) {
cancelAnimationFrame(drawFrame);
}
self.animationId = requestAnimationFrame(drawFrame);
self.animate();
})();
// self.drawStation(this.topCtx, this.map);
};
BranchRiver.prototype.stop = function () {
var self = this;
if (self.animationId) {
cancelAnimationFrame(self.animationId);
}
if (self.timer) {
clearTimeout(self.timer);
}
};
BranchRiver.prototype.addLine = function () {
var options = this.options;
this.runlines = [];
var roadLines = this.roadLines = [],
dataset = this.options.data;
dataset.forEach(function (line, i) {
var color = options.colors[line.type];
// var lineWidth = (i == 0 ? options.renderLineWidth[0] : options.renderLineWidth[1]);
var lineWidth = options.renderLineWidth[line.type];
// var baseLineWidth = (i == 0 ? options.renderLineWidth[0] : 0);
var baseLineWidth = i == 0 ? 1 : 0;
roadLines.push(new Line({
type: line.type,
points: line.list,
color: color || '#a5e7f0',
lineWidth: lineWidth || 1,
baseLineWidth: baseLineWidth
}));
});
};
// BranchRiver.prototype.drawStation = function (context, map) {
// context.clearRect(0, 0, map.width, map.height);
// var options = this.options;
// var stations = options.stations;
// stations.forEach(function (station, i) {
// var _screePoint = map.toScreen(station.point);
// context.beginPath();
// context.arc(_screePoint.x, _screePoint.y, 5, 0, Math.PI * 2);
// context.fillStyle = 'red';
// context.fill();
// });
// };
function Line(options) {
this.type = options.type;
this.points = options.points || [];
this.age = options.age || 0;
this.maxAge = options.maxAge || 0;
this.color = options.color || '#ffff00';
this.grap = options.grap || 10;
this.lineWidth = options.lineWidth || 1;
this.baseLineWidth = options.baseLineWidth || 0;
this.running = false; //是否正在运动
this.finished = false; //是否已经完成第一次运动
this.currentpoint = this.points[0];
this.tempPoints = [0];
}
Line.prototype.getPointList = function (map) {
var path = this.path = [],
points = this.points;
if (points && points.length > 0) {
points.forEach(function (p) {
var _screePoint = map.toScreen(p);
// if (_screePoint.x < 0 || _screePoint.y < 0) {
// return;
// }
path.push({
pixel: map.toScreen(p)
});
});
this.maxAge = path.length;
}
return path;
};
Line.prototype.getStationPointList = function (map, stationList) {
var stations = this.stations = [];
if (stationList && stationList.length > 0) {
stationList.forEach(function (s) {
stations.push({
name: s.name,
grade: s.grade,
isdraw: false,
pixel: map.toScreen(s.point)
});
});
}
return stations;
};
Line.prototype.drawPath = function (context, map, options) {
if (this.baseLineWidth == 0) return;
var pointList = this.path || this.getPointList(map);
context.save();
context.beginPath();
context.lineWidth = this.baseLineWidth;
context.strokeStyle = '#fff'; //this.color;
// context.strokeStyle = options.lineStyle;
context.moveTo(pointList[0].pixel.x, pointList[0].pixel.y);
for (var i = 0, len = pointList.length; i < len; i++) {
context.lineTo(pointList[i].pixel.x, pointList[i].pixel.y);
}
context.stroke();
context.restore();
};
Line.prototype.drawSingleStation = function (context, map, point) {
// context.clearRect(0, 0, map.width, map.height);
// context.beginPath();
// context.arc(point.pixel.x, point.pixel.y, 5, 0, Math.PI * 2);
// context.fillStyle = 'red';
// context.fill();
// context.closePath();
// //绘制文字
// context.font = '12px Arial';
// context.textAlign = 'left';
// context.textBaseline = 'Alphabetic';
// context.strokeStyle = '#FF0000';
// // context.strokeText(point.name, point.pixel.x + 5, point.pixel.y);
// context.fillText(point.name, point.pixel.x + 5, point.pixel.y);
var _img;
switch (parseInt(point.grade)) {
case 1:
_img = img1;
break;
case 2:
_img = img2;
break;
case 3:
_img = img3;
break;
}
context.save();
context.translate(point.pixel.x, point.pixel.y);
// context.drawImage(_img, -12, -12, 24, 24);
context.drawImage(_img, 0, 0, 20, 20);
context.restore();
};
Line.prototype.drawArrow = function (context, map, options) {
var pointList = this.path || this.getPointList(map);
var movePoints = this.movePoints;
if (movePoints && movePoints.length > 0) {
var moveLen = movePoints.length;
for (var i = 0; i < moveLen; i++) {
if (movePoints[i] >= this.maxAge - 1) {
movePoints[i] = 0;
}
var currentPoint = pointList[movePoints[i]];
context.beginPath();
// context.lineWidth = options.animateLineWidth;
context.lineWidth = options.lineWidth;
context.strokeStyle = this.color;
context.moveTo(currentPoint.pixel.x, currentPoint.pixel.y);
context.lineTo(pointList[movePoints[i] + 1].pixel.x, pointList[movePoints[i] + 1].pixel.y);
context.stroke();
context.save();
context.translate(pointList[movePoints[i] + 1].pixel.x, pointList[movePoints[i] + 1].pixel.y);
//我的箭头本垂直向下算出直线偏离Y的角然后旋转 ,rotate是顺时针旋转的所以加个负号
var ang = (pointList[movePoints[i] + 1].pixel.x - currentPoint.pixel.x) / (pointList[movePoints[i] + 1].pixel.y - currentPoint.pixel.y);
ang = Math.atan(ang);
pointList[movePoints[i] + 1].pixel.y - currentPoint.pixel.y >= 0 ? context.rotate(-ang) : context.rotate(Math.PI - ang); //加个180度反过来
context.lineTo(-3, -3);
context.lineTo(0, 3);
context.lineTo(3, -3);
context.lineTo(0, 0);
context.fillStyle = this.color;
context.fill(); //箭头是个封闭图形
context.restore(); //用来恢复Canvas之前保存的状态,否则会影响后续绘制
this.movePoints[i]++;
}
} else {
this.random(map);
}
};
//第一个点从0开始
//0
//010
//01020
//0102030
//010203040
Line.prototype.draw = function (context, map, options, topCtx) {
var self = this;
var pointList = this.path || this.getPointList(map);
if (this.movePoints == undefined || this.movePoints.length == 0) {
this.random(map);
}
var movePoints = this.movePoints;
var moveLen = movePoints.length;
var tempPoints = this.tempPoints;
var stations = this.stations || this.getStationPointList(map, options.stations);
if (tempPoints.length <= moveLen) {
for (var j = 0; j < tempPoints.length; j++) {
if (tempPoints[j] >= this.maxAge - 1) {
tempPoints[j] = 0;
}
var nowPoint = pointList[tempPoints[j]].pixel;
var nextPoint = pointList[tempPoints[j] + 1].pixel;
context.beginPath();
context.lineWidth = this.lineWidth;
context.strokeStyle = this.color;
context.lineCap = "round";
context.moveTo(nowPoint.x, nowPoint.y);
context.lineTo(nextPoint.x, nextPoint.y);
context.stroke();
this.tempPoints[j]++;
//判断当前点是否是站点,如果是则画出站点
for (var s = 0; s < stations.length; s++) {
var _point = stations[s];
if (_point.isdraw == false && _point.pixel.x == nowPoint.x && _point.pixel.y == nowPoint.y) {
self.drawSingleStation(topCtx, map, _point);
_point.isdraw = true;
}
}
}
var index = this.tempPoints[tempPoints.length - 1];
this.currentpoint = this.points[index];
if (movePoints.contains(index)) {
tempPoints.unshift(0);
}
} else {
for (var k = 0; k < moveLen; k++) {
if (movePoints[k] >= this.maxAge - 1) {
movePoints[k] = 0;
this.finished = true;
}
var currentPoint = pointList[movePoints[k]];
context.beginPath();
// context.lineWidth = options.animateLineWidth;
context.lineWidth = this.lineWidth;
context.strokeStyle = this.color;
context.lineCap = "round";
context.moveTo(currentPoint.pixel.x, currentPoint.pixel.y);
context.lineTo(pointList[movePoints[k] + 1].pixel.x, pointList[movePoints[k] + 1].pixel.y);
context.stroke();
this.movePoints[k]++;
}
}
this.running = true;
};
Line.prototype.drawCircle = function (context, map, options) {
var pointList = this.path || this.getPointList(map);
if (this.movePoints == undefined || this.movePoints.length == 0) {
this.random(map);
}
var movePoints = this.movePoints;
var moveLen = movePoints.length;
var tempPoints = this.tempPoints;
if (tempPoints.length < moveLen) {
for (var j = 0; j < tempPoints.length; j++) {
if (tempPoints[j] >= this.maxAge - 1) {
tempPoints[j] = 0;
}
var nowPoint = pointList[tempPoints[j]].pixel;
var nextPoint = pointList[tempPoints[j] + 1].pixel;
context.beginPath();
context.arc(nowPoint.x, nowPoint.y, this.lineWidth, 0, Math.PI * 2);
context.fillStyle = this.color;
context.fill();
this.tempPoints[j]++;
}
var index = this.tempPoints[tempPoints.length - 1];
if (movePoints.contains(index)) {
tempPoints.unshift(0);
}
} else {
for (var k = 0; k < moveLen; k++) {
if (movePoints[k] >= this.maxAge - 1) {
movePoints[k] = 0;
this.finished = true;
}
var currentPoint = pointList[movePoints[k]].pixel;
context.beginPath();
context.arc(currentPoint.x, currentPoint.y, this.lineWidth, 0, Math.PI * 2);
context.fillStyle = this.color;
context.fill();
this.movePoints[k]++;
}
}
this.running = true;
};
Line.prototype.random = function (map) {
var pointList = this.path || this.getPointList(map);
var arr = [],
gap = this.grap; //间隔
if (gap > pointList.length) {
this.grap = Math.floor(pointList.length / 2);
}
var maxNum = Math.floor(pointList.length / gap);
while (arr.length < maxNum) {
for (var i = 0; i < pointList.length; i += gap) {
if (arr.length === 0) {
//如果数组长度为0则直接添加到arr数组
arr.push(i);
} else {
if (arr.indexOf(i) == -1) {
arr.push(i);
}
}
}
}
// this.movePoints = [0];
this.movePoints = arr;
};
//声明----如果有此 contains 直接用最好
Array.prototype.contains = function (needle) {
for (var i in this) {
if (this[i] == needle) return true;
}
return false;
};
return BranchRiver;
})));