feat: festive Chinese red background and prize config unification
- Change all big screen backgrounds to pure Chinese red (#c41230) - Remove vignette effect for consistent display on different screens - Unify all prize data to match prizes.json configuration - Add demo participants fallback when no data imported - Fix particle visibility reset in startGalaxy() Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,7 +10,8 @@ html, body {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: $color-bg-dark;
|
// Chinese New Year festive pure red background
|
||||||
|
background: #c41230;
|
||||||
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||||||
color: $color-text-light;
|
color: $color-text-light;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ $color-gold-light: #ffd966;
|
|||||||
$color-gold-dark: #d4a84b;
|
$color-gold-dark: #d4a84b;
|
||||||
$color-gold-deep: #b8923f;
|
$color-gold-deep: #b8923f;
|
||||||
|
|
||||||
// Cinematic background
|
// Cinematic background - Festive Chinese Red
|
||||||
$color-bg-dark: #0a0a0a;
|
$color-bg-dark: #c41230;
|
||||||
$color-bg-wine: #2a0a0e;
|
$color-bg-wine: #c41230;
|
||||||
$color-bg-gradient: linear-gradient(180deg, #2a0a0e 0%, #1a0808 50%, #0a0505 100%);
|
$color-bg-gradient: linear-gradient(180deg, #d4232a 0%, #c41230 50%, #a01028 100%);
|
||||||
|
|
||||||
// Text
|
// Text
|
||||||
$color-text-light: #ffffff;
|
$color-text-light: #ffffff;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Application, Container, Graphics, Ticker } from 'pixi.js';
|
|||||||
|
|
||||||
// Cinematic color palette
|
// Cinematic color palette
|
||||||
const COLORS = {
|
const COLORS = {
|
||||||
wineRed: 0x2a0a0e,
|
wineRed: 0xc41230, // Festive bright Chinese red
|
||||||
gold: 0xf0c239,
|
gold: 0xf0c239,
|
||||||
goldDark: 0xd4a84b,
|
goldDark: 0xd4a84b,
|
||||||
goldLight: 0xffd700,
|
goldLight: 0xffd700,
|
||||||
@@ -81,24 +81,8 @@ export class BackgroundEffect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private drawVignette(): void {
|
private drawVignette(): void {
|
||||||
const vignette = new Graphics();
|
// Disabled vignette for pure solid color background
|
||||||
const w = this.app.screen.width;
|
// Keep method for potential future use
|
||||||
const h = this.app.screen.height;
|
|
||||||
const cx = w / 2;
|
|
||||||
const cy = h / 2;
|
|
||||||
const maxRadius = Math.sqrt(cx * cx + cy * cy);
|
|
||||||
|
|
||||||
// Create radial gradient effect with multiple circles
|
|
||||||
for (let i = 20; i >= 0; i--) {
|
|
||||||
const ratio = i / 20;
|
|
||||||
const radius = maxRadius * (0.3 + ratio * 0.7);
|
|
||||||
const alpha = ratio * 0.8;
|
|
||||||
|
|
||||||
vignette.circle(cx, cy, radius);
|
|
||||||
vignette.fill({ color: 0x000000, alpha });
|
|
||||||
}
|
|
||||||
|
|
||||||
this.app.stage.addChildAt(vignette, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private initDustParticles(): void {
|
private initDustParticles(): void {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const COLORS = {
|
|||||||
red: 0xc21f30,
|
red: 0xc21f30,
|
||||||
redLight: 0xe63946,
|
redLight: 0xe63946,
|
||||||
redDark: 0x8b0000,
|
redDark: 0x8b0000,
|
||||||
wineRed: 0x2a0a0e,
|
wineRed: 0xc41230, // Festive bright Chinese red
|
||||||
black: 0x000000,
|
black: 0x000000,
|
||||||
white: 0xffffff,
|
white: 0xffffff,
|
||||||
};
|
};
|
||||||
@@ -245,9 +245,13 @@ export class LotteryMachine {
|
|||||||
this.confettiContainer.removeChildren();
|
this.confettiContainer.removeChildren();
|
||||||
this.dimOverlay.clear();
|
this.dimOverlay.clear();
|
||||||
|
|
||||||
// Reset particles
|
// Reset particles - restore visibility
|
||||||
this.nameParticles.forEach((p) => {
|
this.nameParticles.forEach((p) => {
|
||||||
p.isWinner = false;
|
p.isWinner = false;
|
||||||
|
if (p.text) {
|
||||||
|
p.text.visible = true;
|
||||||
|
p.text.alpha = 1;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.phase = 'galaxy';
|
this.phase = 'galaxy';
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ $color-text-muted: #888;
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: #0a0a0a;
|
background: #c41230;
|
||||||
}
|
}
|
||||||
|
|
||||||
.race-canvas {
|
.race-canvas {
|
||||||
|
|||||||
@@ -144,12 +144,22 @@ function startGalaxy() {
|
|||||||
// Clear previous winners
|
// Clear previous winners
|
||||||
winners.value = [];
|
winners.value = [];
|
||||||
|
|
||||||
// 使用真实参与者数据(如果有的话)
|
// 使用真实参与者数据,如果没有则使用演示数据
|
||||||
const participants = realParticipants.length > 0 ? realParticipants : [];
|
let participants = realParticipants.length > 0 ? realParticipants : [];
|
||||||
|
|
||||||
if (participants.length === 0) {
|
if (participants.length === 0) {
|
||||||
console.warn('[抽奖] 无参与者数据,请先导入名单');
|
console.warn('[抽奖] 无参与者数据,使用演示数据');
|
||||||
return;
|
// 演示数据
|
||||||
|
participants = [
|
||||||
|
{ id: 'demo1', name: '张三', department: '技术部', zodiac: 'horse', age: 30 },
|
||||||
|
{ id: 'demo2', name: '李四', department: '市场部', zodiac: 'other', age: 28 },
|
||||||
|
{ id: 'demo3', name: '王五', department: '财务部', zodiac: 'horse', age: 32 },
|
||||||
|
{ id: 'demo4', name: '赵六', department: '人事部', zodiac: 'other', age: 26 },
|
||||||
|
{ id: 'demo5', name: '钱七', department: '运营部', zodiac: 'horse', age: 35 },
|
||||||
|
{ id: 'demo6', name: '孙八', department: '技术部', zodiac: 'other', age: 29 },
|
||||||
|
{ id: 'demo7', name: '周九', department: '市场部', zodiac: 'horse', age: 31 },
|
||||||
|
{ id: 'demo8', name: '吴十', department: '财务部', zodiac: 'other', age: 27 },
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set participants and start galaxy view
|
// Set participants and start galaxy view
|
||||||
|
|||||||
@@ -1,42 +1,42 @@
|
|||||||
{
|
{
|
||||||
"prizes": [
|
"prizes": [
|
||||||
{
|
{
|
||||||
"round": 1,
|
"round": 1,
|
||||||
"level": "第一轮抽奖",
|
"level": "第一轮抽奖",
|
||||||
"name": "幸运伴手礼",
|
"name": "幸运伴手礼",
|
||||||
"winnerCount": 7,
|
"winnerCount": 7,
|
||||||
"poolTag": "6070",
|
"poolTag": "6070",
|
||||||
"description": "60/70年代"
|
"description": "60/70年代"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"round": 2,
|
"round": 2,
|
||||||
"level": "第二轮抽奖",
|
"level": "第二轮抽奖",
|
||||||
"name": "幸运伴手礼",
|
"name": "幸运伴手礼",
|
||||||
"winnerCount": 3,
|
"winnerCount": 3,
|
||||||
"poolTag": "80",
|
"poolTag": "80",
|
||||||
"description": "80年代"
|
"description": "80年代"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"round": 3,
|
"round": 3,
|
||||||
"level": "第三轮抽奖",
|
"level": "第三轮抽奖",
|
||||||
"name": "幸运伴手礼",
|
"name": "幸运伴手礼",
|
||||||
"winnerCount": 4,
|
"winnerCount": 4,
|
||||||
"poolTag": "90",
|
"poolTag": "90",
|
||||||
"description": "90年代"
|
"description": "90年代"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"round": 4,
|
"round": 4,
|
||||||
"level": "第四轮抽奖",
|
"level": "第四轮抽奖",
|
||||||
"name": "幸运伴手礼",
|
"name": "幸运伴手礼",
|
||||||
"winnerCount": 1,
|
"winnerCount": 1,
|
||||||
"poolTag": "horse",
|
"poolTag": "horse",
|
||||||
"zodiacFilter": "horse",
|
"zodiacFilter": "horse",
|
||||||
"description": "属马特供"
|
"description": "属马特供"
|
||||||
}
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"minStormDuration": 3000,
|
|
||||||
"revealAnimationDuration": 2000,
|
|
||||||
"allowRepeatWinner": false
|
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"minStormDuration": 3000,
|
||||||
|
"revealAnimationDuration": 2000,
|
||||||
|
"allowRepeatWinner": false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -419,9 +419,9 @@ class AdminService {
|
|||||||
this.state.lottery = {
|
this.state.lottery = {
|
||||||
round: 1,
|
round: 1,
|
||||||
subPhase: 'IDLE',
|
subPhase: 'IDLE',
|
||||||
prizeLevel: firstPrize?.level || '特等奖',
|
prizeLevel: firstPrize?.level || '第一轮抽奖',
|
||||||
prizeName: firstPrize?.name || '待配置',
|
prizeName: firstPrize?.name || '幸运伴手礼',
|
||||||
winnerCount: firstPrize?.winnerCount || 1,
|
winnerCount: firstPrize?.winnerCount || 7,
|
||||||
currentWinners: [],
|
currentWinners: [],
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
@@ -497,12 +497,15 @@ class AdminService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (scope === 'all' || scope === 'lottery') {
|
if (scope === 'all' || scope === 'lottery') {
|
||||||
|
// 从配置获取第一轮奖项
|
||||||
|
const prizes = prizeConfigService.getPrizes();
|
||||||
|
const firstPrize = prizes.find(p => p.round === 1) || prizes[0];
|
||||||
this.state.lottery = {
|
this.state.lottery = {
|
||||||
round: 1,
|
round: 1,
|
||||||
subPhase: 'IDLE',
|
subPhase: 'IDLE',
|
||||||
prizeLevel: '特等奖',
|
prizeLevel: firstPrize?.level || '第一轮抽奖',
|
||||||
prizeName: 'iPhone 16 Pro Max',
|
prizeName: firstPrize?.name || '幸运伴手礼',
|
||||||
winnerCount: 1,
|
winnerCount: firstPrize?.winnerCount || 7,
|
||||||
currentWinners: [],
|
currentWinners: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,10 +61,10 @@ class PrizeConfigService {
|
|||||||
private getDefaults(): PrizeConfigFile {
|
private getDefaults(): PrizeConfigFile {
|
||||||
return {
|
return {
|
||||||
prizes: [
|
prizes: [
|
||||||
{ round: 1 as LotteryRound, level: '特等奖', name: 'iPhone 16 Pro Max', winnerCount: 1 },
|
{ round: 1 as LotteryRound, level: '第一轮抽奖', name: '幸运伴手礼', winnerCount: 7 },
|
||||||
{ round: 2 as LotteryRound, level: '一等奖', name: 'iPad Pro', winnerCount: 3 },
|
{ round: 2 as LotteryRound, level: '第二轮抽奖', name: '幸运伴手礼', winnerCount: 3 },
|
||||||
{ round: 3 as LotteryRound, level: '二等奖', name: 'AirPods Pro', winnerCount: 5 },
|
{ round: 3 as LotteryRound, level: '第三轮抽奖', name: '幸运伴手礼', winnerCount: 4 },
|
||||||
{ round: 4 as LotteryRound, level: '三等奖', name: '京东卡 500元', winnerCount: 10, zodiacFilter: 'horse' },
|
{ round: 4 as LotteryRound, level: '第四轮抽奖', name: '幸运伴手礼', winnerCount: 1, zodiacFilter: 'horse' },
|
||||||
],
|
],
|
||||||
settings: {
|
settings: {
|
||||||
minStormDuration: 3000,
|
minStormDuration: 3000,
|
||||||
|
|||||||
@@ -140,10 +140,10 @@ export interface PrizeConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const PRIZE_CONFIG: PrizeConfig[] = [
|
export const PRIZE_CONFIG: PrizeConfig[] = [
|
||||||
{ round: 1, level: '特等奖', name: 'iPhone 16 Pro Max', winnerCount: 1 },
|
{ round: 1, level: '第一轮抽奖', name: '幸运伴手礼', winnerCount: 7 },
|
||||||
{ round: 2, level: '一等奖', name: 'iPad Pro', winnerCount: 3 },
|
{ round: 2, level: '第二轮抽奖', name: '幸运伴手礼', winnerCount: 3 },
|
||||||
{ round: 3, level: '二等奖', name: 'AirPods Pro', winnerCount: 5 },
|
{ round: 3, level: '第三轮抽奖', name: '幸运伴手礼', winnerCount: 4 },
|
||||||
{ round: 4, level: '三等奖', name: '京东卡 500元', winnerCount: 10, zodiacFilter: 'horse' },
|
{ round: 4, level: '第四轮抽奖', name: '幸运伴手礼', winnerCount: 1, zodiacFilter: 'horse' },
|
||||||
];
|
];
|
||||||
|
|
||||||
// Default programs for voting
|
// Default programs for voting
|
||||||
@@ -175,9 +175,9 @@ export const INITIAL_ADMIN_STATE: AdminState = {
|
|||||||
lottery: {
|
lottery: {
|
||||||
round: 1,
|
round: 1,
|
||||||
subPhase: 'IDLE',
|
subPhase: 'IDLE',
|
||||||
prizeLevel: '特等奖',
|
prizeLevel: '第一轮抽奖',
|
||||||
prizeName: 'iPhone 16 Pro Max',
|
prizeName: '幸运伴手礼',
|
||||||
winnerCount: 1,
|
winnerCount: 7,
|
||||||
currentWinners: [],
|
currentWinners: [],
|
||||||
},
|
},
|
||||||
music: {
|
music: {
|
||||||
|
|||||||
Reference in New Issue
Block a user