/*
* Copyright (c) Huawei Device Co., Ltd. 2024-2025. All rights reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { CommonUtils } from '@ohos/basicutils';
import { CustomPromise } from '@ohos/frameworkwrapper';
// 通知条目大小预切换监听
export type OnItemPreSizeChange = (paras: NotificationAnimationParas, isForceAnim?: boolean) => void;
/**
* 通知动效配置参数
*
* @since 2023-09-03
*/
@Observed
export class NotificationAnimationParas {
private itemPreSizeChange?: OnItemPreSizeChange;
/**
* 记录通知列表item X轴位移
*/
public ntfItemTranslateX: number;
public clearAnimOpacity: number;
public clearAnimScale: number;
/**
* 通知列表item进入、退出时x轴旋转角度
*/
public ntfItemRotateAngels: number;
/**
* 记录通知列表item Y轴位移
*/
public ntfItemTranslateY: number;
public ntfItemRotateCenterY: string | number;
public ntfItemZIndex: number = 0; // 条目层级
public itemScaleCenterY?: number; // 纵轴缩放中心点
public ntfItemClipHeight: number = -1; // 条目裁切高度
public ntfItemClipOffsetY: number = 0; // 条目裁切竖向偏移
public isGroupExpanded: boolean = false; // 组通知是否展开状态
private isItemTouchEnable?: boolean; // 通知条目是否开启触摸事件
private clipAnim?: AnimateParam; // 更新切割时动效曲线
private clipAnimWait?: CustomPromise<void>; // 切割动效等待
private isDisableEffect?: boolean; // 是否临时关闭模糊效果
public realHeight?: number | undefined;
public templateTranslateY: number = 0;
public isTopItem: boolean = false; // 是否是顶部通知
public isBottomItem: boolean = false; // 是否是底部通知
public clipArea: Area | undefined = undefined;
constructor(transX: number, transY: number, opacity: number, scale: number, rotate: number) {
this.ntfItemTranslateX = transX;
this.ntfItemTranslateY = transY;
this.clearAnimOpacity = opacity;
this.clearAnimScale = scale;
this.ntfItemRotateAngels = rotate;
this.ntfItemRotateCenterY = '0%';
}
reset(transY: number = 0) {
this.ntfItemTranslateX = 0;
this.ntfItemTranslateY = transY;
this.clearAnimOpacity = 1;
this.clearAnimScale = 1;
this.ntfItemRotateAngels = 0;
this.ntfItemRotateCenterY = '0%';
this.ntfItemZIndex = 0;
this.ntfItemClipHeight = -1;
this.ntfItemClipOffsetY = 0;
this.isGroupExpanded = false;
}
public setItemPreSizeChange(listener?: OnItemPreSizeChange): NotificationAnimationParas { // 条目大小预切换监听
this.itemPreSizeChange = listener;
return this;
}
public updateItemPresSize(isForceAnim?: boolean): NotificationAnimationParas { // 条目大小预切换
this.itemPreSizeChange?.(this, isForceAnim);
return this;
}
public isTempDisableEffect(): boolean { // 关闭模糊
return this.isDisableEffect ?? false;
}
public isItemEnable(): boolean { // 条目可触摸状态
if (CommonUtils.isInvalid(this.isItemTouchEnable)) { // 无赋能时,用alpha替代
let alpha = this.clearAnimOpacity ?? 1;
// 阈值要保证用户明显感知卡片堆叠,避免堆叠不显著时用户无法点击卡片而造成误解
return alpha >= 0.8;
}
return this.isItemTouchEnable as boolean;
}
public getClipAnim(): AnimateParam | undefined { // 裁切动效
return this.clipAnim;
}
public updateGroupExpanded(isExpanded: boolean): NotificationAnimationParas { // 更新组通知状态
this.isGroupExpanded = isExpanded;
return this;
}
public updateItemTouchEnable(isEnable?: boolean): NotificationAnimationParas { // 更新可触摸状态
this.isItemTouchEnable = isEnable;
return this;
}
public updateTranX(tranX: number): NotificationAnimationParas { // 更新横向位移
this.ntfItemTranslateX = tranX;
return this;
}
public updateTranY(tranY: number): NotificationAnimationParas { // 更新竖向位移
this.ntfItemTranslateY = tranY;
return this;
}
public updateAlpha(alpha: number): NotificationAnimationParas { // 更新透明度
this.clearAnimOpacity = alpha;
return this;
}
public updateScale(scale: number): NotificationAnimationParas { // 更新缩放
this.clearAnimScale = scale;
return this;
}
public updateScaleCenterY(centerY?: number): NotificationAnimationParas { // 更新缩放纵轴中心点
this.itemScaleCenterY = centerY;
return this;
}
public updateClipHeight(clipHeight: number): NotificationAnimationParas { // 更新裁切高度
this.ntfItemClipHeight = clipHeight;
return this;
}
public updateClipOffsetY(clipOffsetY: number): NotificationAnimationParas { // 更新裁切纵向偏移
this.ntfItemClipOffsetY = clipOffsetY;
return this;
}
public updateClipAnim(anim?: AnimateParam): NotificationAnimationParas { // 更新切割动效参数
this.clipAnim = anim;
return this;
}
public updateZIndex(zIndex: number): NotificationAnimationParas { // 更新层级
this.ntfItemZIndex = zIndex;
return this;
}
public setClipAnimWait(): NotificationAnimationParas { // 标记裁切动效等待
if (!this.clipAnimWait) {
this.clipAnimWait = new CustomPromise();
}
return this;
}
public async startClipAnimWait(): Promise<void> { // 开启裁切动效等待
if (this.clipAnimWait) {
await this.clipAnimWait;
}
}
public resolveClipAnimWait(): void { // 裁切动效放行
setTimeout(() => {
if (this.clipAnimWait) {
this.clipAnimWait.resolve();
this.clipAnimWait = undefined;
}
});
}
public updateDisableEffect(disable?: boolean): NotificationAnimationParas { // 临时关闭模糊
this.isDisableEffect = disable;
return this;
}
/**
* 是否处理堆叠态
*
* @returns
*/
public isStacking(): boolean {
return this.clearAnimOpacity < 1;
}
public updateClipArea(clipArea: Area): void {
this.clipArea = clipArea;
}
}