visual-design
Version:
A Component Library for Vue 3
216 lines (213 loc) • 8.48 kB
JavaScript
import { defineComponent, ref, reactive, onMounted, nextTick, onUnmounted, openBlock, createElementBlock, createElementVNode, Fragment, renderList, toDisplayString } from 'vue';
import _export_sfc from '../../../_virtual/plugin-vue_export-helper.mjs';
const _hoisted_1 = { class: "cloud-bed" };
const _hoisted_2 = ["onClick"];
const __default__ = defineComponent({
name: "VWordCloud"
});
const _sfc_main = defineComponent({
...__default__,
setup(__props) {
const cloudBox = ref();
const tagContent = ref();
const state = reactive({
timer: 50,
radius: 0,
dtr: Math.PI / 180,
active: false,
lasta: 0,
lastb: 0.5,
distr: true,
tspeed: 0,
mouseX: 0,
mouseY: 0,
tagAttrList: [],
sinA: 0,
cosA: 0,
sinB: 0,
cosB: 0,
sinC: 0,
cosC: 0,
dataList: [
{ name: "\u5E02\u5BB9\u73AF\u5883", value: "8" },
{ name: "\u751F\u6D3B\u8D44\u6E90", value: "8" },
{ name: "\u673A\u52A8\u8F66\u4E71\u505C", value: "0" },
{ name: "\u4F9B\u6C14\u8D28\u91CF", value: "0" },
{ name: "\u5546\u4E1A\u566A\u97F3", value: "6" },
{ name: "\u4E71\u642D\u4E71\u5EFA", value: "10" },
{ name: "\u9053\u8DEF\u5783\u573E", value: "2" },
{ name: "\u751F\u6D3B\u7528\u6C34\u7BA1\u7406", value: "5" },
{ name: "\u8DEF\u9762\u4E0D\u6D01", value: "7" },
{ name: "\u70E7\u70E4\u6CB9\u70DF", value: "6" },
{ name: "\u975E\u6CD5\u5E7F\u544A", value: "4" },
{ name: "\u8BBE\u65BD\u7834\u635F", value: "6" },
{ name: "\u75C5\u866B\u5BB3", value: "5" },
{ name: "1111", value: "5" },
{ name: "2222", value: "5" },
{ name: "3333", value: "5" },
{ name: "4444", value: "5" },
{ name: "5555", value: "5" }
]
});
const methods = {
getDataInfo(item) {
},
initWordCloud() {
if (!cloudBox.value) {
return;
}
tagContent.value = cloudBox.value.querySelectorAll("span");
if (tagContent.value) {
for (let i = 0; i < tagContent.value.length; i++) {
const tagObj = {
offsetWidth: 0,
offsetHeight: 0
};
tagObj.offsetWidth = tagContent.value[i].offsetWidth;
tagObj.offsetHeight = tagContent.value[i].offsetHeight;
state.tagAttrList.push(tagObj);
}
}
methods.sineCosine(0, 0, 0);
methods.positionAll();
cloudBox.value.onmouseover = () => {
state.active = true;
};
cloudBox.value.onmouseout = () => {
state.active = false;
};
cloudBox.value.onmousemove = (ev) => {
const oEvent = ev;
state.mouseX = oEvent.clientX - (cloudBox.value.offsetLeft + cloudBox.value.offsetWidth / 2);
state.mouseY = oEvent.clientY - (cloudBox.value.offsetTop + cloudBox.value.offsetHeight / 2);
state.mouseX /= 5;
state.mouseY /= 5;
};
},
positionAll() {
let phi = 0;
let theta = 0;
const max = state.tagAttrList.length;
const aTmp = [];
const oFragment = document.createDocumentFragment();
for (let i = 0; i < tagContent.value.length; i++) {
aTmp.push(tagContent.value[i]);
}
aTmp.sort(() => {
return Math.random() < 0.5 ? 1 : -1;
});
for (const element of aTmp) {
oFragment.appendChild(element);
}
cloudBox.value.appendChild(oFragment);
for (let i = 1; i < max + 1; i++) {
if (state.distr) {
phi = Math.acos(-1 + (2 * i - 1) / max);
theta = Math.sqrt(max * Math.PI) * phi;
} else {
z;
phi = Math.random() * Math.PI;
theta = Math.random() * (2 * Math.PI);
}
state.tagAttrList[i - 1].cx = state.radius * Math.cos(theta) * Math.sin(phi);
state.tagAttrList[i - 1].cy = state.radius * Math.sin(theta) * Math.sin(phi) + 50;
state.tagAttrList[i - 1].cz = state.radius * Math.cos(phi);
tagContent.value[i - 1].style.left = `${state.tagAttrList[i - 1].cx + cloudBox.value.offsetWidth / 2 - state.tagAttrList[i - 1].offsetWidth / 2}px`;
tagContent.value[i - 1].style.top = `${state.tagAttrList[i - 1].cy + cloudBox.value.offsetHeight / 2 - state.tagAttrList[i - 1].offsetHeight}px`;
}
},
update() {
let angleBasicA;
let angleBasicB;
if (state.active) {
angleBasicA = -Math.min(Math.max(-state.mouseY, -200), 200) / state.radius * state.tspeed;
angleBasicB = Math.min(Math.max(-state.mouseX, -200), 200) / state.radius * state.tspeed;
} else {
angleBasicA = state.lasta * 0.98;
angleBasicB = state.lastb * 0.98;
}
methods.sineCosine(angleBasicA, angleBasicB, 0);
for (let j = 0; j < state.tagAttrList.length; j++) {
const rx1 = state.tagAttrList[j].cx;
const ry1 = state.tagAttrList[j].cy * state.cosA + state.tagAttrList[j].cz * -state.sinA;
const rz1 = state.tagAttrList[j].cy * state.sinA + state.tagAttrList[j].cz * state.cosA;
const rx2 = rx1 * state.cosB + rz1 * state.sinB;
const ry2 = ry1;
const rz2 = rx1 * -state.sinB + rz1 * state.cosB;
const rx3 = rx2 * state.cosC + ry2 * -state.sinC;
const ry3 = rx2 * state.sinC + ry2 * state.cosC;
const rz3 = rz2;
state.tagAttrList[j].cx = rx3;
state.tagAttrList[j].cy = ry3;
state.tagAttrList[j].cz = rz3;
const per = 350 / (350 + rz3);
state.tagAttrList[j].x = rx3 * per - 2;
state.tagAttrList[j].y = ry3 * per;
state.tagAttrList[j].scale = per;
state.tagAttrList[j].alpha = per;
state.tagAttrList[j].alpha = (state.tagAttrList[j].alpha - 0.6) * (10 / 6);
}
methods.doPosition();
methods.depthSort();
},
doPosition() {
const len = cloudBox.value.offsetWidth / 2;
const height = cloudBox.value.offsetHeight / 2;
for (let i = 0; i < state.tagAttrList.length; i++) {
tagContent.value[i].style.left = `${state.tagAttrList[i].cx + len - state.tagAttrList[i].offsetWidth / 2}px`;
tagContent.value[i].style.top = `${state.tagAttrList[i].cy + height - state.tagAttrList[i].offsetHeight / 2}px`;
tagContent.value[i].style.fontSize = `${Math.ceil(12 * state.tagAttrList[i].scale / 2) + 2}px`;
tagContent.value[i].style.filter = `alpha(opacity=${100 * state.tagAttrList[i].alpha})`;
tagContent.value[i].style.opacity = state.tagAttrList[i].alpha;
}
},
depthSort() {
const aTmp = [];
for (let i = 0; i < tagContent.value.length; i++) {
aTmp.push(tagContent.value[i]);
}
aTmp.sort((item1, item2) => item2.cz - item1.cz);
for (const i of aTmp) {
aTmp[i].style.zIndex = i;
}
},
sineCosine(a, b, c) {
state.sinA = Math.sin(a * state.dtr);
state.cosA = Math.cos(a * state.dtr);
state.sinB = Math.sin(b * state.dtr);
state.cosB = Math.cos(b * state.dtr);
state.sinC = Math.sin(c * state.dtr);
state.cosC = Math.cos(c * state.dtr);
}
};
onMounted(() => {
nextTick(() => {
if (cloudBox.value) {
state.radius = cloudBox.value.offsetWidth / 2.5;
}
methods.initWordCloud();
});
});
onUnmounted(() => {
});
return (_ctx, _cache) => {
return openBlock(), createElementBlock("section", _hoisted_1, [
createElementVNode("div", {
ref_key: "cloudBox",
ref: cloudBox,
class: "cloud-box"
}, [
(openBlock(true), createElementBlock(Fragment, null, renderList(state.dataList, (item, index) => {
return openBlock(), createElementBlock("span", {
key: index,
onClick: ($event) => methods.getDataInfo(item)
}, toDisplayString(item.name), 9, _hoisted_2);
}), 128))
], 512)
]);
};
}
});
var WordCloud = /* @__PURE__ */ _export_sfc(_sfc_main, [["__file", "G:\\My_Projects\\visual-design\\packages\\components\\demo\\src\\word-cloud.vue"]]);
export { WordCloud as default };
//# sourceMappingURL=word-cloud.mjs.map