全屏组件FullScreenContainer
目录构造
index.vue
<template> <div id="sp-full-screen-container" :ref="ref"> <div id="sp-full-screen-container-content"> <template v-if="ready"> <slot></slot> </template> </div> </div></template><script>import autoResize from "./mixin/autoResize.js";export default { name: "FullScreenContainer", mixins: [autoResize], props: { //设计稿画布大小(单位:px) canvasWidth: { type: Number, default: 0, }, canvasHeight: { type: Number, default: 0, }, }, data() { return { ref: "sp-full-screen-container", ready: false, scale: 1.0, }; }, methods: { afterAutoResizeMixinInit() { const { initConfig, setContainerScale } = this; initConfig(); setContainerScale(); this.ready = true; }, initConfig() { const { dom, canvasWidth, canvasHeight } = this; // debugger; if (canvasWidth > 0 && canvasHeight > 0) { dom.style.cssText = `width: ${canvasWidth}px; height: ${canvasHeight}px;`; } }, setContainerScale() { const { width, height, dom } = this; const { innerWidth, innerHeight } = window; let top = 0; let left = 0; let scale = 0; // 设置缩放率并居中 if (innerWidth / innerHeight > width / height) { // 高低居中 scale = innerHeight / height; left = (innerWidth - scale * 1920) / 2; } else { // 左右居中 scale = innerWidth / width; // top = 0; } // 防止死循环 if (this.scale == scale) { dom.style.left = `${left}px`; dom.style.top = `${top}px`; dom.style.transform = `scale(${scale})`; return; } this.scale = scale; if (width == 0 || height == 0) { dom.style.left = `${left}px`; dom.style.top = `${top}px`; dom.style.transform = `scale(${scale})`; } else { // 升高DOM操作次数 dom.style.cssText = `width: ${width}px; height: ${height}px; left: ${left}px; top: ${top}px; transform: scale(${scale});`; } }, onResize() { const { setContainerScale } = this; setContainerScale(); }, },};</script><style lang="less">#sp-full-screen-container { position: fixed; top: 0px; left: 0px; overflow: visible; -webkit-transform-origin: left top; transform-origin: left top; z-index: 999; display: flex; justify-content: center; align-items: center;}</style>
autoResize.js
import { debounce, observerDomResize } from "../util/index";export default { data() { return { dom: "", width: 0, height: 0, debounceInitWHFun: "", domObserver: "", }; }, methods: { async autoResizeMixinInit() { const { initWH, getDebounceInitWHFun, bindDomResizeCallback, afterAutoResizeMixinInit, } = this; await initWH(false); getDebounceInitWHFun(); bindDomResizeCallback(); if (typeof afterAutoResizeMixinInit === "function") afterAutoResizeMixinInit(); }, initWH(resize = true) { const { $nextTick, $refs, ref, onResize } = this; return new Promise((resolve) => { $nextTick(() => { const dom = (this.dom = $refs[ref]); this.width = dom.clientWidth; this.height = dom.clientHeight; if (typeof onResize === "function" && resize) onResize(); resolve(); }); }); }, getDebounceInitWHFun() { const { initWH } = this; this.debounceInitWHFun = debounce(100, initWH); }, bindDomResizeCallback() { const { dom, debounceInitWHFun } = this; this.domObserver = observerDomResize(dom, debounceInitWHFun); window.addEventListener("resize", debounceInitWHFun); }, unbindDomResizeCallback() { let { domObserver, debounceInitWHFun } = this; domObserver.disconnect(); domObserver.takeRecords(); domObserver = null; // NOSONAR window.removeEventListener("resize", debounceInitWHFun); }, }, mounted() { const { autoResizeMixinInit } = this; autoResizeMixinInit(); }, onBeforeUnMount() { const { unbindDomResizeCallback } = this; unbindDomResizeCallback(); },};
util/index.js
export function randomExtend(minNum, maxNum) { if (arguments.length === 1) { return parseInt(Math.random() * minNum + 1, 10); } else { return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10); }}export function debounce(delay, callback) { let lastTime; return function () { clearTimeout(lastTime); const [that, args] = [this, arguments]; lastTime = setTimeout(() => { callback.apply(that, args); }, delay); };}export function observerDomResize(dom, callback) { const MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; const observer = new MutationObserver(callback); observer.observe(dom, { attributes: true, attributeFilter: ["style"], attributeOldValue: true, }); return observer;}export function getPointDistance(pointOne, pointTwo) { const minusX = Math.abs(pointOne[0] - pointTwo[0]); const minusY = Math.abs(pointOne[1] - pointTwo[1]); return Math.sqrt(minusX * minusX + minusY * minusY);}