vue3项目大屏适配方案(scale)及vue-tv-focusable库使用

发布于:2025-02-10 ⋅ 阅读:(75) ⋅ 点赞:(0)

一. 适配方案代码(scale)

公共代码

export const useAdjustScale = () => {
  // * 指向最外层容器
  const pageRef = ref();
  // * 默认缩放值
  const scale = {
    width: '1',
    height: '1',
  };

  // * 需保持的比例(默认1.77778)
const designWidth = 1920
const designHeight = 1080
  const baseProportion = parseFloat((designWidth / designHeight).toFixed(5));
  const adjustScale = () => {
    // 当前宽高比
    const currentRate = parseFloat((window.innerWidth / window.innerHeight).toFixed(5));
    if (pageRef.value) {
      if (currentRate > baseProportion) {
        // 表示更宽
        scale.width = ((window.innerHeight * baseProportion) / designWidth).toFixed(5);
        scale.height = (window.innerHeight / designHeight).toFixed(5);
        pageRef.value.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)`;
        console.log(scale.width, scale.height, 'moreWidth');
      } else {
        // 表示更高
        scale.height = (window.innerWidth / baseProportion / designHeight).toFixed(5);
        scale.width = (window.innerWidth / designWidth).toFixed(5);
        pageRef.value.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)`;
      }
    }
  };

  onMountedOrActivated(() => adjustScale());
  useWindowSizeFn(() => adjustScale());

  return { pageRef, adjustScale };
};

onMountedOrActivated

import { nextTick, onMounted, onActivated } from 'vue';

export function onMountedOrActivated(hook: Fn) {
  let mounted: boolean;

  onMounted(() => {
    hook();
    nextTick(() => {
      mounted = true;
    });
  });

  onActivated(() => {
    if (mounted) {
      hook();
    }
  });
}

useWindowSizeFn

import { tryOnMounted, tryOnUnmounted, useDebounceFn } from '@vueuse/core';

interface WindowSizeOptions {
  once?: boolean;
  immediate?: boolean;
  listenerOptions?: AddEventListenerOptions | boolean;
}

export function useWindowSizeFn<T>(fn: Fn<T>, wait = 150, options?: WindowSizeOptions) {
  let handler = () => {
    console.log('resizeHander');
    try {
      fn();
    } catch (error) {
      console.error(`${new Date().toLocaleTimeString()}🔥 -> useWindowSizeFn -> error:`, error);
    }
  };
  const handleSize = useDebounceFn(handler, wait);
  handler = handleSize;

  const start = () => {
    if (options && options.immediate) {
      handler();
    }
    window.addEventListener('resize', handler);
  };

  const stop = () => {
    window.removeEventListener('resize', handler);
  };

  tryOnMounted(() => {
    start();
  });

  tryOnUnmounted(() => {
    stop();
  });
  return [start, stop];
}

使用核心举例

  <div id="dashboard" ref="pageRef">
  </div>
// * 适配处理
  const { pageRef } = useAdjustScale();

二.vue-tv-focusable

用途:主要用于大屏项目在tv中显示时,利用遥控器控制dom元素的聚焦
使用示例

<div
              class="secure"
              ref="secureRef"
              v-focusable="true"
              @up="secureFocus('up')"
              @right="secureFocus('right')"
              @click="secureClick"
            >
            </div>
 const secureFocus = (e) => {
    if (e == 'up') {
      proxy.$tv.requestFocus(introduceRef.value);
    } else if (e == 'right') {
      proxy.$tv.requestFocus(qualityRef.value);
    }
  };
 import { getCurrentInstance } from 'vue';
 const { proxy } = getCurrentInstance();
 const introduceRef = ref<HTMLFrameElement>();
 const qualityRef = ref<HTMLFrameElement>();

详细使用方法可参考vue-tv-focusable


网站公告

今日签到

点亮在社区的每一天
去签到