@idmwx/idmui-gl3
Version:
idm webgl3
1,101 lines (1,086 loc) • 466 kB
JavaScript
var mt = Object.defineProperty;
var ut = (a, e, t) => e in a ? mt(a, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[e] = t;
var se = (a, e, t) => (ut(a, typeof e != "symbol" ? e + "" : e, t), t);
import { LayerHelper as $e, CompanyHelper as Ve } from "@idm-plugin/tag";
import ie from "moment";
import Ne from "axios";
import { resolveComponent as R, openBlock as u, createElementBlock as g, createElementVNode as o, normalizeStyle as de, createVNode as O, withCtx as Me, normalizeClass as te, Fragment as ee, renderList as ae, toDisplayString as k, createCommentVNode as q, createBlock as gt, createTextVNode as fe, withDirectives as Oe, createStaticVNode as yt, vShow as Fe, defineComponent as ft, withModifiers as Ze, mergeProps as K } from "vue";
import * as H from "@turf/turf";
import At from "@mapbox/sphericalmercator";
import Re from "mapbox-gl";
import { TropicalHelper as ct, LngLatHelper as ce, LaneHelper as We } from "@idm-plugin/geo";
import { TidesAssist as et, Meteo2Assist as Ke } from "@idm-plugin/meteo";
import Xe from "moment-timezone";
const Y = (a, e) => {
const t = a.__vccOpts || a;
for (const [r, i] of e)
t[r] = i;
return t;
}, wt = {
name: "IdmGlLayer",
props: {
map: {
type: Object
},
mapProjection: {
type: String
},
gateway: {
type: String
},
token: {
type: String
},
top: {
type: Number,
default: 60
},
layerToggle: {
type: Boolean,
default: !1
},
toggleVersion: {
type: Number
},
isLogin: {
type: Boolean,
default: void 0
},
showWindFeather: {
type: Boolean,
default: void 0
},
showWindParticle: {
type: Boolean,
default: void 0
},
showCurrentIsoband: {
type: Boolean,
default: void 0
},
showCurrentParticle: {
type: Boolean,
default: void 0
},
forecastModel: {
type: String
}
},
emits: ["weather", "other", "toggleWindParticle", "toggleWindFeather", "toggleCurrentParticle", "toggleCurrentIsoband", "toggleWindParticeVersion", "toggleCurrentParticeVersion", "coordinate", "measure", "point", "3d", "layerToggle", "handleToggleVersion", "login", "forecastModel"],
data() {
return {
autoActive: !0,
layers: {
weather: [
...$e.WEATHER_LAYERS.filter((a) => a.enabled && !["swell-height", "swell-direction", "current-direction", "current-speed"].includes(a.key))
],
other: [...$e.OTHER_LAYERS.filter((a) => a.enabled)]
},
activeWeatherLayers: [],
activeWeatherLayersCollected: [],
activeOtherLayers: [],
autoActiveCache: "autoActiveCache",
activeWeatherLayersCache: "activeWeatherLayersCache",
activeOtherLayersCache: "activeOtherLayersCache",
collectedLayerCache: "collectedLayerCache",
sourceCache: "defaultSourceCache",
windFeatherCollectedCache: "windFeatherCollectedCache",
currentIsobandCollectedCache: "currentIsobandCollectedCache",
showCoord: !1,
showMeasure: !1,
showPoint: !1,
show3d: !1,
version: {
v: "0.1.1",
k: "glCacheVersion"
},
source: "Best Match",
sourceList: [],
right: 10,
rampColorLayers: ["visibility", "precip3h", "temp", "water-temp", "ice-thickness", "ice-cover"],
showWindParticleCollected: !1,
showWindFeatherCollected: !0,
showCurrentParticleCollected: !1,
showCurrentIsobandCollected: !1
};
},
computed: {
computeLayerClass() {
return function(a, e) {
var r;
let t = "layer flex-between";
return e.some((i) => i.key === a.key) && (t = t + " active"), (!a.enabled || (r = this.layers.weather) != null && r.some((i) => i.key === a.key) && !this.autoActive || this.rampColorLayers.includes(a.key) && this.mapProjection === "globe") && (t = t + " disabled"), t;
};
},
hasCollectedLayers() {
var a;
return ((a = this.layers.weather.filter((e) => e.collected)) == null ? void 0 : a.length) > 0;
},
computeDateZ() {
return function(a) {
var e;
if (a) {
const t = ie(a);
return `${(e = t == null ? void 0 : t.utc()) == null ? void 0 : e.format("MMM-DD/HHmm")}Z`;
}
return "-";
};
},
sourceCode() {
var a;
return (a = this.sourceList.find((e) => e.name === this.source)) == null ? void 0 : a.code;
}
},
watch: {
toggleVersion: {
handler() {
this.$nextTick(() => {
var a;
this.right = (((a = document.getElementsByClassName("right-bar")[0]) == null ? void 0 : a.clientWidth) || 0) + 10;
});
}
},
source: {
handler(a, e) {
a && a !== e && this.$emit("forecastModel", this.source), a && e && a !== e && this.handleConfirm();
}
},
activeWeatherLayers: {
handler(a, e) {
this.autoActive && (this.activeWeatherLayersCollected = this.activeWeatherLayers, localStorage.setItem(this.activeWeatherLayersCache, JSON.stringify(this.activeWeatherLayers)));
}
},
showWindParticle: {
handler(a, e) {
this.autoActive && (this.showWindParticleCollected = this.showWindParticle);
}
},
showWindFeather: {
handler(a, e) {
this.autoActive && (this.showWindFeatherCollected = this.showWindFeather, localStorage.setItem(this.windFeatherCollectedCache, this.showWindFeatherCollected));
}
},
showCurrentParticle: {
handler(a, e) {
this.autoActive && (this.showCurrentParticleCollected = this.showCurrentParticle);
}
},
showCurrentIsoband: {
handler(a, e) {
this.autoActive && (this.showCurrentIsobandCollected = this.showCurrentIsoband, localStorage.setItem(this.currentIsobandCollectedCache, this.showCurrentIsobandCollected));
}
}
},
async mounted() {
await this.fetchMeteoSource(), this.fetchCache(), this.handleConfirm();
},
methods: {
async fetchMeteoSource() {
var e;
this.sourceList = [];
let a = await Ne.get(`${this.gateway}/api/arc/meteo2/models`, {
headers: {
Authorization: this.token
}
});
(a == null ? void 0 : a.data.code) === 0 && (this.sourceList = (e = a == null ? void 0 : a.data.data) == null ? void 0 : e.weather);
},
fetchCache() {
const a = localStorage.getItem(this.version.k);
this.version.v !== a && (localStorage.removeItem(this.autoActiveCache), localStorage.removeItem(this.activeWeatherLayersCache), localStorage.removeItem(this.activeOtherLayersCache), localStorage.removeItem(this.windFeatherCollectedCache), localStorage.removeItem(this.currentIsobandCollectedCache), localStorage.setItem(this.version.k, this.version.v));
let e = localStorage.getItem(this.autoActiveCache);
this.autoActive = e !== "false", e = localStorage.getItem(this.collectedLayerCache);
let t = JSON.parse(
e || '[{"weight": 16, "name": "Sig Waves", "key": "sig-wave-height", "collected": true},{"weight": 1, "name": "Wind", "key": "wind", "h5": true, "collected": true},{"weight": 96, "name": "Current", "key": "current", "collected": true},{"weight": 256,"name": "Tropicals","key": "tropicals", "collected": true}]'
);
this.layers.weather.forEach((r) => {
r.collected = !!t.some((i) => i.key === r.key && i.collected);
}), e = localStorage.getItem(this.activeWeatherLayersCache), e || localStorage.setItem(this.activeWeatherLayersCache, JSON.stringify(
[
{ weight: 1, name: "Wind", key: "wind", enabled: !0, type: "json", particle: !1 },
{ weight: 16, name: "Sig Waves", key: "sig-wave-height", enabled: !0, type: "json" },
{ weight: 256, name: "Tropicals", key: "tropicals", enabled: !0, type: "json" }
]
)), e = localStorage.getItem(this.activeWeatherLayersCache), t = JSON.parse(e), this.autoActive ? this.activeWeatherLayers = [...t] : this.activeWeatherLayersCollected = [...t], t.some((r) => r.key === "wind" && r.particle) && (this.$emit("toggleWindParticle", !0), this.showWindParticleCollected = !0), t.some((r) => r.key === "current" && r.particle) && (this.$emit("toggleCurrentParticle", !0), this.showCurrentParticleCollected = !0), this.showWindFeatherCollected = JSON.parse(localStorage.getItem(this.windFeatherCollectedCache)) ? JSON.parse(localStorage.getItem(this.windFeatherCollectedCache)) : this.showWindFeatherCollected, this.showCurrentIsobandCollected = JSON.parse(localStorage.getItem(this.currentIsobandCollectedCache)) ? JSON.parse(localStorage.getItem(this.currentIsobandCollectedCache)) : this.showCurrentIsobandCollected, this.autoActive && (this.$emit("toggleWindFeather", this.showWindFeatherCollected), this.$emit("toggleCurrentIsoband", this.showCurrentIsobandCollected)), t.some((r) => r.key === "wind" && !r.particle && !this.showWindFeatherCollected) && (t = t.filter((r) => r.key !== "wind")), t.some((r) => r.key === "current" && !r.particle && !this.showCurrentIsobandCollected) && (t = t.filter((r) => r.key !== "current")), e = localStorage.getItem(this.activeOtherLayersCache), t = JSON.parse(e || '[{"weight":4,"name":"ECA Zones","key":"eca-zones","enabled":true,"type":"json"}, {"weight": 2048,"name": "ENC","key": "enc","h5": true,"enabled": true,"type": "origin"}]'), this.activeOtherLayers = t, e = localStorage.getItem(this.sourceCache), this.source = this.forecastModel ? this.forecastModel : e ? e === "CMEMS" ? "ECMWF" : e : this.source, this.$emit("forecastModel", this.source);
},
handleConfirm() {
this.autoActive && this.$emit("weather", JSON.parse(localStorage.getItem(this.activeWeatherLayersCache)), this.sourceCode), this.$emit("other", this.activeOtherLayers), localStorage.setItem(this.autoActiveCache, this.autoActive), localStorage.setItem(this.sourceCache, this.source);
},
handleWeatherLayerPick(a) {
if (this.activeWeatherLayers = JSON.parse(localStorage.getItem(this.activeWeatherLayersCache)), this.rampColorLayers.includes(a.key) && this.mapProjection === "globe" || !this.autoActive)
return !1;
(a.key === "wind" && !this.showWindFeather || a.key === "current" && !this.showCurrentIsoband) && (a.particle = !0), this.activeWeatherLayers.some((e) => e.key === a.key) ? this.activeWeatherLayers = this.activeWeatherLayers.filter((e) => e.key !== a.key) : this.activeWeatherLayers.length < 6 && a.enabled && (["png", "jpg"].includes(a.type) ? (this.activeWeatherLayers.forEach((e) => {
(e.key === "wind" && this.showWindFeather || a.key === "current" && this.showCurrentIsoband) && (e.particle = !1);
}), this.activeWeatherLayers = this.activeWeatherLayers.filter((e) => e.type === "json" && !(["wind", "current"].includes(e.key) && e.particle))) : a.key === "wind" ? (this.activeWeatherLayers.forEach((e) => {
e.key === "current" && this.showCurrentIsoband && (e.particle = !1);
}), this.activeWeatherLayers = this.activeWeatherLayers.filter((e) => e.type === "json" && !(["wind", "current"].includes(e.key) && e.particle))) : a.key === "current" && (this.activeWeatherLayers.forEach((e) => {
e.key === "wind" && this.showWindFeather && (e.particle = !1);
}), this.activeWeatherLayers = this.activeWeatherLayers.filter((e) => e.type === "json" && !(["wind", "current"].includes(e.key) && e.particle))), a.key === "sig-wave-height" && (this.activeWeatherLayers = this.activeWeatherLayers.filter((e) => e.key !== "sig-wave")), a.key === "sig-wave" && (this.activeWeatherLayers = this.activeWeatherLayers.filter((e) => e.key !== "sig-wave-height")), this.activeWeatherLayers.push(a)), this.$emit("weather", this.activeWeatherLayers, this.sourceCode);
},
handleWeatherLayerCollect(a) {
var e;
if (!this.autoActive)
return !1;
!a.collected && ((e = this.layers.weather.filter((t) => t.collected)) == null ? void 0 : e.length) >= 6 && (this.layers.weather.filter((t) => t.collected)[0].collected = !1), a.collected = !a.collected, localStorage.setItem(this.collectedLayerCache, JSON.stringify(this.layers.weather)), this.$emit("handleToggleVersion");
},
handleToggleWindParticle() {
!this.showWindFeather && this.showWindParticle ? this.handleWeatherLayerPick({ weight: 1, name: "Wind", key: "wind", enabled: !0, type: "json", particle: !1 }) : (this.showCurrentParticle && (this.$emit("toggleCurrentParticle", !1), this.showCurrentIsoband || (this.activeWeatherLayers = this.activeWeatherLayers.filter((a) => a.key !== "current"))), this.$emit("toggleWindParticle", !this.showWindParticle), this.$emit("toggleWindParticeVersion"));
},
handleToggleWindFeather() {
this.showWindFeather && !this.showWindParticle && this.handleWeatherLayerPick({ weight: 1, name: "Wind", key: "wind", enabled: !0, type: "json", particle: !1 }), this.$emit("toggleWindFeather", !this.showWindFeather);
},
handleToggleCurrentParticle() {
!this.showCurrentIsoband && this.showCurrentParticle ? this.handleWeatherLayerPick({ weight: 96, name: "Current", key: "current", enabled: !0, type: "json", particle: !1 }) : (this.showWindParticle && (this.$emit("toggleWindParticle", !1), this.showWindFeather || (this.activeWeatherLayers = this.activeWeatherLayers.filter((a) => a.key !== "wind"))), this.$emit("toggleCurrentParticle", !this.showCurrentParticle), this.$emit("toggleCurrentParticeVersion"));
},
handleToggleCurrentIsoband() {
this.showCurrentIsoband && !this.showCurrentParticle && this.handleWeatherLayerPick({ weight: 96, name: "Current", key: "current", enabled: !0, type: "json", particle: !1 }), this.$emit("toggleCurrentIsoband", !this.showCurrentIsoband);
},
handleOtherLayerPick(a) {
this.activeOtherLayers.some((e) => e.key === a.key) ? this.activeOtherLayers = this.activeOtherLayers.filter((e) => e.key !== a.key) : a.enabled && this.activeOtherLayers.push(a), localStorage.setItem(this.activeOtherLayersCache, JSON.stringify(this.activeOtherLayers)), this.$emit("other", this.activeOtherLayers);
},
handleMenuToggle() {
this.$emit("layerToggle", !this.layerToggle);
},
toggleAutoActive() {
this.autoActive = !this.autoActive, localStorage.setItem(this.autoActiveCache, this.autoActive), this.autoActive ? (this.$emit("weather", this.activeWeatherLayersCollected, this.sourceCode), this.$emit("toggleWindFeather", localStorage.getItem(this.windFeatherCollectedCache) === "true"), this.$emit("toggleCurrentIsoband", localStorage.getItem(this.currentIsobandCollectedCache) === "true")) : (this.$emit("weather", [], this.sourceCode), this.$emit("toggleWindFeather", !1), this.$emit("toggleCurrentIsoband", !1));
},
handleCoordToggle() {
this.showCoord = !this.showCoord, this.$emit("coordinate", this.showCoord);
},
handlePointToggle() {
this.isLogin ? (this.showPoint = !this.showPoint, this.$emit("point", this.showPoint)) : this.$emit("login");
},
handleMeasureToggle() {
this.showMeasure = !this.showMeasure, this.$emit("measure", this.showMeasure);
},
handle3DToggle() {
this.show3d = !this.show3d, this.$emit("3d", this.show3d);
}
}
}, vt = { class: "idm-gl3-layer" }, bt = { class: "bar-item layer-bars" }, Lt = { class: "bar-item tool-bars" }, Ct = { class: "flex-between" }, xt = {
key: 0,
class: "iconfont active"
}, _t = {
key: 1,
class: "iconfont"
}, Bt = ["onClick"], It = ["onClick"], Et = {
key: 0,
class: "flex-start"
}, kt = {
key: 1,
class: "flex-start"
}, Dt = { class: "header-box flex-between" }, Pt = { class: "weather-layers card-bg" }, zt = { class: "layers-title flex-between" }, Mt = {
key: 0,
class: "iconfont active"
}, St = {
key: 1,
class: "iconfont"
}, Tt = { class: "layers-body" }, Qt = { class: "flex-start" }, Ht = ["onClick"], Nt = ["onClick"], Ot = {
key: 0,
class: "flex-start"
}, Ft = {
key: 1,
class: "flex-start"
}, Rt = ["onClick"], jt = {
key: 0,
class: "iconfont bookmark-icon active"
}, Wt = {
key: 1,
class: "iconfont bookmark-icon inactive"
}, Gt = { class: "other-layers card-bg" }, Ut = { class: "layers-body" }, Yt = ["onClick"], Kt = { class: "flex-start" }, Xt = { class: "switch flex-center" }, Jt = {
key: 0,
class: "iconfont active"
}, qt = {
key: 1,
class: "iconfont"
}, Vt = { class: "source-layers card-bg" }, Zt = { class: "layers-body" }, $t = { key: 0 }, ea = {
key: 1,
class: "radio-tip"
}, ta = {
key: 2,
class: "radio-tip"
};
function aa(a, e, t, r, i, s) {
const n = R("ElTooltip"), l = R("ElRadio"), c = R("ElRadioGroup"), d = R("ElScrollbar");
return u(), g("div", vt, [
o("div", {
class: "menu-bar-box",
style: de({ top: t.top + 10 + "px", right: i.right + "px" })
}, [
o("div", bt, [
O(n, {
placement: "left",
effect: "light",
content: "Menu",
"show-after": 1e3
}, {
default: Me(() => [
o("div", {
class: te(t.layerToggle ? "menu-icon active" : "menu-icon"),
onClick: e[0] || (e[0] = (...h) => s.handleMenuToggle && s.handleMenuToggle(...h))
}, e[17] || (e[17] = [
o("span", { class: "iconfont" }, "", -1)
]), 2)
]),
_: 1
})
])
], 4),
o("div", {
class: "menu-bar-box",
style: de({ top: t.top + 160 + "px", right: i.right + "px" })
}, [
o("div", Lt, [
O(n, {
placement: "left",
effect: "light",
content: "Measure",
"show-after": 1e3
}, {
default: Me(() => [
o("div", {
class: te(i.showMeasure ? "menu-icon active" : "menu-icon"),
onClick: e[1] || (e[1] = (...h) => s.handleMeasureToggle && s.handleMeasureToggle(...h))
}, e[18] || (e[18] = [
o("span", { class: "iconfont" }, "", -1)
]), 2)
]),
_: 1
}),
O(n, {
placement: "left",
effect: "light",
content: "Point Meteo",
"show-after": 1e3
}, {
default: Me(() => [
o("div", {
class: te(i.showPoint ? "menu-icon active" : "menu-icon"),
onClick: e[2] || (e[2] = (...h) => s.handlePointToggle && s.handlePointToggle(...h))
}, e[19] || (e[19] = [
o("span", { class: "iconfont" }, "", -1)
]), 2)
]),
_: 1
}),
O(n, {
placement: "left",
effect: "light",
content: "Grid",
"show-after": 1e3
}, {
default: Me(() => [
o("div", {
class: te(i.showCoord ? "menu-icon active" : "menu-icon"),
onClick: e[3] || (e[3] = (...h) => s.handleCoordToggle && s.handleCoordToggle(...h))
}, e[20] || (e[20] = [
o("span", { class: "iconfont" }, "", -1)
]), 2)
]),
_: 1
}),
O(n, {
placement: "left",
effect: "light",
content: "3D",
"show-after": 1e3
}, {
default: Me(() => [
o("div", {
class: te(i.show3d ? "menu-icon active" : "menu-icon"),
onClick: e[4] || (e[4] = (...h) => s.handle3DToggle && s.handle3DToggle(...h))
}, e[21] || (e[21] = [
o("span", { class: "iconfont" }, "", -1)
]), 2)
]),
_: 1
})
])
], 4),
s.hasCollectedLayers ? (u(), g("div", {
key: 0,
class: "active-layers",
style: de({ right: i.right + "px", bottom: "100px" })
}, [
o("div", Ct, [
e[22] || (e[22] = o("div", { style: { margin: "2px 5px" } }, "Weather Layers", -1)),
o("div", {
class: "switch flex-center",
style: { "font-size": "28px", "margin-right": "0" },
onClick: e[5] || (e[5] = (...h) => s.toggleAutoActive && s.toggleAutoActive(...h))
}, [
i.autoActive ? (u(), g("i", xt, "")) : (u(), g("i", _t, ""))
])
]),
(u(!0), g(ee, null, ae(i.layers.weather.filter((h) => h.collected), (h) => (u(), g("div", {
key: h.key,
class: te(s.computeLayerClass(h, i.activeWeatherLayersCollected))
}, [
o("div", {
class: "checkbox",
onClick: (p) => s.handleWeatherLayerPick(h)
}, null, 8, Bt),
o("span", {
class: "name",
onClick: (p) => s.handleWeatherLayerPick(h)
}, k(h.name), 9, It),
h.key === "wind" && i.activeWeatherLayersCollected.some((p) => p.key === h.key) ? (u(), g("div", Et, [
o("i", {
class: te(["iconfont sub-layer-icon", i.showWindParticleCollected ? "active" : ""]),
onClick: e[6] || (e[6] = (p) => s.handleToggleWindParticle())
}, "", 2),
o("i", {
class: te(["iconfont sub-layer-icon", i.showWindFeatherCollected ? "active" : ""]),
onClick: e[7] || (e[7] = (p) => s.handleToggleWindFeather())
}, "", 2)
])) : q("", !0),
h.key === "current" && i.activeWeatherLayersCollected.some((p) => p.key === h.key) ? (u(), g("div", kt, [
o("i", {
class: te(["iconfont sub-layer-icon", i.showCurrentParticleCollected ? "active" : ""]),
onClick: e[8] || (e[8] = (p) => s.handleToggleCurrentParticle())
}, "", 2),
o("i", {
class: te(["iconfont sub-layer-icon", i.showCurrentIsobandCollected ? "active" : ""]),
onClick: e[9] || (e[9] = (p) => s.handleToggleCurrentIsoband())
}, "", 2)
])) : q("", !0)
], 2))), 128))
], 4)) : q("", !0),
o("div", {
class: "available-layers flex-center",
style: de({ top: t.top + "px", right: t.layerToggle ? "0px" : "-240px" })
}, [
o("div", {
class: te(["list-box", t.layerToggle ? "right-bar" : ""])
}, [
o("div", Dt, [
e[23] || (e[23] = o("div", null, "Layers", -1)),
o("div", {
class: "iconfont close-btn",
onClick: e[10] || (e[10] = (...h) => s.handleMenuToggle && s.handleMenuToggle(...h))
}, "")
]),
O(d, { style: { flex: "1" } }, {
default: Me(() => [
o("div", Pt, [
o("div", zt, [
e[24] || (e[24] = o("div", null, "Weather Layers", -1)),
o("div", {
class: "switch flex-center",
style: { "margin-right": "0" },
onClick: e[11] || (e[11] = (...h) => s.toggleAutoActive && s.toggleAutoActive(...h))
}, [
i.autoActive ? (u(), g("i", Mt, "")) : (u(), g("i", St, ""))
])
]),
o("div", Tt, [
(u(!0), g(ee, null, ae(i.layers.weather, (h) => (u(), g(ee, {
key: h.key
}, [
h.hide ? q("", !0) : (u(), g("div", {
key: 0,
class: te(s.computeLayerClass(h, i.activeWeatherLayersCollected))
}, [
o("div", Qt, [
o("div", {
class: "checkbox",
onClick: (p) => s.handleWeatherLayerPick(h)
}, null, 8, Ht),
o("span", {
class: "name",
onClick: (p) => s.handleWeatherLayerPick(h)
}, k(h.name), 9, Nt),
h.key === "wind" && i.activeWeatherLayersCollected.some((p) => p.key === h.key) ? (u(), g("div", Ot, [
o("i", {
class: te(["iconfont sub-layer-icon", i.showWindParticleCollected ? "active" : ""]),
onClick: e[12] || (e[12] = (p) => s.handleToggleWindParticle())
}, "", 2),
o("i", {
class: te(["iconfont sub-layer-icon", i.showWindFeatherCollected ? "active" : ""]),
onClick: e[13] || (e[13] = (p) => s.handleToggleWindFeather())
}, "", 2)
])) : q("", !0),
h.key === "current" && i.activeWeatherLayersCollected.some((p) => p.key === h.key) ? (u(), g("div", Ft, [
o("i", {
class: te(["iconfont sub-layer-icon", i.showCurrentParticleCollected ? "active" : ""]),
onClick: e[14] || (e[14] = (p) => s.handleToggleCurrentParticle())
}, "", 2),
o("i", {
class: te(["iconfont sub-layer-icon", i.showCurrentIsobandCollected ? "active" : ""]),
onClick: e[15] || (e[15] = (p) => s.handleToggleCurrentIsoband())
}, "", 2)
])) : q("", !0)
]),
o("div", {
onClick: (p) => s.handleWeatherLayerCollect(h)
}, [
h.collected ? (u(), g("i", jt, "")) : (u(), g("i", Wt, ""))
], 8, Rt)
], 2))
], 64))), 128)),
e[25] || (e[25] = o("div", { class: "tip flex-start" }, [
o("i", {
class: "iconfont bookmark-icon",
style: { "align-self": "flex-start", padding: "5px 5px 0 0" }
}, ""),
o("div", null, "You can add the layers to your favorites. (Max 6)")
], -1))
])
]),
o("div", Gt, [
e[26] || (e[26] = o("div", { class: "layers-title" }, "Other Layers", -1)),
o("div", Ut, [
(u(!0), g(ee, null, ae(i.layers.other, (h) => {
var p;
return u(), g("div", {
key: h.key,
class: te(["layer flex-between", s.computeLayerClass(h, i.activeOtherLayers)]),
onClick: (L) => s.handleOtherLayerPick(h)
}, [
o("div", Kt, [
o("div", Xt, [
(p = s.computeLayerClass(h, i.activeOtherLayers)) != null && p.includes("active") ? (u(), g("i", Jt, "")) : (u(), g("i", qt, ""))
]),
o("span", null, k(h.name), 1)
])
], 10, Yt);
}), 128))
])
]),
o("div", Vt, [
e[27] || (e[27] = o("span", { class: "layers-title" }, "Forecast Model", -1)),
o("div", Zt, [
O(c, {
modelValue: i.source,
"onUpdate:modelValue": e[16] || (e[16] = (h) => i.source = h),
class: "layer-radio flex-col-start-start",
style: { width: "180px", "align-items": "flex-start" }
}, {
default: Me(() => [
(u(!0), g(ee, null, ae(i.sourceList, (h, p) => (u(), gt(l, {
key: `source${h.name}`,
value: h.name
}, {
default: Me(() => {
var L, E, B, y, I, x;
return [
fe(k(h.name) + " ", 1),
p !== 0 ? (u(), g("span", $t, k(h.resolution) + "km " + k(h.length) + "days", 1)) : q("", !0),
p === 0 ? (u(), g("div", ea, "Provides the best forecast")) : (B = (E = (L = h == null ? void 0 : h.update) == null ? void 0 : L.default) == null ? void 0 : E.meta) != null && B.initialisationTime ? (u(), g("div", ta, "Update: " + k(s.computeDateZ((x = (I = (y = h == null ? void 0 : h.update) == null ? void 0 : y.default) == null ? void 0 : I.meta) == null ? void 0 : x.initialisationTime)), 1)) : q("", !0)
];
}),
_: 2
}, 1032, ["value"]))), 128))
]),
_: 1
}, 8, ["modelValue"])
])
])
]),
_: 1
})
], 2)
], 4)
]);
}
const ia = /* @__PURE__ */ Y(wt, [["render", aa]]);
const ra = {
name: "IdmWindBarb",
props: {
map: {
type: Object
},
wind: {
type: Object
},
current: {
type: Object
},
beforeLayer: {
type: String
},
mapProjection: {
type: String
},
showWindFeather: {
type: Boolean,
default: !1
},
showWindParticle: {
type: Boolean,
default: !1
},
toggleParticeVersion: {
type: Number
},
toggleVersion: {
type: Number
}
},
emits: ["particle", "showWindFeather"],
data() {
return {
source: "wind-barb-source",
barbs: [0, 2, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105],
empty: H.featureCollection([]),
right: 10,
bottom: 125,
windBarbLoaded: !1
};
},
watch: {
"wind.version": {
handler() {
var a;
(a = this.wind) != null && a.active && this.showWindFeather ? this.handleRender() : this.handleClear();
},
deep: !0
},
toggleParticeVersion: {
handler() {
this.handleParticle();
}
// immediate: true,
},
showWindFeather: {
handler() {
this.handleToggle();
}
// immediate: true,
}
},
methods: {
handleParticle() {
this.$emit("particle", { particle: this.showWindParticle, key: "wind", weight: 1 });
},
handleRender() {
var a, e, t, r;
if (!this.map)
setTimeout(() => {
this.handleRender();
}, 500);
else if (this.wind) {
const i = (/* @__PURE__ */ new Date()).valueOf();
let s = 0, n = 0, l = this.empty;
if ((a = this.wind) != null && a.active && (l = (e = this.wind) == null ? void 0 : e.data), (t = this.map) != null && t.getSource(this.source))
(r = this.map) == null || r.getSource(this.source).setData(l), n = (/* @__PURE__ */ new Date()).valueOf() - (i + s), console.log("[wind] update elapsed: ", n, ", total: ", s += n);
else {
this.map.addSource(this.source, { type: "geojson", data: l });
for (let c = 0; c < (this.barbs ?? []).length - 1; c++) {
const d = (this.barbs ?? [])[c] || 0, h = (this.barbs ?? [])[c + 1] || 0, p = d < 10 ? `00${d}kts` : d < 100 ? `0${d}kts` : `${d}kts`;
this.map.addLayer(
{
id: p,
type: "symbol",
filter: [
"all",
// @ts-ignore
[">=", "spd", d],
// @ts-ignore
["<", "spd", h]
],
source: this.source,
layout: {
"symbol-placement": "point",
"icon-image": p,
// mapbox sprite
"icon-size": 0.14,
"icon-offset": [0, -20],
"icon-allow-overlap": !0,
"icon-rotation-alignment": "map",
"icon-rotate": {
property: "dir",
stops: [
[0, 0],
[360, 360]
]
}
},
paint: {
"icon-opacity": 1,
"text-color": "#222"
}
},
this.beforeLayer
);
}
this.windBarbLoaded = !0, n = (/* @__PURE__ */ new Date()).valueOf() - (i + s), console.log("[wind] add elapsed: ", n, ", total: ", s += n);
}
}
},
handleToggle() {
if (!this.windBarbLoaded)
this.handleRender();
else
for (const a of this.barbs ?? []) {
const e = a < 10 ? `00${a}kts` : a < 100 ? `0${a}kts` : `${a}kts`;
this.map.getLayer(e) && this.map.setLayoutProperty(e, "visibility", this.showWindFeather ? "visible" : "none");
}
},
handleClear() {
for (const a of this.barbs ?? []) {
const e = a < 10 ? `00${a}kts` : a < 100 ? `0${a}kts` : `${a}kts`;
this.map.getLayer(e) && this.map.removeLayer(e);
}
this.map.getSource(this.source) && this.map.removeSource(this.source), this.windBarbLoaded = !1;
}
}
};
function sa(a, e, t, r, i, s) {
return null;
}
const oa = /* @__PURE__ */ Y(ra, [["render", sa]]);
class tt {
constructor(e) {
se(this, "map");
se(this, "mercator");
se(this, "rampColorLayer");
se(this, "rampColorSource");
se(this, "particleLayer");
se(this, "particleSource");
se(this, "rampColorCanvas");
se(this, "particleCanvas");
se(this, "ratio");
this.map = e, this.mercator = new At(), this.rampColorLayer = "ramp-color-layer", this.rampColorSource = "ramp-color-source", this.particleLayer = "particle-layer", this.particleSource = "particle-source", this.rampColorCanvas = document.createElement("canvas"), this.particleCanvas = document.createElement("canvas"), this.ratio = window.devicePixelRatio;
}
/**
* 转换为[-180, 180]的经度,且包含转换次数
* @param lng
* @param n
*/
convertNLng(e, t = 0) {
return e > 180 ? this.convertNLng(e - 360, t + 1) : e < -180 ? this.convertNLng(e + 360, t + 1) : [e, t];
}
/**
* [4326坐标]
* 返回视窗边界经纬度(从西北方向逆时针返回四个角的经纬度)
* 依次为: NW, NE, SE, SW
* @param map
* @return [[lng, lat], [lng, lat], [lng, lat], [lng, lat]]
*/
getBoundLngLat() {
const e = this.map.getBounds();
return [
[e._sw.lng, e._ne.lat],
[e._ne.lng, e._ne.lat],
[e._ne.lng, e._sw.lat],
[e._sw.lng, e._sw.lat]
];
}
/**
* [视窗像素坐标]
* @see https://github.com/mapbox/sphericalmercator
* 返回视窗边界像素
* 依次为: 左下角(lf = left bottom)、右上角(rt = right top)
* @param [lb.x, lb.y, rt.x, rt.y]
*/
getBoundPixel() {
const e = this.map.getBounds(), t = this.map.getZoom() + 1, r = [e._ne.lng, e._ne.lat], i = [e._sw.lng, e._sw.lat], [s, n] = this.convertNLng(r[0]), [l, c] = this.convertNLng(i[0]), [d, h] = this.mercator.px([s, r[1]], t), [p, L] = this.mercator.px([l, i[1]], t), E = Math.round(this.mercator.size * Math.pow(2, t) * (n + c));
return [p, L, d + E, h];
}
/**
* [视窗边界像素宽度]
*/
getBoundRange() {
const e = this.map.getZoom() + 1, t = this.mercator.size * Math.pow(2, e), r = this.getBoundPixel();
return [r[0] / t, r[2] / t, r[3] / t, r[1] / t];
}
/**
* 获取视窗世界(多世界复本)
* @param pixels
* @param zoom
*/
getWorldCopy(e, t) {
const r = 2 ** t, [i, s, n, l] = e.map((h) => ~~(h / (r * 256))), c = [];
for (let h = l; h <= s; h++)
for (let p = i; p <= n; p++)
c.push([p, h]);
return c.map((h) => {
const p = 2 ** t * 256;
return [h[0] * p, h[1] * p, p];
});
}
resize() {
let e = this.map.getSource(this.rampColorSource);
e.setCoordinates(this.getBoundLngLat()), e = this.map.getSource(this.particleSource), e.setCoordinates(this.getBoundLngLat()), this.rampColorCanvas.width = this.map._canvas.clientWidth, this.rampColorCanvas.height = this.map._canvas.clientHeight, this.particleCanvas.width = this.map._canvas.clientWidth, this.particleCanvas.height = this.map._canvas.clientHeight;
}
toggle(e) {
const t = this.map.getLayoutProperty(this.rampColorLayer, "visibility"), r = e ? "visible" : "none";
t !== r && this.map.setLayoutProperty(this.rampColorLayer, "visibility", r);
}
toggleParticle(e) {
const t = this.map.getLayoutProperty(this.particleLayer, "visibility"), r = e ? "visible" : "none";
t !== r && this.map.setLayoutProperty(this.particleLayer, "visibility", r);
}
}
class je {
/**
* 创建着色器
* @see https://webglfundamentals.org/webgl/lessons/zh_cn/webgl-shaders-and-glsl.html
* @param gl
* @param type [VERTEX_SHADER, FRAGMENT_SHADER]
* @param schema 着色器渲染代码[GLSL]
*/
createShader(e, t, r) {
const i = e.createShader(t);
if (i && (e.shaderSource(i, r), e.compileShader(i), !e.getShaderParameter(i, e.COMPILE_STATUS)))
throw new Error(e.getShaderInfoLog(i) || "error happened while create shader...");
return i;
}
/**
* 创建纹理
* @see https://blog.csdn.net/qq_37987033/article/details/128745577
* @param gl
* @param minFilter
* @param magFilter
* @param wrapFilter
* @param data
* @param width??
* @param height??
*/
createTexture(e, t, r, i, s, n, l) {
const c = e.createTexture();
return e.bindTexture(e.TEXTURE_2D, c), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, t), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, r), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, i), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, i), s instanceof Uint8Array ? e.texImage2D(e.TEXTURE_2D, 0, e.RGBA, n, l, 0, e.RGBA, e.UNSIGNED_BYTE, s) : e.texImage2D(e.TEXTURE_2D, 0, e.RGBA, e.RGBA, e.UNSIGNED_BYTE, s), e.bindTexture(e.TEXTURE_2D, null), c;
}
/**
* 创建数据资源
* @param type [array, element]
* array: ARRAY_BUFFER
* element: ELEMENT_ARRAY_BUFFER
* @param resource 顶点数据
*/
createDataBuffer(e, t, r) {
if (e) {
const i = e.createBuffer();
return t === "array" ? (e.bindBuffer(e.ARRAY_BUFFER, i), r && e.bufferData(e.ARRAY_BUFFER, r, e.STATIC_DRAW)) : t === "element" && (e.bindBuffer(e.ELEMENT_ARRAY_BUFFER, i), r && e.bufferData(e.ELEMENT_ARRAY_BUFFER, r, e.STATIC_DRAW)), i;
}
return null;
}
/**
* 创建程序
* @param gl
* @param vertexSchema
* @param fragmentSchema
*/
createProgram(e, t, r) {
const i = e.createProgram(), s = this.createShader(e, e.VERTEX_SHADER, t), n = this.createShader(e, e.FRAGMENT_SHADER, r);
if (i && s && n && (e.attachShader(i, s), e.attachShader(i, n), e.linkProgram(i), !e.getProgramParameter(i, e.LINK_STATUS)))
throw new Error(e.getProgramInfoLog(i) || "error happened while creating ramp color program");
return i;
}
/**
* 创建程序并提取attrib & uniform参数
* @param gl
* @param vertexSchema
* @param fragmentSchema
*/
createProgramWrapper(e, t, r) {
const i = this.createProgram(e, t, r);
if (i) {
const s = { program: i }, n = e.getProgramParameter(i, e.ACTIVE_ATTRIBUTES);
for (let c = 0; c < n; c++) {
const d = e.getActiveAttrib(i, c);
s[d.name] = e.getAttribLocation(i, d.name);
}
const l = e.getProgramParameter(i, e.ACTIVE_UNIFORMS);
for (let c = 0; c < l; c++) {
const d = e.getActiveUniform(i, c);
s[d.name] = e.getUniformLocation(i, d.name);
}
return s;
}
}
/**
* 初始化渐变色纹理
* @param colors
*/
setup(e, t, r = !1, i, s) {
const n = document.createElement("canvas");
n.width = 256, n.height = 1;
const l = n.getContext("2d");
if (l && e) {
const c = l == null ? void 0 : l.createLinearGradient(0, 0, 256, 0);
return t.forEach(([d, h]) => {
c.addColorStop(d, h);
}), l.fillStyle = c, l.fillRect(0, 0, 256, 1), {
canvas: n,
texture: this.createTexture(
e,
e.LINEAR,
e.LINEAR,
e.CLAMP_TO_EDGE,
r ? new Uint8Array(l.getImageData(0, 0, 256, 1).data) : n,
i,
s
)
};
}
}
setupParticle(e, t = 1e3) {
const r = Math.ceil(Math.sqrt(t)), i = r * r, s = new Uint8Array(i * 4);
for (let h = 0; h < s.length; h++)
s[h] = Math.floor(Math.random() * 256);
const n = this.createTexture(e, e.NEAREST, e.NEAREST, e.CLAMP_TO_EDGE, s, r, r), l = this.createTexture(e, e.NEAREST, e.NEAREST, e.CLAMP_TO_EDGE, s, r, r), c = new Float32Array(i);
for (let h = 0; h < i; h++)
c[h] = h;
const d = this.createDataBuffer(e, "array", c);
return { resolution: r, total: i, texture0: n, texture1: l, indexBuffer: d };
}
bind(e, t, r) {
const i = this.createProgram(e, t, r);
if (i) {
const s = this.createDataBuffer(e, "array", void 0), n = e.getAttribLocation(i, "a_position");
e.enableVertexAttribArray(n), e.vertexAttribPointer(n, 2, e.FLOAT, !1, 0, 0);
const l = new Float32Array([0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1]);
this.createDataBuffer(e, "array", l);
const c = e.getAttribLocation(i, "a_texCoord");
return e.enableVertexAttribArray(c), e.vertexAttribPointer(c, 2, e.FLOAT, !1, 0, 0), { program: i, aPositionBuffer: s };
}
return {};
}
bindParticle(e, t, r, i, s, n) {
const l = this.createProgramWrapper(e, t, r), c = this.createProgramWrapper(e, i, s), d = this.createProgramWrapper(e, i, n), h = this.createDataBuffer(e, "array", new Float32Array([0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1])), p = e.createFramebuffer();
return { particle: l, screen: c, update: d, quadBuffer: h, frameBuffer: p };
}
draw(e, t, r, i, s, n, l) {
var c, d;
if (t && r) {
e.resize(), t == null || t.viewport(0, 0, (c = t == null ? void 0 : t.canvas) == null ? void 0 : c.width, (d = t == null ? void 0 : t.canvas) == null ? void 0 : d.height), t.clearColor(0, 0, 0, 0), t.clear(t.COLOR_BUFFER_BIT | t.DEPTH_BUFFER_BIT);
try {
t.useProgram(r);
const h = {
resolution: t.getUniformLocation(r, "u_resolution"),
image: t.getUniformLocation(r, "u_image"),
color: t.getUniformLocation(r, "u_color"),
scale: t.getUniformLocation(r, "u_scale"),
uvRange: t.getUniformLocation(r, "u_range_u_v"),
sRange: t.getUniformLocation(r, "u_range_s")
};
h.resolution && t.uniform2f(h.resolution, t.canvas.width * e.ratio, t.canvas.height * e.ratio), t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, i), h.image && t.uniform1i(h.image, 0), t.activeTexture(t.TEXTURE1), t.bindTexture(t.TEXTURE_2D, s), h.color && t.uniform1i(h.color, 1), l != null && l.uvRange && (l != null && l.sRange) && (h.uvRange && t.uniform2f(h.uvRange, l.uvRange[0], l.uvRange[1]), h.sRange && t.uniform2f(h.sRange, l.sRange[0], l.sRange[1])), h.scale && t.uniform1f(h.scale, (l == null ? void 0 : l.scale) || 1);
const p = e.getBoundPixel(), L = e.map.getZoom() + 1, E = e.getWorldCopy(p, L);
for (const B of E) {
const y = (B[0] - p[0]) * e.ratio, I = (B[1] - p[3]) * e.ratio, x = B[2] * e.ratio, [f, v, m, b] = [y, x + y, I, x + I], A = new Float32Array([f, m, v, m, f, b, f, b, v, m, v, b]);
t.bindBuffer(t.ARRAY_BUFFER, n), t.bufferData(t.ARRAY_BUFFER, A, t.STATIC_DRAW), t.drawArrays(t.TRIANGLES, 0, 6);
}
} catch (h) {
console.log(`render failed...${h}`);
}
}
}
drawParticle(e, t, r, i, s) {
var n, l;
t && (t == null || t.viewport(0, 0, (n = t == null ? void 0 : t.canvas) == null ? void 0 : n.width, (l = t == null ? void 0 : t.canvas) == null ? void 0 : l.height), t.disable(t.DEPTH_TEST), t.disable(t.STENCIL_TEST), t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, r), t.activeTexture(t.TEXTURE1), t.bindTexture(t.TEXTURE_2D, i.texture0), this.renderScreen(e, t, i, s), this.updateParticles(e, t, i, s));
}
renderScreen(e, t, r, i) {
t.bindFramebuffer(t.FRAMEBUFFER, r.frameBuffer), t.framebufferTexture2D(t.FRAMEBUFFER, t.COLOR_ATTACHMENT0, t.TEXTURE_2D, r.screenTexture, 0), t.viewport(0, 0, t.canvas.width, t.canvas.height), this.renderScreenTexture(t, r.backgroundTexture, r.screen, r.quadBuffer, 0.95), this.renderParticles(e, t, r, i), t.bindFramebuffer(t.FRAMEBUFFER, null), this.renderScreenTexture(t, r.screenTexture, r.screen, r.quadBuffer, 1);
const s = r.backgroundTexture;
r.backgroundTexture = r.screenTexture, r.screenTexture = s;
}
renderScreenTexture(e, t, r, i, s) {
e && (e.useProgram(r.program), e.bindBuffer(e.ARRAY_BUFFER, i), e.enableVertexAttribArray(r.a_pos), e.vertexAttribPointer(r.a_pos, 2, e.FLOAT, !1, 0, 0), e.activeTexture(e.TEXTURE2), e.bindTexture(e.TEXTURE_2D, t), e.uniform1i(r.u_screen, 2), e.uniform1f(r.u_opacity, s), e.drawArrays(e.TRIANGLES, 0, 6));
}
renderParticles(e, t, r, i) {
if (t) {
t.useProgram(r.particle.program), t.bindBuffer(t.ARRAY_BUFFER, r.indexBuffer), t.enableVertexAttribArray(r.particle.a_index), t.vertexAttribPointer(r.particle.a_index, 1, t.FLOAT, !1, 0, 0), t.activeTexture(t.TEXTURE2), t.bindTexture(t.TEXTURE_2D, r.color.texture), t.uniform1i(r.particle.u_factor, 0), t.uniform1i(r.particle.u_particles, 1), t.uniform1i(r.particle.u_color_ramp, 2), t.uniform1f(r.particle.u_particles_resolution, r.resolution * e.ratio), t.uniform1f(r.particle.u_point, e.ratio);
const s = e.getBoundRange();
t.uniform4f(r.particle.u_viewport, s[0], s[1], s[2], s[3]), t.uniform2f(r.particle.u_factor_min, i.uvRange[0], i.uvRange[0]), t.uniform2f(r.particle.u_factor_max, i.uvRange[1], i.uvRange[1]), t.drawArrays(t.POINTS, 0, r.total);
}
}
updateParticles(e, t, r, i) {
var n, l;
if (t) {
t.bindFramebuffer(t.FRAMEBUFFER, r.frameBuffer), t.framebufferTexture2D(t.FRAMEBUFFER, t.COLOR_ATTACHMENT0, t.TEXTURE_2D, r.texture1, 0), t.viewport(0, 0, r.resolution, r.resolution), t.useProgram(r.update.program), t.bindBuffer(t.ARRAY_BUFFER, r.quadBuffer), t.enableVertexAttribArray(r.update.a_pos), t.vertexAttribPointer(r.update.a_pos, 2, t.FLOAT, !1, 0, 0), t.uniform1i(r.update.u_factor, 0), t.uniform1i(r.update.u_particles, 1);
const c = e.getBoundRange();
t.uniform4f(r.update.u_viewport, c[0], c[1], c[2], c[3]), t.uniform1f(r.update.u_rand_seed, Math.random()), t.uniform2f(r.update.u_factor_res, (n = r == null ? void 0 : r.image) == null ? void 0 : n.width, (l = r == null ? void 0 : r.image) == null ? void 0 : l.height), t.uniform2f(r.update.u_factor_min, i.uvRange[0], i.uvRange[0]), t.uniform2f(r.update.u_factor_max, i.uvRange[1], i.uvRange[1]), t.uniform1f(r.update.u_speed_factor, i.speedFactor * e.ratio), t.uniform1f(r.update.u_drop_rate, i.dropRate), t.uniform1f(r.update.u_drop_rate_bump, i.dropRateBump), t.drawArrays(t.TRIANGLES, 0, 6);
}
const s = r.texture0;
r.texture0 = r.texture1, r.texture1 = s;
}
resize(e, t) {
e.resize();
const r = new Uint8Array(t.canvas.width * t.canvas.height * 4).fill(0, 0, t.canvas.width * t.canvas.height * 4), i = this.createTexture(t, t.NEAREST, t.NEAREST, t.CLAMP_TO_EDGE, r, t.canvas.width, t.canvas.height), s = this.createTexture(t, t.NEAREST, t.NEAREST, t.CLAMP_TO_EDGE, r, t.canvas.width, t.canvas.height);
return { screenTexture: i, backgroundTexture: s };
}
async loadImg(e) {
return new Promise((t) => {
const r = new Blob([e], { type: e.type }), i = URL.createObjectURL(r), s = new Image();
s.crossOrigin = "anonymous", s.src = i, s.onload = () => t(s);
});
}
}
class oe {
}
// 顶点渲染
se(oe, "vertexSchema", `
//canvas 坐标系上的坐标 (x, y)
attribute vec2 a_position; //像素坐标
attribute vec2 a_texCoord; //纹理坐标
// canvas 宽高
uniform vec2 u_resolution; //全局变量
varying vec2 v_texCoord; //向fragmentSchema传值
void main() {
// 将屏幕坐标系转化为裁剪坐标(裁剪坐标系) convert the position from pixels to 0.0 to 1.0
vec2 position = (a_position / u_resolution) * 2.0 - 1.0;
// canvas的 Y 轴坐标方向和 设备坐标系的相反
gl_Position = vec4(position * vec2(1, -1), 0.0, 1.0);
v_texCoord = a_texCoord;
}`), // 类如风、流等u v双变量片元渲染
se(oe, "uvFragmentSchema", `
precision mediump float;
uniform sampler2D u_image;
uniform vec2 u_range_u_v;
uniform vec2 u_range_s;
uniform float u_scale;
uniform sampler2D u_color;
varying vec2 v_texCoord;
void main() {
vec4 uv = texture2D(u_image, v_texCoord);
float u = uv.r * (u_range_u_v.y - u_range_u_v.x) + u_range_u_v.x;
float v = uv.g * (u_range_u_v.y - u_range_u_v.x) + u_range_u_v.x;
float s = sqrt(u * u + v * v) * u_scale;
float r = (s - u_range_s.x) / (u_range_s.y - u_range_s.x);
float f = 1.0 - uv.b;
vec4 color = texture2D(u_color, vec2(r, 0.5)) * f;
gl_FragColor = color;
}`), // 类如浪、气压等单变量片元渲染
se(oe, "fragmentSchema", `
precision mediump float;
uniform sampler2D u_image; // 灰度
uniform sampler2D u_color; // 色值映射
varying vec2 v_texCoord;// 坐标
void main() {
vec4 rgba = texture2D(u_image, v_texCoord);
vec4 color = texture2D(u_color, vec2(rgba.r, 0));
gl_FragColor = color;
}`);
class Ie {
}
se(Ie, "vertexSchema", `
precision mediump float;
attribute float a_index; // 索引
uniform sampler2D u_particles; // 粒子纹理
uniform float u_particles_resolution; // Math.ceil(Math.sqrt(numParticles)))
uniform float u_point;
uniform vec4 u_viewport;
varying vec2 v_particle_pos_uv;
void main() {
vec4 color = texture2D(u_particles, vec2(
fract(a_index / u_particles_resolution),
floor(a_index / u_particles_resolution) / u_particles_resolution));
vec2 v_particle_pos = vec2(color.r / 255.0 + color.b, color.g / 255.0 + color.a);
v_particle_pos_uv = vec2(fract(v_particle_pos.x * (u_viewport.y - u_viewport.x) + u_viewport.x), v_particle_pos.y * (u_viewport.w - u_viewport.z) + u_viewport.z);
gl_PointSize = 1.0;
// gl_PointSize = u_point;
gl_Position = vec4(2.0 * v_particle_pos.x - 1.0, 1.0 - 2.0 * v_particle_pos.y, 0, 1);
}`), se(Ie, "fragmentSchema", `
precision mediump float;
uniform sampler2D u_factor;
uniform vec2 u_factor_min;
uniform vec2 u_factor_max;
uniform sampler2D u_color_ramp;
varying vec2 v_particle_pos_uv;
void main() {
vec4 uv = texture2D(u_factor, v_particle_pos_uv);
vec2 velocity = mix(u_factor_min, u_factor_max, uv.rg);
float speed_t = length(velocity) / length(u_factor_max);
// color ramp is