mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-06-08 16:27:58 +08:00
feat: render 包单独构建 & fix: 画布高清问题
This commit is contained in:
parent
e4a6a136ed
commit
226b841124
@ -12,15 +12,15 @@
|
|||||||
"declare": "tsx script/declare.ts",
|
"declare": "tsx script/declare.ts",
|
||||||
"type": "vue-tsc --noEmit",
|
"type": "vue-tsc --noEmit",
|
||||||
"lines": "tsx script/lines.ts packages packages-user",
|
"lines": "tsx script/lines.ts packages packages-user",
|
||||||
"build:packages": "vue-tsx --noEmit && tsx script/build-packages.ts",
|
"build:packages": "vue-tsc --noEmit && tsx script/build-packages.ts",
|
||||||
"build:game": "vue-tsx --noEmit && tsx script/build-game.ts",
|
"build:game": "vue-tsc --noEmit && tsx script/build-game.ts",
|
||||||
|
"build:lib": "vue-tsc --noEmit && tsx script/build-lib.ts",
|
||||||
"docs:dev": "concurrently -k -n SIDEBAR,VITEPRESS -c blue,green \"tsx docs/.vitepress/api.ts\" \"vitepress dev docs\"",
|
"docs:dev": "concurrently -k -n SIDEBAR,VITEPRESS -c blue,green \"tsx docs/.vitepress/api.ts\" \"vitepress dev docs\"",
|
||||||
"docs:build": "vitepress build docs",
|
"docs:build": "vitepress build docs",
|
||||||
"docs:preview": "vitepress preview docs"
|
"docs:preview": "vitepress preview docs"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ant-design/icons-vue": "^6.1.0",
|
"@ant-design/icons-vue": "^6.1.0",
|
||||||
"@vueuse/core": "^10.11.1",
|
|
||||||
"@wasm-audio-decoders/ogg-vorbis": "^0.1.16",
|
"@wasm-audio-decoders/ogg-vorbis": "^0.1.16",
|
||||||
"anon-tokyo": "0.0.0-alpha.0",
|
"anon-tokyo": "0.0.0-alpha.0",
|
||||||
"ant-design-vue": "^3.2.20",
|
"ant-design-vue": "^3.2.20",
|
||||||
@ -35,6 +35,7 @@
|
|||||||
"mutate-animate": "^1.4.2",
|
"mutate-animate": "^1.4.2",
|
||||||
"ogg-opus-decoder": "^1.6.14",
|
"ogg-opus-decoder": "^1.6.14",
|
||||||
"opus-decoder": "^0.7.7",
|
"opus-decoder": "^0.7.7",
|
||||||
|
"vite-plugin-dts": "^4.5.4",
|
||||||
"vue": "^3.5.13"
|
"vue": "^3.5.13"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -81,7 +82,6 @@
|
|||||||
"typescript-eslint": "^8.27.0",
|
"typescript-eslint": "^8.27.0",
|
||||||
"unplugin-vue-components": "^0.22.12",
|
"unplugin-vue-components": "^0.22.12",
|
||||||
"vite": "^6.2.2",
|
"vite": "^6.2.2",
|
||||||
"vite-plugin-dts": "^4.5.3",
|
|
||||||
"vitepress": "^1.6.3",
|
"vitepress": "^1.6.3",
|
||||||
"vitepress-plugin-mermaid": "^2.0.17",
|
"vitepress-plugin-mermaid": "^2.0.17",
|
||||||
"vue-tsc": "^2.2.8",
|
"vue-tsc": "^2.2.8",
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { DefaultProps, ElementLocator, Font, useKey } from '@motajs/render';
|
import { DefaultProps, ElementLocator, Font } from '@motajs/render';
|
||||||
import { computed, defineComponent, reactive, ref } from 'vue';
|
import { computed, defineComponent, reactive, ref } from 'vue';
|
||||||
import { Background, Selection } from './misc';
|
import { Background, Selection } from './misc';
|
||||||
import { TextContent, TextContentExpose, TextContentProps } from './textbox';
|
import { TextContent, TextContentExpose, TextContentProps } from './textbox';
|
||||||
@ -6,6 +6,7 @@ import { SetupComponentOptions } from './types';
|
|||||||
import { TextAlign } from './textboxTyper';
|
import { TextAlign } from './textboxTyper';
|
||||||
import { Page, PageExpose } from './page';
|
import { Page, PageExpose } from './page';
|
||||||
import { GameUI, IUIMountable } from '@motajs/system-ui';
|
import { GameUI, IUIMountable } from '@motajs/system-ui';
|
||||||
|
import { useKey } from '../use';
|
||||||
|
|
||||||
export interface ConfirmBoxProps extends DefaultProps, TextContentProps {
|
export interface ConfirmBoxProps extends DefaultProps, TextContentProps {
|
||||||
text: string;
|
text: string;
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { DefaultProps } from '@motajs/render-vue';
|
import { DefaultProps } from '@motajs/render-vue';
|
||||||
import Scroll from 'packages/legacy-ui/src/components/scroll.vue';
|
|
||||||
import { computed, defineComponent, ref, SlotsType, VNode } from 'vue';
|
import { computed, defineComponent, ref, SlotsType, VNode } from 'vue';
|
||||||
import { Selection } from './misc';
|
import { Selection } from './misc';
|
||||||
import { ElementLocator } from '@motajs/render-core';
|
import { ElementLocator } from '@motajs/render-core';
|
||||||
import { Font } from '@motajs/render-style';
|
import { Font } from '@motajs/render-style';
|
||||||
import { SetupComponentOptions } from '@motajs/system-ui';
|
import { SetupComponentOptions } from '@motajs/system-ui';
|
||||||
|
import { Scroll } from './scroll';
|
||||||
|
|
||||||
export interface ListProps extends DefaultProps {
|
export interface ListProps extends DefaultProps {
|
||||||
/** 列表内容,第一项表示 id,第二项表示显示的内容 */
|
/** 列表内容,第一项表示 id,第二项表示显示的内容 */
|
||||||
@ -64,7 +64,7 @@ export const List = defineComponent<ListProps, ListEmits, keyof ListEmits>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
<Scroll>
|
<Scroll loc={props.loc}>
|
||||||
{props.list.map((v, i) => {
|
{props.list.map((v, i) => {
|
||||||
const [key, value] = v;
|
const [key, value] = v;
|
||||||
const loc: ElementLocator = [
|
const loc: ElementLocator = [
|
||||||
|
@ -70,9 +70,12 @@ export * from './animate';
|
|||||||
export * from './block';
|
export * from './block';
|
||||||
export * from './cache';
|
export * from './cache';
|
||||||
export * from './camera';
|
export * from './camera';
|
||||||
|
export * from './damage';
|
||||||
export * from './frame';
|
export * from './frame';
|
||||||
export * from './hero';
|
export * from './hero';
|
||||||
|
export * from './itemDetail';
|
||||||
export * from './layer';
|
export * from './layer';
|
||||||
export * from './misc';
|
export * from './misc';
|
||||||
export * from './viewport';
|
export * from './props';
|
||||||
export * from './utils';
|
export * from './utils';
|
||||||
|
export * from './viewport';
|
||||||
|
@ -570,11 +570,11 @@ export class Layer extends Container<ELayerEvent> {
|
|||||||
static readonly FRAME_ALL = 15;
|
static readonly FRAME_ALL = 15;
|
||||||
|
|
||||||
/** 静态层,包含除大怪物及正在移动的内容外的内容 */
|
/** 静态层,包含除大怪物及正在移动的内容外的内容 */
|
||||||
protected staticMap: MotaOffscreenCanvas2D = this.requireCanvas();
|
protected staticMap = this.requireCanvas(true, false);
|
||||||
/** 移动层,包含大怪物及正在移动的内容 */
|
/** 移动层,包含大怪物及正在移动的内容 */
|
||||||
protected movingMap: MotaOffscreenCanvas2D = this.requireCanvas();
|
protected movingMap = this.requireCanvas(true, false);
|
||||||
/** 背景图层 */
|
/** 背景图层 */
|
||||||
protected backMap: MotaOffscreenCanvas2D = this.requireCanvas();
|
protected backMap = this.requireCanvas(true, false);
|
||||||
|
|
||||||
/** 最终渲染至的Sprite */
|
/** 最终渲染至的Sprite */
|
||||||
main: Sprite = new Sprite('absolute', false, true);
|
main: Sprite = new Sprite('absolute', false, true);
|
||||||
|
@ -9,9 +9,21 @@ import {
|
|||||||
} from './layer';
|
} from './layer';
|
||||||
import { EAnimateEvent } from './animate';
|
import { EAnimateEvent } from './animate';
|
||||||
import { EIconEvent, EWinskinEvent } from './misc';
|
import { EIconEvent, EWinskinEvent } from './misc';
|
||||||
|
import { IEnemyCollection } from '@motajs/types';
|
||||||
|
import { CanvasStyle } from '@motajs/render-elements';
|
||||||
|
|
||||||
export interface AnimateProps extends BaseProps {}
|
export interface AnimateProps extends BaseProps {}
|
||||||
|
|
||||||
|
export interface DamageProps extends BaseProps {
|
||||||
|
mapWidth?: number;
|
||||||
|
mapHeight?: number;
|
||||||
|
cellSize?: number;
|
||||||
|
enemy?: IEnemyCollection;
|
||||||
|
font?: string;
|
||||||
|
strokeStyle?: CanvasStyle;
|
||||||
|
strokeWidth?: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IconProps extends BaseProps {
|
export interface IconProps extends BaseProps {
|
||||||
/** 图标 id 或数字 */
|
/** 图标 id 或数字 */
|
||||||
icon: AllNumbers | AllIds;
|
icon: AllNumbers | AllIds;
|
||||||
|
@ -47,3 +47,4 @@ export * from './components';
|
|||||||
export * from './ui';
|
export * from './ui';
|
||||||
export * from './use';
|
export * from './use';
|
||||||
export * from './elements';
|
export * from './elements';
|
||||||
|
export * from './renderer';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { GameUI, UIComponentProps } from '@motajs/system-ui';
|
import { GameUI } from '@motajs/system-ui';
|
||||||
import { computed, defineComponent, ref, watch } from 'vue';
|
import { computed, defineComponent, ref, watch } from 'vue';
|
||||||
import { SetupComponentOptions, TextContent } from '../components';
|
import { SetupComponentOptions, TextContent } from '../components';
|
||||||
import {
|
import {
|
||||||
@ -40,7 +40,7 @@ export interface ILeftHeroStatus {
|
|||||||
magicDef: number;
|
magicDef: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface StatusBarProps<T> extends DefaultProps, UIComponentProps {
|
interface StatusBarProps<T> extends DefaultProps {
|
||||||
loc: ElementLocator;
|
loc: ElementLocator;
|
||||||
status: T;
|
status: T;
|
||||||
hidden: boolean;
|
hidden: boolean;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { Hotkey, gameKey } from '@motajs/system-action';
|
||||||
import { loading } from '@user/data-base';
|
import { loading } from '@user/data-base';
|
||||||
import { TimingFn, Transition } from 'mutate-animate';
|
import { TimingFn, Transition } from 'mutate-animate';
|
||||||
import {
|
import {
|
||||||
@ -67,6 +68,25 @@ export function onLoaded(hook: () => void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type KeyUsing = [Hotkey, symbol];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在组件中定义按键操作
|
||||||
|
* @param noScope 是否不创建新作用域
|
||||||
|
*/
|
||||||
|
export function useKey(noScope: boolean = false): KeyUsing {
|
||||||
|
if (noScope) {
|
||||||
|
return [gameKey, gameKey.scope];
|
||||||
|
} else {
|
||||||
|
const sym = Symbol();
|
||||||
|
gameKey.use(sym);
|
||||||
|
onUnmounted(() => {
|
||||||
|
gameKey.dispose();
|
||||||
|
});
|
||||||
|
return [gameKey, sym];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export interface ITransitionedController<T> {
|
export interface ITransitionedController<T> {
|
||||||
readonly ref: Ref<T>;
|
readonly ref: Ref<T>;
|
||||||
readonly value: T;
|
readonly value: T;
|
||||||
|
@ -5,7 +5,7 @@ import type { TowerBoss } from './towerBoss';
|
|||||||
import { IStateDamageable } from '@user/data-state';
|
import { IStateDamageable } from '@user/data-state';
|
||||||
import { PointEffect, PointEffectType } from '../fx/pointShader';
|
import { PointEffect, PointEffectType } from '../fx/pointShader';
|
||||||
import { isNil } from 'lodash-es';
|
import { isNil } from 'lodash-es';
|
||||||
import { mainRenderer } from 'packages-user/client-modules/src/render/renderer';
|
import { mainRenderer } from '@user/client-modules';
|
||||||
|
|
||||||
export const enum ProjectileDirection {
|
export const enum ProjectileDirection {
|
||||||
Vertical,
|
Vertical,
|
||||||
|
@ -13,7 +13,7 @@ import {
|
|||||||
type MoveStep
|
type MoveStep
|
||||||
} from '@user/data-state';
|
} from '@user/data-state';
|
||||||
import EventEmitter from 'eventemitter3';
|
import EventEmitter from 'eventemitter3';
|
||||||
import { mainRenderer } from 'packages-user/client-modules/src/render/renderer';
|
import { mainRenderer } from '@user/client-modules';
|
||||||
|
|
||||||
export interface IChaseController {
|
export interface IChaseController {
|
||||||
/** 本次追逐战实例 */
|
/** 本次追逐战实例 */
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { debounce } from 'lodash-es';
|
|
||||||
import logInfo from './logger.json';
|
import logInfo from './logger.json';
|
||||||
|
|
||||||
export const enum LogLevel {
|
export const enum LogLevel {
|
||||||
@ -21,28 +20,28 @@ interface LoggerCatchReturns<T> {
|
|||||||
info: LoggerCatchInfo[];
|
info: LoggerCatchInfo[];
|
||||||
}
|
}
|
||||||
|
|
||||||
let logTip: HTMLSpanElement;
|
// let logTip: HTMLSpanElement;
|
||||||
if (!main.replayChecking) {
|
// if (!main.replayChecking) {
|
||||||
const tip = document.createElement('span');
|
// const tip = document.createElement('span');
|
||||||
logTip = tip;
|
// logTip = tip;
|
||||||
tip.style.position = 'fixed';
|
// tip.style.position = 'fixed';
|
||||||
tip.style.right = '0';
|
// tip.style.right = '0';
|
||||||
tip.style.bottom = '0';
|
// tip.style.bottom = '0';
|
||||||
tip.style.height = '20px';
|
// tip.style.height = '20px';
|
||||||
tip.style.width = 'auto';
|
// tip.style.width = 'auto';
|
||||||
tip.style.textAlign = 'right';
|
// tip.style.textAlign = 'right';
|
||||||
tip.style.padding = '0 5px';
|
// tip.style.padding = '0 5px';
|
||||||
tip.style.fontSize = '16px';
|
// tip.style.fontSize = '16px';
|
||||||
tip.style.fontFamily = 'Arial';
|
// tip.style.fontFamily = 'Arial';
|
||||||
tip.style.display = 'none';
|
// tip.style.display = 'none';
|
||||||
tip.style.margin = '2px';
|
// tip.style.margin = '2px';
|
||||||
document.body.appendChild(tip);
|
// document.body.appendChild(tip);
|
||||||
}
|
// }
|
||||||
|
|
||||||
const hideTipText = debounce(() => {
|
// const hideTipText = debounce(() => {
|
||||||
if (main.replayChecking) return;
|
// if (main.replayChecking) return;
|
||||||
logTip.style.display = 'none';
|
// logTip.style.display = 'none';
|
||||||
}, 5000);
|
// }, 5000);
|
||||||
|
|
||||||
const nums = new Set('1234567890');
|
const nums = new Set('1234567890');
|
||||||
|
|
||||||
@ -117,12 +116,12 @@ export class Logger {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (this.level <= LogLevel.ERROR && this.enabled) {
|
if (this.level <= LogLevel.ERROR && this.enabled) {
|
||||||
if (!main.replayChecking) {
|
// if (!main.replayChecking) {
|
||||||
logTip.style.color = 'lightcoral';
|
// logTip.style.color = 'lightcoral';
|
||||||
logTip.style.display = 'block';
|
// logTip.style.display = 'block';
|
||||||
logTip.textContent = `Error thrown, please check in console.`;
|
// logTip.textContent = `Error thrown, please check in console.`;
|
||||||
hideTipText();
|
// hideTipText();
|
||||||
}
|
// }
|
||||||
const n = Math.floor(code / 50) + 1;
|
const n = Math.floor(code / 50) + 1;
|
||||||
const n2 = code % 50;
|
const n2 = code % 50;
|
||||||
const url = `/_docs/logger/error/error${n}.html#error-code-${n2}`;
|
const url = `/_docs/logger/error/error${n}.html#error-code-${n2}`;
|
||||||
@ -150,12 +149,12 @@ export class Logger {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (this.level <= LogLevel.WARNING && this.enabled) {
|
if (this.level <= LogLevel.WARNING && this.enabled) {
|
||||||
if (!main.replayChecking) {
|
// if (!main.replayChecking) {
|
||||||
logTip.style.color = 'gold';
|
// logTip.style.color = 'gold';
|
||||||
logTip.style.display = 'block';
|
// logTip.style.display = 'block';
|
||||||
logTip.textContent = `Warning thrown, please check in console.`;
|
// logTip.textContent = `Warning thrown, please check in console.`;
|
||||||
hideTipText();
|
// hideTipText();
|
||||||
}
|
// }
|
||||||
const n = Math.floor(code / 50) + 1;
|
const n = Math.floor(code / 50) + 1;
|
||||||
const n2 = code % 50;
|
const n2 = code % 50;
|
||||||
const url = `/_docs/logger/warn/warn${n}.html#warn-code-${n2}`;
|
const url = `/_docs/logger/warn/warn${n}.html#warn-code-${n2}`;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { EventEmitter } from 'eventemitter3';
|
import { EventEmitter } from 'eventemitter3';
|
||||||
|
|
||||||
interface OffscreenCanvasEvent {
|
interface OffscreenCanvasEvent {
|
||||||
/** 当被动触发resize时(例如core.domStyle.scale变化、窗口大小变化)时触发,使用size函数并不会触发 */
|
/** 当被动触发resize时(例如窗口大小变化)时触发,使用size函数并不会触发 */
|
||||||
resize: [];
|
resize: [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,11 +22,6 @@ export class MotaOffscreenCanvas2D extends EventEmitter<OffscreenCanvasEvent> {
|
|||||||
/** 更新标识符,如果发生变化则说明画布被动清空 */
|
/** 更新标识符,如果发生变化则说明画布被动清空 */
|
||||||
symbol: number = 0;
|
symbol: number = 0;
|
||||||
|
|
||||||
private _active: boolean = true;
|
|
||||||
get active() {
|
|
||||||
return this._active;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建一个新的离屏画布\
|
* 创建一个新的离屏画布\
|
||||||
* **注意**:如果你在自定义渲染元素中使用,请避免使用此构造函数,而应该使用 `RenderItem.requireCanvas`
|
* **注意**:如果你在自定义渲染元素中使用,请避免使用此构造函数,而应该使用 `RenderItem.requireCanvas`
|
||||||
|
@ -43,7 +43,7 @@ export class Container<E extends EContainerEvent = EContainerEvent>
|
|||||||
}
|
}
|
||||||
|
|
||||||
onResize(scale: number): void {
|
onResize(scale: number): void {
|
||||||
this.sortedChildren.forEach(v => v.onResize(scale));
|
this.children.forEach(v => v.onResize(scale));
|
||||||
super.onResize(scale);
|
super.onResize(scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,6 +283,8 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
|
|||||||
composite: GlobalCompositeOperation = 'source-over';
|
composite: GlobalCompositeOperation = 'source-over';
|
||||||
/** 不透明度 */
|
/** 不透明度 */
|
||||||
alpha: number = 1;
|
alpha: number = 1;
|
||||||
|
/** 缩放比 */
|
||||||
|
protected scale: number = 1;
|
||||||
|
|
||||||
/** 鼠标覆盖在此元素上时的光标样式 */
|
/** 鼠标覆盖在此元素上时的光标样式 */
|
||||||
cursor: string = 'inherit';
|
cursor: string = 'inherit';
|
||||||
@ -391,6 +393,7 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
|
|||||||
this.cache = this.requireCanvas();
|
this.cache = this.requireCanvas();
|
||||||
if (!enableCache) {
|
if (!enableCache) {
|
||||||
this.cache.size(1, 1);
|
this.cache.size(1, 1);
|
||||||
|
this.deleteCanvas(this.cache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -456,7 +459,7 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
|
|||||||
* @param alpha 是否启用画布的 alpha 通道
|
* @param alpha 是否启用画布的 alpha 通道
|
||||||
* @param autoScale 是否自动跟随缩放
|
* @param autoScale 是否自动跟随缩放
|
||||||
*/
|
*/
|
||||||
requireCanvas(alpha: boolean = true, autoScale: boolean = false) {
|
requireCanvas(alpha: boolean = true, autoScale: boolean = true) {
|
||||||
const canvas = new MotaOffscreenCanvas2D(alpha);
|
const canvas = new MotaOffscreenCanvas2D(alpha);
|
||||||
this.canvases.add(canvas);
|
this.canvases.add(canvas);
|
||||||
this.canvasMap.set(canvas, { autoScale });
|
this.canvasMap.set(canvas, { autoScale });
|
||||||
@ -475,12 +478,20 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
|
|||||||
//#region 事件处理
|
//#region 事件处理
|
||||||
|
|
||||||
onResize(scale: number): void {
|
onResize(scale: number): void {
|
||||||
this.cache.setScale(scale);
|
this.scale = scale;
|
||||||
this.canvases.forEach(v => {
|
this.canvases.forEach(v => {
|
||||||
if (this.canvasMap.get(v)?.autoScale) {
|
if (this.canvasMap.get(v)?.autoScale) {
|
||||||
v.setScale(scale);
|
v.setScale(scale);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前元素的缩放比,它与根元素应当保持一致
|
||||||
|
*/
|
||||||
|
getScale() {
|
||||||
|
return this.scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
//#region 修改元素属性
|
//#region 修改元素属性
|
||||||
@ -590,7 +601,7 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
|
|||||||
/**
|
/**
|
||||||
* 获取当前元素的绝对位置(不建议使用,因为应当很少会有获取绝对位置的需求)
|
* 获取当前元素的绝对位置(不建议使用,因为应当很少会有获取绝对位置的需求)
|
||||||
*/
|
*/
|
||||||
getAbsolutePosition(x: number = 0, y: number = 0): LocArr {
|
getAbsolutePosition(x: number = 0, y: number = 0): [number, number] {
|
||||||
if (this.type === 'absolute') {
|
if (this.type === 'absolute') {
|
||||||
if (this.parent) return this.parent.getAbsolutePosition(0, 0);
|
if (this.parent) return this.parent.getAbsolutePosition(0, 0);
|
||||||
else return [0, 0];
|
else return [0, 0];
|
||||||
@ -765,6 +776,7 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
|
|||||||
this.checkRoot();
|
this.checkRoot();
|
||||||
this._root?.connect(this);
|
this._root?.connect(this);
|
||||||
this._transform.bind(this);
|
this._transform.bind(this);
|
||||||
|
this.onResize(parent.scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,9 +42,6 @@ export interface MotaRendererConfig {
|
|||||||
export class MotaRenderer extends Container implements IRenderTreeRoot {
|
export class MotaRenderer extends Container implements IRenderTreeRoot {
|
||||||
static list: Map<string, MotaRenderer> = new Map();
|
static list: Map<string, MotaRenderer> = new Map();
|
||||||
|
|
||||||
/** 缩放比 */
|
|
||||||
private scale: number = 1;
|
|
||||||
|
|
||||||
/** 所有连接到此根元素的渲染元素的 id 到元素自身的映射 */
|
/** 所有连接到此根元素的渲染元素的 id 到元素自身的映射 */
|
||||||
protected idMap: Map<string, RenderItem> = new Map();
|
protected idMap: Map<string, RenderItem> = new Map();
|
||||||
|
|
||||||
@ -85,7 +82,6 @@ export class MotaRenderer extends Container implements IRenderTreeRoot {
|
|||||||
this.target.setAntiAliasing(false);
|
this.target.setAntiAliasing(false);
|
||||||
|
|
||||||
this.setAnchor(0.5, 0.5);
|
this.setAnchor(0.5, 0.5);
|
||||||
this.transform.translate(240, 240);
|
|
||||||
|
|
||||||
MotaRenderer.list.set(canvas.id, this);
|
MotaRenderer.list.set(canvas.id, this);
|
||||||
|
|
||||||
@ -105,17 +101,9 @@ export class MotaRenderer extends Container implements IRenderTreeRoot {
|
|||||||
* @param scale 缩放比
|
* @param scale 缩放比
|
||||||
*/
|
*/
|
||||||
setScale(scale: number) {
|
setScale(scale: number) {
|
||||||
this.scale = scale;
|
|
||||||
this.onResize(scale);
|
this.onResize(scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取这个渲染器的缩放比
|
|
||||||
*/
|
|
||||||
getScale() {
|
|
||||||
return this.scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
onResize(scale: number): void {
|
onResize(scale: number): void {
|
||||||
this.target.setScale(scale);
|
this.target.setScale(scale);
|
||||||
const width = this.target.width * scale;
|
const width = this.target.width * scale;
|
||||||
@ -355,8 +343,8 @@ export class MotaRenderer extends Container implements IRenderTreeRoot {
|
|||||||
mouse: MouseType = this.getMouseType(event)
|
mouse: MouseType = this.getMouseType(event)
|
||||||
): IActionEvent {
|
): IActionEvent {
|
||||||
const id = this.getMouseIdentifier(type, mouse);
|
const id = this.getMouseIdentifier(type, mouse);
|
||||||
const x = event.offsetX / core.domStyle.scale;
|
const x = event.offsetX / this.scale;
|
||||||
const y = event.offsetY / core.domStyle.scale;
|
const y = event.offsetY / this.scale;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
target: this,
|
target: this,
|
||||||
@ -426,8 +414,8 @@ export class MotaRenderer extends Container implements IRenderTreeRoot {
|
|||||||
event: TouchEvent,
|
event: TouchEvent,
|
||||||
rect: DOMRect
|
rect: DOMRect
|
||||||
): IActionEvent {
|
): IActionEvent {
|
||||||
const x = (touch.clientX - rect.left) / core.domStyle.scale;
|
const x = (touch.clientX - rect.left) / this.scale;
|
||||||
const y = (touch.clientY - rect.top) / core.domStyle.scale;
|
const y = (touch.clientY - rect.top) / this.scale;
|
||||||
return {
|
return {
|
||||||
target: this,
|
target: this,
|
||||||
identifier: this.getTouchIdentifier(touch, type),
|
identifier: this.getTouchIdentifier(touch, type),
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
} from '@motajs/render-core';
|
} from '@motajs/render-core';
|
||||||
import { logger } from '@motajs/common';
|
import { logger } from '@motajs/common';
|
||||||
import { clamp, isNil } from 'lodash-es';
|
import { clamp, isNil } from 'lodash-es';
|
||||||
|
import { CanvasStyle } from './types';
|
||||||
|
|
||||||
export type CircleParams = [
|
export type CircleParams = [
|
||||||
cx?: number,
|
cx?: number,
|
||||||
|
@ -2,3 +2,5 @@ export type SizedCanvasImageSource = Exclude<
|
|||||||
CanvasImageSource,
|
CanvasImageSource,
|
||||||
VideoFrame | SVGElement
|
VideoFrame | SVGElement
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
export type CanvasStyle = string | CanvasGradient | CanvasPattern;
|
||||||
|
@ -15,7 +15,6 @@ import {
|
|||||||
ConatinerCustomProps,
|
ConatinerCustomProps,
|
||||||
ContainerProps,
|
ContainerProps,
|
||||||
CustomProps,
|
CustomProps,
|
||||||
DamageProps,
|
|
||||||
EllipseProps,
|
EllipseProps,
|
||||||
ImageProps,
|
ImageProps,
|
||||||
LineProps,
|
LineProps,
|
||||||
@ -87,7 +86,6 @@ declare module 'vue/jsx-runtime' {
|
|||||||
image: TagDefine<ImageProps, EImageEvent>;
|
image: TagDefine<ImageProps, EImageEvent>;
|
||||||
comment: TagDefine<CommentProps, ERenderItemEvent>;
|
comment: TagDefine<CommentProps, ERenderItemEvent>;
|
||||||
custom: TagDefine<CustomProps, ERenderItemEvent>;
|
custom: TagDefine<CustomProps, ERenderItemEvent>;
|
||||||
damage: TagDefine<DamageProps, ERenderItemEvent>;
|
|
||||||
'g-rect': TagDefine<RectProps, EGraphicItemEvent>;
|
'g-rect': TagDefine<RectProps, EGraphicItemEvent>;
|
||||||
'g-circle': TagDefine<CirclesProps, EGraphicItemEvent>;
|
'g-circle': TagDefine<CirclesProps, EGraphicItemEvent>;
|
||||||
'g-ellipse': TagDefine<EllipseProps, EGraphicItemEvent>;
|
'g-ellipse': TagDefine<EllipseProps, EGraphicItemEvent>;
|
||||||
|
@ -10,6 +10,7 @@ import {
|
|||||||
} from '@motajs/render-core';
|
} from '@motajs/render-core';
|
||||||
import {
|
import {
|
||||||
BezierParams,
|
BezierParams,
|
||||||
|
CanvasStyle,
|
||||||
CircleParams,
|
CircleParams,
|
||||||
EllipseParams,
|
EllipseParams,
|
||||||
ILineProperty,
|
ILineProperty,
|
||||||
@ -19,7 +20,6 @@ import {
|
|||||||
RectREllipseParams
|
RectREllipseParams
|
||||||
} from '@motajs/render-elements';
|
} from '@motajs/render-elements';
|
||||||
import { Font } from '@motajs/render-style';
|
import { Font } from '@motajs/render-style';
|
||||||
import { IEnemyCollection } from '@motajs/types';
|
|
||||||
|
|
||||||
export interface CustomProps {
|
export interface CustomProps {
|
||||||
_item: (props: BaseProps) => RenderItem;
|
_item: (props: BaseProps) => RenderItem;
|
||||||
@ -122,16 +122,6 @@ export interface CommentProps extends BaseProps {
|
|||||||
text?: string;
|
text?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DamageProps extends BaseProps {
|
|
||||||
mapWidth?: number;
|
|
||||||
mapHeight?: number;
|
|
||||||
cellSize?: number;
|
|
||||||
enemy?: IEnemyCollection;
|
|
||||||
font?: string;
|
|
||||||
strokeStyle?: CanvasStyle;
|
|
||||||
strokeWidth?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GraphicPropsBase extends BaseProps, Partial<ILineProperty> {
|
export interface GraphicPropsBase extends BaseProps, Partial<ILineProperty> {
|
||||||
/** 是否填充,若填写 {@link stroke},那么表现为先填充后描边 */
|
/** 是否填充,若填写 {@link stroke},那么表现为先填充后描边 */
|
||||||
fill?: boolean;
|
fill?: boolean;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Animation, Ticker, Transition } from 'mutate-animate';
|
import { Animation, Ticker, Transition } from 'mutate-animate';
|
||||||
import { ERenderItemEvent, RenderItem } from '@motajs/render-core';
|
import { ERenderItemEvent, RenderItem } from '@motajs/render-core';
|
||||||
import { gameKey, Hotkey } from '@motajs/system-action';
|
|
||||||
import { onMounted, onUnmounted } from 'vue';
|
import { onMounted, onUnmounted } from 'vue';
|
||||||
import EventEmitter from 'eventemitter3';
|
import EventEmitter from 'eventemitter3';
|
||||||
|
|
||||||
@ -44,25 +43,6 @@ export function useTransition(): TransitionUsing {
|
|||||||
return [tran];
|
return [tran];
|
||||||
}
|
}
|
||||||
|
|
||||||
type KeyUsing = [Hotkey, symbol];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 在组件中定义按键操作
|
|
||||||
* @param noScope 是否不创建新作用域
|
|
||||||
*/
|
|
||||||
export function useKey(noScope: boolean = false): KeyUsing {
|
|
||||||
if (noScope) {
|
|
||||||
return [gameKey, gameKey.scope];
|
|
||||||
} else {
|
|
||||||
const sym = Symbol();
|
|
||||||
gameKey.use(sym);
|
|
||||||
onUnmounted(() => {
|
|
||||||
gameKey.dispose();
|
|
||||||
});
|
|
||||||
return [gameKey, sym];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function onEvent<
|
export function onEvent<
|
||||||
T extends ERenderItemEvent,
|
T extends ERenderItemEvent,
|
||||||
K extends EventEmitter.EventNames<T>
|
K extends EventEmitter.EventNames<T>
|
||||||
|
1
packages/render/README.md
Normal file
1
packages/render/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
Documentation is working...
|
@ -1,9 +1,41 @@
|
|||||||
{
|
{
|
||||||
"name": "@motajs/render",
|
"name": "@motajs/render",
|
||||||
"dependencies": {
|
"version": "0.1.0",
|
||||||
"@motajs/render-core": "workspace:*",
|
"main": "dist/render.cjs.js",
|
||||||
"@motajs/render-elements": "workspace:*",
|
"module": "dist/render.es.js",
|
||||||
"@motajs/render-style": "workspace:*",
|
"types": "dist/render.es.d.ts",
|
||||||
"@motajs/render-vue": "workspace:*"
|
"keywords": [
|
||||||
|
"render",
|
||||||
|
"game",
|
||||||
|
"vue",
|
||||||
|
"graphics"
|
||||||
|
],
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/unanmed/HumanBreak/tree/dev"
|
||||||
|
},
|
||||||
|
"author": {
|
||||||
|
"name": "AncTe",
|
||||||
|
"email": "1319491857@qq.com"
|
||||||
|
},
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"import": "./dist/render.es.js",
|
||||||
|
"require": "./dist/render.cjs.js",
|
||||||
|
"types": "./dist/render.es.d.ts"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"dist"
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"eventemitter3": "^5.0.1",
|
||||||
|
"gl-matrix": "^3.4.3",
|
||||||
|
"lodash-es": "^4.17.21",
|
||||||
|
"mutate-animate": "^1.4.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"vue": "^3.5.13"
|
||||||
|
},
|
||||||
|
"license": "LGPL-3.0-only"
|
||||||
}
|
}
|
2265
pnpm-lock.yaml
2265
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
@ -330,7 +330,9 @@ main.prototype.loadAsync = async function (mode, callback) {
|
|||||||
core.domStyle.scale = window.innerWidth / core._PX_;
|
core.domStyle.scale = window.innerWidth / core._PX_;
|
||||||
}
|
}
|
||||||
Mota.r(() => {
|
Mota.r(() => {
|
||||||
Mota.require('@motajs/render').MotaOffscreenCanvas2D.refreshAll();
|
Mota.require('@user/client-modules').mainRenderer.setScale(
|
||||||
|
core.domStyle.scale
|
||||||
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,30 +1,55 @@
|
|||||||
import { build, loadConfigFromFile, mergeConfig, UserConfig } from 'vite';
|
import { build, loadConfigFromFile, mergeConfig, UserConfig } from 'vite';
|
||||||
|
import legacy from '@vitejs/plugin-legacy';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
|
|
||||||
const outputDir = path.resolve(__dirname, '../dist/game');
|
const outputDir = path.resolve('./dist/game');
|
||||||
|
|
||||||
// 清空 dist/game 目录
|
// 清空 dist/game 目录
|
||||||
fs.emptyDirSync(outputDir);
|
fs.emptyDirSync(outputDir);
|
||||||
|
|
||||||
// 构建游戏
|
// 构建游戏
|
||||||
async function buildGame() {
|
async function buildGame() {
|
||||||
const configFile = path.resolve(__dirname, '../vite.config.ts');
|
const configFile = path.resolve('./vite.config.ts');
|
||||||
const config = await loadConfigFromFile(
|
const config = await loadConfigFromFile(
|
||||||
{ command: 'build', mode: 'production' },
|
{ command: 'build', mode: 'production' },
|
||||||
configFile
|
configFile
|
||||||
);
|
);
|
||||||
const resolved = mergeConfig(config?.config ?? {}, {
|
const resolved = mergeConfig(config?.config ?? {}, {
|
||||||
|
plugins: [
|
||||||
|
legacy({
|
||||||
|
targets: [
|
||||||
|
'Chrome >= 56',
|
||||||
|
'Firefox >= 51',
|
||||||
|
'Edge >= 79',
|
||||||
|
'Safari >= 15',
|
||||||
|
'Opera >= 43'
|
||||||
|
],
|
||||||
|
polyfills: true,
|
||||||
|
modernPolyfills: true
|
||||||
|
})
|
||||||
|
],
|
||||||
build: {
|
build: {
|
||||||
outDir: outputDir,
|
outDir: outputDir,
|
||||||
sourcemap: true,
|
sourcemap: true,
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
input: path.resolve(__dirname, '../src/main.ts'),
|
input: path.resolve('./src/main.ts'),
|
||||||
output: {
|
output: {
|
||||||
format: 'es',
|
format: 'es',
|
||||||
entryFileNames: '[name].[hash].js',
|
entryFileNames: '[name].[hash].js',
|
||||||
chunkFileNames: 'chunks/[name].[hash].js',
|
chunkFileNames: 'chunks/[name].[hash].js',
|
||||||
assetFileNames: 'assets/[name].[hash][extname]'
|
assetFileNames: 'assets/[name].[hash][extname]',
|
||||||
|
manualChunks: {
|
||||||
|
antdv: ['ant-design-vue', '@ant-design/icons-vue'],
|
||||||
|
common: [
|
||||||
|
'lodash-es',
|
||||||
|
'axios',
|
||||||
|
'lz-string',
|
||||||
|
'chart.js',
|
||||||
|
'mutate-animate',
|
||||||
|
'@vueuse/core'
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
65
script/build-lib.ts
Normal file
65
script/build-lib.ts
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import { build, loadConfigFromFile, mergeConfig, UserConfig } from 'vite';
|
||||||
|
import path from 'path';
|
||||||
|
import fs from 'fs-extra';
|
||||||
|
import dts from 'vite-plugin-dts';
|
||||||
|
|
||||||
|
const packages = path.resolve(process.cwd(), './packages');
|
||||||
|
|
||||||
|
// 获取所有包目录
|
||||||
|
const packageDirs = ['render'];
|
||||||
|
|
||||||
|
// 构建每一个包
|
||||||
|
async function buildPackages() {
|
||||||
|
for (const packageName of packageDirs) {
|
||||||
|
const packageDir = path.join(packages, packageName);
|
||||||
|
const output = path.join(packageDir, 'dist');
|
||||||
|
await fs.emptyDir(output);
|
||||||
|
const configFile = path.resolve('./vite.config.ts');
|
||||||
|
const config = await loadConfigFromFile(
|
||||||
|
{ command: 'build', mode: 'production' },
|
||||||
|
configFile
|
||||||
|
);
|
||||||
|
const resolved = mergeConfig(config?.config ?? {}, {
|
||||||
|
plugins: [
|
||||||
|
dts({
|
||||||
|
entryRoot: path.join(packageDir, 'src/index.ts'),
|
||||||
|
rollupTypes: true,
|
||||||
|
strictOutput: false,
|
||||||
|
copyDtsFiles: false,
|
||||||
|
exclude: ['packages-user/**/*']
|
||||||
|
})
|
||||||
|
],
|
||||||
|
build: {
|
||||||
|
lib: {
|
||||||
|
entry: path.join(packageDir, 'src/index.ts'),
|
||||||
|
name: packageName,
|
||||||
|
formats: ['es', 'cjs'],
|
||||||
|
fileName: format => `${packageName}.${format}.js`
|
||||||
|
},
|
||||||
|
outDir: output,
|
||||||
|
sourcemap: true,
|
||||||
|
emptyOutDir: true
|
||||||
|
},
|
||||||
|
publicDir: false
|
||||||
|
} satisfies UserConfig);
|
||||||
|
|
||||||
|
await build(resolved);
|
||||||
|
console.log(`✅ Package ${packageName} built successfully.`);
|
||||||
|
}
|
||||||
|
const dirs = await fs.readdir(packages);
|
||||||
|
for (const name of dirs) {
|
||||||
|
const dir = path.join(process.cwd(), name);
|
||||||
|
if (name === 'types') {
|
||||||
|
await fs.emptyDir(path.join(dir, 'src'));
|
||||||
|
await fs.rmdir(path.join(dir, 'src'));
|
||||||
|
} else {
|
||||||
|
await fs.emptyDir(dir);
|
||||||
|
await fs.rmdir(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildPackages().catch(e => {
|
||||||
|
console.error(e);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
@ -2,8 +2,8 @@ import { build, loadConfigFromFile, mergeConfig, UserConfig } from 'vite';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
|
|
||||||
const packagesDir = path.resolve(__dirname, '../packages');
|
const packagesDir = path.resolve('./packages');
|
||||||
const outputDir = path.resolve(__dirname, '../dist/packages');
|
const outputDir = path.resolve('./dist/packages');
|
||||||
|
|
||||||
// 清空 dist 目录
|
// 清空 dist 目录
|
||||||
fs.emptyDirSync(outputDir);
|
fs.emptyDirSync(outputDir);
|
||||||
@ -18,7 +18,7 @@ const packageDirs = fs.readdirSync(packagesDir).filter(name => {
|
|||||||
async function buildPackages() {
|
async function buildPackages() {
|
||||||
for (const packageName of packageDirs) {
|
for (const packageName of packageDirs) {
|
||||||
const packageDir = path.join(packagesDir, packageName);
|
const packageDir = path.join(packagesDir, packageName);
|
||||||
const configFile = path.resolve(__dirname, '../vite.config.ts');
|
const configFile = path.resolve('./vite.config.ts');
|
||||||
const config = await loadConfigFromFile(
|
const config = await loadConfigFromFile(
|
||||||
{ command: 'build', mode: 'production' },
|
{ command: 'build', mode: 'production' },
|
||||||
configFile
|
configFile
|
||||||
@ -37,7 +37,8 @@ async function buildPackages() {
|
|||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
external: [/node_modules/, /^@motajs\/.*/]
|
external: [/node_modules/, /^@motajs\/.*/]
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
publicDir: false
|
||||||
} satisfies UserConfig);
|
} satisfies UserConfig);
|
||||||
|
|
||||||
await build(resolved);
|
await build(resolved);
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
import vue from '@vitejs/plugin-vue';
|
import vue from '@vitejs/plugin-vue';
|
||||||
import legacy from '@vitejs/plugin-legacy';
|
|
||||||
import components from 'unplugin-vue-components/vite';
|
import components from 'unplugin-vue-components/vite';
|
||||||
import vuejsx from '@vitejs/plugin-vue-jsx'
|
import vuejsx from '@vitejs/plugin-vue-jsx'
|
||||||
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers';
|
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers';
|
||||||
import path, { resolve } from 'path';
|
import path from 'path';
|
||||||
import postcssPresetEnv from 'postcss-preset-env';
|
import postcssPresetEnv from 'postcss-preset-env';
|
||||||
import * as glob from 'glob'
|
import * as glob from 'glob'
|
||||||
|
|
||||||
@ -43,17 +42,6 @@ export default defineConfig({
|
|||||||
return custom.includes(tag) || tag.startsWith('g-');
|
return custom.includes(tag) || tag.startsWith('g-');
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
legacy({
|
|
||||||
targets: [
|
|
||||||
'Chrome >= 56',
|
|
||||||
'Firefox >= 51',
|
|
||||||
'Edge >= 79',
|
|
||||||
'Safari >= 15',
|
|
||||||
'Opera >= 43'
|
|
||||||
],
|
|
||||||
polyfills: true,
|
|
||||||
modernPolyfills: true
|
|
||||||
}),
|
|
||||||
components({ resolvers: [AntDesignVueResolver()] })
|
components({ resolvers: [AntDesignVueResolver()] })
|
||||||
],
|
],
|
||||||
base: `./`,
|
base: `./`,
|
||||||
@ -63,23 +51,6 @@ export default defineConfig({
|
|||||||
...aliasesUser
|
...aliasesUser
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
build: {
|
|
||||||
rollupOptions: {
|
|
||||||
output: {
|
|
||||||
manualChunks: {
|
|
||||||
antdv: ['ant-design-vue', '@ant-design/icons-vue'],
|
|
||||||
common: [
|
|
||||||
'lodash-es',
|
|
||||||
'axios',
|
|
||||||
'lz-string',
|
|
||||||
'chart.js',
|
|
||||||
'mutate-animate',
|
|
||||||
'@vueuse/core'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
css: {
|
css: {
|
||||||
preprocessorOptions: {
|
preprocessorOptions: {
|
||||||
less: {
|
less: {
|
||||||
|
Loading…
Reference in New Issue
Block a user