mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-04-11 15:47:06 +08:00
feat: 滚动条渐变
This commit is contained in:
parent
6e990fa926
commit
c5101c9b29
@ -19,9 +19,10 @@ import {
|
||||
Transform
|
||||
} from '@/core/render';
|
||||
import { MotaOffscreenCanvas2D } from '@/core/fx/canvas2d';
|
||||
import { hyper, Transition } from 'mutate-animate';
|
||||
import { hyper, linear, Transition } from 'mutate-animate';
|
||||
import { clamp } from 'lodash-es';
|
||||
import { IActionEvent, IWheelEvent, MouseType } from '@/core/render/event';
|
||||
import { transitioned } from '../use';
|
||||
|
||||
export const enum ScrollDirection {
|
||||
Horizontal,
|
||||
@ -61,7 +62,7 @@ const SCROLL_MIN_LENGTH = 20;
|
||||
/** 滚动条图示的宽度 */
|
||||
const SCROLL_WIDTH = 10;
|
||||
/** 滚动条的颜色 */
|
||||
const SCROLL_COLOR = '#ddd';
|
||||
const SCROLL_COLOR = '255,255,255';
|
||||
|
||||
/**
|
||||
* 滚动条组件,具有虚拟滚动功能,即在画面外的不渲染。参数参考 {@link ScrollProps},暴露接口参考 {@link ScrollExpose}
|
||||
@ -100,11 +101,20 @@ export const Scroll = defineComponent<ScrollProps, {}, string, ScrollSlots>(
|
||||
const content = ref<Container>();
|
||||
const scroll = ref<Sprite>();
|
||||
|
||||
const scrollAlpha = transitioned(0.5, 100, linear())!;
|
||||
|
||||
const width = computed(() => props.loc[2] ?? 200);
|
||||
const height = computed(() => props.loc[3] ?? 200);
|
||||
const direction = computed(() =>
|
||||
props.hor ? ScrollDirection.Horizontal : ScrollDirection.Vertical
|
||||
);
|
||||
const scrollColor = computed(
|
||||
() => `rgba(${SCROLL_COLOR},${scrollAlpha.ref.value ?? 0.5})`
|
||||
);
|
||||
|
||||
watch(scrollColor, () => {
|
||||
scroll.value?.update();
|
||||
});
|
||||
|
||||
/** 滚动内容的当前位置 */
|
||||
let contentPos = 0;
|
||||
@ -301,7 +311,7 @@ export const Scroll = defineComponent<ScrollProps, {}, string, ScrollSlots>(
|
||||
const ctx = canvas.ctx;
|
||||
ctx.lineCap = 'round';
|
||||
ctx.lineWidth = 3;
|
||||
ctx.strokeStyle = SCROLL_COLOR;
|
||||
ctx.strokeStyle = scrollColor.value;
|
||||
ctx.beginPath();
|
||||
const scroll = transition.value.scroll;
|
||||
if (direction.value === ScrollDirection.Horizontal) {
|
||||
@ -435,6 +445,7 @@ export const Scroll = defineComponent<ScrollProps, {}, string, ScrollSlots>(
|
||||
} else {
|
||||
scrollMutate = true;
|
||||
}
|
||||
scrollAlpha.set(0.9);
|
||||
};
|
||||
|
||||
const moveScroll = (ev: IActionEvent) => {
|
||||
@ -461,6 +472,7 @@ export const Scroll = defineComponent<ScrollProps, {}, string, ScrollSlots>(
|
||||
};
|
||||
|
||||
const upScroll = (ev: IActionEvent) => {
|
||||
scrollAlpha.set(0.7);
|
||||
if (!scrollMutate) return;
|
||||
const pos = getPos(ev);
|
||||
if (pos < scrollPos) {
|
||||
@ -470,6 +482,14 @@ export const Scroll = defineComponent<ScrollProps, {}, string, ScrollSlots>(
|
||||
}
|
||||
};
|
||||
|
||||
const enter = () => {
|
||||
scrollAlpha.set(0.7);
|
||||
};
|
||||
|
||||
const leave = () => {
|
||||
scrollAlpha.set(0.5);
|
||||
};
|
||||
|
||||
//#endregion
|
||||
|
||||
onMounted(() => {
|
||||
@ -508,6 +528,8 @@ export const Scroll = defineComponent<ScrollProps, {}, string, ScrollSlots>(
|
||||
onDown={downScroll}
|
||||
onUp={upScroll}
|
||||
zIndex={10}
|
||||
onEnter={enter}
|
||||
onLeave={leave}
|
||||
></sprite>
|
||||
</container>
|
||||
);
|
||||
|
@ -3,7 +3,6 @@ import { defineComponent } from 'vue';
|
||||
import { SetupComponentOptions } from '../components';
|
||||
import { ElementLocator } from '@/core/render';
|
||||
import { Scroll } from '../components/scroll';
|
||||
import { Page } from '../components/page';
|
||||
|
||||
export interface ILeftHeroStatus {
|
||||
hp: number;
|
||||
@ -171,21 +170,6 @@ export const RightStatusBar = defineComponent<StatusBarProps<IRightHeroStatus>>(
|
||||
<container loc={p.loc}>
|
||||
<g-rect loc={[0, 0, p.loc[2], p.loc[3]]} stroke></g-rect>
|
||||
<Scroll loc={[0, 0, 180, 100]}></Scroll>
|
||||
<Page loc={[0, 200, 180, 100]} pages={3}>
|
||||
{(page: number) => {
|
||||
switch (page) {
|
||||
case 1: {
|
||||
return <text text="测试"></text>;
|
||||
}
|
||||
case 2: {
|
||||
return <text text="测试2"></text>;
|
||||
}
|
||||
case 3: {
|
||||
return <text text="测试3"></text>;
|
||||
}
|
||||
}
|
||||
}}
|
||||
</Page>
|
||||
</container>
|
||||
);
|
||||
};
|
||||
|
@ -1,4 +1,12 @@
|
||||
import { onMounted, onUnmounted } from 'vue';
|
||||
import { TimingFn, Transition } from 'mutate-animate';
|
||||
import {
|
||||
ComponentInternalInstance,
|
||||
getCurrentInstance,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
ref,
|
||||
Ref
|
||||
} from 'vue';
|
||||
|
||||
export const enum Orientation {
|
||||
/** 横屏 */
|
||||
@ -58,3 +66,65 @@ export function onLoaded(hook: () => void) {
|
||||
hook();
|
||||
}
|
||||
}
|
||||
|
||||
export interface ITransitionedController {
|
||||
readonly ref: Ref<number>;
|
||||
readonly value: number;
|
||||
set(value: number): void;
|
||||
}
|
||||
|
||||
class RenderTransition implements ITransitionedController {
|
||||
private static key: number = 0;
|
||||
|
||||
private readonly key: string = `$${RenderTransition.key++}`;
|
||||
|
||||
public readonly ref: Ref<number>;
|
||||
|
||||
set value(v: number) {
|
||||
this.transition.transition(this.key, v);
|
||||
}
|
||||
get value() {
|
||||
return this.transition.value[this.key];
|
||||
}
|
||||
|
||||
constructor(
|
||||
value: number,
|
||||
public readonly transition: Transition,
|
||||
public readonly time: number,
|
||||
public readonly curve: TimingFn
|
||||
) {
|
||||
this.ref = ref(value);
|
||||
transition.ticker.add(() => {
|
||||
this.ref.value = transition.value[this.key];
|
||||
});
|
||||
}
|
||||
|
||||
set(value: number): void {
|
||||
this.transition
|
||||
.time(this.time)
|
||||
.mode(this.curve)
|
||||
.transition(this.key, value);
|
||||
}
|
||||
}
|
||||
|
||||
const transitionMap = new Map<ComponentInternalInstance, Transition>();
|
||||
|
||||
export function transitioned(
|
||||
value: number,
|
||||
time: number,
|
||||
curve: TimingFn
|
||||
): ITransitionedController | null {
|
||||
const instance = getCurrentInstance();
|
||||
if (!instance) return null;
|
||||
if (!transitionMap.has(instance)) {
|
||||
const tran = new Transition();
|
||||
transitionMap.set(instance, tran);
|
||||
onUnmounted(() => {
|
||||
transitionMap.delete(instance);
|
||||
tran.ticker.destroy();
|
||||
});
|
||||
}
|
||||
const tran = transitionMap.get(instance);
|
||||
if (!tran) return null;
|
||||
return new RenderTransition(value, tran, time, curve);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user