@fit-screen/react
Version:
Scale-based large-screen adaptive solution for React Everything is based on the design draft's px size, and the adaptation is done by scale, everything is so simple
343 lines (342 loc) • 12.6 kB
JavaScript
(function() {
"use strict";
try {
if (typeof document != "undefined") {
var elementStyle = document.createElement("style");
elementStyle.appendChild(document.createTextNode("body {\n overflow: hidden;\n}\n\n._fit-screen_119nw_5 {\n position: relative;\n height: 100vh;\n width: 100vw;\n}\n._fit-screen_119nw_5._fit_119nw_5, ._fit-screen_119nw_5._full_119nw_10 {\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n}\n._fit-screen_119nw_5._fit_119nw_5 ._fit-screen-scale_119nw_16, ._fit-screen_119nw_5._full_119nw_10 ._fit-screen-scale_119nw_16 {\n transform-origin: center center;\n}\n._fit-screen_119nw_5._scrollY_119nw_19 {\n overflow-x: hidden;\n}\n._fit-screen_119nw_5._scrollY_119nw_19 ._fit-screen-scale_119nw_16 {\n transform-origin: left top;\n}\n._fit-screen_119nw_5._scrollX_119nw_25 {\n overflow-y: hidden;\n}\n._fit-screen_119nw_5._scrollX_119nw_25 ._fit-screen-scale_119nw_16 {\n transform-origin: left top;\n}\n._fit-screen_119nw_5 ._fit-screen-entity_119nw_31 {\n overflow: hidden;\n}"));
document.head.appendChild(elementStyle);
}
} catch (e) {
console.error("vite-plugin-css-injected-by-js", e);
}
})();
var __defProp = Object.defineProperty;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
(function(global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("react"), require("react/jsx-runtime")) : typeof define === "function" && define.amd ? define(["exports", "react", "react/jsx-runtime"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.FitScreen = {}, global.React, global.jsx));
})(this, function(exports2, React, jsxRuntime) {
"use strict";
function _interopNamespace(e) {
if (e && e.__esModule)
return e;
var n = /* @__PURE__ */ Object.create(null);
if (e) {
Object.keys(e).forEach(function(k) {
if (k !== "default") {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function() {
return e[k];
}
});
}
});
}
n["default"] = e;
return Object.freeze(n);
}
var React__namespace = /* @__PURE__ */ _interopNamespace(React);
var __defProp2 = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols2 = Object.getOwnPropertySymbols;
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
var __propIsEnum2 = Object.prototype.propertyIsEnumerable;
var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues2 = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp2.call(b, prop))
__defNormalProp2(a, prop, b[prop]);
if (__getOwnPropSymbols2)
for (var prop of __getOwnPropSymbols2(b)) {
if (__propIsEnum2.call(b, prop))
__defNormalProp2(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var FitScreenEnum = /* @__PURE__ */ ((FitScreenEnum2) => {
FitScreenEnum2["FIT"] = "fit";
FitScreenEnum2["SCROLL_Y"] = "scrollY";
FitScreenEnum2["SCROLL_X"] = "scrollX";
FitScreenEnum2["FULL"] = "full";
return FitScreenEnum2;
})(FitScreenEnum || {});
function throttle(func, wait, options) {
let timeout, context, args;
let previous = 0;
if (!options)
options = {};
const later = function() {
previous = (options == null ? void 0 : options.leading) === false ? 0 : new Date().getTime();
timeout = null;
func.apply(context, args);
if (!timeout)
context = args = null;
};
const throttled = function(...rests) {
const now = new Date().getTime();
if (!previous && (options == null ? void 0 : options.leading) === false)
previous = now;
const remaining = wait - (now - previous);
context = this;
args = rests;
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
func.apply(context, args);
if (!timeout)
context = args = null;
} else if (!timeout && (options == null ? void 0 : options.trailing)) {
timeout = setTimeout(later, remaining);
}
};
return throttled;
}
function debounce(func, wait) {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func.apply(this, args);
}, wait);
};
}
const useFitScale = (options) => createCalcRateFn(__spreadProps(__spreadValues2({}, options), { mode: FitScreenEnum.FIT }));
const useScrollYScale = (options) => createCalcRateFn(__spreadProps(__spreadValues2({}, options), { mode: FitScreenEnum.SCROLL_Y }));
const useScrollXScale = (options) => createCalcRateFn(__spreadProps(__spreadValues2({}, options), { mode: FitScreenEnum.SCROLL_X }));
const useFullScale = (options) => createCalcRateFn(__spreadProps(__spreadValues2({}, options), { mode: FitScreenEnum.FULL }));
function createCalcRateFn(options) {
const {
width = 1920,
height = 1080,
el,
mode,
executeMode = "throttle",
waitTime = 200,
beforeCalculate,
afterCalculate
} = options;
let scale = {
widthRatio: 1,
heightRatio: 1
};
const baseProportion = parseFloat((width / height).toFixed(5));
const calcRate = () => {
if (beforeCalculate) {
const flag = beforeCalculate(scale);
if (flag === false)
return;
}
if (el) {
switch (mode) {
case FitScreenEnum.FIT:
{
const currentRate = parseFloat((window.innerWidth / window.innerHeight).toFixed(5));
scale = currentRate > baseProportion ? calcRateByHeight(width, height, baseProportion) : calcRateByWidth(width, height, baseProportion);
}
break;
case FitScreenEnum.SCROLL_X:
scale = calcRateByHeight(width, height, baseProportion);
break;
case FitScreenEnum.SCROLL_Y:
scale = calcRateByWidth(width, height, baseProportion);
break;
case FitScreenEnum.FULL:
scale = calcRateByStretch(width, height);
break;
}
el.style.transform = `scale(${scale.widthRatio}, ${scale.heightRatio})`;
if (afterCalculate)
afterCalculate(scale);
}
};
let tFn = () => {
};
switch (executeMode) {
case "none":
tFn = calcRate;
break;
case "debounce":
tFn = debounce(() => {
calcRate();
}, waitTime);
break;
case "throttle":
tFn = throttle(() => {
calcRate();
}, waitTime, { trailing: true });
break;
default:
tFn = throttle(() => {
calcRate();
}, waitTime, { trailing: true });
break;
}
const resize = () => {
window.addEventListener("resize", tFn);
};
const unResize = () => {
window.removeEventListener("resize", tFn);
};
return {
calcRate,
resize,
unResize
};
}
function calcRateByWidth(baseWidth, baseHeight, baseProportion) {
const heightRatio = parseFloat((window.innerWidth / baseProportion / baseHeight).toFixed(5));
const widthRatio = parseFloat((window.innerWidth / baseWidth).toFixed(5));
return { widthRatio, heightRatio };
}
function calcRateByHeight(baseWidth, baseHeight, baseProportion) {
const widthRatio = parseFloat((window.innerHeight * baseProportion / baseWidth).toFixed(5));
const heightRatio = parseFloat((window.innerHeight / baseHeight).toFixed(5));
return { widthRatio, heightRatio };
}
function calcRateByStretch(baseWidth, baseHeight) {
const widthRatio = parseFloat((window.innerWidth / baseWidth).toFixed(5));
const heightRatio = parseFloat((window.innerHeight / baseHeight).toFixed(5));
return { widthRatio, heightRatio };
}
const useFitScreen = (options) => {
const entityRef = React__namespace.useRef(null);
const previewRef = React__namespace.useRef(null);
const { width, height, mode, executeMode, waitTime, onScaleChange } = options;
const initFitScreenByMode = () => {
let fn;
const options2 = {
width,
height,
executeMode,
waitTime,
el: previewRef.current,
beforeCalculate(scale) {
const dom = entityRef.current;
dom.style.width = `${width * scale.widthRatio}px`;
dom.style.height = `${height * scale.heightRatio}px`;
},
afterCalculate(scale) {
onScaleChange && onScaleChange(scale);
}
};
switch (mode) {
case FitScreenEnum.FIT:
fn = useFitScale;
delete options2.beforeCalculate;
break;
case FitScreenEnum.SCROLL_X:
fn = useScrollXScale;
break;
case FitScreenEnum.SCROLL_Y:
fn = useScrollYScale;
break;
case FitScreenEnum.FULL:
fn = useFullScale;
delete options2.beforeCalculate;
break;
default:
fn = useFitScale;
delete options2.beforeCalculate;
}
return fn(options2);
};
React__namespace.useEffect(() => {
const { calcRate, resize, unResize } = initFitScreenByMode();
calcRate();
resize();
return () => unResize();
}, [width, height, mode]);
return {
entityRef,
previewRef
};
};
const fit = "_fit_119nw_5";
const full = "_full_119nw_10";
const scrollY = "_scrollY_119nw_19";
const scrollX = "_scrollX_119nw_25";
var styles = {
"fit-screen": "_fit-screen_119nw_5",
fit,
full,
"fit-screen-scale": "_fit-screen-scale_119nw_16",
scrollY,
scrollX,
"fit-screen-entity": "_fit-screen-entity_119nw_31"
};
const InnerFitScreen = React__namespace.forwardRef((props, ref) => {
const {
width = 1920,
height = 1080,
mode = "fit",
executeMode = "throttle",
waitTime = 200,
scaleClass,
scaleStyle,
className,
children,
onScaleChange
} = props;
const showEntity = mode === FitScreenEnum.SCROLL_Y || mode === FitScreenEnum.SCROLL_X;
const previewRefStyle = [{
position: "relative",
width: width ? `${width}px` : "100%",
height: height ? `${height}px` : "100%"
}, ...Array.isArray(scaleStyle) ? scaleStyle : [scaleStyle]].reduce((style, refStyle) => __spreadValues(__spreadValues({}, style), refStyle), {});
const {
previewRef,
entityRef
} = useFitScreen({
width,
height,
mode,
executeMode,
waitTime,
onScaleChange
});
const scaleDom = /* @__PURE__ */ jsxRuntime.jsx("div", {
ref: previewRef,
className: `fit-screen-scale ${styles["fit-screen-scale"]}`,
children: /* @__PURE__ */ jsxRuntime.jsx("div", {
className: scaleClass,
style: previewRefStyle,
children
})
});
const entityDom = /* @__PURE__ */ jsxRuntime.jsx("div", {
ref: entityRef,
className: `fit-screen-entity ${styles["fit-screen-entity"]}`,
children: scaleDom
});
return /* @__PURE__ */ jsxRuntime.jsx("div", {
ref,
className: `fit-screen ${styles["fit-screen"]} ${styles[mode]} ${className || ""} `,
children: showEntity ? entityDom : scaleDom
});
});
InnerFitScreen.displayName = "FitScreen";
const FitScreen = React__namespace.memo(InnerFitScreen);
var FitScreen$1 = FitScreen;
exports2["default"] = FitScreen$1;
Object.defineProperty(exports2, "__esModule", { value: true });
});