提交 f03c3e07 编写于 作者: fxy060608's avatar fxy060608

feat: add loadFontFace

上级 0fb61a2e
...@@ -45,6 +45,8 @@ export * from './protocols/location/getLocation' ...@@ -45,6 +45,8 @@ export * from './protocols/location/getLocation'
export * from './protocols/route/route' export * from './protocols/route/route'
export * from './protocols/ui/loadFontFace'
export * from './protocols/ui/pageScrollTo'
export * from './protocols/ui/navigationBar' export * from './protocols/ui/navigationBar'
export * from './protocols/ui/popup' export * from './protocols/ui/popup'
export * from './protocols/ui/tabBar' export * from './protocols/ui/tabBar'
......
import { hasOwn } from '@vue/shared'
export const API_PAGE_SCROLL_TO = 'pageScrollTo' export const API_PAGE_SCROLL_TO = 'pageScrollTo'
export type API_TYPE_PAGE_SCROLL_TO = typeof uni.pageScrollTo export type API_TYPE_PAGE_SCROLL_TO = typeof uni.pageScrollTo
export const PageScrollToProtocol: ApiProtocol<API_TYPE_PAGE_SCROLL_TO> = { export const PageScrollToProtocol: ApiProtocol<API_TYPE_PAGE_SCROLL_TO> = {
...@@ -11,20 +9,11 @@ export const PageScrollToProtocol: ApiProtocol<API_TYPE_PAGE_SCROLL_TO> = { ...@@ -11,20 +9,11 @@ export const PageScrollToProtocol: ApiProtocol<API_TYPE_PAGE_SCROLL_TO> = {
type: Number, type: Number,
}, },
} }
const DEFAULT_DURATION = 400 const DEFAULT_DURATION = 300
export const PageScrollToOptions: ApiOptions<API_TYPE_PAGE_SCROLL_TO> = { export const PageScrollToOptions: ApiOptions<API_TYPE_PAGE_SCROLL_TO> = {
formatArgs: { formatArgs: {
duration(value, params) { duration(value, params) {
if (!hasOwn(params, 'duration')) { params.duration = Math.max(0, parseInt(value + '') || DEFAULT_DURATION)
return (params.duration = DEFAULT_DURATION)
}
value = parseInt(value + '')
if (isNaN(value)) {
value = DEFAULT_DURATION
} else {
value = Math.max(0, value)
}
params.duration = value
}, },
}, },
} }
...@@ -35,7 +35,6 @@ const props = { ...@@ -35,7 +35,6 @@ const props = {
type ImageProps = ExtractPropTypes<typeof props> type ImageProps = ExtractPropTypes<typeof props>
type ImageState = ReturnType<typeof useImageState> type ImageState = ReturnType<typeof useImageState>
type FixSize = ReturnType<typeof useImageSize>['fixSize'] type FixSize = ReturnType<typeof useImageSize>['fixSize']
type ResetSize = ReturnType<typeof useImageSize>['resetSize']
const FIX_MODES = { const FIX_MODES = {
widthFix: ['width', 'height'], widthFix: ['width', 'height'],
...@@ -64,11 +63,10 @@ export default /*#__PURE__*/ defineComponent({ ...@@ -64,11 +63,10 @@ export default /*#__PURE__*/ defineComponent({
const rootRef = ref<HTMLElement | null>(null) const rootRef = ref<HTMLElement | null>(null)
const state = useImageState(rootRef, props) const state = useImageState(rootRef, props)
const trigger = useCustomEvent(rootRef, emit) const trigger = useCustomEvent(rootRef, emit)
const { fixSize, resetSize } = useImageSize(rootRef, props, state) const { fixSize } = useImageSize(rootRef, props, state)
useImageLoader(state, { useImageLoader(state, {
trigger, trigger,
fixSize, fixSize,
resetSize,
}) })
return () => { return () => {
const { mode } = props const { mode } = props
...@@ -127,20 +125,21 @@ function useImageLoader( ...@@ -127,20 +125,21 @@ function useImageLoader(
{ {
trigger, trigger,
fixSize, fixSize,
resetSize,
}: { }: {
fixSize: FixSize fixSize: FixSize
resetSize: ResetSize
trigger: CustomEventTrigger trigger: CustomEventTrigger
} }
) { ) {
let img: HTMLImageElement | null let img: HTMLImageElement | null
const setState = (width = 0, height = 0, imgSrc = '') => {
state.origWidth = width
state.origHeight = height
state.imgSrc = imgSrc
}
const loadImage = (src: string) => { const loadImage = (src: string) => {
if (!src) { if (!src) {
resetImage() resetImage()
state.origWidth = 0 setState()
state.origHeight = 0
state.imgSrc = ''
// 与微信小程序保持一致,保留之前样式 // 与微信小程序保持一致,保留之前样式
// resetSize() // resetSize()
return return
...@@ -150,9 +149,7 @@ function useImageLoader( ...@@ -150,9 +149,7 @@ function useImageLoader(
} }
img.onload = (evt) => { img.onload = (evt) => {
const { width, height } = img! const { width, height } = img!
state.origWidth = width setState(width, height, src)
state.origHeight = height
state.imgSrc = src
fixSize() fixSize()
resetImage() resetImage()
trigger('load', evt, { trigger('load', evt, {
...@@ -161,13 +158,10 @@ function useImageLoader( ...@@ -161,13 +158,10 @@ function useImageLoader(
}) })
} }
img.onerror = (evt) => { img.onerror = (evt) => {
const { src } = state setState()
state.origWidth = 0
state.origHeight = 0
state.imgSrc = ''
resetImage() resetImage()
trigger('error', evt as Event, { trigger('error', evt as Event, {
errMsg: `GET ${src} 404 (Not Found)`, errMsg: `GET ${state.src} 404 (Not Found)`,
}) })
} }
img.src = src img.src = src
......
...@@ -10,6 +10,7 @@ export function $normalizeNativeEvent( ...@@ -10,6 +10,7 @@ export function $normalizeNativeEvent(
this: ComponentPublicInstance, this: ComponentPublicInstance,
evt: Event evt: Event
) { ) {
// TODO 目前内置组件,也会进入以下处理逻辑,是否有影响?
const { currentTarget } = evt const { currentTarget } = evt
if (!(evt instanceof Event) || !(currentTarget instanceof HTMLElement)) { if (!(evt instanceof Event) || !(currentTarget instanceof HTMLElement)) {
return evt return evt
...@@ -24,6 +25,10 @@ export function $normalizeNativeEvent( ...@@ -24,6 +25,10 @@ export function $normalizeNativeEvent(
normalizeClickEvent((res as unknown) as WechatMiniprogram.Touch, evt) normalizeClickEvent((res as unknown) as WechatMiniprogram.Touch, evt)
} else if (__PLATFORM__ === 'h5' && isMouseEvent(evt)) { } else if (__PLATFORM__ === 'h5' && isMouseEvent(evt)) {
normalizeMouseEvent((res as unknown) as WechatMiniprogram.Touch, evt) normalizeMouseEvent((res as unknown) as WechatMiniprogram.Touch, evt)
} else if (evt instanceof TouchEvent) {
const { top } = getWindowOffset()
;(res as any).touches = normalizeTouchEvent(evt.touches, top)
;(res as any).changedTouches = normalizeTouchEvent(evt.changedTouches, top)
} }
return res return res
...@@ -85,3 +90,19 @@ function createTouchEvent(evt: MouseEvent) { ...@@ -85,3 +90,19 @@ function createTouchEvent(evt: MouseEvent) {
pageY: evt.pageY, pageY: evt.pageY,
} }
} }
function normalizeTouchEvent(touches: TouchList, top: number) {
const res = []
for (let i = 0; i < touches.length; i++) {
const { identifier, pageX, pageY, clientX, clientY, force } = touches[i]
res.push({
identifier,
pageX,
pageY: pageY - top,
clientX: clientX,
clientY: clientY - top,
force: force || 0,
})
}
return res
}
import {isFunction, extend, isPlainObject, isString, invokeArrayFns as invokeArrayFns$1, hyphenate, isArray, hasOwn as hasOwn$1, isObject as isObject$1, capitalize, toRawType, makeMap as makeMap$1, isPromise} from "@vue/shared"; import {isFunction, extend, isPlainObject, isString, invokeArrayFns as invokeArrayFns$1, hyphenate, isArray, hasOwn as hasOwn$1, isObject as isObject$1, capitalize, toRawType, makeMap as makeMap$1, isPromise} from "@vue/shared";
import {injectHook, createVNode, inject, provide, reactive, computed, nextTick, getCurrentInstance, onBeforeMount, onMounted, onBeforeActivate, onBeforeDeactivate, openBlock, createBlock, mergeProps, toDisplayString, ref, defineComponent, resolveComponent, toHandlers, renderSlot, watch, onActivated, onBeforeUnmount, withModifiers, withDirectives, vShow, vModelDynamic, createCommentVNode, createTextVNode, Fragment, renderList, vModelText, watchEffect, withCtx, KeepAlive, resolveDynamicComponent} from "vue"; import {injectHook, createVNode, inject, provide, reactive, computed, nextTick, getCurrentInstance, onBeforeMount, onMounted, onBeforeActivate, onBeforeDeactivate, openBlock, createBlock, mergeProps, toDisplayString, ref, defineComponent, resolveComponent, toHandlers, renderSlot, watch, onActivated, onBeforeUnmount, withModifiers, withDirectives, vShow, vModelDynamic, createCommentVNode, createTextVNode, Fragment, renderList, vModelText, watchEffect, withCtx, KeepAlive, resolveDynamicComponent} from "vue";
import {once, passive, normalizeTarget, invokeArrayFns, NAVBAR_HEIGHT, parseQuery, decodedQuery, plusReady, debounce, PRIMARY_COLOR as PRIMARY_COLOR$1, removeLeadingSlash, getLen, updateElementStyle} from "@dcloudio/uni-shared"; import {once, passive, normalizeTarget, invokeArrayFns, NAVBAR_HEIGHT, parseQuery, decodedQuery, plusReady, debounce, PRIMARY_COLOR as PRIMARY_COLOR$1, removeLeadingSlash, getLen, updateElementStyle, addFont} from "@dcloudio/uni-shared";
import {useRoute, createRouter, createWebHistory, createWebHashHistory, isNavigationFailure, RouterView} from "vue-router"; import {useRoute, createRouter, createWebHistory, createWebHashHistory, isNavigationFailure, RouterView} from "vue-router";
function applyOptions(options, instance2, publicThis) { function applyOptions(options, instance2, publicThis) {
Object.keys(options).forEach((name) => { Object.keys(options).forEach((name) => {
...@@ -633,6 +633,10 @@ function $normalizeNativeEvent(evt) { ...@@ -633,6 +633,10 @@ function $normalizeNativeEvent(evt) {
normalizeClickEvent(res, evt); normalizeClickEvent(res, evt);
} else if (isMouseEvent(evt)) { } else if (isMouseEvent(evt)) {
normalizeMouseEvent(res, evt); normalizeMouseEvent(res, evt);
} else if (evt instanceof TouchEvent) {
const {top} = getWindowOffset();
res.touches = normalizeTouchEvent(evt.touches, top);
res.changedTouches = normalizeTouchEvent(evt.changedTouches, top);
} }
return res; return res;
} }
...@@ -682,6 +686,21 @@ function createTouchEvent(evt) { ...@@ -682,6 +686,21 @@ function createTouchEvent(evt) {
pageY: evt.pageY pageY: evt.pageY
}; };
} }
function normalizeTouchEvent(touches, top) {
const res = [];
for (let i2 = 0; i2 < touches.length; i2++) {
const {identifier, pageX, pageY, clientX, clientY, force} = touches[i2];
res.push({
identifier,
pageX,
pageY: pageY - top,
clientX,
clientY: clientY - top,
force: force || 0
});
}
return res;
}
var instance = /* @__PURE__ */ Object.freeze({ var instance = /* @__PURE__ */ Object.freeze({
__proto__: null, __proto__: null,
[Symbol.toStringTag]: "Module", [Symbol.toStringTag]: "Module",
...@@ -4925,6 +4944,18 @@ function createNormalizeUrl(type) { ...@@ -4925,6 +4944,18 @@ function createNormalizeUrl(type) {
} }
}; };
} }
const API_LOAD_FONT_FACE = "loadFontFace";
const LoadFontFaceProtocol = {
family: {
type: String,
required: true
},
source: {
type: String,
required: true
},
desc: Object
};
const FRONT_COLORS = ["#ffffff", "#000000"]; const FRONT_COLORS = ["#ffffff", "#000000"];
const API_SET_NAVIGATION_BAR_COLOR = "setNavigationBarColor"; const API_SET_NAVIGATION_BAR_COLOR = "setNavigationBarColor";
const SetNavigationBarColorOptions = { const SetNavigationBarColorOptions = {
...@@ -5861,13 +5892,11 @@ var index$3 = /* @__PURE__ */ defineComponent({ ...@@ -5861,13 +5892,11 @@ var index$3 = /* @__PURE__ */ defineComponent({
const state = useImageState(rootRef, props2); const state = useImageState(rootRef, props2);
const trigger = useCustomEvent(rootRef, emit); const trigger = useCustomEvent(rootRef, emit);
const { const {
fixSize, fixSize
resetSize
} = useImageSize(rootRef, props2, state); } = useImageSize(rootRef, props2, state);
useImageLoader(state, { useImageLoader(state, {
trigger, trigger,
fixSize, fixSize
resetSize
}); });
return () => { return () => {
const { const {
...@@ -5928,16 +5957,18 @@ function useImageState(rootRef, props2) { ...@@ -5928,16 +5957,18 @@ function useImageState(rootRef, props2) {
} }
function useImageLoader(state, { function useImageLoader(state, {
trigger, trigger,
fixSize, fixSize
resetSize
}) { }) {
let img; let img;
const setState = (width = 0, height = 0, imgSrc = "") => {
state.origWidth = width;
state.origHeight = height;
state.imgSrc = imgSrc;
};
const loadImage = (src) => { const loadImage = (src) => {
if (!src) { if (!src) {
resetImage(); resetImage();
state.origWidth = 0; setState();
state.origHeight = 0;
state.imgSrc = "";
return; return;
} }
if (!img) { if (!img) {
...@@ -5948,9 +5979,7 @@ function useImageLoader(state, { ...@@ -5948,9 +5979,7 @@ function useImageLoader(state, {
width, width,
height height
} = img; } = img;
state.origWidth = width; setState(width, height, src);
state.origHeight = height;
state.imgSrc = src;
fixSize(); fixSize();
resetImage(); resetImage();
trigger("load", evt, { trigger("load", evt, {
...@@ -5959,15 +5988,10 @@ function useImageLoader(state, { ...@@ -5959,15 +5988,10 @@ function useImageLoader(state, {
}); });
}; };
img.onerror = (evt) => { img.onerror = (evt) => {
const { setState();
src: src2
} = state;
state.origWidth = 0;
state.origHeight = 0;
state.imgSrc = "";
resetImage(); resetImage();
trigger("error", evt, { trigger("error", evt, {
errMsg: `GET ${src2} 404 (Not Found)` errMsg: `GET ${state.src} 404 (Not Found)`
}); });
}; };
img.src = src; img.src = src;
...@@ -12246,6 +12270,13 @@ function getTabBarPageId(url) { ...@@ -12246,6 +12270,13 @@ function getTabBarPageId(url) {
const switchTab = defineAsyncApi(API_SWITCH_TAB, ({url}, {resolve, reject}) => { const switchTab = defineAsyncApi(API_SWITCH_TAB, ({url}, {resolve, reject}) => {
return removeNonTabBarPages(), navigate(API_SWITCH_TAB, url, getTabBarPageId(url)).then(resolve).catch(reject); return removeNonTabBarPages(), navigate(API_SWITCH_TAB, url, getTabBarPageId(url)).then(resolve).catch(reject);
}, SwitchTabProtocol, SwitchTabOptions); }, SwitchTabProtocol, SwitchTabOptions);
const loadFontFace = defineAsyncApi(API_LOAD_FONT_FACE, ({family, source, desc}, {resolve, reject}) => {
addFont(family, source, desc).then(() => {
resolve();
}).catch((err) => {
reject(`loadFontFace:fail ${err}`);
});
}, LoadFontFaceProtocol);
function setNavigationBar(pageMeta, type, args, resolve, reject) { function setNavigationBar(pageMeta, type, args, resolve, reject) {
if (!pageMeta) { if (!pageMeta) {
return reject("page not found"); return reject("page not found");
...@@ -12474,6 +12505,7 @@ var api = /* @__PURE__ */ Object.freeze({ ...@@ -12474,6 +12505,7 @@ var api = /* @__PURE__ */ Object.freeze({
redirectTo, redirectTo,
reLaunch, reLaunch,
switchTab, switchTab,
loadFontFace,
setNavigationBarColor, setNavigationBarColor,
showNavigationBarLoading, showNavigationBarLoading,
hideNavigationBarLoading, hideNavigationBarLoading,
...@@ -13523,4 +13555,4 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { ...@@ -13523,4 +13555,4 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
]); ]);
} }
_sfc_main.render = _sfc_render; _sfc_main.render = _sfc_render;
export {_sfc_main$1 as AsyncErrorComponent, _sfc_main as AsyncLoadingComponent, _sfc_main$l as Audio, index$5 as Button, _sfc_main$k as Canvas, _sfc_main$j as Checkbox, _sfc_main$i as CheckboxGroup, _sfc_main$h as Editor, index$6 as Form, index$4 as Icon, index$3 as Image, _sfc_main$g as Input, _sfc_main$f as Label, LayoutComponent, _sfc_main$e as MovableView, _sfc_main$d as Navigator, index as PageComponent, _sfc_main$c as Progress, _sfc_main$b as Radio, _sfc_main$a as RadioGroup, ResizeSensor, _sfc_main$9 as RichText, _sfc_main$8 as ScrollView, _sfc_main$7 as Slider, _sfc_main$6 as SwiperItem, _sfc_main$5 as Switch, index$2 as Text, _sfc_main$4 as Textarea, UniServiceJSBridge$1 as UniServiceJSBridge, UniViewJSBridge$1 as UniViewJSBridge, _sfc_main$3 as Video, index$1 as View, addInterceptor, arrayBufferToBase64, base64ToArrayBuffer, canIUse, chooseFile, chooseImage, chooseVideo, clearStorage, clearStorageSync, closeSocket, connectSocket, createInnerAudioContext, createIntersectionObserver, createSelectorQuery, createVideoContext, cssBackdropFilter, cssConstant, cssEnv, cssVar, downloadFile, getApp$1 as getApp, getCurrentPages$1 as getCurrentPages, getFileInfo, getImageInfo, getLocation, getNetworkType, getStorage, getStorageInfo, getStorageInfoSync, getStorageSync, getSystemInfo, getSystemInfoSync, getVideoInfo, hideKeyboard, hideLoading, hideNavigationBarLoading, hideTabBar, hideTabBarRedDot, hideToast, makePhoneCall, navigateBack, navigateTo, offAccelerometerChange, offCompassChange, offNetworkStatusChange, onAccelerometerChange, onCompassChange, onNetworkStatusChange, onSocketClose, onSocketError, onSocketMessage, onSocketOpen, onTabBarMidButtonTap, openDocument, index$7 as plugin, promiseInterceptor, reLaunch, redirectTo, removeInterceptor, removeStorage, removeStorageSync, removeTabBarBadge, request, sendSocketMessage, setNavigationBarColor, setNavigationBarTitle, setStorage, setStorageSync, setTabBarBadge, setTabBarItem, setTabBarStyle, setupApp, setupPage, showActionSheet, showLoading, showModal, showNavigationBarLoading, showTabBar, showTabBarRedDot, showToast, startAccelerometer, startCompass, stopAccelerometer, stopCompass, switchTab, uni$1 as uni, uploadFile, upx2px, useCustomEvent, usePageRoute, useSubscribe, vibrateLong, vibrateShort}; export {_sfc_main$1 as AsyncErrorComponent, _sfc_main as AsyncLoadingComponent, _sfc_main$l as Audio, index$5 as Button, _sfc_main$k as Canvas, _sfc_main$j as Checkbox, _sfc_main$i as CheckboxGroup, _sfc_main$h as Editor, index$6 as Form, index$4 as Icon, index$3 as Image, _sfc_main$g as Input, _sfc_main$f as Label, LayoutComponent, _sfc_main$e as MovableView, _sfc_main$d as Navigator, index as PageComponent, _sfc_main$c as Progress, _sfc_main$b as Radio, _sfc_main$a as RadioGroup, ResizeSensor, _sfc_main$9 as RichText, _sfc_main$8 as ScrollView, _sfc_main$7 as Slider, _sfc_main$6 as SwiperItem, _sfc_main$5 as Switch, index$2 as Text, _sfc_main$4 as Textarea, UniServiceJSBridge$1 as UniServiceJSBridge, UniViewJSBridge$1 as UniViewJSBridge, _sfc_main$3 as Video, index$1 as View, addInterceptor, arrayBufferToBase64, base64ToArrayBuffer, canIUse, chooseFile, chooseImage, chooseVideo, clearStorage, clearStorageSync, closeSocket, connectSocket, createInnerAudioContext, createIntersectionObserver, createSelectorQuery, createVideoContext, cssBackdropFilter, cssConstant, cssEnv, cssVar, downloadFile, getApp$1 as getApp, getCurrentPages$1 as getCurrentPages, getFileInfo, getImageInfo, getLocation, getNetworkType, getStorage, getStorageInfo, getStorageInfoSync, getStorageSync, getSystemInfo, getSystemInfoSync, getVideoInfo, hideKeyboard, hideLoading, hideNavigationBarLoading, hideTabBar, hideTabBarRedDot, hideToast, loadFontFace, makePhoneCall, navigateBack, navigateTo, offAccelerometerChange, offCompassChange, offNetworkStatusChange, onAccelerometerChange, onCompassChange, onNetworkStatusChange, onSocketClose, onSocketError, onSocketMessage, onSocketOpen, onTabBarMidButtonTap, openDocument, index$7 as plugin, promiseInterceptor, reLaunch, redirectTo, removeInterceptor, removeStorage, removeStorageSync, removeTabBarBadge, request, sendSocketMessage, setNavigationBarColor, setNavigationBarTitle, setStorage, setStorageSync, setTabBarBadge, setTabBarItem, setTabBarStyle, setupApp, setupPage, showActionSheet, showLoading, showModal, showNavigationBarLoading, showTabBar, showTabBarRedDot, showToast, startAccelerometer, startCompass, stopAccelerometer, stopCompass, switchTab, uni$1 as uni, uploadFile, upx2px, useCustomEvent, usePageRoute, useSubscribe, vibrateLong, vibrateShort};
...@@ -36,6 +36,7 @@ export * from './route/redirectTo' ...@@ -36,6 +36,7 @@ export * from './route/redirectTo'
export * from './route/reLaunch' export * from './route/reLaunch'
export * from './route/switchTab' export * from './route/switchTab'
export * from './ui/loadFontFace'
export * from './ui/navigationBar' export * from './ui/navigationBar'
export * from './ui/popup' export * from './ui/popup'
export * from './ui/tabBar' export * from './ui/tabBar'
......
import {
API_LOAD_FONT_FACE,
API_TYPE_LOAD_FONT_FACE,
defineAsyncApi,
LoadFontFaceProtocol,
} from '@dcloudio/uni-api'
import { addFont } from '@dcloudio/uni-shared'
export const loadFontFace = defineAsyncApi<API_TYPE_LOAD_FONT_FACE>(
API_LOAD_FONT_FACE,
({ family, source, desc }, { resolve, reject }) => {
addFont(family, source, desc)
.then(() => {
resolve()
})
.catch((err) => {
reject(`loadFontFace:fail ${err}`)
})
},
LoadFontFaceProtocol
)
...@@ -19,6 +19,31 @@ function normalizeTarget(el) { ...@@ -19,6 +19,31 @@ function normalizeTarget(el) {
offsetTop, offsetTop,
offsetLeft, offsetLeft,
}; };
}
function addFont(family, source, desc) {
const fonts = document.fonts;
if (fonts) {
const fontFace = new FontFace(family, source, desc);
return fontFace.load().then(() => {
fonts.add(fontFace);
});
}
return new Promise((resolve) => {
const style = document.createElement('style');
const values = [];
if (desc) {
const { style, weight, stretch, unicodeRange, variant, featureSettings, } = desc;
style && values.push(`font-style:${style}`);
weight && values.push(`font-weight:${weight}`);
stretch && values.push(`font-stretch:${stretch}`);
unicodeRange && values.push(`unicode-range:${unicodeRange}`);
variant && values.push(`font-variant:${variant}`);
featureSettings && values.push(`font-feature-settings:${featureSettings}`);
}
style.innerText = `@font-face{font-family:"${family}";src:${source};${values.join(';')}}`;
document.head.appendChild(style);
resolve();
});
} }
function plusReady(callback) { function plusReady(callback) {
...@@ -247,6 +272,7 @@ exports.PRIMARY_COLOR = PRIMARY_COLOR; ...@@ -247,6 +272,7 @@ exports.PRIMARY_COLOR = PRIMARY_COLOR;
exports.RESPONSIVE_MIN_WIDTH = RESPONSIVE_MIN_WIDTH; exports.RESPONSIVE_MIN_WIDTH = RESPONSIVE_MIN_WIDTH;
exports.TABBAR_HEIGHT = TABBAR_HEIGHT; exports.TABBAR_HEIGHT = TABBAR_HEIGHT;
exports.TAGS = TAGS; exports.TAGS = TAGS;
exports.addFont = addFont;
exports.debounce = debounce; exports.debounce = debounce;
exports.decode = decode; exports.decode = decode;
exports.decodedQuery = decodedQuery; exports.decodedQuery = decodedQuery;
......
import { FontFaceDescriptors } from 'css-font-loading-module';
export declare function addFont(family: string, source: string, desc?: FontFaceDescriptors): Promise<void>;
export declare const BUILT_IN_TAGS: string[]; export declare const BUILT_IN_TAGS: string[];
......
...@@ -15,6 +15,31 @@ function normalizeTarget(el) { ...@@ -15,6 +15,31 @@ function normalizeTarget(el) {
offsetTop, offsetTop,
offsetLeft, offsetLeft,
}; };
}
function addFont(family, source, desc) {
const fonts = document.fonts;
if (fonts) {
const fontFace = new FontFace(family, source, desc);
return fontFace.load().then(() => {
fonts.add(fontFace);
});
}
return new Promise((resolve) => {
const style = document.createElement('style');
const values = [];
if (desc) {
const { style, weight, stretch, unicodeRange, variant, featureSettings, } = desc;
style && values.push(`font-style:${style}`);
weight && values.push(`font-weight:${weight}`);
stretch && values.push(`font-stretch:${stretch}`);
unicodeRange && values.push(`unicode-range:${unicodeRange}`);
variant && values.push(`font-variant:${variant}`);
featureSettings && values.push(`font-feature-settings:${featureSettings}`);
}
style.innerText = `@font-face{font-family:"${family}";src:${source};${values.join(';')}}`;
document.head.appendChild(style);
resolve();
});
} }
function plusReady(callback) { function plusReady(callback) {
...@@ -233,4 +258,4 @@ const RESPONSIVE_MIN_WIDTH = 768; ...@@ -233,4 +258,4 @@ const RESPONSIVE_MIN_WIDTH = 768;
const COMPONENT_NAME_PREFIX = 'VUni'; const COMPONENT_NAME_PREFIX = 'VUni';
const PRIMARY_COLOR = '#007aff'; const PRIMARY_COLOR = '#007aff';
export { BUILT_IN_TAGS, COMPONENT_NAME_PREFIX, COMPONENT_PREFIX, COMPONENT_SELECTOR_PREFIX, NAVBAR_HEIGHT, PLUS_RE, PRIMARY_COLOR, RESPONSIVE_MIN_WIDTH, TABBAR_HEIGHT, TAGS, debounce, decode, decodedQuery, getLen, invokeArrayFns, isBuiltInComponent, isCustomElement, isNativeTag, normalizeDataset, normalizeTarget, once, parseQuery, passive, plusReady, removeLeadingSlash, stringifyQuery, updateElementStyle }; export { BUILT_IN_TAGS, COMPONENT_NAME_PREFIX, COMPONENT_PREFIX, COMPONENT_SELECTOR_PREFIX, NAVBAR_HEIGHT, PLUS_RE, PRIMARY_COLOR, RESPONSIVE_MIN_WIDTH, TABBAR_HEIGHT, TAGS, addFont, debounce, decode, decodedQuery, getLen, invokeArrayFns, isBuiltInComponent, isCustomElement, isNativeTag, normalizeDataset, normalizeTarget, once, parseQuery, passive, plusReady, removeLeadingSlash, stringifyQuery, updateElementStyle };
import { FontFaceDescriptors } from 'css-font-loading-module'
export function passive(passive: boolean) { export function passive(passive: boolean) {
return { passive } return { passive }
} }
...@@ -16,3 +18,42 @@ export function normalizeTarget(el: HTMLElement) { ...@@ -16,3 +18,42 @@ export function normalizeTarget(el: HTMLElement) {
offsetLeft, offsetLeft,
} }
} }
export function addFont(
family: string,
source: string,
desc?: FontFaceDescriptors
): Promise<void> {
const fonts = document.fonts
if (fonts) {
const fontFace = new FontFace(family, source, desc)
return fontFace.load().then(() => {
fonts.add(fontFace)
})
}
return new Promise((resolve) => {
const style = document.createElement('style')
const values = []
if (desc) {
const {
style,
weight,
stretch,
unicodeRange,
variant,
featureSettings,
} = desc as FontFaceDescriptors
style && values.push(`font-style:${style}`)
weight && values.push(`font-weight:${weight}`)
stretch && values.push(`font-stretch:${stretch}`)
unicodeRange && values.push(`unicode-range:${unicodeRange}`)
variant && values.push(`font-variant:${variant}`)
featureSettings && values.push(`font-feature-settings:${featureSettings}`)
}
style.innerText = `@font-face{font-family:"${family}";src:${source};${values.join(
';'
)}}`
document.head.appendChild(style)
resolve()
})
}
...@@ -22,7 +22,8 @@ ...@@ -22,7 +22,8 @@
"node", "node",
"@dcloudio/types", "@dcloudio/types",
"vue", "vue",
"miniprogram-api-typings" "miniprogram-api-typings",
"css-font-loading-module"
], ],
"rootDir": ".", "rootDir": ".",
"paths": { "paths": {
......
...@@ -767,6 +767,11 @@ ...@@ -767,6 +767,11 @@
dependencies: dependencies:
"@babel/types" "^7.3.0" "@babel/types" "^7.3.0"
"@types/css-font-loading-module@^0.0.4":
version "0.0.4"
resolved "https://registry.yarnpkg.com/@types/css-font-loading-module/-/css-font-loading-module-0.0.4.tgz#94a835e27d1af444c65cba88523533c174463d64"
integrity sha512-ENdXf7MW4m9HeDojB2Ukbi7lYMIuQNBHVf98dbzaiG4EEJREBd6oleVAjrLRCrp7dm6CK1mmdmU9tcgF61acbw==
"@types/debug@^4.1.5": "@types/debug@^4.1.5":
version "4.1.5" version "4.1.5"
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd" resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册