直接上代码
import * as ol from "ol";
import * as layer from "ol/layer"; // 图层类
import * as source from "ol/source"; // 数据源相关
import * as geom from "ol/geom"; // 各类要素相关(点、线、面等)
import * as interaction from "ol/interaction"; // 地图交互类
import ScaleLine from "ol/control/ScaleLine.js";
import { defaults } from "ol/control/defaults";
import * as style from "ol/style"; // 给要素添加样式
import * as proj from "ol/proj";
import img1 from "@/assets/img/img1.png";
import OlDrawFunc from "@/utils/ol/olfun.js"; // 绘制其他箭头
// 算法
import getDayNightLine from "@/utils/getDayNightLine";
export default class olMap {
constructor(dom) {
this.map = null;
this.lineLayer = null; // 绘制线图层
this.pointLayer = null; // 绘制点图层
this.areaLayer = null; // 绘制区域图层
this.moreLayer = null; //
this.chLayer = null; // 晨昏线图层
this.graticuleLay = null; // 经纬线图层
this.eleMouse = null; // 经纬度跟着鼠标移动 的dom
this.tooltipMouse = null; // 经纬度跟着鼠标移动 的dom
this.drawType = null; // 绘制点线区 类型
this.draw = null; // 绘制点线区 类型
// 这个方法放最后
this.initMap(dom);
}
/**
* 初始化地图
*/
initMap(dom) {
// 创建4个图层
//ArcGIS地图
let esriMapLayer = new layer.Tile({
source: new source.XYZ({
url: "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
}),
title: "ESRI影像",
});
//OSM地图
let osmLayer = new layer.Tile({
source: new source.OSM(),
title: "OSM影像",
});
//天地图
let tiandituSatelliteLayer = new layer.Tile({
source: new source.XYZ({
url: "http://t3.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=008a8816d2eee25a677670273eaee891",
crossOrigin: "anonymous",
}),
title: "天地图影像",
});
//高德地图
let gaodeMapLayer = new layer.Tile({
source: new source.XYZ({
url: "http://webst0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}",
}),
});
// 本地引入
let myMap = new layer.Tile({
source: new source.XYZ({
url: "http://localhost:7777/image/mapbox/{z}/{x}/{y}.png",
}),
});
console.log(ol);
let scaleLine = new ScaleLine();
// 创建地图
this.map = new ol.Map({
layers: [
new layer.Tile({
source: new source.XYZ({
url: "http://localhost:7777/image/mapbox/{z}/{x}/{y}.png",
}),
}),
],
view: new ol.View({
center: proj.transform([104, 30], "EPSG:4326", "EPSG:3857"),
zoom: 3,
}),
constrols: defaults().extend([scaleLine]),
target: dom,
});
// 添加图层
this.addLayers();
}
/**
* 添加图层
* @returns
*/
addLayers() {
this.lineLayer = this.createVector(5);
this.pointLayer = this.createVector(5);
this.areaLayer = this.createVector(5);
this.moreLayer = this.createVector(5);
this.vectorLayer = this.createVector(5);
// 传入 地图和图层
this.oldf = new OlDrawFunc(this.map, this.vectorLayer)
}
// 经纬度图层
graticule(isShow) {
if (isShow) {
this.graticuleLay = new layer.Graticule({
strokeStyle: new style.Stroke({
color: "gray",
width: 2,
lineDash: [0.5, 4]
}),
showLabels: true,
visible: isShow,
})
this.map.addLayer(this.graticuleLay);
} else {
this.map.removeLayer(this.graticuleLay)
}
}
/**
* 绘制和修改线
* @param {*} type 名称内容
* @param {*} corrdinates 位置
* @param {*} id id
* @param {*} status 默认传入经纬度 如果不是经纬度 传false
*/
createLine(name, corrdinates, id, status = true) {
let geometry = new geom.LineString(corrdinates);
if (status) geometry.applyTransform(proj.getTransform("EPSG:4326", "EPSG:3857"));
let entity = this.lineLayer.getSource().getFeatureById(id);
if (entity) {
entity.setGeometry(geometry)
} else {
let featureMain = new ol.Feature({
geometry: geometry,
//setStyle:{}
});
featureMain.setId(id);
featureMain.setStyle(
new style.Style({
// 填充颜色
fill: new style.Fill({
color: "#aa3300",
}),
// 边界
stroke: new style.Stroke({
width: 2,
color: "#FF4500",
}),
// text
text: new style.Text({
textAlign: "center",
textBaseline: "middle",
font: "normal 14px 微软雅黑",
text: name + "",
fill: new style.Fill({
color: "#aa3300",
}),
stroke: new style.Stroke({
color: "#ffcc33",
width: 1,
}),
}),
// image 圆角
image: new style.Circle({
redius: 3,
fill: new style.Fill({
color: "#aa3300",
}),
}),
})
);
this.lineLayer.getSource().addFeature(featureMain);
}
}
/**
* 绘制和修改点
* @param {*} type 名称内容
* @param {*} corrdinates 位置
* @param {*} id id
* @param {*} status 默认传入经纬度 如果不是经纬度 传false
*/
createPoint(name, coordinates, id, status = true) {
if (!name) name = "点-" + new Date().getTime();
let entity = this.pointLayer.getSource().getFeatureById(id);
if (entity) {
console.log("修改")
entity
.getGeometry()
.setCoordinates(proj.transform(coordinates, "EPSG:4326", "EPSG:3857"));
} else {
let featureGeometry = new geom.Point(coordinates); // 创建要素
if (status) {
featureGeometry.applyTransform(
proj.getTransform("EPSG:4326", "EPSG:3857")
);
}
let featureMain = new ol.Feature({
geometry: featureGeometry,
});
featureMain.setId(id);
featureMain.setStyle(
new style.Style({
// 填充颜色
fill: new style.Fill({
color: "#aa3300",
}),
// 边界
stroke: new style.Stroke({
width: 5,
color: "#FF4500",
}),
// image 圆角
image: new style.Circle({
radius: 8,
fill: new style.Fill({
color: "#ff0000",
}),
stroke: new style.Stroke({
color: "#ffcc33",
width: 2,
}),
}),
// text
text: new style.Text({
textAlign: "center",
textBaseline: "middle",
font: "normal 14px 微软雅黑",
text: name + "",
fill: new style.Fill({
color: "#aa3300",
}),
stroke: new style.Stroke({
color: "#ffcc33",
width: 2,
}),
}),
})
);
this.pointLayer.getSource().addFeature(featureMain);
}
}
/**
* 绘制和修改区域
* @param {*} name 名称内容 目前没有使用 如果需要可以修改下
* @param {*} corrdinates 位置
* @param {*} id id
* @param {*} fillColor 填充颜色
* @param {*} strokeColor 边框颜色
* @param {*} status 默认传入经纬度 如果不是经纬度 传false
*/
createArea(name, corrdinates, id, fillColor = "rgba(255,0,0,0.3)", strokeColor = "rgba(255,0,0,1)", status = true) {
let geometry = new geom.Polygon([corrdinates]);
if (status) {
geometry.applyTransform(proj.getTransform("EPSG:4326", "EPSG:3857"));
}
let entity = this.areaLayer.getSource().getFeatureById(id);
console.log(geometry);
if (entity) {
let arr = corrdinates.map((element) => {
return proj.transform(element, "EPSG:4326", "EPSG:3857");
});
entity.getGeometry().setCoordinates(status ? [arr] : [corrdinates]);
} else {
let featureMain = new ol.Feature({
geometry: geometry,
//setStyle:{}
});
featureMain.setId(id);
featureMain.setStyle(
new style.Style({
// 填充颜色
fill: new style.Fill({
color: fillColor,
}),
// 边界
stroke: new style.Stroke({
width: 2,
color: strokeColor,
}),
// text
text: new style.Text({
textAlign: "center",
textBaseline: "middle",
font: "normal 14px 微软雅黑",
text: name + "", // 这里防止传入的是数字
fill: new style.Fill({
color: "#aa3300",
}),
stroke: new style.Stroke({
color: "#ffcc33",
width: 1,
}),
}),
})
);
this.areaLayer.getSource().addFeature(featureMain);
}
}
// 创建图层
createVector() {
let lay = new layer.Vector({
source: new source.Vector({
wrapX: true, // 禁止在x轴方向平铺
zIndex: 10,
}),
});
this.map.addLayer(lay);
return lay;
}
// 创建图层1
createCulVector() {
let lay = new layer.Vector({
source: new source.Cluster({
source: new source.Vector({
wrapX: true, // 禁止在x轴方向平铺
zIndex: 10,
}),
zIndex: 10,
distance: 10,
}),
});
map.addLayer(lay);
return lay;
}
// 图层的显示隐藏
showLayer() {
this.map.on("moveend", () => {
// 获取图层
let zoom = this.map.getView().getZoom();
console.log(zoom);
if (zoom > 4) {
this.lineLayer.setVisible(true);
this.moreLayer.setVisible(false);
} else {
this.moreLayer.setVisible(true);
this.lineLayer.setVisible(false);
}
});
}
// 飞入地点 center [lon,lat]
flyCenter(center, zomm, isanimate = true) {
let point = proj.transform(center, "EPSG:4326", "EPSG:3857");
let view = this.map.getView();
if (zomm) {
view.setZoom(zomm); // 放大等级
}
if (isanimate) {
view.animate({
center: point,
duration: 500,
});
} else {
view.setCenter(point); // 视角中心
}
}
// 飞入区域 center [lon,lat,lon,lat] 矩形的 斜对角俩个坐标
flyPoylgon(center) {
this.map.fit(center);
}
/**
* -180到180 问题
*/
linePaardeData(data) {
let lineArray = new Array();
lineArray.push(new Array());
let points = data;
if (points.length > 1) {
let conn1 = new Array();
conn1[0] = points[0][0];
conn1[1] = points[0][1];
lineArray[lineArray.length - 1].push(conn1);
for (let j = 1; j < points.length; j++) {
let lon1 = points[j - 1][0];
let lat1 = points[j - 1][1];
let lon2 = points[j][0];
let lat2 = points[j][1];
let lon = Math.abs(lon2 - lon1);
if (lon > 180) {
let endPoint;
let startPoint;
let latthis;
if (lon1 > lon2) {
if (lat1 > lat2) {
latthis =
lat1 -
((180 - lon1) * Math.abs(lat1 - lat2)) / (360 - lon1 + lon2);
} else if (lat1 <= lat2) {
latthis =
lat1 +
((180 - lon1) * Math.abs(lat1 - lat2)) / (360 - lon1 + lon2);
}
} else if (lon1 <= lon2) {
if (lat1 > lat2) {
latthis =
lat1 -
((180 + lon1) * Math.abs(lat1 - lat2)) / (360 + lon1 - lon2);
} else if (lat1 <= lat2) {
latthis =
lat1 +
((180 + lon1) * Math.abs(lat1 - lat2)) / (360 + lon1 - lon2);
}
}
if (lon1 > 0 && lon1 != 180) {
endPoint = [180.0, latthis];
startPoint = [-180.0, latthis];
lineArray[lineArray.length - 1].push(endPoint);
} else if (lon1 == 180) {
startPoint = [-180.0, points[j - 1][1]];
} else if (lon1 < 0 && lon1 != -180) {
endPoint = [-180.0, latthis];
lineArray[lineArray.length - 1].push(endPoint);
startPoint = [180.0, latthis];
} else if (lon1 == -180) {
startPoint = [180.0, points[j - 1][1]];
}
lineArray.push(new Array());
lineArray[lineArray.length - 1].push(startPoint);
let conn = new Array();
conn[0] = points[j][0];
conn[1] = points[j][1];
lineArray[lineArray.length - 1].push(conn);
} else {
let conn = new Array();
conn[0] = points[j][0];
conn[1] = points[j][1];
lineArray[lineArray.length - 1].push(conn);
}
}
}
console.log(lineArray, "lineArray");
let lineDatas = new Array();
for (let j = 0; j < lineArray.length; j++) {
for (let k = 1; k < lineArray[j].length; k++) {
if (lineArray[j][k - 1][0] < 0 && lineArray[j][k - 1][0] >= -180) {
lineArray[j][k - 1][0] += 360;
}
if (lineArray[j][k][0] < 0 && lineArray[j][k][0] >= -180) {
lineArray[j][k][0] += 360;
}
lineDatas.push(lineArray[j][k - 1]);
lineDatas.push(lineArray[j][k]);
}
}
return lineDatas;
}
/**
* -180到180 跨度大解决问题 原理 切成多条线
*/
linePaardeDataPlus(data) {
let headArr = data[0];
let arr = [];
let index = -1;
let status = true;
let temp = [];
function getEndArr(val) {
let temp;
if (val) {
temp = JSON.parse(JSON.stringify(val[val.length - 1]));
}
return temp;
}
data.map((val) => {
if (val[0] >= 0) {
if (status) {
index++;
status = false;
}
temp = getEndArr(arr[index - 1]);
if (temp && Math.abs(temp[0]) > 90) temp[0] = temp[0] + 360;
} else {
if (!status) {
index++;
status = true;
}
temp = getEndArr(arr[index - 1]);
if (temp && Math.abs(temp[0]) > 90) temp[0] = temp[0] - 360;
}
if (!arr[index]) {
arr[index] = [];
if (temp) arr[index].push(temp);
}
arr[index].push(val);
});
}
/**
* 闪烁点
*/
twinkingPoint(point, id, isimg) {
// 新建dom元素 注意:这里创建的元素样式 需要在全局引入的css里有
let dom = document.createElement("div");
dom.className = "twinkingPoint";
// 是否用
if (isimg) {
let img = document.createElement("img");
img.src = img1;
img.style = "width:100%;height:100%";
dom.appendChild(img);
}
// 创建overlay
let overlay = new ol.Overlay({
element: dom,
positioning: "center-center",
id: id,
});
overlay.setPosition(proj.transform(point, "EPSG:4326", "EPSG:3857"));
// 添加到地图上
this.map.addOverlay(overlay);
}
/**
* 删除闪烁点
*/
deleteTwinking(id) {
this.map.removeOverlay(this.map.getOverlayById(id));
}
/**
* 清除全部闪烁点
*/
deleteAllTwinking() {
this.map.getOverlays().clear();
}
/**
* 清空当前Layers的数据源(比如Feature)
*/
delAllInteraction(layers) {
layers.getSource().clear();
}
/**
* 获取经纬度
*/
getLonlat(obj) {
this.map.on("pointermove", (evt) => {
let helpMsg = this.parseMouseCoordinate(evt.coordinate);
obj.lon = helpMsg[0].toFixed(3);
obj.lat = helpMsg[1].toFixed(3);
});
}
/**
* 获取移动经纬度
* @param {*} point
* @returns
*/
mouseMovePos() {
this.eleMouse = document.createElement("div");
this.eleMouse.className = "tooltip";
this.tooltipMouse = new ol.Overlay({
element: this.eleMouse,
offset: [15, 0],
positioning: "center-left",
});
this.map.addOverlay(this.tooltipMouse);
this.map.on("pointermove", (evt) => {
let helpMsg = this.parseMouseCoordinate(evt.coordinate);
let lon = helpMsg[0].toFixed(3);
let lat = helpMsg[1].toFixed(3);
if (this.eleMouse) {
this.eleMouse.innerText = lon + "," + lat;
this.tooltipMouse.setPosition(evt.coordinate);
}
});
}
// 处理获取经纬度 超过-180和+180
parseMouseCoordinate(point) {
let len = point.length;
let pointstr = "";
let lon;
let coordinate;
if (len > 0) {
let coordData = [point[0], point[1]];
coordinate = proj.transform(coordData, "EPSG:3857", "EPSG:4326");
pointstr += "";
lon = parseFloat(coordinate[0]);
let yu = lon % 360;
if (yu < -180) {
lon = yu + 360;
} else if (yu > 180) {
lon = yu - 360;
} else {
lon = yu;
}
}
return [lon, coordinate[1]];
}
/**
* 晨昏线 大佬算的 是 utc时间
*/
createCH(y, m, d, h, dd, s) {
let arr = getDayNightLine(y, m, d, h, dd, s);
let coordinates = arr.map((val, index) => {
return val;
});
let a1 = [];
let a2 = [];
let aa = false;
let aindex = 178;
coordinates.map((val) => {
if (aindex - val[0] > 356 || aindex - val[0] < -356) {
aa = true;
} else {
aindex = val[0];
}
if (aa) {
a1.push(val);
} else {
a2.push(val);
}
});
let aar = [...a1, ...a2];
if (aar[0][0] > 0) {
if (aar[0][1] > 0) {
aar.unshift([180, -85]);
aar.push([-180, -85]);
} else {
aar.unshift([180, -85]);
aar.push([-180, -85]);
}
} else {
if (aar[0][1] > 0) {
aar.unshift([-180, -85]);
aar.push([180, -85]);
} else {
aar.unshift([-180, -85]);
aar.push([180, -85]);
}
}
aar.push(aar[0]);
console.log(aar);
let featureGeometry = new geom.Polygon([aar]);
featureGeometry.applyTransform(proj.getTransform("EPSG:4326", "EPSG:3857"));
// 创建Feature
let featureMain = new ol.Feature({
type: "night",
geometry: featureGeometry,
});
let layerch = new layer.Vector({
source: new source.Vector({
features: [featureMain],
}),
style: new style.Style({
fill: new style.Fill({
color: "rgba(255,0,0,0.8)",
}),
}),
});
this.map.addLayer(layerch);
}
/**
* 晨昏线
*/
addDayNightTerminator(tiem) {
var twilightWidth = 667918;
var twilightSteps = 13;
var points = 288;
var maxDimension = proj.get("EPSG:3857").getExtent()[3];
var minDimension = proj.get("EPSG:3857").getExtent()[1];
var dayFeatures = [];
var nightFeatures = [];
var _terminatorCurveSetCache = {};
var _generateTerminatorCurveSet = function(dayOfYear) {
var offsetX = maxDimension;
var declination =
0.40927971 * Math.sin(((2 * Math.PI) / 365) * (dayOfYear - 81.5));
var termFunction = function(lon) {
var cosFactor = -Math.cos((lon + offsetX) * (Math.PI / maxDimension));
return (
((2 * maxDimension) / Math.PI) *
Math.atan(cosFactor / Math.tan(declination))
);
};
var lonPrimeFunction = function(t) {
return (maxDimension - minDimension) / points;
};
var latPrimeFunction = function(t) {
var aFactor = (2 * maxDimension) / Math.PI;
var bFactor = offsetX;
var cFactor = Math.PI / maxDimension;
var dFactor = Math.tan(declination);
var cosOperand =
(minDimension +
((maxDimension - minDimension) / points) * t +
bFactor) *
cFactor;
return (
((aFactor / (1 + Math.pow(-Math.cos(cosOperand) / dFactor, 2))) *
(Math.sin(cosOperand) / dFactor) *
(cFactor * (maxDimension - minDimension))) /
points
);
};
var lonParallelFunction = function(dist, t) {
return (
(dist * latPrimeFunction(t)) /
Math.sqrt(
Math.pow(lonPrimeFunction(t), 2) + Math.pow(latPrimeFunction(t), 2)
)
);
};
var latParallelFunction = function(dist, t) {
return (
(dist * lonPrimeFunction(t)) /
Math.sqrt(
Math.pow(lonPrimeFunction(t), 2) + Math.pow(latPrimeFunction(t), 2)
)
);
};
var lineCoords = [];
for (var i = 0; i < twilightSteps; i++) {
lineCoords.push([]);
}
for (var i = 0; i < points; i++) {
var lon = minDimension + ((maxDimension - minDimension) / points) * i;
var lat = termFunction(lon);
lineCoords[0].push([lon, lat]);
var latDeg = proj.toLonLat([lon, lat])[1];
var latRad = (latDeg * Math.PI) / 180;
var baseDist = twilightWidth / (twilightSteps - 1) / Math.cos(latRad);
var steps = (twilightSteps - 1) / 2;
for (var j = 1; j <= steps; j++) {
var dist = baseDist * j;
lineCoords[j].push([
lon + lonParallelFunction(dist, i),
Math.max(lat - latParallelFunction(dist, i), minDimension),
]);
lineCoords[j + steps].push([
lon - lonParallelFunction(dist, i),
Math.min(lat + latParallelFunction(dist, i), maxDimension),
]);
}
}
var dayShimCoord = declination < 0 ? minDimension : maxDimension;
var nightShimCoord = declination < 0 ? maxDimension : minDimension;
return {
curves: lineCoords,
dayShimCoord: dayShimCoord,
nightShimCoord: nightShimCoord,
};
};
this.getTerminatorCurveSet = function(dayOfYear) {
if (!(dayOfYear in _terminatorCurveSetCache)) {
_terminatorCurveSetCache[dayOfYear] =
_generateTerminatorCurveSet(dayOfYear);
}
return $.extend(true, {}, _terminatorCurveSetCache[dayOfYear]);
};
this.setClock = function(clock) {
var now = moment.unix(clock).utc();
var baseCurveData = this.getTerminatorCurveSet(now.dayOfYear());
var dayFraction =
(now.hour() * 3600 + now.minute() * 60 + now.second()) / 86400;
var offsetX = dayFraction * 2 * maxDimension;
offsetX =
Math.round(offsetX / ((2 * maxDimension) / points)) *
((2 * maxDimension) / points);
$.each(
baseCurveData.curves,
$.proxy(function(k1, curve) {
$.each(curve, function(k2, coord) {
curve[k2][0] -= offsetX;
});
var count = 0;
while (true) {
if (count > curve.length) {
break;
}
if (curve[0][0] < minDimension) {
var coord = curve.shift();
coord[0] += maxDimension - minDimension;
curve.push(coord);
} else {
break;
}
count++;
}
curve.push([
curve[0][0] + (maxDimension - minDimension),
curve[0][1],
]);
var nightCoords = curve.slice(0);
nightCoords.push(
[maxDimension, baseCurveData.nightShimCoord], [minDimension, baseCurveData.nightShimCoord],
curve[0]
);
var nightGeometry = new geom.Polygon([nightCoords]);
nightFeatures[k1].setGeometry(nightGeometry);
}, this)
);
};
for (var i = 0; i < twilightSteps; i++) {
nightFeatures.push(
new ol.Feature({
type: "night",
})
);
}
let tt = new Date(tiem).getTime() / 1000;
this.setClock(Math.round(tt)); //设置时间,不设置则为当前时间 '2017-03-22 12:00'
return [].concat(nightFeatures);
}
// 晨昏线 网上找的 是北京时间
createCH2(tiem) {
this.map.removeLayer(this.chLayer);
this.chLayer = new layer.Vector({
source: new source.Vector({
features: this.addDayNightTerminator(tiem),
}),
opacity: 0.8,
style: new style.Style({
fill: new style.Fill({
color: "rgba(0,0,0,1)",
}),
}),
});
this.map.addLayer(this.chLayer);
}
/**
* 绘制扫描效果
*/
createRadarMoveView(pointArr, id, color) {
let index = 0;
setInterval(() => {
let arr = [
pointArr[0],
pointArr[index + 1],
pointArr[index + 2],
pointArr[index + 3],
pointArr[index + 4],
];
this.createArea("", arr, id, color, color);
index = index + 4;
if (index + 4 > pointArr.length) {
index = 0;
}
}, 100);
}
// 绘制 Point点 LineString线 Polygon区域
drawEntity(type) {
this.draw = new interaction.Draw({
source: this.moreLayer.getSource(),
type: type,
});
// 给地图添加交互
this.map.addInteraction(this.draw);
this.draw.on("drawend", (evt) => {
let id = "entity_" + new Date().getTime();
evt.feature.setId(id);
evt.feature.setStyle(new style.Style({
// 填充颜色
fill: new style.Fill({
width: 3,
color: "rgba(255,0,0,0.3)",
}),
// 边界
stroke: new style.Stroke({
width: 3,
color: "rgba(255,0,0,1)",
}),
image: new style.Circle({
radius: 8,
fill: new style.Fill({
color: "#ff0000",
}),
stroke: new style.Stroke({
color: "#ffcc33",
width: 2,
}),
}),
}))
const geometry = evt.feature.getGeometry();
let coordinates = geometry.getCoordinates()
setTimeout(() => {
this.map.removeInteraction(this.draw)
});
});
}
/**
* 创建图形
*/
addshape(type, index) {
this.oldf.currentType = type
this.oldf.current = type
this.oldf.currentObj = new this.oldf.mapType[type](this.oldf.startDelineation)
this.map.on("click", this.oldf.firstclick)
}
/**
* 根据值的占比 计算属于那种颜色颜色
* x 实际值
* min 最小值
* max 最大值
*/
getredorblueColor(x, min, max) {
if (min < max) {
let x1 = (max - min) / 4;
let x2 = (max - min) / 2;
let x3 = 3 / 4 * (max - min);
let x4 = max - min;
let r, g, b
if (x <= x1) {
r = 255;
g = 255 / x1 * x
b = 0
}
if (x1 < x && x <= x2) {
r = 255 / (x1 - x2) * x + 255 / (x2 - x1) * x2
}
if (x > x2) {
r = 0;
}
if (x1 < x && x <= x3) {
g = 255
}
if (x > x3) {
g = 255 / (x3 - x4) * x + 255 / (x4 - x3) * x4
}
if (x <= x2) {
b = 0
}
if (x2 < x && x <= x3) {
b = 255 / (x3 - x2) * x + 255 / (x2 - x3) * x2
}
if (x > x3) {
b = 255
}
return [r, g, b]
} else {
// 蓝
return [0, 0, 255]
}
}
}