cione-comp-lib
Version:
`$ yarn add cione-comp-lib` 或者 `$ npm i cione-comp-lib -S`
310 lines (309 loc) • 9.23 kB
JavaScript
import { defineComponent, ref, onMounted, onUnmounted, watch, toRefs, openBlock, createElementBlock, normalizeStyle, createElementVNode } from "vue";
import "./index.vue_vue_type_style_index_0_scoped_true_lang.mjs";
import _export_sfc from "../../_virtual/plugin-vue_export-helper.mjs";
const _sfc_main = defineComponent({
name: "CoLabelTextAnimation",
props: {
width: {
type: String
},
height: {
type: String
},
type: {
type: String,
default: "radiation"
},
text: {
type: String,
default: "\u8FD9\u662F\u4E00\u4E2A\u6D4B\u8BD5\u5185\u5BB9"
},
fontSize: {
type: Number,
default: 26
},
titleFamily: { type: String, default: "\u5FAE\u8F6F\u96C5\u9ED1" },
fontWeight: { type: String, default: "normal" },
rayColor1: { type: String, default: "rgba(224,247,250,1)" },
rayColor2: { type: String, default: "rgba(24,255,255,1)" },
lineLength: { type: Number, default: 2 },
isLoop: { type: Boolean },
loopTimer: { type: Number },
speed: { type: Number, default: 10 },
isAnimation: { type: Boolean, default: false }
},
setup(props) {
const timerRadiation = ref();
const timeoutTimer = ref();
ref();
const txtH = ref(props.fontSize);
const txtW = ref();
const canvasRadiationBox = ref();
const canvasRadiation = ref();
const current = ref(1);
const ctx = ref();
const cw = ref();
const ch = ref();
const bufferCanvas = ref();
const buffer = ref();
var sx;
var sy;
var rays = [];
var pi2;
const init = () => {
current.value = 1;
txtH.value = props.fontSize;
ctx.value = canvasRadiation.value.getContext("2d");
cw.value = canvasRadiationBox.value.offsetWidth;
ch.value = canvasRadiationBox.value.offsetHeight;
canvasRadiation.value.width = cw.value;
canvasRadiation.value.height = ch.value;
if (!props.isAnimation) {
ctx.value.clearRect(0, 0, cw.value, ch.value);
ctx.value.fillStyle = props.rayColor1;
ctx.value.font = `${props.fontWeight} ` + txtH.value + "px " + props.titleFamily;
ctx.value.textBaseline = "middle";
ctx.value.textAlign = "center";
ctx.value.fillText(props.text, cw.value / 2, ch.value / 2);
if (props.isLoop) {
timeoutTimer.value = setTimeout(() => {
dataInit();
restart();
clearTimeout(timeoutTimer.value);
}, props.loopTimer);
}
} else {
dataInit();
timerRadiation.value = setInterval(() => {
tick();
}, props.speed);
}
};
const tick = () => {
ctx.value.clearRect(0, 0, cw.value, ch.value);
ctx.value.drawImage(
bufferCanvas.value,
0,
0,
current.value,
txtH.value,
sx,
sy,
current.value,
txtH.value
);
ctx.value.save();
ctx.value.globalAlpha = 0.07;
ctx.value.globalCompositeOperation = "lighter";
if (drawRays(current.value)) {
current.value++;
current.value = Math.min(current.value, txtW.value);
} else {
fadeOut();
}
ctx.value.restore();
};
const dataInit = () => {
var w2 = cw.value / 2;
var h2 = ch.value / 2;
var pi = Math.PI;
pi2 = pi * 0.5;
var txtCanvas = document.createElement("canvas");
var txtCtx = txtCanvas.getContext("2d");
txtCtx.font = `${props.fontWeight} ` + txtH.value + "px " + props.titleFamily + " blod";
txtCtx.textBaseline = "middle";
txtW.value = Math.floor(txtCtx.measureText(props.text).width);
txtCanvas.width = txtW.value;
txtCanvas.height = txtH.value * 1;
var gradient = ctx.value.createRadialGradient(w2, h2, 0, w2, h2, txtW.value);
gradient.addColorStop(0, props.rayColor2);
gradient.addColorStop(1, props.rayColor1);
ctx.value.strokeStyle = gradient;
txtCtx.fillStyle = gradient;
txtCtx.font = `${props.fontWeight} ` + txtH.value + "px " + props.titleFamily;
txtCtx.textBaseline = "middle";
txtCtx.fillText(props.text, 0, txtH.value * 0.6);
txtH.value *= 1;
bufferCanvas.value = document.createElement("canvas");
bufferCanvas.value.width = txtW.value;
bufferCanvas.value.height = txtH.value;
buffer.value = bufferCanvas.value.getContext("2d");
sx = (cw.value - txtW.value) * 0.5;
sy = (ch.value - txtH.value) * 0.5;
rays = [];
var txtData = txtCtx.getImageData(0, 0, txtW.value, txtH.value);
for (var i = 0; i < txtData.data.length; i += 4) {
var ii = i / 4;
Math.floor(ii / txtW.value);
ii % txtW.value;
var alpha = txtData.data[i + 3];
if (alpha !== 0) {
var c = "rgba(";
c += [txtData.data[i], txtData.data[i + 1], txtData.data[i + 2], alpha / 255];
c += ")";
rays.push(new Ray(Math.floor(ii / txtW.value), ii % txtW.value, c));
}
}
};
function fadeOut() {
clearInterval(timerRadiation.value);
ctx.value.globalAlpha *= 0.95;
ctx.value.drawImage(
bufferCanvas.value,
0,
0,
current.value,
txtH,
sx,
sy,
current.value,
txtH
);
if (ctx.value.globalAlpha > 0.01) {
window.requestAnimationFrame(fadeOut);
} else {
if (props.isLoop) {
timeoutTimer.value = setTimeout(() => {
restart();
clearTimeout(timeoutTimer.value);
}, props.loopTimer);
}
}
}
function restart() {
for (var i = 0; i < rays.length; i++) {
rays[i].reset();
}
ctx.value.globalAlpha = 1;
buffer.value.clearRect(0, 0, txtW.value, txtH.value);
current.value = 1;
timerRadiation.value = setInterval(() => {
tick();
}, props.speed);
}
function drawRays(c) {
var count = 0;
ctx.value.beginPath();
for (var i = 0; i < rays.length; i++) {
var ray = rays[i];
if (ray.col < c) {
count += ray.draw();
}
}
ctx.value.stroke();
return count !== rays.length;
}
function Ray(row, col, f) {
this.col = col;
this.row = row;
var xp = sx + col;
var yp = sy + row;
var fill = f;
var ath = txtH.value / 1;
var a = pi2 * (this.row - ath * 0.5) / ath;
if (a === 0) {
a = (Math.random() - 0.5) * pi2;
}
var da = 0.02 * Math.sign(a);
da += (Math.random() - 0.5) * 5e-3;
var l = 0;
var dl = Math.random() * 2 + props.lineLength;
var buffered = false;
this.reset = function() {
a = pi2 * (this.row - ath * 0.5) / ath;
if (a === 0) {
a = -pi2 * 0.5;
}
l = 0;
buffered = false;
};
this.draw = function() {
if (l < 0) {
if (!buffered) {
buffer.value.fillStyle = fill;
buffer.value.fillRect(this.col, this.row, 1, 1);
buffered = true;
}
return 1;
} else {
ctx.value.moveTo(xp, yp);
ctx.value.lineTo(xp + Math.cos(a) * l, yp + Math.sin(a) * l);
a += da;
l += Math.cos(a) * dl;
return 0;
}
};
}
const removeRect = () => {
var _a;
clearInterval(timerRadiation.value);
clearTimeout(timeoutTimer.value);
(_a = ctx.value) == null ? void 0 : _a.clearRect(0, 0, cw.value, ch.value);
};
const RESET_VIEW = () => {
if (props.type === "radiation") {
removeRect();
init();
}
};
const updataText = (url) => {
};
onMounted(() => {
init();
});
onUnmounted(() => {
if (props.type === "radiation") {
clearInterval(timerRadiation.value);
clearTimeout(timeoutTimer.value);
}
});
watch(
() => props.text,
() => {
removeRect();
init();
}
);
watch(
() => [
props.text,
props.fontSize,
props.titleFamily,
props.rayColor1,
props.rayColor2,
props.lineLength,
props.speed,
props.isAnimation
],
() => {
removeRect();
init();
},
{ deep: true }
);
return {
canvasRadiationBox,
canvasRadiation,
updataText,
RESET_VIEW,
...toRefs(props)
};
}
});
const _hoisted_1 = {
class: "label-text-animation__box text__radiation",
ref: "canvasRadiationBox"
};
const _hoisted_2 = { ref: "canvasRadiation" };
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return openBlock(), createElementBlock("div", {
class: "co-label-text-animation",
style: normalizeStyle({ width: _ctx.width || "100%", height: _ctx.height || "100%" })
}, [
createElementVNode("div", _hoisted_1, [
createElementVNode("canvas", _hoisted_2, null, 512)
], 512)
], 4);
}
var CoLabelTextAnimation = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-7820ec32"]]);
export { CoLabelTextAnimation as default };