补充座驾动画标题用户信息
This commit is contained in:
@@ -41,6 +41,7 @@ class EffectBroadcast implements ShouldBroadcastNow
|
||||
* @param string|null $giftMessage 附带赠言
|
||||
* @param string|null $effectTitle 特效画面标题
|
||||
* @param string|null $rideName 座驾名称
|
||||
* @param string|null $effectUserInfo 特效画面用户身份信息
|
||||
*/
|
||||
public function __construct(
|
||||
public readonly int $roomId,
|
||||
@@ -50,6 +51,7 @@ class EffectBroadcast implements ShouldBroadcastNow
|
||||
public readonly ?string $giftMessage = null,
|
||||
public readonly ?string $effectTitle = null,
|
||||
public readonly ?string $rideName = null,
|
||||
public readonly ?string $effectUserInfo = null,
|
||||
) {}
|
||||
|
||||
/**
|
||||
@@ -79,6 +81,7 @@ class EffectBroadcast implements ShouldBroadcastNow
|
||||
'gift_message' => $this->giftMessage,
|
||||
'effect_title' => $this->effectTitle,
|
||||
'ride_name' => $this->rideName,
|
||||
'effect_user_info' => $this->effectUserInfo,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,6 +251,7 @@ class ChatController extends Controller
|
||||
'ride_key' => $ridePresencePayload['ride_key'],
|
||||
'ride_name' => $ridePresencePayload['ride_name'],
|
||||
'effect_title' => $ridePresencePayload['effect_title'],
|
||||
'effect_user_info' => $ridePresencePayload['effect_user_info'],
|
||||
'sent_at' => now()->toDateTimeString(),
|
||||
];
|
||||
|
||||
@@ -263,11 +264,13 @@ class ChatController extends Controller
|
||||
$user->username,
|
||||
effectTitle: $ridePresencePayload['effect_title'],
|
||||
rideName: $ridePresencePayload['ride_name'],
|
||||
effectUserInfo: $ridePresencePayload['effect_user_info'],
|
||||
))->toOthers();
|
||||
|
||||
$initialRideEffect = $ridePresencePayload['ride_key'];
|
||||
$initialRideEffectOptions = [
|
||||
'effect_title' => $ridePresencePayload['effect_title'],
|
||||
'effect_user_info' => $ridePresencePayload['effect_user_info'],
|
||||
'ride_name' => $ridePresencePayload['ride_name'],
|
||||
'operator' => $user->username,
|
||||
];
|
||||
|
||||
@@ -242,6 +242,7 @@ class RideService
|
||||
'ride_name' => $item->name,
|
||||
'ride_icon' => (string) ($item->icon ?? '🚘'),
|
||||
'effect_title' => "{$user->username} 乘坐【{$item->name}】闪亮登场",
|
||||
'effect_user_info' => $identitySummary['inline'],
|
||||
'identity_text' => ChatContentSanitizer::htmlText($identitySummary['inline']),
|
||||
'welcome_text' => ChatContentSanitizer::htmlText($rendered),
|
||||
];
|
||||
|
||||
@@ -484,6 +484,7 @@ export function bindChatEvents() {
|
||||
const myName = window.chatContext?.username;
|
||||
const effectOptions = {
|
||||
effect_title: e.detail?.effect_title,
|
||||
effect_user_info: e.detail?.effect_user_info,
|
||||
ride_name: e.detail?.ride_name,
|
||||
operator,
|
||||
};
|
||||
|
||||
@@ -447,8 +447,9 @@ const Type99AEffect = (() => {
|
||||
* @param {number} h 画布高度
|
||||
* @param {number} progress 播放进度
|
||||
* @param {string} title 入场标题
|
||||
* @param {string} userInfo 用户身份信息
|
||||
*/
|
||||
function drawHud(ctx, w, h, progress, title) {
|
||||
function drawHud(ctx, w, h, progress, title, userInfo) {
|
||||
const enter = Math.min(1, Math.max(0, (progress - 0.14) / 0.2));
|
||||
const leave = Math.min(1, Math.max(0, (1 - progress) / 0.16));
|
||||
const alpha = easeInOutSine(enter) * leave;
|
||||
@@ -462,16 +463,19 @@ const Type99AEffect = (() => {
|
||||
ctx.fillStyle = "rgba(28,25,23,0.66)";
|
||||
ctx.strokeStyle = "rgba(253,230,138,0.72)";
|
||||
ctx.lineWidth = 2;
|
||||
roundRect(ctx, w * 0.5 - 320, y - 46, 640, 96, 18);
|
||||
roundRect(ctx, w * 0.5 - 340, y - 56, 680, 120, 18);
|
||||
ctx.fill();
|
||||
ctx.stroke();
|
||||
|
||||
ctx.fillStyle = "#fef3c7";
|
||||
ctx.font = "700 16px serif";
|
||||
ctx.fillText("ZTZ-99A ARMORED FORCE", w * 0.5, y - 12);
|
||||
ctx.fillText("ZTZ-99A ARMORED FORCE", w * 0.5, y - 24);
|
||||
ctx.fillStyle = "#fde68a";
|
||||
ctx.font = "700 18px serif";
|
||||
ctx.fillText(userInfo, w * 0.5, y + 8, 620);
|
||||
ctx.fillStyle = "#ffffff";
|
||||
ctx.font = "900 38px serif";
|
||||
ctx.fillText(title, w * 0.5, y + 28, 590);
|
||||
ctx.font = "900 34px serif";
|
||||
ctx.fillText(title, w * 0.5, y + 45, 620);
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
@@ -513,6 +517,7 @@ const Type99AEffect = (() => {
|
||||
const h = canvas.height;
|
||||
const dust = createDust(w, h);
|
||||
const title = String(options.effect_title || "99A主战坦克 重装入场").trim() || "99A主战坦克 重装入场";
|
||||
const userInfo = String(options.effect_user_info || "").trim();
|
||||
const startTime = performance.now();
|
||||
let animId = null;
|
||||
let finished = false;
|
||||
@@ -556,7 +561,7 @@ const Type99AEffect = (() => {
|
||||
drawDust(ctx, dust, w, progress);
|
||||
drawShockwave(ctx, w, h, progress);
|
||||
drawTank(ctx, tankX, tankY, scale, progress);
|
||||
drawHud(ctx, w, h, progress, title);
|
||||
drawHud(ctx, w, h, progress, title, userInfo);
|
||||
|
||||
if (progress < 1) {
|
||||
animId = requestAnimationFrame(animate);
|
||||
|
||||
@@ -270,8 +270,9 @@ const Df5cEffect = (() => {
|
||||
* @param {number} h 画布高度
|
||||
* @param {number} progress 播放进度
|
||||
* @param {string} title 入场标题
|
||||
* @param {string} userInfo 用户身份信息
|
||||
*/
|
||||
function drawHud(ctx, w, h, progress, title) {
|
||||
function drawHud(ctx, w, h, progress, title, userInfo) {
|
||||
const enter = Math.min(1, Math.max(0, (progress - 0.1) / 0.18));
|
||||
const leave = Math.min(1, Math.max(0, (1 - progress) / 0.14));
|
||||
const alpha = easeInOutCubic(enter) * leave;
|
||||
@@ -283,17 +284,20 @@ const Df5cEffect = (() => {
|
||||
ctx.fillStyle = "rgba(15,23,42,0.68)";
|
||||
ctx.strokeStyle = "rgba(248,113,113,0.72)";
|
||||
ctx.lineWidth = 2;
|
||||
roundRect(ctx, w * 0.5 - 330, y - 46, 660, 96, 18);
|
||||
roundRect(ctx, w * 0.5 - 350, y - 56, 700, 120, 18);
|
||||
ctx.fill();
|
||||
ctx.stroke();
|
||||
ctx.shadowColor = "rgba(248,113,113,0.95)";
|
||||
ctx.shadowBlur = 22;
|
||||
ctx.fillStyle = "#fee2e2";
|
||||
ctx.font = "700 16px serif";
|
||||
ctx.fillText("DF-5C STRATEGIC LAUNCH PREVIEW", w * 0.5, y - 12);
|
||||
ctx.fillText("DF-5C STRATEGIC LAUNCH PREVIEW", w * 0.5, y - 24);
|
||||
ctx.fillStyle = "#fecaca";
|
||||
ctx.font = "700 18px serif";
|
||||
ctx.fillText(userInfo, w * 0.5, y + 8, 640);
|
||||
ctx.fillStyle = "#ffffff";
|
||||
ctx.font = "900 38px serif";
|
||||
ctx.fillText(title, w * 0.5, y + 28, 610);
|
||||
ctx.font = "900 34px serif";
|
||||
ctx.fillText(title, w * 0.5, y + 45, 640);
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
@@ -335,6 +339,7 @@ const Df5cEffect = (() => {
|
||||
const h = canvas.height;
|
||||
const particles = createParticles(120);
|
||||
const title = String(options.effect_title || "东风-5C 洲际导弹 升空").trim() || "东风-5C 洲际导弹 升空";
|
||||
const userInfo = String(options.effect_user_info || "").trim();
|
||||
const startTime = performance.now();
|
||||
let animId = null;
|
||||
let finished = false;
|
||||
@@ -378,7 +383,7 @@ const Df5cEffect = (() => {
|
||||
drawLaunchPad(ctx, w, h, progress);
|
||||
drawExhaust(ctx, particles, tailX, tailY, progress);
|
||||
drawMissile(ctx, launchX, launchY, scale, progress);
|
||||
drawHud(ctx, w, h, progress, title);
|
||||
drawHud(ctx, w, h, progress, title, userInfo);
|
||||
|
||||
if (progress < 1) {
|
||||
animId = requestAnimationFrame(animate);
|
||||
|
||||
@@ -394,8 +394,9 @@ const FujianEffect = (() => {
|
||||
* @param {number} h 画布高度
|
||||
* @param {number} progress 播放进度
|
||||
* @param {string} title 入场标题
|
||||
* @param {string} userInfo 用户身份信息
|
||||
*/
|
||||
function drawHud(ctx, w, h, progress, title) {
|
||||
function drawHud(ctx, w, h, progress, title, userInfo) {
|
||||
const enter = Math.min(1, Math.max(0, (progress - 0.12) / 0.2));
|
||||
const leave = Math.min(1, Math.max(0, (1 - progress) / 0.14));
|
||||
const alpha = easeInOutCubic(enter) * leave;
|
||||
@@ -407,17 +408,20 @@ const FujianEffect = (() => {
|
||||
ctx.fillStyle = "rgba(15,23,42,0.68)";
|
||||
ctx.strokeStyle = "rgba(103,232,249,0.72)";
|
||||
ctx.lineWidth = 2;
|
||||
roundRect(ctx, w * 0.5 - 320, y - 46, 640, 96, 18);
|
||||
roundRect(ctx, w * 0.5 - 340, y - 56, 680, 120, 18);
|
||||
ctx.fill();
|
||||
ctx.stroke();
|
||||
ctx.shadowColor = "rgba(103,232,249,0.95)";
|
||||
ctx.shadowBlur = 20;
|
||||
ctx.fillStyle = "#cffafe";
|
||||
ctx.font = "700 16px serif";
|
||||
ctx.fillText("FUJIAN AIRCRAFT CARRIER PREVIEW", w * 0.5, y - 12);
|
||||
ctx.fillText("FUJIAN AIRCRAFT CARRIER PREVIEW", w * 0.5, y - 24);
|
||||
ctx.fillStyle = "#a5f3fc";
|
||||
ctx.font = "700 18px serif";
|
||||
ctx.fillText(userInfo, w * 0.5, y + 8, 620);
|
||||
ctx.fillStyle = "#ffffff";
|
||||
ctx.font = "900 38px serif";
|
||||
ctx.fillText(title, w * 0.5, y + 28, 590);
|
||||
ctx.font = "900 34px serif";
|
||||
ctx.fillText(title, w * 0.5, y + 45, 620);
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
@@ -459,6 +463,7 @@ const FujianEffect = (() => {
|
||||
const h = canvas.height;
|
||||
const waves = createWaves(w, h);
|
||||
const title = String(options.effect_title || "福建舰 航母入场").trim() || "福建舰 航母入场";
|
||||
const userInfo = String(options.effect_user_info || "").trim();
|
||||
const startTime = performance.now();
|
||||
let animId = null;
|
||||
let finished = false;
|
||||
@@ -500,7 +505,7 @@ const FujianEffect = (() => {
|
||||
drawBackdrop(ctx, w, h, progress);
|
||||
drawWaves(ctx, waves, w, progress, carrierX, carrierY, scale);
|
||||
drawCarrier(ctx, carrierX, carrierY, scale, progress);
|
||||
drawHud(ctx, w, h, progress, title);
|
||||
drawHud(ctx, w, h, progress, title, userInfo);
|
||||
|
||||
if (progress < 1) {
|
||||
animId = requestAnimationFrame(animate);
|
||||
|
||||
@@ -337,8 +337,9 @@ const J35Effect = (() => {
|
||||
* @param {number} h 画布高度
|
||||
* @param {number} progress 播放进度
|
||||
* @param {string} title 入场标题
|
||||
* @param {string} userInfo 用户身份信息
|
||||
*/
|
||||
function drawHud(ctx, w, h, progress, title) {
|
||||
function drawHud(ctx, w, h, progress, title, userInfo) {
|
||||
const enter = Math.min(1, Math.max(0, (progress - 0.13) / 0.18));
|
||||
const leave = Math.min(1, Math.max(0, (1 - progress) / 0.16));
|
||||
const alpha = easeInOutSine(enter) * leave;
|
||||
@@ -352,16 +353,19 @@ const J35Effect = (() => {
|
||||
ctx.fillStyle = "rgba(2,6,23,0.62)";
|
||||
ctx.strokeStyle = "rgba(56,189,248,0.72)";
|
||||
ctx.lineWidth = 2;
|
||||
roundRect(ctx, w * 0.5 - 320, y - 46, 640, 96, 18);
|
||||
roundRect(ctx, w * 0.5 - 340, y - 56, 680, 120, 18);
|
||||
ctx.fill();
|
||||
ctx.stroke();
|
||||
|
||||
ctx.fillStyle = "#bae6fd";
|
||||
ctx.font = "700 16px serif";
|
||||
ctx.fillText("STEALTH FIGHTER ARRIVAL", w * 0.5, y - 12);
|
||||
ctx.fillText("STEALTH FIGHTER ARRIVAL", w * 0.5, y - 24);
|
||||
ctx.fillStyle = "#e0f2fe";
|
||||
ctx.font = "700 18px serif";
|
||||
ctx.fillText(userInfo, w * 0.5, y + 8, 620);
|
||||
ctx.fillStyle = "#ffffff";
|
||||
ctx.font = "900 38px serif";
|
||||
ctx.fillText(title, w * 0.5, y + 28, 590);
|
||||
ctx.font = "900 34px serif";
|
||||
ctx.fillText(title, w * 0.5, y + 45, 620);
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
@@ -403,6 +407,7 @@ const J35Effect = (() => {
|
||||
const h = canvas.height;
|
||||
const speedLines = createSpeedLines(w, h);
|
||||
const title = String(options.effect_title || "中国歼-35 破空入场").trim() || "中国歼-35 破空入场";
|
||||
const userInfo = String(options.effect_user_info || "").trim();
|
||||
const startTime = performance.now();
|
||||
let animId = null;
|
||||
let finished = false;
|
||||
@@ -446,7 +451,7 @@ const J35Effect = (() => {
|
||||
drawSpeedLines(ctx, speedLines, w, progress);
|
||||
drawSonicRing(ctx, w, h, progress);
|
||||
drawJet(ctx, jetX, jetY, scale, progress);
|
||||
drawHud(ctx, w, h, progress, title);
|
||||
drawHud(ctx, w, h, progress, title, userInfo);
|
||||
|
||||
if (progress < 1) {
|
||||
animId = requestAnimationFrame(animate);
|
||||
|
||||
@@ -1133,10 +1133,12 @@ class ChatControllerTest extends TestCase
|
||||
$this->assertSame('座驾播报', $rideMessage['from_user']);
|
||||
$this->assertSame('j35', $rideMessage['ride_key']);
|
||||
$this->assertSame("{$user->username} 乘坐【歼-35测试座驾】闪亮登场", $rideMessage['effect_title']);
|
||||
$this->assertSame('部门 无部门 · 职务 无职务 · 会员 普通会员', $rideMessage['effect_user_info']);
|
||||
$this->assertStringContainsString($user->username, $rideMessage['content']);
|
||||
$this->assertSame('j35', $response->viewData('initialRideEffect'));
|
||||
$this->assertSame([
|
||||
'effect_title' => "{$user->username} 乘坐【歼-35测试座驾】闪亮登场",
|
||||
'effect_user_info' => '部门 无部门 · 职务 无职务 · 会员 普通会员',
|
||||
'ride_name' => '歼-35测试座驾',
|
||||
'operator' => $user->username,
|
||||
], $response->viewData('initialRideEffectOptions'));
|
||||
@@ -1210,8 +1212,10 @@ class ChatControllerTest extends TestCase
|
||||
$this->assertNotNull($rideMessage);
|
||||
$this->assertNull($vipPresenceMessage);
|
||||
$this->assertStringContainsString('部门 战备部 · 职务 🛡️ 试飞官 · 会员 👑 至尊会员', $rideMessage['content']);
|
||||
$this->assertSame('部门 战备部 · 职务 🛡️ 试飞官 · 会员 👑 至尊会员', $rideMessage['effect_user_info']);
|
||||
$this->assertStringContainsString($user->username, $rideMessage['content']);
|
||||
$this->assertSame('99a', $response->viewData('initialRideEffect'));
|
||||
$this->assertSame('部门 战备部 · 职务 🛡️ 试飞官 · 会员 👑 至尊会员', $response->viewData('initialRideEffectOptions')['effect_user_info']);
|
||||
$this->assertNull($response->viewData('initialPresenceTheme'));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user