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