云顶娱乐棋牌-云顶娱乐每天送6元
做最好的网站

【云顶娱乐棋牌】你先要知道这几点细节,写一

写贰个网页进程loading

2017/02/26 · JavaScript · 2 评论 · Loading

初藳出处: jack_lo   

loading四处可以知道,比如多少个app日常会有下拉刷新,上拉加载的成效,在刷新和加载的历程中为了让客户感知到 load 的经过,我们会动用一些连片动画来发挥。最分布的举例“转圈圈”,“省略号”等等。

网页loading有这一个用处,举例页面包车型客车加载进度,数据的加载进程等等,数据的加载loading很好做,只要求在加载数据早前(before ajax)展现loading效果,在数额重返之后(ajax completed)停止loading效果,就足以了。

唯独页面的加载进程,必要或多或少本事。

页面加载进度一如既往都以一个广泛而又晦涩的必要,不认为奇是因为它在一些“重”网页(特别是网络电游)的利用非常重大;晦涩是因为web的特性,种种零散能源支配它很难是“真实”的速度,只可以是生机勃勃种“假”的速度,起码在逻辑代码加载成功此前,大家都不可能总括到速度,而逻辑代码本身的速度也无能为力总计。其余,大家不或者监控到全部财富的加载情形。

于是页面包车型客车加载进程都以“假”的,它存在的指标是为了做实顾客体验,使顾客不至于在开垦页面之后长日子面前碰到一片空白,导致客户流失。

既是是“假”的,我们将要变成“仿真”才有用。仿真是有含义的,事实上客户并不在乎某一刻你是或不是真的加载到了百分之几,他只关怀你还要load多久。所以接下去我们就来贯彻多个页面加载进程loading。

首先希图黄金年代段loading的html:

XHTML

<!DOCTYPE html> <html> <head> <title>写贰个网页进程loading</title> </head> <body> <div class="loading" id="loading"> <div class="progress" id="progress">0%</div> </div> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
<head>
    <title>写一个网页进度loading</title>
</head>
<body>
  <div class="loading" id="loading">
    <div class="progress" id="progress">0%</div>
  </div>
</body>
</html>

来点样式装扮一下:

CSS

.loading { display: table; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: #fff; z-index: 5; } .loading .progress { display: table-cell; vertical-align: middle; text-align: center; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.loading {
  display: table;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: #fff;
  z-index: 5;
}
 
.loading .progress {
  display: table-cell;
  vertical-align: middle;
  text-align: center;
}

大家先如若这几个loading只要求在页面加载成功之后遮掩,中间没有必要体现速度。那么十分轻松,大家第一时间想到的正是window.onload:

(以下内容为了便于演示,暗中认可使用jQuery,语法有es6的箭头函数)

JavaScript

var $loading = $('#loading') var $progress = $('#progress') window.onload = () => { $loading.hide() }

1
2
3
4
5
6
var $loading = $('#loading')
var $progress = $('#progress')
 
window.onload = () => {
  $loading.hide()
}

ok,那样基本的loading流程就有了,大家扩展多个速度的意义,每间距100ms就自增1,一贯到百分百得了,而一方面window loaded的时候,大家把loading给隐瞒。

我们来填补一下速度:

JavaScript

var $loading = $('#loading') var $progress = $('#progress') var prg = 0 // 伊始化进程 var timer = window.setInterval(() => { // 设置电火花计时器if (prg >= 100) { // 达到极限,关闭电火花计时器 window.clearInterval(timer) prg = 100 } else { // 未到终端,进度自增 prg++ } $progress.html(prg + '%') console.log(prg) }, 100) window.onload = () => { $loading.hide() }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var $loading = $('#loading')
var $progress = $('#progress')
var prg = 0  // 初始化进度
 
var timer = window.setInterval(() => {  // 设置定时器
  if (prg >= 100) {  // 到达终点,关闭定时器
    window.clearInterval(timer)
    prg = 100
  } else {  // 未到终点,进度自增
    prg++
  }
 
  $progress.html(prg + '%')
  console.log(prg)
}, 100)
 
window.onload = () => {
  $loading.hide()
}

效果与利益不错,然而有个难题,万风流倜傥window loaded太慢了,导致进程呈现load到百分之百了,loading还一贯不藏身,那就打脸了。所以,大家需求让loading在window loaded的时候才到达顶峰,在这前边,loading能够保持二个等候的景象,比方在五分四的时候,先停风流倜傥停,然后在loaded的时候快速将进度推至百分之百。那一个做法是近年来绝大部份进程条的做法。

JavaScript

var $loading = $('#loading') var $progress = $('#progress') var prg = 0 var timer = window.setInterval(() => { if (prg >= 80) { // 达到第一等第百分之七十,关闭停车计时器,保持等待 window.clearInterval(timer) prg = 100 } else { prg++ } $progress.html(prg + '%') console.log(prg) }, 100) window.onload = () => { window.clearInterval(timer) window.setInterval(() => { if (prg >= 100) { // 到达终点,关闭计时器 window.clearInterval(timer) prg = 100 $loading.hide() } else { prg++ } $progress.html(prg + '%') console.log(prg) }, 10) // 时间距离降低 }

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
var $loading = $('#loading')
var $progress = $('#progress')
var prg = 0
 
var timer = window.setInterval(() => {
  if (prg >= 80) {  // 到达第一阶段80%,关闭定时器,保持等待
    window.clearInterval(timer)
    prg = 100
  } else {
    prg++
  }
 
  $progress.html(prg + '%')
  console.log(prg)
}, 100)
 
window.onload = () => {
  window.clearInterval(timer)
  window.setInterval(() => {
    if (prg >= 100) {  // 到达终点,关闭定时器
      window.clearInterval(timer)
      prg = 100
      $loading.hide()
    } else {
      prg++
    }
 
    $progress.html(prg + '%')
    console.log(prg)
  }, 10)  // 时间间隔缩短
}

ok,这基本上正是大家想要的功能了,大家来提炼一下代码,把重复的代码给封装一下:

JavaScript

var $loading = $('#loading') var $progress = $('#progress') var prg = 0 var timer = 0 progress(80, 100) window.onload = () => { progress(100, 10, () => { $loading.hide() }) } function progress (dist, delay, callback) { window.clearInterval(timer) timer = window.setInterval(() => { if (prg >= dist) { window.clearInterval(timer) prg = dist callback && callback() } else { prg++ } $progress.html(prg + '%') console.log(prg) }, delay) }

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
var $loading = $('#loading')
var $progress = $('#progress')
var prg = 0
 
var timer = 0
 
progress(80, 100)
 
window.onload = () => {
  progress(100, 10, () => {
    $loading.hide()
  })
}
 
function progress (dist, delay, callback) {
  window.clearInterval(timer)
  timer = window.setInterval(() => {
    if (prg >= dist) {
      window.clearInterval(timer)
      prg = dist
      callback && callback()
    } else {
      prg++
    }
 
    $progress.html(prg + '%')
    console.log(prg)
  }, delay)
}

作者们获得了贰个progress函数,那一个函数正是我们根本的功用模块,通过传播二个对象值、三个时光间距,就能够一成不改变进程的演变进度。

近来来看,那个速度仍旧稍稍难题的:

  1. 进程太平均,相通的日子间隔,相同的增量,不符合网络景况的性状;
  2. window.onload太快,大家还不如看清百分之百,loading就已经扬弃了;
  3. 每一次第一等第都以在十分之八就有始无终了,露馅儿了;

首先个点,大家要让岁月间距随机,增量也随意;第1个点相当轻松,大家延缓一下就好了;第三点也亟需我们随意爆发三个早先值。

增量随机很好办,如何让日子间距随机?setInterval是力不胜任动态设置delay的,那么大家就要把它校勘一下,使用setTimeout来完结。(setInterval跟setTimeout的用法和界别就不细说了吧?)

JavaScript

var $loading = $('#loading') var $progress = $('#progress') var prg = 0 var timer = 0 progress([80, 90], [1, 3], 100) // 使用数组来表示随机数的区间 window.onload = () => { progress(100, [1, 5], 10, () => { window.setTimeout(() => { // 延迟了大器晚成秒再隐敝loading $loading.hide() }, 1000) }) } function progress (dist, speed, delay, callback) { var _dist = random(dist) var _delay = random(delay) var _speed = random(speed) window.clearTimeout(timer) timer = window.setTimeout(() => { if (prg + _speed >= _dist) { window.clearTimeout(timer) prg = _dist callback && callback() } else { prg += _speed progress (_dist, speed, delay, callback) } $progress.html(parseInt(prg) + '%') // 介意,由于已经不是自增1,所以这里要取整 console.log(prg) }, _delay) } function random (n) { if (typeof n === 'object') { var times = n[1] - n[0] var offset = n[0] return Math.random() * times + offset } else { return n } }

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
var $loading = $('#loading')
var $progress = $('#progress')
var prg = 0
 
var timer = 0
 
progress([80, 90], [1, 3], 100)  // 使用数组来表示随机数的区间
 
window.onload = () => {
  progress(100, [1, 5], 10, () => {
    window.setTimeout(() => {  // 延迟了一秒再隐藏loading
      $loading.hide()
    }, 1000)
  })
}
 
function progress (dist, speed, delay, callback) {
  var _dist = random(dist)
  var _delay = random(delay)
  var _speed = random(speed)
  window.clearTimeout(timer)
  timer = window.setTimeout(() => {
    if (prg + _speed >= _dist) {
      window.clearTimeout(timer)
      prg = _dist
      callback && callback()
    } else {
      prg += _speed
      progress (_dist, speed, delay, callback)
    }
 
    $progress.html(parseInt(prg) + '%')  // 留意,由于已经不是自增1,所以这里要取整
    console.log(prg)
  }, _delay)
}
 
function random (n) {
  if (typeof n === 'object') {
    var times = n[1] - n[0]
    var offset = n[0]
    return Math.random() * times + offset
  } else {
    return n
  }
}

由来,我们基本上完毕了须要。

but,还应该有二个比较隐瞒的难题,大家前几天应用window.onload,发掘从步入页面,到window.onload那中档相隔时间非常短,大家着力是感受不到第生机勃勃阶段速度(70%)的,那是绝非难点的——大家注意的是,假设页面的加载能源数量非常多,体量超级大的时候,从进来页面,到window.onload就不是如此急速了,那中档恐怕会很遥远(5~20秒不等),但实际上,大家只须要为 首屏能源 的加载争取时间就足以了,不要求拭目以俟全体财富就绪,而且越来越快地显现页面也是增进客商体验的首要。

笔者们应有思考页面loading停留过久的意况,大家须要为loading设置三个过期时间,超越那些时间,假诺window.onload还并未能如愿,大家也要把速度推到百分百,把loading甘休掉。

JavaScript

var $loading = $('#loading') var $progress = $('#progress') var prg = 0 var timer = 0 progress([80, 90], [1, 3], 100) // 使用数组来表示随机数的间隔 window.onload = () => { progress(100, [1, 5], 10, () => { window.setTimeout(() => { // 延迟了豆蔻年华秒再隐敝loading $loading.hide() }, 1000) }) } window.setTimeout(() => { // 设置5秒的晚点时间 progress(100, [1, 5], 10, () => { window.setTimeout(() => { // 延迟了风姿浪漫秒再隐蔽loading $loading.hide() }, 1000) }) }, 5000) function progress (dist, speed, delay, callback) { var _dist = random(dist) var _delay = random(delay) var _speed = random(speed) window.clearTimeout(timer) timer = window.setTimeout(() => { if (prg

  • _speed >= _dist) { window.clearTimeout(timer) prg = _dist callback && callback() } else { prg += _speed progress (_dist, speed, delay, callback) } $progress.html(parseInt(prg) + '%') // 在乎,由于已经不是自增1,所以这里要取整 console.log(prg) }, _delay) } function random (n) { if (typeof n === 'object') { var times = n[1] - n[0] var offset = n[0] return Math.random() * times + offset } else { return n } }
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
var $loading = $('#loading')
var $progress = $('#progress')
var prg = 0
 
var timer = 0
 
progress([80, 90], [1, 3], 100)  // 使用数组来表示随机数的区间
 
window.onload = () => {
  progress(100, [1, 5], 10, () => {
    window.setTimeout(() => {  // 延迟了一秒再隐藏loading
      $loading.hide()
    }, 1000)
  })
}
 
window.setTimeout(() => {  // 设置5秒的超时时间
  progress(100, [1, 5], 10, () => {
    window.setTimeout(() => {  // 延迟了一秒再隐藏loading
      $loading.hide()
    }, 1000)
  })
}, 5000)
 
function progress (dist, speed, delay, callback) {
  var _dist = random(dist)
  var _delay = random(delay)
  var _speed = random(speed)
  window.clearTimeout(timer)
  timer = window.setTimeout(() => {
    if (prg + _speed >= _dist) {
      window.clearTimeout(timer)
      prg = _dist
      callback && callback()
    } else {
      prg += _speed
      progress (_dist, speed, delay, callback)
    }
 
    $progress.html(parseInt(prg) + '%')  // 留意,由于已经不是自增1,所以这里要取整
    console.log(prg)
  }, _delay)
}
 
function random (n) {
  if (typeof n === 'object') {
    var times = n[1] - n[0]
    var offset = n[0]
    return Math.random() * times + offset
  } else {
    return n
  }
}

大家直接设置了一个电磁打点计时器,5s的年华来作为超时时间。那样做是能够的。

but,还是有毛病,那么些计时器是在js加载达成之后才起始生效的,也正是说,我们忽略了js加载达成此前的时光,这基值误差可大可小,大家设置的5s,实际顾客大概等待了8s,那是不不荒谬的。大家做顾客体验,供给从实质上景况去考虑,所以那一个最初时间还要求再提前一些,大家在head里来记录这一个领头时间,然后在js个中去做相比,如若时间差大于超时时间,那大家就足以一贯实施最后的完成步骤,要是低于超时时间,则等待 剩余的年月 过后,再造成速度。

先在head里埋点,记录顾客走入页面包车型客车时日loadingStartTime

XHTML

<!DOCTYPE html> <html> <head> <title>写一个网页进程loading</title> <script> window.loadingStart提姆e = new Date() </script> <script src="index.js"></script> </head> <body> <div class="loading" id="loading"> <div class="progress" id="progress">0%</div> </div> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html>
<head>
  <title>写一个网页进度loading</title>
  <script>
    window.loadingStartTime = new Date()
  </script>
  <script src="index.js"></script>
</head>
<body>
  <div class="loading" id="loading">
    <div class="progress" id="progress">0%</div>
  </div>
</body>
</html>

下一场,大家比较 当前的小时 ,看是或不是过期:(为了便利复用代码,笔者把达成的有个别封装成函数complete)

JavaScript

var $loading = $('#loading') var $progress = $('#progress') var prg = 0 var timer = 0 var now = new Date() // 记录当前岁月 var timeout = 5000 // 超时时间 progress([80, 90], [1, 3], 100) window.onload = () => { complete() } if (now - loadingStartTime > timeout) { // 超时 complete() } else { window.setTimeout(() => { // 未超时,则等待剩余时间 complete() }, timeout - (now - loadingStartTime)) } function complete () { // 封装达成进程作用 progress(100, [1, 5], 10, () => { window.setTimeout(() => { $loading.hide() }, 1000) }) } function progress (dist, speed, delay, callback) { var _dist = random(dist) var _delay = random(delay) var _speed = random(speed) window.clearTimeout(timer) timer = window.setTimeout(() => { if (prg

  • _speed >= _dist) { window.clearTimeout(timer) prg = _dist callback && callback() } else { prg += _speed progress (_dist, speed, delay, callback) } $progress.html(parseInt(prg) + '%') console.log(prg) }, _delay) } function random (n) { if (typeof n === 'object') { var times = n[1] - n[0] var offset = n[0] return Math.random() * times + offset } else { return n } }
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
var $loading = $('#loading')
var $progress = $('#progress')
var prg = 0
 
var timer = 0
var now = new Date()  // 记录当前时间
var timeout = 5000  // 超时时间
 
progress([80, 90], [1, 3], 100)
 
window.onload = () => {
  complete()
}
 
if (now - loadingStartTime > timeout) {  // 超时
  complete()
} else {
  window.setTimeout(() => {  // 未超时,则等待剩余时间
    complete()
  }, timeout - (now - loadingStartTime))
}
 
function complete () {  // 封装完成进度功能
  progress(100, [1, 5], 10, () => {
    window.setTimeout(() => {
      $loading.hide()
    }, 1000)
  })
}
 
function progress (dist, speed, delay, callback) {
  var _dist = random(dist)
  var _delay = random(delay)
  var _speed = random(speed)
  window.clearTimeout(timer)
  timer = window.setTimeout(() => {
    if (prg + _speed >= _dist) {
      window.clearTimeout(timer)
      prg = _dist
      callback && callback()
    } else {
      prg += _speed
      progress (_dist, speed, delay, callback)
    }
 
    $progress.html(parseInt(prg) + '%')
    console.log(prg)
  }, _delay)
}
 
function random (n) {
  if (typeof n === 'object') {
    var times = n[1] - n[0]
    var offset = n[0]
    return Math.random() * times + offset
  } else {
    return n
  }
}

到现在甘休,大家到底完整地促成了那大器晚成功用。

不过,事情还尚无终结,少年你太天真。

假若指标是为着写二个自始自终障眼法的伪loading,那跟别的loading的得以达成就没怎么分别了,大家做事讲究足履实地,能完结的达成,不可能达成的,为了组织和谐,大家不得已招摇撞骗。那么大家仍为能够更周边实际情况一点啊?其实是足以的。

咱们来剖判八个气象,借使大家想让大家的loading特别真实一些,那么我们得以选用性地对页面上多少个非常大的财富的加载进行追踪,然后拆分整个进程条,例如大家页面有三张大图a、b、c,那么大家将进度条拆成五段,每加载完一张图大家就拉动一个速度:

轻松开始化[10, 20] ->
图a推进20%的进度 ->
图b推进25%的进度 ->
图c推进30%的进度 ->
【云顶娱乐棋牌】你先要知道这几点细节,写一个网页过程loading。完成100%

那三张图要占20% + 25% + 30% = 75%的进度。

主题素材是,即使图片加载成功是依据顺序来的,那我们能够相当粗略地:10(假设初叶进程是百分之十) -> 30 -> 55 -> 85 -> 100,但实际是,图片不会根据顺序来,哪个人早到什么人晚到是说禁绝的,所以大家需求更客观的主意去管理那些进程增量,使它们不会相互覆盖。

  1. 大家需求贰个力所能致替大家合併增量的变量next
  2. 由于大家的progress都以传目标快慢的,大家供给其它二个函数add,来传增量进程。

JavaScript

var $loading = $('#loading') var $progress = $('#progress') var prg = 0 var timer = 0 var now = new Date() var timeout = 5000 var next = prg add([30, 50], [1, 3], 100) // 第黄金年代等第 window.setTimeout(() => { // 模拟图a加载完 add(20, [1, 3], 200) }, 1000) window.setTimeout(() => { // 模拟图c加载完 add(30, [1, 3], 200) }, 2000) window.setTimeout(() => { // 模拟图b加载完 add(25, [1, 3], 200) }, 2500) window.onload = () => { complete() } if (now - loadingStartTime > timeout) { complete() } else { window.setTimeout(() => { complete() }, timeout - (now - loadingStartTime)) } function complete () { add(100, [1, 5], 10, () => { window.setTimeout(() => { $loading.hide() }, 1000) }) } function add (dist, speed, delay, callback) { var _dist = random(dist) if (next + _dist > 100) { // 对超越部分裁剪对齐 next = 100 } else { next += _dist } progress(next, speed, delay, callback) } function progress (dist, speed, delay, callback) { var _delay = random(delay) var _speed = random(speed) window.clearTimeout(timer) timer = window.setTimeout(() => { if (prg

  • _speed >= dist) { window.clearTimeout(timer) prg = dist callback && callback() } else { prg += _speed progress (dist, speed, delay, callback) } $progress.html(parseInt(prg) + '%') console.log(prg) }, _delay) } function random (n) { if (typeof n === 'object') { var times = n[1] - n[0] var offset = n[0] return Math.random() * times + offset } else { return n } }
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
83
var $loading = $('#loading')
var $progress = $('#progress')
var prg = 0
 
var timer = 0
var now = new Date()
var timeout = 5000
 
var next = prg
 
add([30, 50], [1, 3], 100)  // 第一阶段
 
window.setTimeout(() => {  // 模拟图a加载完
  add(20, [1, 3], 200)
}, 1000)
 
window.setTimeout(() => {  // 模拟图c加载完
  add(30, [1, 3], 200)
}, 2000)
 
window.setTimeout(() => {  // 模拟图b加载完
  add(25, [1, 3], 200)
}, 2500)
 
window.onload = () => {
  complete()
}
 
if (now - loadingStartTime > timeout) {
  complete()
} else {
  window.setTimeout(() => {
    complete()
  }, timeout - (now - loadingStartTime))
}
 
function complete () {
  add(100, [1, 5], 10, () => {
    window.setTimeout(() => {
      $loading.hide()
    }, 1000)
  })
}
 
function add (dist, speed, delay, callback) {
  var _dist = random(dist)
  if (next + _dist > 100) {  // 对超出部分裁剪对齐
    next = 100
  } else {
    next += _dist
  }
 
  progress(next, speed, delay, callback)
}
 
function progress (dist, speed, delay, callback) {
  var _delay = random(delay)
  var _speed = random(speed)
  window.clearTimeout(timer)
  timer = window.setTimeout(() => {
    if (prg + _speed >= dist) {
      window.clearTimeout(timer)
      prg = dist
      callback && callback()
    } else {
      prg += _speed
      progress (dist, speed, delay, callback)
    }
 
    $progress.html(parseInt(prg) + '%')
    console.log(prg)
  }, _delay)
}
 
function random (n) {
  if (typeof n === 'object') {
    var times = n[1] - n[0]
    var offset = n[0]
    return Math.random() * times + offset
  } else {
    return n
  }
}

作者们这里为了便于,用setTimeout来模拟图片的加载,真实应用应该是采用image.onload

以上,就是大家一步步贯彻一个速度loading的进度了,演示代码能够戳笔者的codePen 写一个网页进程loading。

恍如很简短的壹个效果与利益,其实留意切磋,照旧有超多细节要牵挂的。

到此处,其实确实已经产生了,代码有一些多有一点点乱是否?你能够收拾一下,封装成为插件的。

唯独,好呢,其实小编早就把那个速度封装成插件了。。。

不错,其实作者便是来帮团结打广告的。。。

好呢,github货仓在这里 ez-progress。

ez-progress 是二个web(伪)进度插件,使用 ez-progress 达成那么些效应很简单:

JavaScript

var Progress = require('ez-progress') var prg = new Progress() var $loading = $('#loading') var $progress = $('#progress') prg.on('progress', function (res) { var progress = parseInt(res.progress) // 注意进程取整,不然有十分的大恐怕会产出小数 $progress.html(progress + '%') }) prg.go([60, 70], function (res) { prg.complete(null, [0, 5], [0, 50]) // 飞日常地冲向终点 }, [0, 3], [0, 200]) window.onload = function () { prg.complete(null, [0, 5], [0, 50]) // 飞日常地冲向终点 }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var Progress = require('ez-progress')
var prg = new Progress()
 
var $loading = $('#loading')
var $progress = $('#progress')
 
prg.on('progress', function (res) {
  var progress = parseInt(res.progress)  // 注意进度取整,不然有可能会出现小数
  $progress.html(progress + '%')
})
 
prg.go([60, 70], function (res) {
  prg.complete(null, [0, 5], [0, 50])  // 飞一般地冲向终点
}, [0, 3], [0, 200])
 
window.onload = function () {
  prg.complete(null, [0, 5], [0, 50])  // 飞一般地冲向终点
}

木油错,94那样轻巧!

那恐怕是自己眼下写过最短的博文了,由此来看从前是有多么的啰嗦,哈哈哈哈!

1 赞 13 收藏 2 评论

云顶娱乐每天送6元 1

钻探首屏时间?你先要知道这几点细节

2016/01/11 · CSS, JavaScript · 首屏

原稿出处: AlloyTeam   

做运动web页面,受移动网络网速和终端属性影响,大家平常要关心首屏内容彰显时间(以下简单称谓首屏时间)这些目标,它度量着大家的页面是或不是能在客商耐心消磨完在此以前体现出来,非常的大程度影响着顾客的施用满意度。

浅析 requestAnimationFrame

2017/03/02 · JavaScript · 1 评论 · requestAnimationFrame

原来的书文出处: Tmall前端共青团和少先队(FED)- 腾渊   

云顶娱乐每天送6元 2

相信今后超越二分之一人在 JavaScript 中绘制动画已经在动用 requestAnimationFrame 了,关于 requestAnimationFrame 的各类就相当少说了,关于那一个 API 的素材,详见 http://www.w3.org/TR/animation-timing/,https://developer.mozilla.org/en/docs/Web/API/window.requestAnimationFrame。

假如我们把石英钟往前拨到引进 requestAnimationFrame 以前,即使在 JavaScript 中要落实动画效果,如何是好呢?无外乎使用 setTimeout 或 setInterval。那么难点就来了:

  • 什么分明科学的日子间距(浏览器、机器硬件的质量各不相像)?
  • 微秒的不精确性怎么解决?
  • 如何防止过度渲染(渲染频率太高、tab 不可知等等)?

开辟者能够用数不尽方法来减轻这么些题指标病症,不过通透到底消除,那些、基本、很难。

终于,难点的来源在于时机。对于前端开荒者来讲,setTimeout 和 setInterval 提供的是三个等长的停车计时器循环(timer loop),可是对于浏览器内核查渲染函数的响应以致哪一天能够发起下叁个动画帧的时机,是完全不了然的。对于浏览器内核来说,它能够通晓发起下二个渲染帧的适当时机,不过对于此外setTimeout 和 setInterval 传入的回调函数施行,都是同等对待的,它很难知晓哪个回调函数是用来动画渲染的,因而,优化的机遇特别难以理解。谬论就在于,写 JavaScript 的人询问后生可畏帧动画片在哪行代码领头,哪行代码截至,却不打听应该什么时候早前,应该哪一天结束,而在根本引擎来讲,事情却偏巧相反,所以两岸很难完美兼容,直到 requestAnimationFrame 现身。

自己超高兴 requestAnimationFrame 那一个名字,因为起得那些直白 – request animation frame,对于那一个 API 最棒的演说正是名字本人了。那样二个API,你传入的 API 不是用来渲染意气风发帧卡通,你上街都不佳意思跟人打招呼。

是因为小编是个珍视阅读代码的人,为了显示团结好学的势态,特意读了下 Chrome 的代码去询问它是怎么贯彻 requestAnimationFrame 的(代码基于 Android 4.4):

JavaScript

int Document::requestAnimationFrame(PassRefPtr<RequestAnimationFrameCallback> callback) { if (!m_scriptedAnimationController) { m_scriptedAnimationController = ScriptedAnimationController::create(this); // We need to make sure that we don't start up the animation controller on a background tab, for example. if (!page()) m_scriptedAnimationController->suspend(); } return m_scriptedAnimationController->registerCallback(callback); }

1
2
3
4
5
6
7
8
9
10
11
int Document::requestAnimationFrame(PassRefPtr<RequestAnimationFrameCallback> callback)
{
  if (!m_scriptedAnimationController) {
    m_scriptedAnimationController = ScriptedAnimationController::create(this);
    // We need to make sure that we don't start up the animation controller on a background tab, for example.
      if (!page())
        m_scriptedAnimationController->suspend();
  }
 
  return m_scriptedAnimationController->registerCallback(callback);
}

留神看看就觉着底层达成意各地归纳,生成二个 ScriptedAnimationController 的实例,然后注册那个 callback。那我们就看看 ScriptAnimationController 里面做了些什么:

JavaScript

void ScriptedAnimationController::serviceScriptedAnimations(double monotonicTimeNow) { if (!m_callbacks.size() || m_suspendCount) return; double highResNowMs = 1000.0 * m_document->loader()->timing()->monotonicTimeToZeroBasedDocumentTime(monotonicTimeNow); double legacyHighResNowMs = 1000.0 * m_document->loader()->timing()->monotonicTimeToPseudoWallTime(monotonicTimeNow); // First, generate a list of callbacks to consider. Callbacks registered from this point // on are considered only for the "next" frame, not this one. CallbackList callbacks(m_callbacks); // Invoking callbacks may detach elements from our document, which clears the document's // reference to us, so take a defensive reference. RefPtr<ScriptedAnimationController> protector(this); for (size_t i = 0; i < callbacks.size(); ++i) { RequestAnimationFrameCallback* callback = callbacks[i].get(); if (!callback->m_firedOrCancelled) { callback->m_firedOrCancelled = true; InspectorInstrumentationCookie cookie = InspectorInstrumentation::willFireAnimationFrame(m_document, callback->m_id); if (callback->m_useLegacyTimeBase) callback->handleEvent(legacyHighResNowMs); else callback->handleEvent(highResNowMs); InspectorInstrumentation::didFireAnimationFrame(cookie); } } // Remove any callbacks we fired from the list of pending callbacks. for (size_t i = 0; i < m_callbacks.size();) { if (m_callbacks[i]->m_firedOrCancelled) m_callbacks.remove(i); else ++i; } if (m_callbacks.size()) scheduleAnimation(); }

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
void ScriptedAnimationController::serviceScriptedAnimations(double monotonicTimeNow)
{
  if (!m_callbacks.size() || m_suspendCount)
    return;
 
    double highResNowMs = 1000.0 * m_document->loader()->timing()->monotonicTimeToZeroBasedDocumentTime(monotonicTimeNow);
    double legacyHighResNowMs = 1000.0 * m_document->loader()->timing()->monotonicTimeToPseudoWallTime(monotonicTimeNow);
 
    // First, generate a list of callbacks to consider.  Callbacks registered from this point
    // on are considered only for the "next" frame, not this one.
    CallbackList callbacks(m_callbacks);
 
    // Invoking callbacks may detach elements from our document, which clears the document's
    // reference to us, so take a defensive reference.
    RefPtr<ScriptedAnimationController> protector(this);
 
    for (size_t i = 0; i < callbacks.size(); ++i) {
        RequestAnimationFrameCallback* callback = callbacks[i].get();
      if (!callback->m_firedOrCancelled) {
        callback->m_firedOrCancelled = true;
        InspectorInstrumentationCookie cookie = InspectorInstrumentation::willFireAnimationFrame(m_document, callback->m_id);
        if (callback->m_useLegacyTimeBase)
          callback->handleEvent(legacyHighResNowMs);
        else
          callback->handleEvent(highResNowMs);
        InspectorInstrumentation::didFireAnimationFrame(cookie);
      }
    }
 
    // Remove any callbacks we fired from the list of pending callbacks.
    for (size_t i = 0; i < m_callbacks.size();) {
      if (m_callbacks[i]->m_firedOrCancelled)
        m_callbacks.remove(i);
      else
        ++i;
    }
 
    if (m_callbacks.size())
      scheduleAnimation();
}

以此函数自然就是进行回调函数的地点了。那么动画是何许被触发的吗?大家供给火速地看后生可畏串函数(八个从下往上的 call stack):

JavaScript

void PageWidgetDelegate::animate(Page* page, double monotonicFrameBeginTime) { FrameView* view = mainFrameView(page); if (!view) return; view->serviceScriptedAnimations(monotonicFrameBeginTime); }

1
2
3
4
5
6
7
void PageWidgetDelegate::animate(Page* page, double monotonicFrameBeginTime)
{
  FrameView* view = mainFrameView(page);
  if (!view)
    return;
  view->serviceScriptedAnimations(monotonicFrameBeginTime);
}

JavaScript

void WebViewImpl::animate(double monotonicFrameBeginTime) { TRACE_EVENT0("webkit", "WebViewImpl::animate"); if (!monotonicFrameBeginTime) monotonicFrameBeginTime = monotonicallyIncreasingTime(); // Create synthetic wheel events as necessary for fling. if (m_gestureAnimation) { if (m_gestureAnimation->animate(monotonicFrameBeginTime)) scheduleAnimation(); else { m_gestureAnimation.clear(); if (m_layerTreeView) m_layerTreeView->didStopFlinging(); PlatformGestureEvent endScrollEvent(PlatformEvent::GestureScrollEnd, m_positionOnFlingStart, m_globalPositionOnFlingStart, 0, 0, 0, false, false, false, false); mainFrameImpl()->frame()->eventHandler()->handleGestureScrollEnd(endScrollEvent); } } if (!m_page) return; PageWidgetDelegate::animate(m_page.get(), monotonicFrameBeginTime); if (m_continuousPaintingEnabled) { ContinuousPainter::setNeedsDisplayRecursive(m_rootGraphicsLayer, m_pageOverlays.get()); m_client->scheduleAnimation(); } }

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
void WebViewImpl::animate(double monotonicFrameBeginTime)
{
  TRACE_EVENT0("webkit", "WebViewImpl::animate");
 
  if (!monotonicFrameBeginTime)
      monotonicFrameBeginTime = monotonicallyIncreasingTime();
 
  // Create synthetic wheel events as necessary for fling.
  if (m_gestureAnimation) {
    if (m_gestureAnimation->animate(monotonicFrameBeginTime))
      scheduleAnimation();
    else {
      m_gestureAnimation.clear();
      if (m_layerTreeView)
        m_layerTreeView->didStopFlinging();
 
      PlatformGestureEvent endScrollEvent(PlatformEvent::GestureScrollEnd,
          m_positionOnFlingStart, m_globalPositionOnFlingStart, 0, 0, 0,
          false, false, false, false);
 
      mainFrameImpl()->frame()->eventHandler()->handleGestureScrollEnd(endScrollEvent);
    }
  }
 
  if (!m_page)
    return;
 
  PageWidgetDelegate::animate(m_page.get(), monotonicFrameBeginTime);
 
  if (m_continuousPaintingEnabled) {
    ContinuousPainter::setNeedsDisplayRecursive(m_rootGraphicsLayer, m_pageOverlays.get());
    m_client->scheduleAnimation();
  }
}

JavaScript

void RenderWidget::AnimateIfNeeded() { if (!animation_update_pending_) return; // Target 60FPS if vsync is on. Go as fast as we can if vsync is off. base::TimeDelta animationInterval = IsRenderingVSynced() ? base::TimeDelta::FromMilliseconds(16) : base::TimeDelta(); base::Time now = base::Time::Now(); // animation_floor_time_ is the earliest time that we should animate when // using the dead reckoning software scheduler. If we're using swapbuffers // complete callbacks to rate limit, we can ignore this floor. if (now >= animation_floor_time_ || num_swapbuffers_云顶娱乐每天送6元,complete_pending_ > 0) { TRACE_EVENT0("renderer", "RenderWidget::AnimateIfNeeded") animation_floor_time_ = now + animationInterval; // Set a timer to call us back after animationInterval before // running animation callbacks so that if a callback requests another // we'll be sure to run it at the proper time. animation_timer_.Stop(); animation_timer_.Start(FROM_HERE, animationInterval, this, &RenderWidget::AnimationCallback); animation_update_pending_ = false; if (is_accelerated_compositing_active_ && compositor_) { compositor_->Animate(base::TimeTicks::Now()); } else { double frame_begin_time = (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); webwidget_->animate(frame_begin_time); } return; } TRACE_EVENT0("renderer", "EarlyOut_AnimatedTooRecently"); if (!animation_timer_.IsRunning()) { // This code uses base::Time::Now() to calculate the floor and next fire // time because javascript's Date object uses base::Time::Now(). The // message loop uses base::TimeTicks, which on windows can have a // different granularity than base::Time. // The upshot of all this is that this function might be called before // base::Time::Now() has advanced past the animation_floor_time_. To // avoid exposing this delay to javascript, we keep posting delayed // tasks until base::Time::Now() has advanced far enough. base::TimeDelta delay = animation_floor_time_ - now; animation_timer_.Start(FROM_HERE, delay, this, &RenderWidget::AnimationCallback); } }

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
void RenderWidget::AnimateIfNeeded() {
  if (!animation_update_pending_)
    return;
 
  // Target 60FPS if vsync is on. Go as fast as we can if vsync is off.
  base::TimeDelta animationInterval = IsRenderingVSynced() ? base::TimeDelta::FromMilliseconds(16) : base::TimeDelta();
 
  base::Time now = base::Time::Now();
 
  // animation_floor_time_ is the earliest time that we should animate when
  // using the dead reckoning software scheduler. If we're using swapbuffers
  // complete callbacks to rate limit, we can ignore this floor.
  if (now >= animation_floor_time_ || num_swapbuffers_complete_pending_ > 0) {
    TRACE_EVENT0("renderer", "RenderWidget::AnimateIfNeeded")
    animation_floor_time_ = now + animationInterval;
    // Set a timer to call us back after animationInterval before
    // running animation callbacks so that if a callback requests another
    // we'll be sure to run it at the proper time.
    animation_timer_.Stop();
    animation_timer_.Start(FROM_HERE, animationInterval, this, &RenderWidget::AnimationCallback);
    animation_update_pending_ = false;
    if (is_accelerated_compositing_active_ && compositor_) {
      compositor_->Animate(base::TimeTicks::Now());
    } else {
      double frame_begin_time = (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
      webwidget_->animate(frame_begin_time);
    }
    return;
  }
  TRACE_EVENT0("renderer", "EarlyOut_AnimatedTooRecently");
  if (!animation_timer_.IsRunning()) {
    // This code uses base::Time::Now() to calculate the floor and next fire
    // time because javascript's Date object uses base::Time::Now().  The
    // message loop uses base::TimeTicks, which on windows can have a
    // different granularity than base::Time.
    // The upshot of all this is that this function might be called before
    // base::Time::Now() has advanced past the animation_floor_time_.  To
    // avoid exposing this delay to javascript, we keep posting delayed
    // tasks until base::Time::Now() has advanced far enough.
    base::TimeDelta delay = animation_floor_time_ - now;
    animation_timer_.Start(FROM_HERE, delay, this, &RenderWidget::AnimationCallback);
  }
}

特意表达:RenderWidget 是在 ./content/renderer/render_widget.cc 中(content::RenderWidget)而非在 ./core/rendering/RenderWidget.cpp 中。笔者最初读 RenderWidget.cpp 还因为此中未有其余关于 animation 的代码而纠结了非常久。

看看这里其实 requestAnimationFrame 的实现原理就很明朗了:

  • 挂号回调函数
  • 浏览器更新时触发 animate
  • animate 会触发全部注册过的 callback

此间的做事机制得以领悟为全数权的退换,把触发帧更新的时刻全体权交给浏览器内核,与浏览器的创新保持同步。那样做既可以够幸免浏览器更新与动画帧更新的不一齐,又能够赋予浏览器丰裕大的优化空间。
在往上的调用入口就广大了,超多函数(RenderWidget::didInvalidateRect,RenderWidget::CompleteInit等)会触发动画检查,进而需求一遍动画帧的翻新。

这里一张图表达 requestAnimationFrame 的兑现机制(来自官方):
云顶娱乐每天送6元 3

题图: By Kai Oberhäuser

1 赞 1 收藏 1 评论

云顶娱乐每天送6元 4

挪动前端调节和测量检验页面–weinre

云顶娱乐棋牌,2015/07/30 · HTML5 · weinre, 调试

原来的书文出处: 涂根华的博客   

生机勃勃:远程调式工具—weinre

Weinre是什么?

Weinre是Web Inspector Remote的缩写(远程web检查器),它的职能正是黄金时代对意气风发于chrome的稽审成分同样,分界面和用法也基本相似,无非分歧的是:weinre相符在运动端页面调节和测量试验,比如手提式有线电话机访谈页面包车型地铁时候,大家可以应用chrome浏览器查看页面包车型大巴html成分和css代码,大家得以对此开展转移,然后在手提式有线电话机端无需刷新,立即能够看出功能;在移动端调式html和css比较便于。前段时间weiner也揭露到npm上,大家得以动用npm实行安装;npm如下: 

二: 安装weinre

npm install -g weinre

1
npm install -g weinre

云顶娱乐每天送6元 5

安装完事后,须求在地点开启三个监听服务器,例如小编前不久的IP地址是:172.16.28.162

今后亟需试行如下命令:

weinre –boundHost 172.16.28.162

能够开启本地监听服务器如下:

云顶娱乐每天送6元 6

如上边网站 http://172.16.28.162:8080  weinre默许使用8080端口,我们也足以应用如下命令举行校订端口号;如下命令:

云顶娱乐每天送6元 7

三: 访问weinre及在页面上调用

开发浏览器,访谈如下地址: 172.16.28.162:8081 如下:

云顶娱乐每天送6元 8

如上截图页面;我们供给在调式的页面中参加远程调式所急需的JS代码即可,比方上海教室截图的终极一句JS代码:

JavaScript

<script src=";

1
<script src="http://172.16.28.162:8081/target/target-script-min.js#anonymous"></script>

引进到供给中间距调式页面就可以;

咱俩昨天先访谈页面 http://172.16.28.162:8081;如下所示:

云顶娱乐每天送6元 9

目前大家继续行使小编手提式有线电话机来访谈小编本机上的网页后,在查阅刚点击步入后的页面显示如下:

云顶娱乐每天送6元 10

如下:

云顶娱乐每天送6元 11

但weinre能够实惠大家调式HTML元素及css代码,至于JS,大家得以选拔Fiddler替换就能够满意前端在移动端基本调式了;

四:多用户

Weinre的默许使用中,都以用anonymous作为id的;

诸如上边的代码引用:

JavaScript

<script src=";

1
<script src="http://172.16.28.162:8081/target/target-script-min.js#anonymous"></script>

可是纵然多少个客户同期调式各自的页面会有标题,weinre使用多客商机制化解该难题。Weinre私下认可扶持多客商的,那样叁个局域网同事只需求后生可畏台Computer上设置weinre就可以,不须求各样人都设置,多少个顾客同不常间使用时,每种客商采用本身的id来区分,每一种客户调式信息能够单独,不会互相影响;

操作如下:

云顶娱乐每天送6元 12

云顶娱乐每天送6元 13

接下来继续刷新设备中的页面,然后在Computer端就能够看来如下音信:

云顶娱乐每天送6元 14

就足以开展多客户调式了;

2 赞 2 收藏 评论

云顶娱乐每天送6元 15

H5 游戏开辟:横屏适配

2017/10/31 · HTML5 · 1 评论 · 横屏, 游戏

原稿出处: 坑坑洼洼实验室   

对于移动端的轻量级 HTML5 互动小游戏(简单称谓为 H5 轻互动),如果从显示屏表现方式来划分的话,能够分类为:竖屏式和横屏式。

 

云顶娱乐每天送6元 16

HTML5互动小游戏案例截图

日常大家做过的要求里,首假设以竖屏式为主,而横屏式少之又少。对于竖屏式场景来讲,大家的经验会相比充裕,因而,此次首要式商量下横屏式场景下的片段亟需注意的点,特别是何等去做横屏适配。

对此 H5 轻互动娱乐来讲,要促成横屏的话,首尽管解决两点:
1.无论顾客手持方向怎么样,都亟需保障显示屏横向呈现。
2.由于显示器分辨率的多样化,因而就算是横屏下也是急需张开横屏适配,有限帮衬镜头在拥有分辨率下都能够客观适配。

上边,大家本着这两点分别演说怎样减轻。

怎么获取首屏时间吗?

小编们平常要先问本身:页面是怎么加载数据?

A:加载完静态财富后透过ajax诉求去后台获取数据,数据回来后渲染内容

云顶娱乐每天送6元 17

 

在各个点打上二个时间戳,首屏时间 = 点8 – 点1;

B:使用后台直出,重临的html已经带上内容了

云顶娱乐每天送6元 18

这个时候首屏时间 = 点4 – 点1。

注:1. 打了这么七个点,是因为当大家搜集到首屏时间以往,要去深入分析到底是哪风流洒脱段是性质瓶颈,哪一段还只怕有优化空间,所以大家须要收罗点2 – 点1、点3 – 点1 ……那几个时刻以作深入分析;

  1. 贿赂选举1大家日常是在html文件head标签的开头打个小时戳;

  2. 在css文件加载前平常未有别的加载管理,所以照望1和行贿2平常能够统后生可畏。

 

到此我们就收罗到首屏相关各类数据,能够做各样针对优化。Wait!在你坚决优化前,你要打听一些细节,它们有扶持你做纠正确的分析和更加细致的优化。

强制横屏显示

页面内容显示方向可分为竖排方向和排行方向,如下图所示。

 

云顶娱乐每天送6元 19

页面内容展现方式:竖向排版和横向排版

对于竖屏式 H5 轻互动的话,页面会被期望保持竖排方向展现。而只要页面现身横排方向呈现的情事,开垦者往往会筛选采用提示蒙层来拓宽温馨提醒,让客商自己作主保持竖屏体验,如下图所示。

 

云顶娱乐每天送6元 20

升迁蒙层提示顾客保持竖屏体验

平等地,在横屏式 H5 轻互动娱乐中得以接受生机勃勃致的艺术实行轻易管理,在页面内容按竖排方向突显时,开拓者实行对客户提示其维持横屏体验。

但是,那对客户体验并不和睦,因为那对于这一个习贯于打开锁定为竖排方向成效(如下图所示)的 iOS 平台客商,大概是关闭显示器旋转功用(如下图所示)的 Android 平台客商来讲,他们需求多二个拍卖步骤——先关闭竖排方向锁定大概开启荧屏旋转,然后再横向手持设备。

 

云顶娱乐每天送6元 21

竖排方向锁定作用(iOS)与显示器旋转(Android)功用

为此,更加好的做法是挟持横屏彰显,对显示屏 resize 事件举行监听,当决断为竖屏时将整个根容器举办逆时针 CSS3 旋转 90 度就可以,代码如下所示。

JavaScript

// 利用 CSS3 旋转 对根容器逆时针旋转 90 度 var detectOrient = function() { var width = document.documentElement.clientWidth, height = document.documentElement.clientHeight, $wrapper = document.getElementById("J_wrapper"), style = ""; if( width >= height ){ // 横屏 style += "width:" + width + "px;"; // 注意旋转后的宽高切换 style += "height:" + height + "px;"; style += "-webkit-transform: rotate(0); transform: rotate(0);"; style += "-webkit-transform-origin: 0 0;"; style += "transform-origin: 0 0;"; } else{ // 竖屏 style += "width:" + height + "px;"; style += "height:" + width + "px;"; style += "-webkit-transform: rotate(90deg); transform: rotate(90deg);"; // 注意旋转中式点心的管理 style += "-webkit-transform-origin: " + width / 2 + "px " + width / 2 + "px;"; style += "transform-origin: " + width / 2 + "px " + width / 2 + "px;"; } $wrapper.style.cssText = style; } window.onresize = detectOrient; detectOrient();

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
// 利用 CSS3 旋转 对根容器逆时针旋转 90 度
var detectOrient = function() {
  var width = document.documentElement.clientWidth,
      height =  document.documentElement.clientHeight,
      $wrapper =  document.getElementById("J_wrapper"),
      style = "";
  if( width >= height ){ // 横屏
      style += "width:" + width + "px;";  // 注意旋转后的宽高切换
      style += "height:" + height + "px;";
      style += "-webkit-transform: rotate(0); transform: rotate(0);";
      style += "-webkit-transform-origin: 0 0;";
      style += "transform-origin: 0 0;";
  }
  else{ // 竖屏
      style += "width:" + height + "px;";
      style += "height:" + width + "px;";
      style += "-webkit-transform: rotate(90deg); transform: rotate(90deg);";
      // 注意旋转中点的处理
      style += "-webkit-transform-origin: " + width / 2 + "px " + width / 2 + "px;";
      style += "transform-origin: " + width / 2 + "px " + width / 2 + "px;";
  }
  $wrapper.style.cssText = style;
}
window.onresize = detectOrient;
detectOrient();

但是!这里有坑:假诺你是利用 CreateJS 框架实行付出,那么就不可能由此 CSS3 门路对含蓄 Canvas 的根容器举行旋转管理,因为旋转后会导致 Canvas 内的戏台成分的风云响应地点错乱。
解决办法是,换来采用 CreateJS 框架内的 Stage 的 rotation 属性对总体舞台旋转管理,代码如下:

JavaScript

if(self.isPortrait) { // 竖屏 // 舞台旋转 self.stage.x = self.canvasHeight; // 注意:x偏移也就是旋转中式茶食管理,更简明 self.stage.rotation = 90; // more... }else { // 横屏 self.stage.x = 0; self.stage.rotation = 0; // more... }

1
2
3
4
5
6
7
8
9
10
if(self.isPortrait) { // 竖屏
  // 舞台旋转
  self.stage.x = self.canvasHeight; // 注意:x偏移相当于旋转中点处理,更简单
  self.stage.rotation = 90;
  // more...
}else { // 横屏
  self.stage.x = 0;
  self.stage.rotation = 0;
  // more...
}

本文由云顶娱乐棋牌发布于云顶娱乐棋牌,转载请注明出处:【云顶娱乐棋牌】你先要知道这几点细节,写一

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。