Ajax Loader
HTML
<!DOCTYPE HTML>
1
<!DOCTYPE HTML>
2
<html lang="en-US">
3
<head>
4
  <meta charset="UTF-8">
5
  <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
6
  <title>Countdown timer on jQuery Canvas</title>
7
</head>
8
<body>
9
  <div class="container">
10
    <div class="header">      
11
      <div class="time">
12
        <em class="clock"></em>
13
        <div class="c-block c-block-3"><div class="bl-inner"><span>12</span></div> <span class="etitle etitle-1">days</span></div> <ins></ins>
14
        <div class="c-block c-block-2"><div class="bl-inner"><span>18</span></div> <span class="etitle etitle-2">hours</span></div> <ins></ins>
15
        <div class="c-block c-block-2"><div class="bl-inner"><span>35</span></div> <span class="etitle etitle-3">minutes</span></div> <ins></ins>
16
        <div class="c-block c-block-2"><div class="bl-inner"><span>5</span></div> <span class="etitle etitle-4">seconds</span></div>
17
      </div>
18
    </div><!-- /.header -->
19
  </div><!-- /.container -->
20
  <footer>
21
    <h2><i>Example:</i> Countdown timer on jQuery Canvas</h2>
22
            <a href="http://web-zone.com.ua/tajmer-obratnogo-otscheta-na-jquery-canvas.html" class="link" target="_blank">Return to <strong>Web Zone</strong> and download example</a>
23
    </footer>
24
</body>
25
</html>
 
CSS
* {
1
* {
2
  margin: 0;
3
  padding: 0;
4
}
5
 
6
html{
7
  width: 100%;
8
  height: 100%;
9
}
10
 
11
body{
12
  position: relative;
13
  background: #fff url(http://web-zone.com.ua/wp-content/uploads/samples/timer/i/bg.png);
14
  width: 100%;
15
  height: auto !important;
16
  height: 100%;
17
  min-height: 100%;
18
  font: normal 1em/1.2em Tahoma, Arial, Helvetica, sans-serif;
19
  /*min-width: 970px;*/
20
  color: #333;
21
}
22
 
23
 
24
.container{
25
  padding-top: 100px;
26
  width: 94%;
27
  max-width: 1300px;
28
  margin: 0 auto;
29
}
30
 
31
.time{
32
  display: block;
33
    margin: 0 auto;
34
    padding: 20px 0 50px;
35
    position: relative;
36
    text-align: center;
37
    width: 70%;
38
}
39
 
40
.time *{vertical-align: top;}
41
 
42
.time ins,
43
.time .clock{
44
  position: relative;
45
  top: 10px;
46
  width: 40px;
47
  height: 55px;
48
  display: inline-block;
49
  *display: inline;
50
  zoom: 1;
51
  background: transparent url(http://web-zone.com.ua//wp-content/uploads/samples/timer/i/sprites.png) no-repeat -260px -154px;
52
}
53
 
54
.time .clock{margin-right: 7px;}
55
 
56
.time ins{width: 10px;}
57
 
58
.time ins{background-position: -300px -154px;}
59
 
60
.time .etitle{
61
  position: absolute;
62
  width: 110px;
63
  text-align: center;
64
  left: 50%;
65
  margin-left: -47px;
66
  top: 55px;
67
  line-height: 30px;
68
}
69
 
70
.etitle-1{font-size: 1.6em;}
71
 
72
.etitle-2{
73
  font-size: 1.37em;
74
  padding-top: .1em;
75
}
76
 
77
.etitle-3{
78
  font-size: 1.12em;
79
  padding-top: .2em;
80
}
81
 
82
.etitle-4{
83
  font-size: .87em;
84
  padding-top: .3em;
85
}
86
 
87
.c-block{
88
  display: inline-block;
89
  *display: inline;
90
  zoom: 1;
91
  margin: 0 18px 0 3px;
92
  padding: 4px 0 40px 3px;
93
  position: relative;
94
  background: transparent url(http://web-zone.com.ua/wp-content/uploads/samples/timer/i/sprites.png) no-repeat -260px 0;
95
}
96
 
97
.c-block:before{
98
  content: '';
99
  position: absolute;
100
  left: 100%;
101
  top: 0;
102
  width: 31px;
103
  background: transparent url(http://web-zone.com.ua/wp-content/uploads/samples/timer/i/sprites.png) no-repeat 100% -77px;
104
  height: 77px;
105
}
106
 
107
.bl-inner{
108
  position: relative;
109
  margin-right: -10px;
110
  height: 48px;
111
  background: transparent url(http://web-zone.com.ua/wp-content/uploads/samples/timer/i/sprites.png) no-repeat -5px -48px;
112
}
113
 
114
.bl-inner span{
115
  display: none;
116
  font-size: 46px;
117
  color: #fff;
118
  line-height: 46px;
119
  margin-left: 2px;
120
}
121
 
122
.bl-inner:before{
123
  content: '';
124
  position: absolute;
125
  left: 100%;
126
  top: 0;
127
  width: 3px;
128
  background: transparent url(http://web-zone.com.ua/wp-content/uploads/samples/timer/i/sprites.png) no-repeat -122px -48px;
129
  height: 48px;
130
}
131
 
132
.c-block-1{width: 20px;}
133
.c-block-2{width: 45px;}
134
.c-block-3{width: 70px;}
135
 
136
/************* DEMO *****************/
137
@import url(http://fonts.googleapis.com/css?family=Philosopher&subset=latin,cyrillic);
138
footer {
139
    background-color: #111111;
140
    bottom: 0;
141
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.4);
142
    font: 14px/1.3 'Philosopher',Arial,sans-serif;
143
    height: 45px;
144
    left: 0;
145
    position: fixed;
146
    width: 100%;
147
    z-index: 100000;
148
}
149
footer h2 {
150
    color: #EEEEEE;
151
    font-size: 14px;
152
    font-weight: normal;
153
    left: 50%;
154
    margin-left: -400px;
155
    padding: 13px 0 0;
156
    position: absolute;
157
    width: 540px;
158
}
159
footer h2 i {
160
    color: #888888;
161
    font-style: normal;
162
}
163
footer a.link, a.link:visited {
164
    color: #999999;
165
    font-size: 12px;
166
    left: 50%;
167
    margin: 16px 0 0 110px;
168
    position: absolute;
169
    text-decoration: none;
170
    top: 0;
171
}
172
 
173
footer a strong {
174
    color: #CCCCCC;
175
    font-style: normal;
176
}
 
JavaScript
$(function() {
1
$(function() {
2
  
3
  if (document.createElement('canvas').getContext) {
4
    var image = $('<img />').load(function() {
5
      var image = this,
6
        offset_left = 5,
7
        offset_number = 4;
8
      
9
      function drawNumberLine(context, position, number, line) {
10
        context.drawImage(image, number * 25, line, 25, 1, position * 25 + offset_left + offset_number, line, 25, 1);
11
      }
12
      
13
      function drawNumberBottom(context, position, number) {
14
        context.drawImage(image, number * 25, 25, 25, 23, position * 25 + offset_left + offset_number, 25, 25, 23);
15
      }
16
      
17
      function drawNumberTop(context, position, number) {
18
        context.drawImage(image, number * 25, 0, 25, 23, position * 25 + offset_left + offset_number, 0, 25, 23);
19
      }
20
      
21
      function cf_draw(from, to, canvas, step) {
22
        var context = canvas.getContext('2d'),
23
          offsets = [
24
                   {w: 2,   h: -2},
25
                   {w: 4,   h: -5},
26
                   {w: 6,   h: -9},
27
                   {w: 8,   h: -14},
28
                   {w: 10,  h: -20},
29
                   {w: 0,   h:  0},
30
                   {w: 10,  h: -20},
31
                   {w: 8,   h: -14},
32
                   {w: 6,   h: -9},
33
                   {w: 4,   h: -5},
34
                   {w: 2,   h: -2},
35
                   {w: 0,   h:  0}
36
          ],
37
          width = canvas.width,
38
          nwidth = width + offsets[step].w,
39
          maxscale = nwidth/width,
40
          height = 23,
41
          nheight = height + offsets[step].h,
42
          scale_y = nheight / height,
43
          dig_col = parseInt($(canvas).parents('div.c-block')[0].className.substr(-1), 10);
44
        
45
        from = from.toString();
46
        to = to.toString();
47
        
48
        while (from.length < dig_col) {from = '0' + from;}
49
        while (to.length < dig_col) {to = '0' + to;}
50
        
51
        
52
        context.clearRect(0, 0, width, canvas.height);
53
        context.save();
54
  
55
        for (var j = 0; j <= to.length - 1; j++) {
56
          drawNumberTop(context, j, to[j]);
57
        }
58
        
59
        if (step == 11) {
60
          for (var j = 0; j <= to.length - 1; j++) {
61
            drawNumberBottom(context, j, to[j]);
62
          }
63
          return;
64
        }
65
        
66
        
67
        for (var j = 0; j <= from.length - 1; j++) {
68
          drawNumberBottom(context, j, from[j]);
69
        }
70
  
71
        // draw bg
72
        context.drawImage(image, 0, 96 + step * 48, width - 5, 48, 0, 0, width - 5, 48);
73
        context.drawImage(image, 125, 96 + step * 48, 4, 48, width - 5, 0, 5, 48);
74
  
75
        for (var i = 0; i < 24; i++) {
76
          if (step < 5) {
77
            context.setTransform(maxscale - (maxscale - 1) * i / 23, 0, 0, scale_y, -(nwidth - width) / 2 * (1 - i / 23), -offsets[step].h);
78
            for (var j = 0; j <= from.length - 1; j++) {
79
              drawNumberLine(context, j, from[j], i);
80
            }
81
          }
82
          
83
          if (step > 5) {
84
            context.setTransform(1 + (maxscale - 1) * i / 23, 0, 0, scale_y, -(nwidth - width) / 2 * (i / 23), -offsets[step].h);
85
            for (var j = 0; j <= to.length - 1; j++) {
86
              drawNumberLine(context, j, to[j], 25+i);
87
            }
88
          }
89
          context.restore();
90
        }
91
        context.setTransform(1, 0, 0, 1, 0, 0);
92
  
93
        // draw blick
94
        context.drawImage(image, 130, 96 + step * 48, width - 5, 48, 0, 0, width - 5, 48);
95
        context.drawImage(image, 255, 96 + step * 48, 4, 48, width -5, 0, 5, 48);
96
      }
97
        
98
      function cf_animate(from, to, canvas, step) {
99
        cf_draw(from, to, canvas, step);
100
        step ++;
101
        if (step > 11) return;
102
  
103
        setTimeout(function() {
104
          cf_animate(from, to, canvas, step);
105
        }, 50 - 20 * step/11);
106
      }
107
      
108
      function seconds(from, canvas) {
109
        var to = from - 1;
110
        
111
        if (from <= 0) {
112
          to = 59;
113
          
114
          // minutes animate
115
          var minutes_from = parseInt($('span', minutes_cnt).text(), 10);
116
          var minutes_to = minutes_from - 1;
117
          
118
          if (minutes_from <= 0) {
119
            minutes_to = 59;
120
            
121
            // hourses animate
122
            var hourses_from = parseInt($('span', hourses_cnt).text(), 10);
123
            var hourses_to = hourses_from - 1;
124
            
125
            if (hourses_from <= 0) {
126
              hourses_to = 23;
127
              
128
              var days_from = parseInt($('span', days_cnt).text(), 10);
129
              var days_to = days_from - 1;
130
              
131
              if (days_from == 0) {
132
                return;
133
              }
134
              cf_animate(days_from, days_to, $('canvas', days_cnt)[0], 0);
135
              $('span', days_cnt).text(days_to);
136
            }
137
            cf_animate(hourses_from, hourses_to, $('canvas', hourses_cnt)[0], 0);
138
            $('span', hourses_cnt).text(hourses_to);
139
          }
140
  
141
          cf_animate(minutes_from, minutes_to, $('canvas', minutes_cnt)[0], 0);
142
          $('span', minutes_cnt).text(minutes_to);
143
        }
144
      
145
        cf_animate(from, to, canvas, 0);
146
        
147
        from--;
148
        if (from < 0) {from = 59;}
149
  
150
        setTimeout(function() {
151
          seconds(from, canvas);
152
        }, 1000);
153
      }
154
      
155
      
156
      $('div.bl-inner').each(function() {
157
        var canvas = $('<canvas></canvas>').css({
158
          position: 'absolute',
159
          left: -5,
160
          top: 0
161
        }).appendTo(this)[0];
162
        
163
        canvas.width = $(this).width() + offset_left * 2 + 3;
164
        canvas.height = $(this).height();
165
        
166
        cf_draw(parseInt($('span', this).text(), 10), parseInt($('span', this).text(), 10), canvas, 11);
167
      });
168
      
169
      var seconds_cnt = $('div.time .bl-inner:last'),
170
        minutes_cnt = $('div.time .bl-inner:eq(2)'),
171
        hourses_cnt = $('div.time .bl-inner:eq(1)'),
172
        days_cnt  = $('div.time .bl-inner:eq(0)');
173
  
174
      seconds(parseInt($('span', seconds_cnt).text(), 10), $('canvas', seconds_cnt)[0]);
175
    });
176
    image.attr('src', 'http://web-zone.com.ua/wp-content/uploads/samples/timer/i/sprites.png');
177
  } else {
178
    $('div.bl-inner span').show();
179
  }
180
});
 

Countdown timer on jQuery Canvas

CSSDeck G+