UNPKG

cione-comp-lib

Version:

`$ yarn add cione-comp-lib` 或者 `$ npm i cione-comp-lib -S`

310 lines (309 loc) 9.23 kB
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 };