微信排行榜渲染相关。我在 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,这个是用来适配不同尺寸的设备的,我也尝试禁用这个组件了,禁用了之后还是有这个被拉伸的问题
知道了……我的 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)); }