全屏组件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);
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。