收藏
回答

微信排行榜渲染相关,每个标签的 class 的 width 和 height 都是相同的,但是被拉伸

框架类型 问题类型 操作系统 工具版本
小游戏 Bug Windows 1.05.2204264

微信排行榜渲染相关。我在 css 的每一个标签相关的 class 中都设置了长宽是相等的,但是最终渲染出来的效果是所有标签都被拉伸了,请问这是为什么,除了把标签的长宽对应改成长方形这种 hack 的方法之外,还有什么解决方法?

渲染图:

样式代码:

open-data\render\styles\friendRank.js

/**
 * 定义一些样式,方便在 tpls 文件夹中的定义内容的文件来使用
 */
export default function getStyle(data) {
  // let data = { width: 356, height: 400 };
  let itemHeight = data.height / 2 / 3;
  let itemWidth = Math.ceil(data.width * 0.94);


  return {
    // 容器
    container: {
      width: data.width,
      height: data.height,
      borderRadius: 12,
      paddingLeft: data.width * 0.03,
      paddingRight: data.width * 0.03,
    },
    
    // 每一行排名的背景
    rankBg: {
      position: 'absolute',
      top: 0,
      left: 0,
      width: itemWidth,
      height: itemHeight,
    },


    // 列表中一个排名对象的大小
    listItem: {
      position: 'relative',
      width: itemWidth,
      height: itemHeight,
      flexDirection: 'row',
      alignItems: 'center',
      marginTop: 2,
    },


    // 每个列表对象的排名
    listItemRank: {
      position: 'relative',
      width: itemHeight * 0.8,
      height: itemHeight * 0.8,
      fontSize: 12,
      fontWeight: 'bold',
      textAlign: 'center',
      //marginTop: itemHeight*0.4,
      //marginBottom: itemHeight*0.1,
    },


    // 每个列表对象的头像
    listItemAvatar: {
      position: 'relative',
      width: itemHeight * 0.8 ,
      height: itemHeight * 0.8,
      //borderRadius: 15,
      //borderWidth: 5,
      borderColor: 'black',
    },


    // 每个列表对象的名称
    listItemName: {
      position: 'relative',
      // 除去其他 4 个元素,剩下的长度就是名字的长度
      // 但是每一行排名的背景图本身占据的范围不一定是 itemWidth
      // 所以这个列表对象的名称的 width 还要稍微缩小一点
      width: (itemWidth - 4 * itemHeight * 0.8) * 0.8,
      height: itemHeight*0.5,
      fontSize: 12,
      //marginLeft: 30,
      //marginTop: itemHeight*0.4,
      //marginBottom: itemHeight*0.1,
    },


    // 超级动物的数量
    listItemSuperAnimalCount: {
      position: 'relative',
      width: itemHeight * 0.8,
      height: itemHeight * 0.8,
      fontSize: 12,
      fontWeight: 'bold',
      textAlign: 'right',
      //marginRight: 30,
      //marginTop: itemHeight*0.4,
      //marginBottom: itemHeight*0.1,
    },


    // 普通动物的数量
    listItemNormalAnimalCount: {
      position: 'relative',
      width: itemHeight * 0.8,
      height: itemHeight * 0.8,
      fontSize: 12,
      fontWeight: 'bold',
      textAlign: 'right',
      //marginRight: 30,
      //marginTop: itemHeight*0.4,
      //marginBottom: itemHeight*0.1,
    },
  };
}


h5 转微信渲染引擎代码:

open-data\render\tpls\friendRank.js

export default function anonymous(it) {
  let out = '<view class="container" id="main"> <view class="rankList"> <scrollview class="list" scrollY="true"> ';
  const arr1 = it.data;
  if (arr1) {
    let item;
    let index = -1;
    const l1 = arr1.length - 1;
    while (index < l1) {
      item = arr1[(index += 1)];
      out += ` <view class="listItem"> 
          <image src="open-data/render/image/rankBg.png" class="rankBg"></image> 
          <text class="listItemRank" value="${index +1 }"></text> 
          <image class="listItemAvatar" src="${item.avatarUrl}"></image>
          <text class="listItemName" value="${item.nickname}"></text> 
          <text class="listItemSuperAnimalCount" value="${item.superAnimCount || 0}"></text> 
          <text class="listItemNormalAnimalCount" value="${item.normalAnimCount || 0}"></text> 
        </view> `;
    }
  }
  out += ' </scrollview> </view></view>';
  return out;
}


排行榜使用的 RawImage 在场景树中的排布如图



RawImage 的每一个父节点我都看过了,Scale 都是 1

RawImage 的父节点中包含的与 Canvas 调整相关的组件也就是一个 Canvas Scaler,这个是用来适配不同尺寸的设备的,我也尝试禁用这个组件了,禁用了之后还是有这个被拉伸的问题

最后一次编辑于  2023-05-18
回答关注问题邀请回答
收藏

1 个回答

  • 我不廉价
    我不廉价
    2023-05-18

    知道了……我的 CanvasScaler 放在父级,但是官方 Demo 的应该是就放在跟 RawImage 一起,我应该用 `GetComponentInParent<CanvasScaler>()` 的

     void ShowOpenData()
    {
        // 
        // 注意这里传x,y,width,height是为了点击区域能正确点击,x,y 是距离屏幕左上角的距离,宽度传 (int)RankBody.rectTransform.rect.width是在canvas的UI Scale Mode为 Constant Pixel Size的情况下设置的。
        /**
         * 如果父元素占满整个窗口的话,pivot 设置为(0,0),rotation设置为180,则左上角就是离屏幕的距离
         * 注意这里传x,y,width,height是为了点击区域能正确点击,因为开放数据域并不是使用 Unity 进行渲染而是可以选择任意第三方渲染引擎
         * 所以开放数据域名要正确处理好事件处理,就需要明确告诉开放数据域,排行榜所在的纹理绘制在屏幕中的物理坐标系
         * 比如 iPhone Xs Max 的物理尺寸是 414 * 896,如果排行榜被绘制在屏幕中央且物理尺寸为 200 * 200,那么这里的 x,y,width,height应当是 107,348,200,200
         * x,y 是距离屏幕左上角的距离,宽度传 (int)RankBody.rectTransform.rect.width是在canvas的UI Scale Mode为 Constant Pixel Size的情况下设置的
         * 如果是Scale With Screen Size,且设置为以宽度作为缩放,则要这要做一下换算,比如canavs宽度为960,rawImage设置为200 则需要根据 referenceResolution 做一些换算
         * 不过不管是什么屏幕适配模式,这里的目的就是为了算出 RawImage 在屏幕中绝对的位置和尺寸
         */
    
        // 这里要注意 CanvasScaler 放在 RawImage 的哪里
        // 官方 Demo 的是放在跟 RawImage 我的 CanvasScaler 在 RawImage 的父级
        // CanvasScaler scaler = gameObject.GetComponent<CanvasScaler>();
        CanvasScaler scaler = gameObject.GetComponentInParent<CanvasScaler>();
        var referenceResolution = scaler.referenceResolution;
        var p = rankListBody.transform.position;
    
        var rect = rankListBody.rectTransform.rect;
        WX.ShowOpenData(rankListBody.texture, (int)p.x, Screen.height - (int)p.y,
            (int)((Screen.width / referenceResolution.x) * rect.width),
            (int)((Screen.width / referenceResolution.x) * rect.height));
    }
    
    2023-05-18
    有用
    回复
登录 后发表内容