Files
PC-official/static/js/tagcloud-2.2.js
DESKTOP-RQ919RC\Pc 4087c429fa refactor(页面布局): 重构页面布局和样式
- 移除未使用的HTML文件和冗余代码
- 调整侧边栏位置和样式
- 优化标签云组件交互和性能
- 更新播放器控件样式和功能
- 改进预览弹窗的背景透明度
- 添加favicon图标
2025-09-22 17:49:06 +08:00

332 lines
13 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 3d标签云
* 功能:鼠标移入标签,当前标签静止放大
* 说明radius 控制滚动区域(横椭圆、纵椭圆、正圆)
* 版本2.2
* */
window.tagCloud = (function (win, doc) {
// 判断对象
function isObject(obj) {
return Object.prototype.toString.call(obj) === "[object Object]";
}
// 构造函数
function TagCloud(options) {
var self = this;
self.config = TagCloud._getConfig(options);
self.box = self.config.element; // 组件元素
self.fontsize = self.config.fontsize; // 平均字体大小
if (Number.isInteger(self.config.radius)) {
self._radiusX = self._radiusY = self.config.radius;
} else if (self.config.radius instanceof Array) {
if (self.config.radius.length === 1) {
self._radiusX = self._radiusY = self.config.radius[0];
} else {
self._radiusX = self.config.radius[0];
self._radiusY = self.config.radius[1];
}
}
self.radius = self._radiusX; // 滚动半径
_ratio = Math.round((self._radiusX * 10) / self._radiusY) / 10; // 滚动区域比例,保留一位小数
if (_ratio < 1) {
// 焦点在Y轴的椭圆
self.ratioX = _ratio;
self.ratioY = 1;
self.radius = self._radiusY; // 滚动半径,选择长半径
} else if (_ratio > 1) {
// 焦点在X轴的椭圆
self.ratioX = 1;
self.ratioY = _ratio;
} else {
self.ratioX = self.ratioY = 1; // 正圆
}
self.depth = 2 * self.radius; // 滚动深度
self.size = 2 * self.radius; // 随鼠标滚动变速作用区域
self.mspeed = TagCloud._getMsSpeed(self.config.mspeed);
self.ispeed = TagCloud._getIsSpeed(self.config.ispeed);
self.items = self._getItems();
self.direction = self.config.direction; // 初始滚动方向
self.keep = self.config.keep; // 鼠标移出后是否保持之前滚动
// 初始化
self.active = false; // 是否为激活状态
self.lasta = 1;
self.lastb = 1;
self.mouseX0 = self.ispeed * Math.sin((self.direction * Math.PI) / 180); // 鼠标与滚动圆心x轴初始距离
self.mouseY0 = -self.ispeed * Math.cos((self.direction * Math.PI) / 180); // 鼠标与滚动圆心y轴初始距离
self.mouseX = self.mouseX0; // 鼠标与滚动圆心x轴距离
self.mouseY = self.mouseY0; // 鼠标与滚动圆心y轴距离
self.index = -1;
// 鼠标移入
TagCloud._on(self.box, "mouseover", function () {
self.active = true;
});
// 鼠标移出
TagCloud._on(self.box, "mouseout", function () {
self.active = false;
});
// 鼠标在内移动
TagCloud._on(self.keep ? win : self.box, "mousemove", function (ev) {
var oEvent = win.event || ev;
var boxPosition = self.box.getBoundingClientRect();
self.mouseX = (oEvent.clientX - (boxPosition.left + self.box.offsetWidth / 2)) / 5;
self.mouseY = (oEvent.clientY - (boxPosition.top + self.box.offsetHeight / 2)) / 5;
});
for (var j = 0, len = self.items.length; j < len; j++) {
self.items[j].element.index = j;
// 鼠标移出子元素,当前元素静止放大
self.items[j].element.onmouseover = function () {
self.index = this.index;
};
// 鼠标移出子元素,当前元素继续滚动
self.items[j].element.onmouseout = function () {
self.index = -1;
};
}
// 定时更新
TagCloud.boxs.push(self.box);
self.update(self); // 初始更新
self.box.style.visibility = "visible";
self.box.style.position = "relative";
for (var j = 0, len = self.items.length; j < len; j++) {
self.items[j].element.style.position = "absolute";
self.items[j].element.style.zIndex = j + 1;
}
self.up = setInterval(function () {
self.update(self);
});
}
//实例
TagCloud.boxs = []; //实例元素数组
// 静态方法们
TagCloud._set = function (element) {
if (TagCloud.boxs.indexOf(element) === -1) {
// ie8不支持数组的indexOf方法所以自定义indexOf
return true;
}
};
//添加数组IndexOf方法
if (!Array.prototype.indexOf) {
// Array.prototype.indexOf = function (elt /*, from*/) {
Array.prototype.indexOf = function (elt) {
var len = this.length >>> 0;
var from = Number(arguments[1]) || 0;
from = from < 0 ? Math.ceil(from) : Math.floor(from);
if (from < 0) from += len;
for (; from < len; from++) {
if (from in this && this[from] === elt) return from;
}
return -1;
};
}
TagCloud._getConfig = function (config) {
var defaultConfig = {
// 默认值
fontsize: 16, // 基本字体大小, 单位px
radius: 60, // 滚动纵轴半径, 默认60, 单位px取值60[60][60, 60]
mspeed: "normal", // 滚动最大速度, 取值: slow, normal(默认), fast
ispeed: "normal", // 滚动初速度, 取值: slow, normal(默认), fast
direction: 135, // 初始滚动方向, 取值角度(顺时针360): 0对应top, 90对应left, 135对应right-bottom(默认)...
keep: true, // 鼠标移出组件后是否继续随鼠标滚动, 取值: false, true(默认) 对应 减速至初速度滚动, 随鼠标滚动
multicolour: true, // 是否为彩色字体颜色随机取值true(默认),false
};
if (isObject(config)) {
for (var i in config) {
if (config.hasOwnProperty(i)) {
//hasOwnProperty()用来判断一个属性是定义在对象本身而不是继承自原型链
defaultConfig[i] = config[i]; //用户配置
}
}
}
return defaultConfig; // 配置 Merge
};
TagCloud._getMsSpeed = function (mspeed) {
//滚动最大速度
var speedMap = {
slow: 1.5,
normal: 3,
fast: 5,
};
return speedMap[mspeed] || 3;
};
TagCloud._getIsSpeed = function (ispeed) {
//滚动初速度
var speedMap = {
slow: 10,
normal: 25,
fast: 50,
};
return speedMap[ispeed] || 25;
};
TagCloud._getSc = function (a, b) {
var l = Math.PI / 180;
//数组顺序0,1,2,3表示asin,acos,bsin,bcos
return [Math.sin(a * l), Math.cos(a * l), Math.sin(b * l), Math.cos(b * l)];
};
TagCloud._on = function (ele, eve, handler, cap) {
if (ele.addEventListener) {
ele.addEventListener(eve, handler, cap);
} else if (ele.attachEvent) {
ele.attachEvent("on" + eve, handler);
} else {
ele["on" + eve] = handler;
}
};
// 原型方法
TagCloud.prototype = {
constructor: TagCloud, // 反向引用构造器
update: function () {
var self = this,
a,
b;
if (!self.active && !self.keep) {
self.mouseX = Math.abs(self.mouseX - self.mouseX0) < 1 ? self.mouseX0 : (self.mouseX + self.mouseX0) / 2; //重置鼠标与滚动圆心x轴距离
self.mouseY = Math.abs(self.mouseY - self.mouseY0) < 1 ? self.mouseY0 : (self.mouseY + self.mouseY0) / 2; //重置鼠标与滚动圆心y轴距离
}
a = -((Math.min(Math.max(-self.mouseY, -self.size), self.size) * 2) / self.radius) * self.mspeed;
b = ((Math.min(Math.max(-self.mouseX, -self.size), self.size) * 2) / self.radius) * self.mspeed;
if (Math.abs(a) <= 0.01 && Math.abs(b) <= 0.01) {
return;
}
self.lasta = a;
self.lastb = b;
var sc = TagCloud._getSc(a, b);
for (var j = 0, len = self.items.length; j < len; j++) {
var rx1 = self.items[j].x,
ry1 = self.items[j].y * sc[1] + self.items[j].z * -sc[0],
rz1 = self.items[j].y * sc[0] + self.items[j].z * sc[1];
var rx2 = rx1 * sc[3] + rz1 * sc[2],
ry2 = ry1,
rz2 = rz1 * sc[3] - rx1 * sc[2];
if (self.index == j) {
self.items[j].scale = 1; //取值范围0.6 ~ 3
self.items[j].fontsize = 18;
self.items[j].alpha = 1;
self.items[j].element.style.zIndex = 99;
} else {
var per = self.depth / (self.depth + rz2);
self.items[j].x = rx2;
self.items[j].y = ry2;
self.items[j].z = rz2;
self.items[j].scale = per; //取值范围0.6 ~ 3
self.items[j].fontsize = Math.ceil(per * 2) + self.fontsize - 6;
self.items[j].alpha = 1.5 * per - 0.5;
self.items[j].element.style.zIndex = Math.ceil(per * 10 - 5);
}
self.items[j].element.style.fontSize = self.items[j].fontsize + "px";
self.items[j].element.style.left = self.items[j].x * self.ratioX + (self.box.offsetWidth - self.items[j].offsetWidth) / 2 + "px";
self.items[j].element.style.top = self.items[j].y / self.ratioY + (self.box.offsetHeight - self.items[j].offsetHeight) / 2 + "px";
self.items[j].element.style.filter = "alpha(opacity=" + 100 * self.items[j].alpha + ")";
self.items[j].element.style.opacity = self.items[j].alpha;
}
},
_getItems: function () {
var self = this,
items = [],
element = self.box.children, // children 全部是Element
length = element.length,
item;
for (var i = 0; i < length; i++) {
item = {};
item.angle = {};
item.angle.phi = Math.acos(-1 + (2 * i + 1) / length);
item.angle.theta = Math.sqrt((length + 1) * Math.PI) * item.angle.phi;
item.element = element[i];
item.offsetWidth = item.element.offsetWidth;
item.offsetHeight = item.element.offsetHeight;
item.x = (self.radius / 2) * 1.5 * Math.cos(item.angle.theta) * Math.sin(item.angle.phi);
item.y = (self.radius / 2) * 1.5 * Math.sin(item.angle.theta) * Math.sin(item.angle.phi);
item.z = (self.radius / 2) * 1.5 * Math.cos(item.angle.phi);
item.element.style.left = item.x * self.ratioX + (self.box.offsetWidth - item.offsetWidth) / 2 + "px";
item.element.style.top = item.y / self.ratioY + (self.box.offsetHeight - item.offsetHeight) / 2 + "px";
if (self.config.multicolour) {
// 初始化文字颜色为彩色
_color = self._randomNumBoth(0, 360); // 定义色相 (0 到 360) - 0 (或 360) 红120绿180青240蓝300紫
_light = self._randomNumBoth(30, 60); // 定义亮度 0% 为暗, 50% 为普通, 100% 为白
item.element.style.color = "hsl(" + _color + ", 100%, " + _light + "%)"; // 中间值为饱和度; 0%灰色100%全色
// item.element.style.color = 'rgb(' + parseInt(Math.random() * 255) + ',' + parseInt(Math.random() * 255) + ',' + parseInt(Math.random() * 255) + ')';
}
items.push(item);
}
return items; //单元素数组
},
// 取随机值Min ≤ num ≤ Max
_randomNumBoth: function (Min, Max) {
var Range = Max - Min;
var Rand = Math.random();
var num = Min + Math.round(Rand * Range); //四舍五入
return num;
},
};
if (!doc.querySelectorAll) {
// ie7不支持querySelectorAll所以要重新定义
doc.querySelectorAll = function (selectors) {
var style = doc.createElement("style"),
elements = [],
element;
doc.documentElement.firstChild.appendChild(style);
doc._qsa = [];
style.styleSheet.cssText = selectors + "{x-qsa:expression(document._qsa && document._qsa.push(this))}";
window.scrollBy(0, 0);
style.parentNode.removeChild(style);
while (doc._qsa.length) {
element = doc._qsa.shift();
element.style.removeAttribute("x-qsa");
elements.push(element);
}
doc._qsa = null;
return elements;
};
}
return function (options) {
// factory
options = options || {}; // 短路语法
var selector = options.selector || ".tagcloud", // 默认选择class为tagcloud的元素
elements = doc.querySelectorAll(selector),
instance = [];
for (var index = 0, len = elements.length; index < len; index++) {
options.element = elements[index];
if (!!TagCloud._set(options.element)) {
instance.push(new TagCloud(options));
}
}
return instance;
};
})(window, document);