Skip to content

Commit

Permalink
feat: 新增mobileDisplay选项, 以及移动端样式兼容选项, 现在您可以单独为移动端配置样式
Browse files Browse the repository at this point in the history
  • Loading branch information
hacxy committed Mar 12, 2024
1 parent 46ef487 commit 3850838
Show file tree
Hide file tree
Showing 12 changed files with 150 additions and 54 deletions.
2 changes: 2 additions & 0 deletions packages/oh-my-live2d/src/config/config.ts
Expand Up @@ -5,6 +5,7 @@ const libServicePath = 'https://lib.oml2d.com';

// 默认配置选项, 实例化时会与用户传进来的合并
export const DEFAULT_OPTIONS: DefaultOptions = {
mobileDisplay: false,
fixed: true,
primaryColor: '#38B0DE',
sayHello: true,
Expand All @@ -18,6 +19,7 @@ export const DEFAULT_OPTIONS: DefaultOptions = {
models: [],
tips: {
messageLine: 3,
mobileStyle: {},
style: {},
idleTips: {
wordTheDay: false,
Expand Down
23 changes: 23 additions & 0 deletions packages/oh-my-live2d/src/config/style.ts
@@ -1,3 +1,5 @@
import { CSSProperties } from '../types/index.js';

export const generateGlobalStyle = (primaryColor: string): string => {
return `
@keyframes oml2d-shake-tips{
Expand Down Expand Up @@ -120,3 +122,24 @@ export const generateGlobalStyle = (primaryColor: string): string => {
}
`;
};

export const TIPS_DEFAULT_STYLE: CSSProperties = {
position: 'absolute',
fontSize: '18px',
borderRadius: '10px',
filter: 'drop-shadow(0 0 5px #999)',
border: '2px solid #fff',
color: '#fff',
padding: '15px 5px',
opacity: 0,
visibility: 'hidden',
transform: 'translateX(-50%)',
textAlign: 'center',
justifyContent: 'center',
animationDuration: `1000ms,1000ms`,
animationFillMode: 'forwards, none',
animationIterationCount: '1, infinite',
width: '60%',
left: '50%',
top: 0
};
72 changes: 61 additions & 11 deletions packages/oh-my-live2d/src/modules/index.ts
Expand Up @@ -64,8 +64,8 @@ export class OhMyLive2D {

// 初始化
initialize(): void {
this.verifyWindowSizeType();
if (this.windowSizeType !== WindowSizeType.pc) {
this.getWindowSizeType();
if (this.windowSizeType !== WindowSizeType.pc && !this.options.mobileDisplay) {
this.statusBar.popup('看板娘休息中', SystemState.info, 8000);

return;
Expand All @@ -82,18 +82,30 @@ export class OhMyLive2D {
this.statusBar.setStyle(commonStyle);
}

// 校验当前窗口大小
verifyWindowSizeType(): void {
// 获取窗口大小
getWindowSizeType(): void {
if (this.mediaQuery.matches) {
this.windowSizeType = WindowSizeType.mobile;
} else {
this.windowSizeType = WindowSizeType.pc;
}
}

onWindowSizeChange(onPc: () => void, onMobile: () => void): void {
if (this.mediaQuery.matches) {
this.windowSizeType = WindowSizeType.mobile;
onMobile();
} else {
this.windowSizeType = WindowSizeType.pc;
onPc();
}
this.mediaQuery.addEventListener('change', (e) => {
if (e.matches) {
this.windowSizeType = WindowSizeType.mobile;
onMobile();
} else {
this.windowSizeType = WindowSizeType.pc;
onPc();
}
});
}
Expand All @@ -104,14 +116,52 @@ export class OhMyLive2D {
loadModel(showLoading = true): void {
showLoading && this.statusBar.showLoading();
this.model = new Model(this.pixiLive2dDisplayModule.Live2DModel, this.currentModelOption, this.application, this.HitAreaFrames);
this.model?.setScale(this.currentModelOption?.scale, this.currentModelOption?.scale);
this.model?.setPosition(...(this.currentModelOption?.position || []));

// 模型所有资源加载完毕
this.model?.onLoaded((modelStyleInfo) => {
const finalStageStyle = mergeDeep(handleCommonStyle(modelStyleInfo), handleCommonStyle(this.currentModelOption.stageStyle || {}));

this.stage.setStyle(finalStageStyle, () => this.application.resize());
this.model?.onLoaded(() => {
this.onWindowSizeChange(
() => {
// pc
this.model?.setScale(this.currentModelOption?.scale, this.currentModelOption.scale);
this.model?.setPosition(...(this.currentModelOption.position || []));
const modelSize = {
width: this.model?.width,
height: this.model?.height
};
const finalStageStyle = mergeDeep(handleCommonStyle(modelSize), handleCommonStyle(this.currentModelOption.stageStyle || {}));

this.stage.setStyle(finalStageStyle, () => this.application.resize());
// if (!this.options.mobileDisplay) {
// void this.stage.slideIn(this.options.transitionTime);
// void this.tips.idlePlayer?.start();
// this.statusBar.popup('闪亮登场', SystemState.info, 3000);
// }
this.tips.setStyle(handleCommonStyle(this.options.tips.style || {}));
},
() => {
// mobile
if (!this.options.mobileDisplay) {
this.statusBar.popup('看板娘休息中', SystemState.info, 8000);
void this.stage.slideOut(this.options.transitionTime);
this.tips.clear();

return;
}
this.model?.setScale(this.currentModelOption?.mobileScale, this.currentModelOption.mobileScale);
this.model?.setPosition(...(this.currentModelOption.mobilePosition || []));
const modelSize = {
width: this.model?.width,
height: this.model?.height
};
const finalStageStyle = mergeDeep(
handleCommonStyle(modelSize),
handleCommonStyle(this.currentModelOption.mobileStageStyle || {})
);

this.stage.setStyle(finalStageStyle, () => this.application.resize());
this.tips.setStyle(handleCommonStyle(this.options.tips.mobileStyle || {}));
}
);
void this.stage.slideIn(this.options?.transitionTime);
this.statusBar.hideLoading();
});
Expand Down Expand Up @@ -166,7 +216,7 @@ export class OhMyLive2D {
switch (name) {
case 'Rest':
void this.stage.slideOut(this.options.transitionTime);
this.statusBar.popup('休息中', SystemState.info, false, () => {
this.statusBar.popup('看板娘休息中', SystemState.info, false, () => {
void this.stage.slideIn(this.options.transitionTime);
this.statusBar.popup('闪亮登场');
void this.tips.idlePlayer?.start();
Expand Down
6 changes: 6 additions & 0 deletions packages/oh-my-live2d/src/modules/model.ts
Expand Up @@ -118,4 +118,10 @@ export class Model {
callback({ status: true });
}
}
get width(): number {
return this.model.width;
}
get height(): number {
return this.model.height;
}
}
2 changes: 1 addition & 1 deletion packages/oh-my-live2d/src/modules/stage.ts
Expand Up @@ -13,9 +13,9 @@ export class Stage {
element: HTMLElement;
canvasElement: HTMLCanvasElement;
wrapperElement: HTMLElement;
status: Status = Status.hidden;
private style: CSSProperties = {};
private canvasStyle: CSSProperties = {};
private status: Status = Status.hidden;
private slideChangeEnd?: (status: Status) => void;
constructor(
private targetElement: HTMLElement,
Expand Down
37 changes: 9 additions & 28 deletions packages/oh-my-live2d/src/modules/tips.ts
@@ -1,17 +1,17 @@
import { getRandomArrayItem, isFunction, mergeDeep, setIntervalAsync } from 'tianjie';

import { CONFIG } from '../config/index.js';
import { CONFIG, TIPS_DEFAULT_STYLE } from '../config/index.js';
import type { IdleTimer } from '../types/common.js';
import type { CSSProperties, DefaultTipsOptions } from '../types/index.js';
import { createElement, getWelcomeMessage, getWordTheDay, handleCommonStyle, setStyleForElement, sleep } from '../utils/index.js';
import { createElement, getWelcomeMessage, getWordTheDay, setStyleForElement, sleep } from '../utils/index.js';

export class Tips {
private element: HTMLElement;
// private status: Status = Status.Hidden;
idlePlayer?: IdleTimer;
private closeTimer = 0;
private transitionTime = 1000; // 默认的消息过渡动画持续时长
private style: CSSProperties = {};
private style: CSSProperties = TIPS_DEFAULT_STYLE;
private priority = 0; // 当前优先级
private contentElement: HTMLElement;
private contentStyle: CSSProperties = {};
Expand All @@ -31,26 +31,7 @@ export class Tips {
* 初始化样式
*/
initStyle(): void {
this.setStyle({
position: 'absolute',
fontSize: '18px',
borderRadius: '10px',
filter: 'drop-shadow(0 0 5px #999)',
border: '2px solid #fff',
color: '#fff',
padding: '15px 5px',
opacity: 0,
visibility: 'hidden',
transform: 'translateX(-50%)',
textAlign: 'center',
justifyContent: 'center',
animationDuration: `${this.transitionTime}ms,${this.transitionTime}ms`,
animationFillMode: 'forwards, none',
animationIterationCount: '1, infinite',
width: '60%',
left: '50%',
top: 0
});
// this.setStyle();

this.setContentStyle({
display: '-webkit-box',
Expand All @@ -60,18 +41,18 @@ export class Tips {
overflow: 'hidden'
});

if (this.tipsOptions) {
const style = handleCommonStyle(this.tipsOptions.style || {});
// if (this.tipsOptions) {
// const style = handleCommonStyle(this.tipsOptions.style || {});

this.setStyle(style);
}
// this.setStyle(style);
// }
}

/**
* 设置提示框样式
* @param style
*/
setStyle(style: CSSProperties): void {
setStyle(style: CSSProperties = {}): void {
this.style = mergeDeep(this.style, style);
setStyleForElement(this.style, this.element);
}
Expand Down
3 changes: 2 additions & 1 deletion packages/oh-my-live2d/src/types/index.ts
Expand Up @@ -30,8 +30,9 @@ export type DefaultOptions = Omit<DeepRequired<Options>, 'parentElement' | 'mode
} & {
models: ModelOptions[];
};
export type DefaultTipsOptions = Omit<DeepRequired<TipsOptions>, 'style'> & {
export type DefaultTipsOptions = Omit<DeepRequired<TipsOptions>, 'style' | 'mobileStyle'> & {
style?: CommonStyleType;
mobileStyle?: CommonStyleType;
};

export type Live2DModelType = typeof Live2DModel;
Expand Down
31 changes: 25 additions & 6 deletions packages/oh-my-live2d/src/types/model.ts
Expand Up @@ -18,7 +18,6 @@ export interface ModelOptions {
path: string;
/**
* 模型的缩放比例
*
* @default 0.1
*/
scale?: number;
Expand All @@ -31,15 +30,35 @@ export interface ModelOptions {
*/
position?: [x: number, y: number];

/**
* 定义舞台样式, 支持传入CSS对象, 传入的样式将通过内联样式作用于舞台元素, 舞台的默认宽高将自适应模型的宽高, 舞台内Canvas元素的宽高始终与舞台保持一致
* @valueType object
*/
stageStyle?: CommonStyleType;

/**
* 移动端时模型的缩放比例
* @default 0.1
*/
mobileScale?: number;

/**
* 移动端时模型在舞台中的位置。x: 横坐标, y: 纵坐标
* @valueType [x: number, y:number]
* @default [0,0]
*/
mobilePosition?: [x: number, y: number];

/**
* 移动端时舞台的样式, 支持传入CSS对象, 传入的样式将通过内联样式作用于舞台元素, 舞台的默认宽高将自适应模型的宽高, 舞台内Canvas元素的宽高始终与舞台保持一致
* @valueType object
*/
mobileStageStyle?: CommonStyleType;

/**
* 动作预加载策略
* @valueType ALL | IDLE | NONE
* @default IDLE
*/
motionPreloadStrategy?: 'ALL' | 'IDLE' | 'NONE';
/**
* 定义舞台样式, 支持传入CSS对象, 传入的样式将通过内联样式作用于舞台元素, 舞台的默认宽高将自适应模型的宽高, 舞台内Canvas元素的宽高始终与舞台保持一致
* @valueType object
*/
stageStyle?: CommonStyleType;
}
5 changes: 5 additions & 0 deletions packages/oh-my-live2d/src/types/options.ts
Expand Up @@ -9,6 +9,11 @@ import type { ImportType } from './index.js';
* @name 配置选项
*/
export interface Options {
/**
* 移动端是否展示, 开启后将以移动端样式展示各元素
* @default false
*/
mobileDisplay?: boolean;
/**
* 导入类型, 默认使用全量导入: complete
* @default complete
Expand Down
5 changes: 5 additions & 0 deletions packages/oh-my-live2d/src/types/tips.ts
Expand Up @@ -21,6 +21,11 @@ export interface TipsOptions {
*/
style?: CommonStyleType;

/**
*
* 移动端时的提示框样式, 支持传入CSS对象, 提示框的默认情况下, 始终与舞台保持水平居中, 默认宽度为舞台的60%, 高度自动被内容撑开.
*/
mobileStyle?: CommonStyleType;
/**
* 闲置状态下的提示
*
Expand Down

0 comments on commit 3850838

Please sign in to comment.