文章目录
  1. 1. 效果预览
  2. 2. 需求
  3. 3. 实现
  4. 4. 问题 bug 产生
  5. 5. bug 解决方案实现

某些机型出现 渲染结果与实际设置不一致的 bug

效果预览

一如既往,demo 效果必须有

需求

本次活动需要实现一个老虎机抽奖效果的小游戏。
由于开发周期比较短,活动要求也不是特别高,就没打算使用 canvas 制作,选用 dom 方式实现。

实现

实现方式有很多种,比如:

  1. 通过 更新 background-position 属性值
  2. 通过 transform 更新 translate 属性值
  3. 通过 position 定位,更新定位属性值
  4. 通过 更新 scroll 属性值

这里选用最简单的 background-position 实现

原理描述(设定竖向 y 轴滚动):

  1. 设置一条按照固定格子大小拼接起来的长背景图
  2. 设置 background-repeat: repeat-y,达到无限重复的效果;
  3. 启动定时器更新 background-position-y 的属性值即可.

由于项目还有其他动画效果,不想再造轮子,这里推荐一款比较好用的轮子:
animateplus github 地址
由于移动端项目,页面需要做设备适配,使用 rem 或者 vw 都可。

问题 bug 产生

很快就开发完毕了,测试都没问题,愉快的发布之后,最新版的 iphone XR 出现了一个匪夷所思的问题。
截图如下:
视觉渲染bug
计算设置的属性值一模一样完全没问题,但是视觉上却 出现了 偏差。
最初无法定位原因,后来联机在 safari 调试的时候发现,safari 这个神奇的浏览器竟然偶尔可以触发。
匪夷所思的 bug,这里没有小数点计算精确度的问题,也不是网页性能掉帧的问题,纯粹是一个迷之所在。
上面的问题我都是一一定位排除了的,包括还了 transform 和 position 等实现方式,都不能解决。

最后差点改用 canvas 重写了,所幸灵机一动,想到了一种解决方案。

思路如下:
既然是视觉上的浏览器 bug,那么应用视觉效果去解决应该能生效。由于之前定位 bug 的时候,采用过各种方案,用 px 写死是没问题的,但是引发的副作用是无法做到设备兼容,这里既然想用 px,又想设备兼容,很自然想到了 css3 的变形缩放,在视觉上缩放响应比例的 scale 即可。

bug 解决方案实现

解决方案及其简单,写一个缩放函数 initGameScale 即可。
全部源码实现如下:(无压缩加上样式也才 七八十行):
直接使用 vue-cli3 的快速原型开发即可启动预览。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<template>
<div class="stage">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<div class="list game1111">
<div class="colitem"></div>
<div class="colitem"></div>
<div class="colitem"></div>
</div>
</div>
</template>

<script>
import animate from './animateplus';

export default {
data() {
return {
elColItemHeight: 0,
ANGLE: [
[3, 6, 0], // 0
[2, 2, 2], // 1
[0, 0, 0], // 2
[7, 7, 7], // 3
[9, 9, 9], // 4
[8, 8, 8], // 5
[5, 5, 5], // 6
[6, 6, 6], // 7
[1, 1, 1], // 8
[3, 3, 3], // 9
[4, 4, 4], // 10
],
};
},
methods: {
getRandom(n, m) {
return Math.floor(Math.random() * (m - n + 1) + n);
},
getDomRect(dom) {
return document.querySelector(dom).getBoundingClientRect();
},
run(arr) {
const u = 136;
animate({
elements: '.colitem',
duration: index => 5000 + index * 1000,
easing: 'in-out-cubic',
'background-position-y': index => ['0px', u * 60 - u * arr[index]],
}).then(() => {});
},
initGameScale() {
this.gameScale = window.innerWidth / 750;
document.querySelector('.game1111').style.transform = `scale(${
this.gameScale
})`;
},
},
mounted() {
this.initGameScale();
setTimeout(() => {
this.run(this.ANGLE[this.getRandom(1, 10)]);
}, 300);
},
};
</script>

<style>
.list {
transform-origin: 0% 0%;
transform: scale(0.5);
width: 396px;
height: 136px;
background: rgba(0, 255, 0, 0.4);
}
.colitem {
float: left;
width: 126px;
height: 136px;
margin-right: 3px;
background: url(./luck_types.png) repeat-y 0px 0px;
background-size: 100%;
}
</style>
文章目录
  1. 1. 效果预览
  2. 2. 需求
  3. 3. 实现
  4. 4. 问题 bug 产生
  5. 5. bug 解决方案实现
顶部