|
@@ -43,30 +43,6 @@ struct PlayerWidgetMedium {
|
|
|
@LocalStorageProp('imageColorHex') imageColorHex: string = '2A2A2A';
|
|
@LocalStorageProp('imageColorHex') imageColorHex: string = '2A2A2A';
|
|
|
@LocalStorageProp('imgName') imgName: string = ''; // 图片文件名,用于memory://协议
|
|
@LocalStorageProp('imgName') imgName: string = ''; // 图片文件名,用于memory://协议
|
|
|
|
|
|
|
|
- /**
|
|
|
|
|
- * 获取按钮透明度
|
|
|
|
|
- */
|
|
|
|
|
- private getButtonOpacity(enabled: boolean): number {
|
|
|
|
|
- return enabled ? 1.0 : 0.4;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 获取按钮颜色
|
|
|
|
|
- */
|
|
|
|
|
- private getButtonColor(enabled: boolean): string {
|
|
|
|
|
- return enabled ? '#FF007DFF' : '#66000000';
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 获取播放按钮图标
|
|
|
|
|
- */
|
|
|
|
|
- private getPlayButtonIcon(): Resource {
|
|
|
|
|
- if (this.isLoading) {
|
|
|
|
|
- return $r('app.media.hm_more'); // 加载状态图标
|
|
|
|
|
- }
|
|
|
|
|
- return this.isPlaying ? $r('app.media.hm_pause') : $r('app.media.hm_play');
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
/**
|
|
/**
|
|
|
* 格式化歌曲标题显示
|
|
* 格式化歌曲标题显示
|
|
|
*/
|
|
*/
|
|
@@ -95,9 +71,14 @@ struct PlayerWidgetMedium {
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 生成渐变色
|
|
* 生成渐变色
|
|
|
- * 根据主色生成更丰富的渐变效果
|
|
|
|
|
|
|
+ * 根据封面图片的主色调生成合适的渐变背景
|
|
|
*/
|
|
*/
|
|
|
private generateGradientColors(): [string, number][] {
|
|
private generateGradientColors(): [string, number][] {
|
|
|
|
|
+ // 如果没有封面或颜色信息,使用默认渐变
|
|
|
|
|
+ if (!this.imageColorHex || this.imageColorHex.trim() === '' || this.imageColorHex === '2A2A2A') {
|
|
|
|
|
+ return this.getDefaultGradientColors();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
const baseColor = this.imageColorHex;
|
|
const baseColor = this.imageColorHex;
|
|
|
|
|
|
|
|
// 解析RGB值
|
|
// 解析RGB值
|
|
@@ -105,6 +86,86 @@ struct PlayerWidgetMedium {
|
|
|
const g = parseInt(baseColor.substring(2, 4), 16);
|
|
const g = parseInt(baseColor.substring(2, 4), 16);
|
|
|
const b = parseInt(baseColor.substring(4, 6), 16);
|
|
const b = parseInt(baseColor.substring(4, 6), 16);
|
|
|
|
|
|
|
|
|
|
+ // 计算亮度,用于判断是深色还是浅色
|
|
|
|
|
+ const brightness = (r * 299 + g * 587 + b * 114) / 1000;
|
|
|
|
|
+
|
|
|
|
|
+ // 根据亮度调整渐变策略
|
|
|
|
|
+ if (brightness < 60) {
|
|
|
|
|
+ // 深色封面:从更深的色调渐变到原色调
|
|
|
|
|
+ return this.generateDarkGradient(r, g, b);
|
|
|
|
|
+ } else if (brightness > 180) {
|
|
|
|
|
+ // 浅色封面:降低亮度,创建柔和渐变
|
|
|
|
|
+ return this.generateLightGradient(r, g, b);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 中等亮度:标准渐变
|
|
|
|
|
+ return this.generateStandardGradient(r, g, b);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 生成深色渐变(适用于深色封面)
|
|
|
|
|
+ */
|
|
|
|
|
+ private generateDarkGradient(r: number, g: number, b: number): [string, number][] {
|
|
|
|
|
+ // 生成更深的起始色
|
|
|
|
|
+ const darkerR = Math.max(0, Math.floor(r * 0.2));
|
|
|
|
|
+ const darkerG = Math.max(0, Math.floor(g * 0.2));
|
|
|
|
|
+ const darkerB = Math.max(0, Math.floor(b * 0.2));
|
|
|
|
|
+
|
|
|
|
|
+ // 中间色稍微提亮
|
|
|
|
|
+ const midR = Math.floor(r * 0.6);
|
|
|
|
|
+ const midG = Math.floor(g * 0.6);
|
|
|
|
|
+ const midB = Math.floor(b * 0.6);
|
|
|
|
|
+
|
|
|
|
|
+ // 终点色适度提亮
|
|
|
|
|
+ const lightR = Math.min(255, Math.floor(r * 1.2));
|
|
|
|
|
+ const lightG = Math.min(255, Math.floor(g * 1.2));
|
|
|
|
|
+ const lightB = Math.min(255, Math.floor(b * 1.2));
|
|
|
|
|
+
|
|
|
|
|
+ const darkerColor = `#ff${darkerR.toString(16).padStart(2, '0')}${darkerG.toString(16).padStart(2, '0')}${darkerB.toString(16).padStart(2, '0')}`;
|
|
|
|
|
+ const midColor = `#ff${midR.toString(16).padStart(2, '0')}${midG.toString(16).padStart(2, '0')}${midB.toString(16).padStart(2, '0')}`;
|
|
|
|
|
+ const lightColor = `#ff${lightR.toString(16).padStart(2, '0')}${lightG.toString(16).padStart(2, '0')}${lightB.toString(16).padStart(2, '0')}`;
|
|
|
|
|
+
|
|
|
|
|
+ return [
|
|
|
|
|
+ [darkerColor, 0.0],
|
|
|
|
|
+ [midColor, 0.6],
|
|
|
|
|
+ [lightColor, 1.0]
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 生成浅色渐变(适用于浅色封面)
|
|
|
|
|
+ */
|
|
|
|
|
+ private generateLightGradient(r: number, g: number, b: number): [string, number][] {
|
|
|
|
|
+ // 大幅降低亮度作为起始色
|
|
|
|
|
+ const darkerR = Math.floor(r * 0.3);
|
|
|
|
|
+ const darkerG = Math.floor(g * 0.3);
|
|
|
|
|
+ const darkerB = Math.floor(b * 0.3);
|
|
|
|
|
+
|
|
|
|
|
+ // 中间色适度降低亮度
|
|
|
|
|
+ const midR = Math.floor(r * 0.5);
|
|
|
|
|
+ const midG = Math.floor(g * 0.5);
|
|
|
|
|
+ const midB = Math.floor(b * 0.5);
|
|
|
|
|
+
|
|
|
|
|
+ // 终点色保持相对较暗,避免过亮
|
|
|
|
|
+ const endR = Math.floor(r * 0.7);
|
|
|
|
|
+ const endG = Math.floor(g * 0.7);
|
|
|
|
|
+ const endB = Math.floor(b * 0.7);
|
|
|
|
|
+
|
|
|
|
|
+ const darkerColor = `#ff${darkerR.toString(16).padStart(2, '0')}${darkerG.toString(16).padStart(2, '0')}${darkerB.toString(16).padStart(2, '0')}`;
|
|
|
|
|
+ const midColor = `#ff${midR.toString(16).padStart(2, '0')}${midG.toString(16).padStart(2, '0')}${midB.toString(16).padStart(2, '0')}`;
|
|
|
|
|
+ const endColor = `#ff${endR.toString(16).padStart(2, '0')}${endG.toString(16).padStart(2, '0')}${endB.toString(16).padStart(2, '0')}`;
|
|
|
|
|
+
|
|
|
|
|
+ return [
|
|
|
|
|
+ [darkerColor, 0.0],
|
|
|
|
|
+ [midColor, 0.5],
|
|
|
|
|
+ [endColor, 1.0]
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 生成标准渐变(适用于中等亮度封面)
|
|
|
|
|
+ */
|
|
|
|
|
+ private generateStandardGradient(r: number, g: number, b: number): [string, number][] {
|
|
|
// 生成较深的颜色作为渐变起始
|
|
// 生成较深的颜色作为渐变起始
|
|
|
const darkerR = Math.max(0, Math.floor(r * 0.4));
|
|
const darkerR = Math.max(0, Math.floor(r * 0.4));
|
|
|
const darkerG = Math.max(0, Math.floor(g * 0.4));
|
|
const darkerG = Math.max(0, Math.floor(g * 0.4));
|
|
@@ -117,7 +178,7 @@ struct PlayerWidgetMedium {
|
|
|
|
|
|
|
|
const darkerColor = `#ff${darkerR.toString(16).padStart(2, '0')}${darkerG.toString(16).padStart(2, '0')}${darkerB.toString(16).padStart(2, '0')}`;
|
|
const darkerColor = `#ff${darkerR.toString(16).padStart(2, '0')}${darkerG.toString(16).padStart(2, '0')}${darkerB.toString(16).padStart(2, '0')}`;
|
|
|
const midColor = `#ff${midR.toString(16).padStart(2, '0')}${midG.toString(16).padStart(2, '0')}${midB.toString(16).padStart(2, '0')}`;
|
|
const midColor = `#ff${midR.toString(16).padStart(2, '0')}${midG.toString(16).padStart(2, '0')}${midB.toString(16).padStart(2, '0')}`;
|
|
|
- const originalColor = `#ff${baseColor}`;
|
|
|
|
|
|
|
+ const originalColor = `#ff${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
|
|
|
|
|
|
|
|
return [
|
|
return [
|
|
|
[darkerColor, 0.0],
|
|
[darkerColor, 0.0],
|
|
@@ -126,6 +187,17 @@ struct PlayerWidgetMedium {
|
|
|
];
|
|
];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取默认渐变色(当没有封面时使用)
|
|
|
|
|
+ */
|
|
|
|
|
+ private getDefaultGradientColors(): [string, number][] {
|
|
|
|
|
+ return [
|
|
|
|
|
+ ['#ff1a1a1a', 0.0], // 深灰色
|
|
|
|
|
+ ['#ff2a2a2a', 0.5], // 中灰色
|
|
|
|
|
+ ['#ff3a3a3a', 1.0] // 浅灰色
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 获取专辑封面
|
|
* 获取专辑封面
|
|
|
*/
|
|
*/
|
|
@@ -192,7 +264,6 @@ struct PlayerWidgetMedium {
|
|
|
.alignRules(MediumCoverAlignRules)
|
|
.alignRules(MediumCoverAlignRules)
|
|
|
.id('musicCover')
|
|
.id('musicCover')
|
|
|
.onClick(() => {
|
|
.onClick(() => {
|
|
|
- console.info('Heanup PlayerWidgetMedium: Album cover clicked');
|
|
|
|
|
postCardAction(this, {
|
|
postCardAction(this, {
|
|
|
'action': 'router',
|
|
'action': 'router',
|
|
|
'abilityName': 'EntryAbility'
|
|
'abilityName': 'EntryAbility'
|
|
@@ -211,7 +282,6 @@ struct PlayerWidgetMedium {
|
|
|
.width(40)
|
|
.width(40)
|
|
|
.height(40)
|
|
.height(40)
|
|
|
.backgroundColor(Color.Transparent)
|
|
.backgroundColor(Color.Transparent)
|
|
|
- .enabled(!this.isLoading && this.hasPrevious)
|
|
|
|
|
.opacity(this.hasPrevious ? 1.0 : 0.5)
|
|
.opacity(this.hasPrevious ? 1.0 : 0.5)
|
|
|
.onClick(() => {
|
|
.onClick(() => {
|
|
|
console.info(`Heanup PlayerWidgetMedium: Previous button clicked`);
|
|
console.info(`Heanup PlayerWidgetMedium: Previous button clicked`);
|
|
@@ -238,7 +308,6 @@ struct PlayerWidgetMedium {
|
|
|
.height(48)
|
|
.height(48)
|
|
|
.backgroundColor(Color.Transparent)
|
|
.backgroundColor(Color.Transparent)
|
|
|
.margin({ left: 20, right: 20 })
|
|
.margin({ left: 20, right: 20 })
|
|
|
- .enabled(!this.isLoading)
|
|
|
|
|
.onClick(() => {
|
|
.onClick(() => {
|
|
|
console.info('Heanup PlayerWidgetMedium: Play/Pause button clicked');
|
|
console.info('Heanup PlayerWidgetMedium: Play/Pause button clicked');
|
|
|
if (!this.isLoading) {
|
|
if (!this.isLoading) {
|
|
@@ -264,7 +333,6 @@ struct PlayerWidgetMedium {
|
|
|
.width(40)
|
|
.width(40)
|
|
|
.height(40)
|
|
.height(40)
|
|
|
.backgroundColor(Color.Transparent)
|
|
.backgroundColor(Color.Transparent)
|
|
|
- .enabled(!this.isLoading && this.hasNext)
|
|
|
|
|
.opacity(this.hasNext ? 1.0 : 0.5)
|
|
.opacity(this.hasNext ? 1.0 : 0.5)
|
|
|
.onClick(() => {
|
|
.onClick(() => {
|
|
|
console.info(`Heanup PlayerWidgetMedium: Next button clicked`);
|
|
console.info(`Heanup PlayerWidgetMedium: Next button clicked`);
|