style
This commit is contained in:
@@ -16,7 +16,7 @@ import * as PIXI from "pixi.js";
|
||||
|
||||
const appRef = ref(null); // 存储 PIXI 应用实例
|
||||
|
||||
// 标签数据:包含名称、颜色、大小、位置(角度、半径)
|
||||
// 名称、颜色、大小、位置(角度、半径)
|
||||
const mockTags = [
|
||||
{
|
||||
name: "医生",
|
||||
@@ -34,7 +34,7 @@ const mockTags = [
|
||||
size: 14,
|
||||
opacity: 1,
|
||||
angle: -Math.PI / 2, // 12点方向
|
||||
radius: 60,
|
||||
radius: 68,
|
||||
tailRotation: Math.PI / 2, // 拖尾向下
|
||||
},
|
||||
{
|
||||
@@ -43,8 +43,8 @@ const mockTags = [
|
||||
fontColor: 0xf86e6e,
|
||||
size: 11.5,
|
||||
opacity: 1,
|
||||
angle: -Math.PI / 4, // 1点方向
|
||||
radius: 115,
|
||||
angle: -Math.PI / 4.2, // 1点方向
|
||||
radius: 125,
|
||||
tailRotation: (3 * Math.PI) / 4, // 拖尾向左下
|
||||
},
|
||||
{
|
||||
@@ -69,10 +69,10 @@ const mockTags = [
|
||||
},
|
||||
{
|
||||
name: "程序员",
|
||||
bgColor: 0xff9d57,
|
||||
bgColor: 0xffd4b6,
|
||||
fontColor: 0xffffff,
|
||||
size: 14.5,
|
||||
opacity: 0.6,
|
||||
opacity: 1,
|
||||
angle: Math.PI / 9, // 4点方向
|
||||
radius: 120,
|
||||
tailRotation: (5 * Math.PI) / 4, // 拖尾向左上
|
||||
@@ -113,7 +113,7 @@ const mockTags = [
|
||||
fontColor: 0xffffff,
|
||||
size: 15,
|
||||
opacity: 1,
|
||||
angle: (6.3 * Math.PI) / 6, // 10点方向
|
||||
angle: (6.3 * Math.PI) / 5.9, // 10点方向
|
||||
radius: 110,
|
||||
tailRotation: Math.PI / 4, // 拖尾向右下
|
||||
},
|
||||
@@ -123,8 +123,8 @@ const mockTags = [
|
||||
fontColor: 0xfbc55f,
|
||||
size: 13,
|
||||
opacity: 1,
|
||||
angle: (7.2 * Math.PI) / 6, // 11点方向
|
||||
radius: 115,
|
||||
angle: (7.2 * Math.PI) / 5.9, // 11点方向
|
||||
radius: 120,
|
||||
tailRotation: Math.PI / 4, // 拖尾向右下
|
||||
},
|
||||
];
|
||||
@@ -135,7 +135,6 @@ onMounted(async () => {
|
||||
const canvas = document.getElementById("matchCanvas");
|
||||
const sw = canvas.clientWidth;
|
||||
const sh = canvas.clientHeight;
|
||||
|
||||
const app = new PIXI.Application({
|
||||
backgroundAlpha: 0,
|
||||
antialias: true,
|
||||
@@ -148,11 +147,11 @@ onMounted(async () => {
|
||||
|
||||
canvas.appendChild(app.view);
|
||||
|
||||
// 标签容器(管理所有标签)
|
||||
// 标签容器(
|
||||
const tagsContainer = new PIXI.Container();
|
||||
app.stage.addChild(tagsContainer);
|
||||
|
||||
// 存储已放置标签的信息(位置、尺寸、浮动动画参数)
|
||||
// 存储已放置标签的信息
|
||||
const placedTags = [];
|
||||
|
||||
for (let i = 0; i < mockTags.length; i++) {
|
||||
@@ -167,15 +166,12 @@ onMounted(async () => {
|
||||
let floatSpeed = 0.01 + Math.random() * 0.02;
|
||||
let floatRange = 2 + Math.random() * 2;
|
||||
|
||||
// 为标签添加彗星拖尾效果
|
||||
// 拖尾效果
|
||||
if (radius > 0) {
|
||||
// 中心标签不需要拖尾
|
||||
const tail = createCometTail(tagData.bgColor, tailRotation, tag);
|
||||
|
||||
// 修正:使用 addChildAt 将拖尾添加到最底层
|
||||
// 使用 addChildAt
|
||||
tag.addChildAt(tail, 0);
|
||||
|
||||
// 为拖尾添加单独的动画
|
||||
// 拖尾动画
|
||||
app.ticker.add(() => {
|
||||
if (tail.updateTail) {
|
||||
tail.updateTail();
|
||||
@@ -183,7 +179,7 @@ onMounted(async () => {
|
||||
});
|
||||
}
|
||||
|
||||
// 使用PIXI ticker进行动画
|
||||
// 上下浮动动画
|
||||
app.ticker.add(() => {
|
||||
floatOffset += floatSpeed;
|
||||
tag.y = originalY + Math.sin(floatOffset) * floatRange;
|
||||
@@ -194,19 +190,11 @@ onMounted(async () => {
|
||||
}
|
||||
});
|
||||
|
||||
// 销毁时清理资源
|
||||
onUnmounted(() => {
|
||||
if (appRef.value) {
|
||||
appRef.value.destroy(true, true);
|
||||
appRef.value = null;
|
||||
}
|
||||
});
|
||||
|
||||
// 创建彗星拖尾效果
|
||||
// 创建拖尾
|
||||
function createCometTail(bgColor, tailRotation, tag) {
|
||||
const tailGroup = new PIXI.Container();
|
||||
|
||||
// 拖尾直接放在标签中心位置
|
||||
// 拖尾位置
|
||||
tailGroup.x = 0;
|
||||
tailGroup.y = 0;
|
||||
|
||||
@@ -222,7 +210,7 @@ function createCometTail(bgColor, tailRotation, tag) {
|
||||
let breathPhase = Math.random() * Math.PI * 2;
|
||||
const breathSpeed = 0.04;
|
||||
|
||||
// 更新拖尾的呼吸动画
|
||||
// 更新拖尾呼吸动画
|
||||
tailGroup.updateTail = () => {
|
||||
breathPhase += breathSpeed;
|
||||
const breathScale = 0.85 + 0.15 * Math.sin(breathPhase);
|
||||
@@ -230,13 +218,12 @@ function createCometTail(bgColor, tailRotation, tag) {
|
||||
|
||||
// 绘制梯形拖尾
|
||||
const currentLength = baseLength * breathScale;
|
||||
|
||||
// 计算拖尾的四个顶点
|
||||
// 长边在标签中心,水平方向(与标签长边平行)
|
||||
// 长边在标签中心 水平方向
|
||||
const startLeft = { x: -startWidth / 2, y: 0 };
|
||||
const startRight = { x: startWidth / 2, y: 0 };
|
||||
|
||||
// 短边在拖尾方向,保持水平
|
||||
// 短边在拖尾方向 保持水平
|
||||
const endCenter = {
|
||||
x: Math.cos(tailRotation) * currentLength,
|
||||
y: Math.sin(tailRotation) * currentLength,
|
||||
@@ -276,7 +263,7 @@ function createCometTail(bgColor, tailRotation, tag) {
|
||||
y: startRight.y * (1 - nextProgress) + endRight.y * nextProgress,
|
||||
};
|
||||
|
||||
// 透明度从0.4渐变到0
|
||||
// 透明度渐变
|
||||
const segmentAlpha = 0.4 * (1 - progress);
|
||||
|
||||
tail.beginFill(bgColor, segmentAlpha);
|
||||
@@ -289,19 +276,19 @@ function createCometTail(bgColor, tailRotation, tag) {
|
||||
}
|
||||
};
|
||||
|
||||
// 初始绘制
|
||||
// 绘制
|
||||
tailGroup.updateTail();
|
||||
|
||||
return tailGroup;
|
||||
}
|
||||
|
||||
// 创建单个标签(背景+文本)
|
||||
// 创建标签
|
||||
function createTag(tagData, x, y, placedTags, app, index) {
|
||||
const tagGroup = new PIXI.Container();
|
||||
tagGroup.x = x;
|
||||
tagGroup.y = y;
|
||||
|
||||
// 先创建文本以测量宽度
|
||||
// 创建文本测量宽度
|
||||
const text = new PIXI.Text(tagData.name, {
|
||||
fontFamily: "Arial",
|
||||
fontSize: tagData.size,
|
||||
@@ -309,7 +296,6 @@ function createTag(tagData, x, y, placedTags, app, index) {
|
||||
});
|
||||
text.anchor.set(0.5);
|
||||
|
||||
// 根据文字个数动态计算宽度
|
||||
const padding = 10;
|
||||
const charWidth = tagData.size * 1.5;
|
||||
const charHeight = tagData.size * 1.3;
|
||||
@@ -320,7 +306,7 @@ function createTag(tagData, x, y, placedTags, app, index) {
|
||||
|
||||
const height = charHeight + padding;
|
||||
|
||||
// 背景(圆角矩形)
|
||||
// 背景
|
||||
const bg = new PIXI.Graphics();
|
||||
bg.beginFill(tagData.bgColor, tagData.opacity ?? 1);
|
||||
bg.drawRoundedRect(-width / 2, -height / 2, width, height, 20);
|
||||
@@ -332,6 +318,13 @@ function createTag(tagData, x, y, placedTags, app, index) {
|
||||
|
||||
return tagGroup;
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
if (appRef.value) {
|
||||
appRef.value.destroy(true, true);
|
||||
appRef.value = null;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
Reference in New Issue
Block a user