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

384 lines
12 KiB
JavaScript
Raw Permalink 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.LineGradient = 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;
},
//是否在矩形内
isPointInRect: function isPointInRect(point, bound) {
var wn = bound.wn; //西北
var es = bound.es; //东南
return point.x >= wn.x && point.x <= es.x && point.y >= wn.y && point.y <= es.y;
},
//是否在圆内
isPointInCircle: function isPointInCircle(point, center, radius) {
var dis = this.getDistanceNew(point, center);
return dis <= radius;
},
//两点间距离
getDistanceNew: function getDistanceNew(point1, point2) {
return Math.sqrt(Math.pow(point1.x - point2.x, 2) + Math.pow(point1.y - point2.y, 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 LineGradient = function LineGradient(map, userOptions) {
var self = this;
self.map = map;
self.lines = [];
self.pixelList = [];
//默认参数
var options = {
//线条宽度
lineWidth: 1
};
self.init(userOptions, options);
//全局变量
this.baseCtx = self.options.baseCanvas.getContext("2d");
this.animateCtx = self.options.animateCanvas.getContext("2d");
this.width = map.width;
this.height = map.height;
this.clickEvent = this.clickEvent.bind(this);
this.bindEvent();
};
LineGradient.prototype.start = function () {
var self = this;
self.stop();
self.adjustSize();
self.renderBaselayer(); //底层canvas渲染
(function drawFrame() {
self.timer = setTimeout(function () {
self.animationId = requestAnimationFrame(drawFrame);
self.renderAnimatelayer(); //动画层canvas渲染
}, 1000 / 10);
})();
};
LineGradient.prototype.stop = function () {
var self = this;
if (self.animationId) {
cancelAnimationFrame(self.animationId);
}
if (self.timer) {
clearTimeout(self.timer);
}
};
LineGradient.prototype.adjustSize = function () {
var width = this.width;
var height = this.height;
this.baseCtx.canvas.width = width;
this.baseCtx.canvas.height = height;
this.animateCtx.canvas.width = width;
this.animateCtx.canvas.height = height;
resolutionScale(this.baseCtx);
resolutionScale(this.animateCtx);
};
LineGradient.prototype.addLine = function () {
var self = this,
options = this.options;
if (self.lines && self.lines.length > 0) return;
var dataset = options.data;
var legend = new Legend();
dataset.forEach(function (item, i) {
var line = new Line({
name: item.name,
label: item.label,
labelColor: item.labelColor,
path: []
});
item.data.forEach(function (point, j) {
point.color = legend.getColor(point.value).color;
line.path.push(point);
});
self.lines.push(line);
});
};
LineGradient.prototype.init = function (settings, defaults) {
//合并参数
tool.merge(settings, defaults);
this.options = defaults;
//初始化线条数据
this.addLine();
};
LineGradient.prototype.renderBaselayer = function () {
var self = this;
var context = self.baseCtx;
if (!context) return;
context.clearRect(0, 0, self.width, self.height);
self.pixelList = [];
self.lines.forEach(function (line) {
self.pixelList.push({
name: line.name,
label: line.label,
labelColor: line.labelColor,
data: line.getPointList(self.map)
});
line.draw(context, self.map, self.options);
});
};
LineGradient.prototype.renderAnimatelayer = function () {
var context = this.animateCtx;
if (!context) return;
context.fillStyle = 'rgba(0,0,0,.2)';
var prev = context.globalCompositeOperation;
context.globalCompositeOperation = 'destination-in';
context.fillRect(0, 0, this.width, this.height);
context.globalCompositeOperation = prev;
var lines = this.lines;
for (var i = 0; i < lines.length; i++) {
lines[i].drawArrow(context, this.map); //画箭头
}
};
LineGradient.prototype.bindEvent = function (e) {
var map = this.map;
if (this.options.methods) {
if (this.options.methods.mousemove) {
map.on('mouse-move', this.clickEvent);
}
}
};
LineGradient.prototype.clickEvent = function (e) {
var self = this,
flag = false,
lines = self.pixelList;
if (lines.length > 0) {
lines.forEach(function (line, i) {
for (var j = 0; j < line.data.length; j++) {
var beginPt = line.data[j].pixel;
if (line.data[j + 1] == undefined) return;
var curPt = e;
var inCircle = tool.isPointInCircle(curPt, beginPt, self.options.lineWidth);
if (inCircle) {
self.options.methods.mousemove(e, line.data[j]);
flag = true;
return;
}
}
});
if (!flag) {
document.getElementById('tooltips').style.visibility = 'hidden';
}
}
};
function Line(opts) {
this.name = opts.name;
this.label = opts.label;
this.labelColor = opts.labelColor;
this.path = opts.path;
this.step = 0;
}
Line.prototype.getPointList = function (map) {
var points = this.path;
if (points && points.length > 0) {
points.forEach(function (point) {
point.pixel = map.toScreen(point.lonlat);
});
}
return points;
};
Line.prototype.draw = function (context, map, options) {
var pointList = this.pixelList || this.getPointList(map);
for (var i = 0, len = pointList.length; i < len - 1; i++) {
context.save();
context.beginPath();
context.lineWidth = options.lineWidth;
context.strokeStyle = pointList[i].color;
context.moveTo(pointList[i].pixel.x, pointList[i].pixel.y);
context.lineTo(pointList[i + 1].pixel.x, pointList[i + 1].pixel.y);
context.stroke();
context.closePath();
context.restore();
}
var lastpoint = pointList[pointList.length - 1];
context.font = 'bold 14px Arial';
context.textAlign = 'left';
context.textBaseline = 'middle';
context.fillStyle = this.labelColor;
context.fillText(this.label, lastpoint.pixel.x, lastpoint.pixel.y);
};
Line.prototype.drawArrow = function (context, map, options) {
var pointList = this.pixelList || this.getPointList(map);
if (this.step >= pointList.length - 1) {
this.step = 0;
}
context.beginPath();
// context.lineWidth = options.animateLineWidth;
context.lineWidth = 5;
context.strokeStyle = '#fff';
context.moveTo(pointList[this.step].pixel.x, pointList[this.step].pixel.y);
context.lineTo(pointList[this.step + 1].pixel.x, pointList[this.step + 1].pixel.y);
context.stroke();
context.save();
context.translate(pointList[this.step + 1].pixel.x, pointList[this.step + 1].pixel.y);
//我的箭头本垂直向下算出直线偏离Y的角然后旋转 ,rotate是顺时针旋转的所以加个负号
var ang = (pointList[this.step + 1].pixel.x - pointList[this.step].pixel.x) / (pointList[this.step + 1].pixel.y - pointList[this.step].pixel.y);
ang = Math.atan(ang);
pointList[this.step + 1].pixel.y - pointList[this.step].pixel.y >= 0 ? context.rotate(-ang) : context.rotate(Math.PI - ang); //加个180度反过来
context.lineTo(-6, -6);
context.lineTo(0, 6);
context.lineTo(6, -6);
context.lineTo(0, 0);
context.fillStyle = '#fff';
context.fill(); //箭头是个封闭图形
context.restore(); //用来恢复Canvas之前保存的状态,否则会影响后续绘制
this.step += 1;
};
function Legend() {
var options = this.options = {
width: 400,
height: 15,
range: [700, 750, 800, 850, 900, 950, 1000, 1050, 1100],
gradient: {
0.1: '#fe0000',
0.4: '#ffaa01',
0.7: '#b0e000',
1.0: '#38a702'
}
};
this.init();
}
Legend.prototype.init = function () {
var options = this.options;
var canvas = this.canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
canvas.width = options.width;
canvas.height = options.height;
var grad = context.createLinearGradient(0, 0, canvas.width, canvas.height);
for (var gradient in options.gradient) {
grad.addColorStop(gradient, options.gradient[gradient]);
}
context.fillStyle = grad;
context.fillRect(0, 0, canvas.width, canvas.height);
this.imageData = context.getImageData(0, 0, canvas.width, canvas.height);
};
Legend.prototype.d2Hex = function (d) {
var hex = Number(d).toString(16);
while (hex.length < 2) {
hex = "0" + hex;
}
return hex.toUpperCase();
};
Legend.prototype.getRgbColor = function (point) {
var imageData = this.imageData;
var data = imageData.data;
var i = (point.y * this.canvas.width + point.x) * 4;
var rgb = [],
color = '#',
objRgbColor = {
"rgb": rgb,
"color": color
};
for (var j = 0; j < 3; j++) {
rgb.push(data[i + j]);
color += this.d2Hex(data[i + j]);
}
objRgbColor.color = color;
return objRgbColor;
};
Legend.prototype.getColor = function (value) {
var options = this.options;
var colorValue = value - options.range[0];
var point = {
x: Math.round(colorValue * this.canvas.width / (options.range[options.range.length - 1] - options.range[0])),
y: 1
};
return this.getRgbColor(point);
};
return LineGradient;
})));