此文为 h5 屏幕适配具体公式推导,原理和使用参考 https://www.helpdocshub.com/720.html
缩放
有时我们需要的是设计稿宽高比 v/g
大于屏幕宽高比 u/f
时设计稿宽 v1
等于屏幕宽 u
,否则设计稿高 g1
等于屏幕高 f
。求满足要求得设计稿缩放值 s
?
由条件可得 x1 = x*s y1 = y*s v1 = v*s g1 = g*s w1 = w*s h1 = h*s 当 v/g >= u/f 时 两边乘 f/v 得 f/g >= u/v 由 v1 = u 得 v1 = v*s = u s = u/v 即 f/g >= u/v 时 s = u/v 当 v/g < u/f 时 两边乘 f/v 得 f/g < u/v 由 g1 = f,得 g1 = g*s = f s = f/g 即 f/g < u/v 时 s = f/g 即 s 为 f/g 和 u/v 最小值 即设计稿缩放值 s = Math.min(f/g, u/v)
内存优化
如果每一层都是宽 v1
高 g1
,层数一多,占用 gpu 内存就非常多,特别是需要做 css 动画时,大内存会导致动画卡顿,应当减小推到 gpu 内存的层实际面积减少内存占用。 如果拉伸设计稿 v*g
至 屏幕 u*f
大小,对应 w*h
区域坐标变成 (x3, y3)
,宽高变成 w3*h3
,假设此时横向拉伸 sx
纵向拉伸 sy
。
由条件得 u = v*sx f = g*sy x3 = x*sx y3 = y*sy w3 = w*sx h3 = h*sy 进而得 sx = u/v sy = f/g x3 = x*u/v y3 = y*f/g w3 = w*u/v h3 = h*f/g 内存优化 (w3*h3)/(v1*g1) = ((w*u/v)*(h*f/g))/(v*s*g*s) = w*u*h*f/(v*v*g*g*s*s) 当 v/g >= u/f 时 v1 = v*s = u u = v*sx 得 s = sx = u/v w3 = w*sx = w*s = w1 (w3*h3)/(v1*g1) = w*u*h*f/(v*v*g*g*s*s) = w*h*f/(g*g*u) 由 v/g >= u/f 得 g/v <= f/u 得 g/v*(w*h/(g*g) <= f/u*(w*h/(g*g)) 得 w*h/(v*g) <= w*h*f/(g*g*u) 得 (w3*h3)/(v1*g1) >= w*h/(v*g) 当 v/g < u/f 时 g1 = g*s = f f = g*sy 得 s = sy = f/g h3 = h*sy = h*s = h1 (w3*h3)/(v1*g1) = w*u*h*f/(v*v*g*g*s*s) = w*u*h/(v*v*f) 由 v/g < u/f 得 v/g*(w*h/(v*v) < u/f*(w*h/(v*v)) 得 w*h/(v*g) < w*u*h/(v*v*f) 得 (w3*h3)/(v1*g1) > w*h/(v*g) 即 (w3*h3)/(v1*g1) >= w*h/(v*g) 当 v/g >= u/f 时 v1 = u 且 w1 = w3 当 v/g < u/f 时 g1 = f 且 h1 = h3
所以可以构造出一个更小的层 w3*h3
且满足 w3 = w*u/v
h3 = h*f/g
,元素在该区域内的保持不变形缩放,即可和设计稿整体在屏幕内缩放导致元素缩放一致。
如果仅将区域 w1*h1
推到 gpu 内存,则内存占用率达到最低点,相比推 v1*g1
减少了 1 - (w1*h1)/(v1*g1) = (w*h)/(v*g)
,而推 w3*h3
次之,减少了 1 - (w3*h3)/(v1*g1) <= 1 - w*h/(v*g)
。 以 w = 544
h = 142
v = 1080
g = 1920
为例,推 w1*h1
减少了约 96.27%
,而推 w3*h3
最多减少约 96.27%
gpu 内存占用。
定位
缩放后还需要确定在容器中的定位,常见的就是贴边和居中。实际上就是求元素贴边或居中的坐标 `(x2, y2)
已知设计稿宽 v
高 g
,其中任意元素的宽 w
高 h
和坐标 (x, y)
,横向左留白占总留白的比值为 m
,纵向上留白占总留白的比值为 n
,假设设计稿尺寸到实际尺寸缩放了 s
倍,求经过屏幕适配后该元素的实际宽 w2
高 h2
和坐标(x2, y2)
?
由条件可得 x1 = x*s y1 = y*s v1 = v*s g1 = g*s w1 = w*s h1 = h*s m = x2/(u - v1) n = y2/(f - g1) 继而得 y2 = n*(f - g1) = n*(f - g*s) = n*f - n*g*s y2 + y1 = n*f - n*g*s + y1 = n*f - n*g*s + y*s = n*f + (y - n*g)*s = n*f + (y - n*g)/h*h*s = n*f + (y - n*g)/h*h1 同理 x2 = m*(u - v1) = m*(u - v*s) = m*u - m*v*s x2 + x1 = m*u - m*v*s + x1 = m*u - m*v*s + x*s = m*u + (x - m*v)*s = m*u + (x - m*v)/w*w*s = m*u + (x - m*v)/w*w1
background-size 实现
假设对于区域 w3*h3
, 求 w3*h3
内横向上左留白 x2 + x1 - x3
占总留白 h3 - h1
比值 p
和纵向上上留白 y2 + y1 - y3
占总留白 w3 - w1
比值 o
?
已知 x3 = x*u/v y3 = y*f/g w3 = w*u/v h3 = h*f/g p = (y2 + y1 - y3)/(h3 - h1) o = (x2 + x1 - x3)/(w3 - w1) 得 p = (n*f - n*g*s + y*s - y*f/g)/(h*f/g - h*s) = (n*(f - g*s) + y*(s - f/g))/(h*(f/g - s)) = n*(f - g*s)/(h*(f/g - s)) + y*(s - f/g)/(h*(f/g - s)) = n*(f - g*s)/(h/g*(f - g*s)) - y*(f/g - s)/(h*(f/g - s)) = n*g/h - y/h = (n*g - y)/h 同理 o = m*v/w - x/w = (m*v - x)/w
svg 标签实现
已知 h3 = h*f/g 得 f = h3*g/h y2 + y1 = n*f - n*g*s + y*s = n*h3*g/h + (y - n*g)*s = n*g/h*h3 + (y - n*g)/h*h*s = n*g/h*h3 + (y - n*g)/h*h1 同理 已知 w3 = w*u/v 得 u = w3*v/w 得 x2 + x1 = m*v/w*w3 + (x - m*v)/w*w1
方案完善
上面以刚好全部显示的屏幕适配方案,同理可推导刚好占满适配及拉伸适配
占满适配屏幕
原理
设计稿缩放值 s = Math.max(f/g, u/v) 内存优化 (w3*h3)/(v1*g1) >= w*h/(v*g) 当 v/g < u/f 时 v1 = u 且 w1 = w3 当 v/g >= u/f 时 g1 = f 且 h1 = h3 x1 = x*s y1 = y*s w1 = w*s h1 = h*s v1 = v*s g1 = g*s 横向上左超出占总超出比值 m = x2/(v1 - u) 贴屏幕顶时 m = 0 垂直居中时 m = .5 贴屏幕顶时 m = 1 纵向上上超出占总超出比值 n = y2/(g1 - f) 贴屏幕左时 n = 0 水平居中时 n = .5 贴屏幕右时 n = 1 x2 = m*(v1 - u) = m*v*s - m*u y2 = n*(g1 - f) = n*g*s - n*f x1 - x2 = m*u - m*v*s + x*s = m*u + (x - m*v)/w*w1 = m*v/w*w3 + (x - m*v)/w*w1 y1 - y2 = n*f - n*g*s + y*s = n*f + (y - n*g)/h*h1 = n*g/h*h3 + (y - n*g)/h*h1 x3 = x*u/v y3 = y*f/g w3 = w*u/v h3 = h*f/g o = (x3 - x1 + x2)/(w3 - w1) = (x - m*v)/w p = (y3 - y1 + y2)/(h3 - h1) = (y - n*g)/h
⚠️:此文章原站失效,无更多快照
原文标题:H5分层屏幕适配公式推导
原文链接:http://hai.li/2018/03/14/h5-screen-adaptation-formula-derivation.html
原文快照:https://web.archive.org/web/20210923173258/http://hai.li/2018/03/14/h5-screen-adaptation-formula-derivation.html
文章评论