179 lines
9.3 KiB
HTML
179 lines
9.3 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<title>标签气泡动效</title>
|
||
<style></style>
|
||
|
||
<link rel="stylesheet" href="./static/css/song-request-station.css" />
|
||
<script src="./static/js/tagcloud-2.2.js"></script>
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<div class="container-box mar1200">
|
||
<img class="logo" src="./static/img/logo.png" alt="" />
|
||
<div class="header">
|
||
<img class="halo" src="./static/img/halo.png" />
|
||
<img class="record-black" src="./static/img/record-black.svg" />
|
||
<div class="record-circle"></div>
|
||
<img class="star-icon" src="./static/img/star-icon.png" alt="" />
|
||
<img class="bj-2" src="./static/img/song-request-bj-2.svg" alt="" />
|
||
<img class="love-little" src="./static/img/love-little.svg" alt="" />
|
||
<img class="music-icon" src="./static/img/music-icon.svg" alt="" />
|
||
<img class="bj" src="./static/img/song-request-bj.svg" alt="" />
|
||
<img class="love-big" src="./static/img/love-big.svg" alt="" />
|
||
<img class="music-score" src="./static/img/music-score.png" />
|
||
<img class="robot" src="./static/img/robot.png" />
|
||
<img class="text" src="./static/img/song-request-text.svg" />
|
||
<img class="face" src="./static/img/smiling-face.png" />
|
||
<img class="star-icon-2" src="./static/img/star-icon-2.png" />
|
||
<img class="ai-music" src="./static/img/ai-music.png" />
|
||
<img class="green-glow" src="./static/img/green-glow.png" />
|
||
<img class="shadow" src="./static/img/shadow.png" />
|
||
</div>
|
||
<div class="list-box">
|
||
<img class="left-icon" src="./static/img/left-icon.png" alt="" />
|
||
<img class="right-icon" src="./static/img/right-icon.png" alt="" />
|
||
<div class="list-fill" id="bubbleContainerFill"></div>
|
||
<div class="list" id="bubbleContainer"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
// 标签数据
|
||
// let tags = ["前端开发", "JavaScript", "CSS动画", "HTML5", "React", "Vue", "TypeScript", "Node.js", "UI设计", "用户体验", "响应式布局", "性能优化", "微信小程序", "PWA", "Canvas", "SVG", "WebGL", "数据可视化", "模块化", "组件化", "前端开发", "JavaScript", "CSS动画", "HTML5", "React", "Vue", "TypeScript", "Node.js", "UI设计", "用户体验", "响应式布局", "性能优化", "微信小程序", "PWA", "Canvas", "SVG", "WebGL", "数据可视化", "模块化", "组件化"];
|
||
let tags = [];
|
||
|
||
// 获取容器
|
||
const containerFill = document.getElementById("bubbleContainerFill");
|
||
const container = document.getElementById("bubbleContainer");
|
||
|
||
// 计算容器尺寸
|
||
function getContainerDimensions() {
|
||
const containerWidth = container.offsetWidth;
|
||
const containerHeight = container.offsetHeight;
|
||
return { containerWidth, containerHeight };
|
||
}
|
||
|
||
// 创建标签并添加动画
|
||
function createTags() {
|
||
const { containerWidth, containerHeight } = getContainerDimensions();
|
||
|
||
const fillLength = tags.length + tags.length / 2;
|
||
for (let i = 0; i < fillLength; i++) {
|
||
const outcome = getRandomOutcome();
|
||
// 创建标签元素
|
||
const tag = document.createElement("div");
|
||
tag.className = `fill-item item${Math.floor(Math.random() * 5) + 1}`;
|
||
|
||
tag.style.width = `${Math.floor(Math.random() * 77) + 33}`;
|
||
tag.style.height = `${Math.floor(Math.random() * 15) + 23}`;
|
||
containerFill.appendChild(tag);
|
||
}
|
||
|
||
tagCloud({
|
||
selector: "#bubbleContainerFill", // 元素选择器,id 或 class
|
||
// fontsize: 20, // 基本字体大小, 默认16,单位px
|
||
radius: [containerWidth / 2, containerHeight / 2], // 滚动横/纵轴半径, 默认60,单位px,取值60,[60],[60, 60]
|
||
mspeed: "slow", // 滚动最大速度, 取值: slow, normal(默认), fast
|
||
ispeed: "slow", // 滚动初速度, 取值: slow, normal(默认), fast
|
||
direction: 45, // 初始滚动方向, 取值角度(顺时针360): 0对应top, 90对应left, 135对应right-bottom(默认)...
|
||
keep: false, // 鼠标移出组件后是否继续随鼠标滚动, 取值: false, true(默认) 对应 减速至初速度滚动, 随鼠标滚动
|
||
multicolour: false, // 彩色字体,颜色随机,取值:true(默认),false
|
||
});
|
||
|
||
let redIndex = 0;
|
||
let redAmount = 5;
|
||
|
||
const redCount = Math.min(5, tags.length);
|
||
const redIndexes = [];
|
||
|
||
while (redIndexes.length < redCount) {
|
||
const randomIdx = Math.floor(Math.random() * tags.length);
|
||
if (!redIndexes.includes(randomIdx)) redIndexes.push(randomIdx);
|
||
}
|
||
console.log("redIndexes", redIndexes);
|
||
|
||
const surplus = Math.floor(tags.length % redAmount); // 向下取整
|
||
tags.forEach((item, index) => {
|
||
const outcome = getRandomOutcome();
|
||
// 创建标签元素
|
||
const tag = document.createElement("div");
|
||
tag.className = `tag-item item${outcome}`;
|
||
tag.textContent = item.tag;
|
||
// 关键判断:当前索引是否在“要加 red 的索引列表”中
|
||
if (redIndexes.includes(index)) tag.classList.add("red");
|
||
|
||
// 绑定点击事件
|
||
tag.addEventListener("click", () => {
|
||
const songs = item.songs || [];
|
||
console.log("songs", songs);
|
||
});
|
||
|
||
container.appendChild(tag);
|
||
});
|
||
|
||
// 3D云标签
|
||
tagCloud({
|
||
selector: "#bubbleContainer", // 元素选择器,id 或 class
|
||
// fontsize: 20, // 基本字体大小, 默认16,单位px
|
||
radius: [containerWidth / 2, containerHeight / 2], // 滚动横/纵轴半径, 默认60,单位px,取值60,[60],[60, 60]
|
||
mspeed: "slow", // 滚动最大速度, 取值: slow, normal(默认), fast
|
||
ispeed: "normal", // 滚动初速度, 取值: slow, normal(默认), fast
|
||
direction: 135, // 初始滚动方向, 取值角度(顺时针360): 0对应top, 90对应left, 135对应right-bottom(默认)...
|
||
keep: false, // 鼠标移出组件后是否继续随鼠标滚动, 取值: false, true(默认) 对应 减速至初速度滚动, 随鼠标滚动
|
||
multicolour: false, // 彩色字体,颜色随机,取值:true(默认),false
|
||
});
|
||
}
|
||
|
||
// // 窗口大小变化时重新创建标签
|
||
// window.addEventListener("resize", () => {
|
||
// createTags();
|
||
// });
|
||
|
||
// 初始创建标签
|
||
|
||
const init = () => {
|
||
// 发送请求读取本地 data.json
|
||
fetch("./static/js/music.json")
|
||
.then((response) => {
|
||
// 检查请求是否成功(状态码 200-299)
|
||
if (!response.ok) {
|
||
throw new Error(`请求失败:${response.status}`);
|
||
}
|
||
// 将响应解析为 JSON 格式
|
||
return response.json();
|
||
})
|
||
.then((data) => {
|
||
// 成功获取 JSON 数据,后续处理(如使用 tags 数组)
|
||
console.log("读取到的 JSON 数据:", data);
|
||
const tagsData = data.data; // 提取 tags 数组
|
||
console.log("tags 数组:", tagsData); // 输出:["HTML", "CSS", "JavaScript", "Vue", "React"]
|
||
tags = tagsData;
|
||
createTags();
|
||
|
||
// 这里可以继续你的标签生成逻辑(如之前的 tag.forEach...)
|
||
});
|
||
// createTags();
|
||
};
|
||
init();
|
||
|
||
// 生成单次随机结果的函数
|
||
function getRandomOutcome() {
|
||
const random = Math.random(); // 生成0-1之间的随机数
|
||
let cumulativeProbability = 0;
|
||
const outcomes = [0.1, 0.2, 0.3, 0.4];
|
||
|
||
for (const outcome of outcomes) {
|
||
cumulativeProbability += outcome;
|
||
if (random < cumulativeProbability) {
|
||
return outcomes.indexOf(outcome) + 1;
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|