272 lines
5.9 KiB
Vue
272 lines
5.9 KiB
Vue
<script>
|
|
import {
|
|
getCurrentWebviewUrl,
|
|
refreshCurrentWebviewToken,
|
|
} from "./utils/webview-token";
|
|
|
|
let numberFontSupportPromise = null;
|
|
let numberFontSupportState = null;
|
|
|
|
function hasBrowserDom() {
|
|
return typeof window !== "undefined" && typeof document !== "undefined";
|
|
}
|
|
|
|
function toggleNumberFontReadyClass(enabled) {
|
|
if (!hasBrowserDom() || !document.documentElement) {
|
|
return;
|
|
}
|
|
|
|
document.documentElement.classList.toggle(
|
|
"asset-din-font-ready",
|
|
Boolean(enabled),
|
|
);
|
|
}
|
|
|
|
function waitForBodyReady() {
|
|
return new Promise((resolve) => {
|
|
if (!hasBrowserDom() || document.body) {
|
|
resolve();
|
|
return;
|
|
}
|
|
|
|
const finish = () => resolve();
|
|
|
|
if (document.readyState === "loading") {
|
|
document.addEventListener("DOMContentLoaded", finish, {
|
|
once: true,
|
|
});
|
|
return;
|
|
}
|
|
|
|
setTimeout(finish, 0);
|
|
});
|
|
}
|
|
|
|
function createMeasureNode(fontFamily) {
|
|
const node = document.createElement("span");
|
|
node.textContent = "0123456789";
|
|
node.style.position = "absolute";
|
|
node.style.left = "-99999px";
|
|
node.style.top = "-99999px";
|
|
node.style.visibility = "hidden";
|
|
node.style.whiteSpace = "nowrap";
|
|
node.style.fontSize = "32px";
|
|
node.style.fontWeight = "800";
|
|
node.style.fontFamily = fontFamily;
|
|
return node;
|
|
}
|
|
|
|
function verifyDinFontRender() {
|
|
if (!hasBrowserDom() || !document.body) {
|
|
return false;
|
|
}
|
|
|
|
const container = document.createElement("div");
|
|
container.style.position = "absolute";
|
|
container.style.left = "-99999px";
|
|
container.style.top = "-99999px";
|
|
container.style.visibility = "hidden";
|
|
container.style.pointerEvents = "none";
|
|
|
|
const fallbackFamilies = ["monospace", "sans-serif", "serif"];
|
|
const loadedWidths = [];
|
|
const fallbackWidths = [];
|
|
|
|
fallbackFamilies.forEach((family) => {
|
|
const fallbackNode = createMeasureNode(family);
|
|
const loadedNode = createMeasureNode('"DIN-Bold", ' + family);
|
|
|
|
container.appendChild(fallbackNode);
|
|
container.appendChild(loadedNode);
|
|
});
|
|
|
|
document.body.appendChild(container);
|
|
|
|
Array.prototype.forEach.call(container.childNodes, (node, index) => {
|
|
const width = node.getBoundingClientRect().width;
|
|
if (index % 2 === 0) {
|
|
fallbackWidths.push(width);
|
|
return;
|
|
}
|
|
|
|
loadedWidths.push(width);
|
|
});
|
|
|
|
const isFontAvailable = fallbackWidths.some((width, index) => {
|
|
return Math.abs(loadedWidths[index] - width) > 0.1;
|
|
});
|
|
|
|
document.body.removeChild(container);
|
|
|
|
return isFontAvailable;
|
|
}
|
|
|
|
async function ensureNumberFontSupport() {
|
|
if (!hasBrowserDom()) {
|
|
return false;
|
|
}
|
|
|
|
if (!document.fonts || typeof document.fonts.load !== "function") {
|
|
return false;
|
|
}
|
|
|
|
await waitForBodyReady();
|
|
|
|
const loadSucceeded = await Promise.race([
|
|
document.fonts
|
|
.load('800 32px "DIN-Bold"', "0123456789")
|
|
.then((fonts) => Array.isArray(fonts) ? fonts.length > 0 : true)
|
|
.catch(() => false),
|
|
new Promise((resolve) => {
|
|
setTimeout(() => resolve(false), 2500);
|
|
}),
|
|
]);
|
|
|
|
if (
|
|
!loadSucceeded ||
|
|
!document.fonts.check('800 32px "DIN-Bold"', "0123456789")
|
|
) {
|
|
return false;
|
|
}
|
|
|
|
return verifyDinFontRender();
|
|
}
|
|
|
|
export default {
|
|
onLaunch: function () {
|
|
console.log("App Launch");
|
|
this.logCurrentWebviewToken("launch");
|
|
this.syncNumberFontSupport();
|
|
},
|
|
onShow: function () {
|
|
console.log("App Show");
|
|
this.logCurrentWebviewToken("show");
|
|
this.syncNumberFontSupport();
|
|
},
|
|
onHide: function () {
|
|
console.log("App Hide");
|
|
},
|
|
methods: {
|
|
logCurrentWebviewToken(scene) {
|
|
const currentUrl = getCurrentWebviewUrl();
|
|
const token = refreshCurrentWebviewToken(currentUrl);
|
|
|
|
if (token) {
|
|
console.log("[webview-token][" + scene + "]", token);
|
|
return;
|
|
}
|
|
|
|
console.log("[webview-token][" + scene + "] token not found", currentUrl);
|
|
},
|
|
async syncNumberFontSupport() {
|
|
if (!hasBrowserDom()) {
|
|
return;
|
|
}
|
|
|
|
if (numberFontSupportState !== null) {
|
|
toggleNumberFontReadyClass(numberFontSupportState);
|
|
return;
|
|
}
|
|
|
|
if (!numberFontSupportPromise) {
|
|
numberFontSupportPromise = ensureNumberFontSupport()
|
|
.then((result) => {
|
|
numberFontSupportState = Boolean(result);
|
|
return numberFontSupportState;
|
|
})
|
|
.catch(() => {
|
|
numberFontSupportState = false;
|
|
return false;
|
|
});
|
|
}
|
|
|
|
const canUseDinFont = await numberFontSupportPromise;
|
|
toggleNumberFontReadyClass(canUseDinFont);
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
@import "./styles/tokens.scss";
|
|
|
|
@font-face {
|
|
font-family: "DIN-Bold";
|
|
src:
|
|
local("DIN-Bold"),
|
|
local("DIN Bold"),
|
|
local("DIN Alternate Bold"),
|
|
url("/static/fonts/din-bold-2.ttf") format("truetype"),
|
|
url("https://imgs.agrimedia.cn/din-bold-2.ttf") format("truetype");
|
|
font-style: normal;
|
|
font-weight: 800;
|
|
font-display: optional;
|
|
}
|
|
|
|
:root {
|
|
--asset-number-font-family:
|
|
"Helvetica Neue",
|
|
Arial,
|
|
"PingFang SC",
|
|
sans-serif;
|
|
--asset-number-font-family-din:
|
|
"DIN-Bold",
|
|
DIN,
|
|
"DIN Alternate",
|
|
"Helvetica Neue",
|
|
Arial,
|
|
"PingFang SC",
|
|
sans-serif;
|
|
}
|
|
|
|
.asset-din-font-ready {
|
|
--asset-number-font-family: var(--asset-number-font-family-din);
|
|
}
|
|
|
|
.asset-number-font {
|
|
font-family: var(--asset-number-font-family) !important;
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
html,
|
|
body,
|
|
#app {
|
|
min-height: 100%;
|
|
margin: 0;
|
|
background: #191e32;
|
|
}
|
|
|
|
uni-page,
|
|
uni-page-wrapper,
|
|
uni-page-body {
|
|
min-height: 100%;
|
|
background: #191e32;
|
|
}
|
|
|
|
page {
|
|
min-height: 100%;
|
|
background: #191e32;
|
|
color: $asset-text-main;
|
|
font-family: "PingFang SC", "Helvetica Neue", Arial, sans-serif;
|
|
}
|
|
|
|
view,
|
|
text,
|
|
button,
|
|
input,
|
|
textarea,
|
|
scroll-view {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.asset-theme {
|
|
--asset-accent: #4cc9ff;
|
|
--asset-accent-strong: #5a71ff;
|
|
--asset-success: #5ad7a1;
|
|
--asset-danger: #ff7285;
|
|
--asset-text-main: #ffffff;
|
|
--asset-text-muted: rgba(255, 255, 255, 0.78);
|
|
--asset-text-dark: #112446;
|
|
}
|
|
</style>
|