Html5 Canvas背光文字动画特效代码

Html5 Canvas背光文字动画特效代码

一款基于canvas自定义设置文字背光动画特效。支持英文、数字、中文等。Html5 Canvas背光文字动画特效代码。

使用方法
javascript代码

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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
//把站长天下修改为自己需要显示的名称
var txt = "站长天下";
var txtH = 100;
var font = "sans-serif";
var bg = "#000";
var rayColor1 = "#e0f7fa";
var rayColor2 = "#18ffff";
var fade = 1000;

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var cw = canvas.width = window.innerWidth;
var ch = canvas.height = window.innerHeight;

var w2 = cw/2;
var h2 = ch/2;
var pi = Math.PI;
var pi2 = pi*.5;

var txtCanvas = document.createElement("canvas");
var txtCtx = txtCanvas.getContext("2d");
txtCtx.font = txtH + "px " + font;
txtCtx.textBaseline = "middle";
var txtW = Math.floor(txtCtx.measureText(txt).width);
txtCanvas.width = txtW;
txtCanvas.height = txtH*1.5;

var gradient = ctx.createRadialGradient(w2, h2, 0, w2, h2, txtW);
gradient.addColorStop(0, rayColor2);
gradient.addColorStop(1, rayColor1);
ctx.strokeStyle = gradient;

txtCtx.fillStyle = gradient;
txtCtx.font = txtH + "px " + font;
txtCtx.textBaseline = "middle";
txtCtx.fillText(txt,0,txtH*.5);

//dirty adjust for descends
txtH *= 1.5;

var bufferCanvas = document.createElement("canvas");
bufferCanvas.width = txtW;
bufferCanvas.height = txtH;
var buffer = bufferCanvas.getContext("2d");

//text start position
var sx = (cw-txtW)*0.5
var sy = (ch-txtH)*0.5

////generate data
var rays = [];
var txtData = txtCtx.getImageData(0,0,txtW,txtH);
for (var i = 0; i < txtData.data.length; i+=4) {
  var ii = i/4;
  var row = Math.floor(ii/txtW)
  var col = ii%txtW
  var alpha = txtData.data[i+3]
  if(alpha !== 0){
    var c = "rgba("
    c += [txtData.data[i],txtData.data[i+1],txtData.data[i+2], alpha/255 ]
    c += ")";
    rays.push(new Ray(Math.floor(ii/txtW), ii%txtW, c));  
  }
}

var current = 1;
//start animation
tick();

function tick() {
  ctx.clearRect(0,0,cw,ch)
  ctx.drawImage(bufferCanvas, 0, 0, current, txtH, sx, sy, current, txtH)
  ctx.save()
  ctx.globalAlpha = .07;
  ctx.globalCompositeOperation = "lighter";
  if(drawRays(current)){
    current++;
    current = Math.min(current, txtW)
    window.requestAnimationFrame(tick)  
  }else{
    fadeOut()
  }
  ctx.restore()
}

function fadeOut(){
  ctx.clearRect(0,0,cw,ch)
  ctx.globalAlpha *= .95;
  ctx.drawImage(bufferCanvas, 0, 0, current, txtH, sx, sy, current, txtH)
  if(ctx.globalAlpha > .01){
   window.requestAnimationFrame(fadeOut)
  }else{
    window.setTimeout(restart, 500)
  }
}
function restart(){
  for(var i = 0; i < rays.length; i++){
    rays[i].reset()
  }
  ctx.globalAlpha = 1
  buffer.clearRect(0,0,txtW,txtH)
  current = 1;
  tick();
}
function drawRays(c){
  var count = 0;
  ctx.beginPath()
  for(var i = 0; i < rays.length; i++){
    var ray = rays[i];
    if(ray.col < c){
      count += ray.draw()
    }
  }
  ctx.stroke()
  return count !== rays.length;
}

function filterRays(r){
  return Boolean(r);
}

function Ray(row, col, f){
  this.col = col;
  this.row = row;
 
  var xp = sx + col;
  var yp = sy + row;
  var fill = f;
 
  var ath = (txtH/1.5)
 
  var a = pi2 * (this.row - ath*.5) / ath;
  if(a === 0){
    a = (Math.random() - .5) * pi2;
  }
  var da = .02 * Math.sign(a);
  da += (Math.random() - .5) * .005;
  var l = 0;
  var dl = Math.random()*2 + 2;
 
  var buffered = false;
  this.reset = function(){
    a = pi2 * (this.row - ath*.5) / ath;
    if(a === 0){
      a = -pi2*.5;
    }
    l = 0;
    buffered = false
  }
  this.draw = function(){
    if(l < 0){
      if(!buffered){
        buffer.fillStyle = fill;
        buffer.fillRect(this.col, this.row, 1, 1);
        buffered = true
      }
      return 1;
    }else{
      ctx.moveTo(xp, yp)
      ctx.lineTo(xp + Math.cos(a) * l, yp + Math.sin(a) * l);
      a += da;
      l += Math.cos(a)*dl;
      return 0;
    }
  }
}
当前内容只有登录了才能查看,如果您已经注册,请登录
2

发表评论