C’était cette horloge numérique. Je pensais que c’était une bonne idée à l’époque, mais je ne m’en suis pas soucié. Jusqu'à hier, mon collègue a vu ce cas sur Internet. Il l'a trouvé très cool, alors il est venu me demander comment cela était mis en œuvre. Ensuite, j'ai réfléchi à la méthode de mise en œuvre et je me suis un peu intéressé, alors j'ai passé du temps à l'imiter. il. J'en ai fait un. La différence est que Cen An utilise div pour le créer. Et je l'ai fait en utilisant de la toile. Il sera préférable d'utiliser canevas pour les performances, car juste pour contrôler le mouvement de chaque point, utiliser js pour contrôler l'attribut de style de dom manque définitivement de performances par rapport à l'utilisation de js pour contrôler le dessin du canevas.
Jetons d'abord un coup d'œil à la DÉMO que j'ai réalisée, puis décrivons brièvement la méthode pour procéder : S'il vous plaît, piquez-moi pour voir la DÉMO.
L'idée de faire cela est très simple, qui est de sauvegarder la position de chaque numéro via une chaîne :
Copier le code
Code XML/HTMLCopier le contenu dans le presse-papiers
- var numData = [
- "1111/1001/1001/1001/1001/1001/1111", //0
- "0001/0001/0001/0001/0001/0001/0001", //1
- "1111/0001/0001/1111/1000/1000/1111", //2
- "1111/0001/0001/1111/0001/0001/1111", //3
- "1010/1010/1010/1111/0010/0010/0010", //4
- "1111/1000/1000/1111/0001/0001/1111", //5
- "1111/1000/1000/1111/1001/1001/1111", //6
- "1111/0001/0001/0001/0001/0001/0001", //7
- "1111/1001/1001/1111/1001/1001/1111", //8
- "1111/1001/1001/1111/0001/0001/1111", //9
- "0000/0000/0010/0000/0010/0000/0000", // :
- ]
0 signifie pas de pixels, 1 signifie qu'il y a des pixels, / est pour une meilleure apparence, c'est une branche. Pour faire simple : par exemple, 0 vaut :
.
Code XML/HTMLCopier le contenu dans le presse-papiers
- 1 1 1 1
-
- 1 0 0 1
-
- 1 0 0 1
-
- 1 0 0 1
-
- 1 0 0 1
-
- 1 0 0 1
-
- 1 1 1 1
Cela devrait être très clair. Il existe également un nombre : de 0 à 9, qui est représenté par une chaîne.
Ensuite, écrivez un objet particule, qui est un pixel :
Code XML/HTMLCopier le contenu dans le presse-papiers
- var P_radius = 8,Gravité = 9.8 ;
-
var Particule = fonction(){
-
this.x = 0;
-
this.y = 0;
-
this.vx = 0;
-
this.vy = 0;
-
this.color = "";
-
this.visible = false;
-
this.drop = false;
- }
-
Particule.prototype = {
- constructeurs : Particule,
- paint:function(){ //绘制自身
-
ctx.fillStyle = this.color;
- ctx.beginPath();
- ctx.arc(this.x,this.y,P_radius,0,2*Math.PI);
- ctx.fill();
- },
- reset:function(x,y,color){ //重置
-
this.x = x;
-
this.y = y;
-
this.vx = 0;
-
this.vy = 0;
-
this.color = couleur;
-
this.visible = vrai;
-
this.drop = false;
- },
- isDrop:function(){ //落下
-
this.drop = true;
-
var vx = Math.random()*20 15
-
this.vx = Math.random()> =0,5?-vx : vx ;
- },
- update:function(time){ //每一帧的动作
- if(this.drop){
- this.x = this.vx*time ;
- this.y = this.vy*time ;
-
-
var vy = ce.vy Gravity*time ;
-
-
if(this.y>=canvas.height-P_radius){
-
this.y = toile.height-P_radius
-
vy = -vy*0.7;
- }
-
-
this.vy = vy;
-
-
if(this.x<-P_radius||this.x>canvas.width P_radius||this.y<-P_radius||this.y>canvas.height P_radius){
-
this.visible = false;
- }
- }
- }
- }
-
粒子对象的属性比较简单,就位置,速度,以及是否可视化。方法的话,paint是绘制方法,reset是重置( Mise à jour de isDrop Mise à jour de la mise à jour de la toile sur toile false子容器中保存起来等待下一次调用。
写好粒子对象后,就要考虑如何让粒子按照位置画上去,同时当粒子不需要用时能够让他做自由落体的动画了。
先画背景(也就是那没有像素的白点):
Code XML/HTML复制内容到剪贴板
- fonction drawBg(){
-
var tx = (canvas.width-((P_radius*2 X_J)*4*8 7*xjg))/2;
-
pour(var i=0;i<8;i ){
- var ty = (canvas.height-((P_radius yjg)*6))/2;
- pour(var j=0;j<numData[0].length;j ){
- var tt = numData[0].charAt(j);
- if(tt==="/"){
- ty =yjg;
- }autre {
- var x = tx j%5*(P_radius*2 X_J),
- y = ty;
- bgctx.fillStyle = "#FFF";
- bgctx.beginPath();
- bgctx.arc(x,y,P_radius,0,2*Math.PI);
- bgctx.fill();
- }
- }
- tx =xjg 4*(P_radius*2 X_J);
- }
- }
Dessinez d'abord l'arrière-plan dans un canevas hors écran et mettez-le en cache. Ensuite, aucun calcul logique n'est nécessaire lors du redessinage de chaque image. Dessinez simplement le canevas hors écran. La logique ci-dessus ne devrait pas être difficile à comprendre. Il s'agit de parcourir 8 nombres à travers deux boucles, puis de dessiner chaque nombre point par point. Lorsque "/" est rencontré, cela signifie qu'une nouvelle ligne est requise et le ty dessiné. Ajoutez un intervalle de nouvelle ligne, réinitialisez l'émission, puis dessinez. Ainsi, tous les points peuvent être dessinés. Le rendu est le suivant :
Une fois l'arrière-plan dessiné, commencez à dessiner des pixels numériques en fonction de chaque seconde. La méthode principale est la suivante :
Code XML/HTMLCopier le contenu dans le presse-papiers
- fonction setTime(time){
- var h = heure.getHours() "",
- m = heure.getMinutes() "",
- s = heure.getSeconds() "";
- hh = h.length===1?"0" h:h;
- mm = m.length===1?"0" m:m;
- ss = s.length===1?"0" s:s;
-
- var nowdate = h ":" m ":" s;
- var tx = (canvas.width-((P_radius*2 X_J)*4*8 7*xjg))/2,couleur = "";
- pour(var i=0;i<nowdate.length;i ){
- var n = date actuelle.charAt(i)===":"?10:parseInt( nowdate.charAt(i)),
- text = numData[n];
-
- var ty = (canvas.height-((P_radius yjg)*6))/2;
-
- switch(i){
- case 0:color = "#4DCB74";break;
- cas 2:couleur = "#4062E0";pause;
- cas 3:couleur = "#D65050";pause;
- cas 5:couleur = "#4062E0";pause;
- cas 6:couleur = "#797C17";pause;
- }
-
- pour(var j=0;j<text.length;j ){
- var tt = text.charAt(j);
- if(tt==="/"){
- ty =yjg;
- }autre{
- var x = tx j%5*(P_radius*2 X_J),
- y = ty,
- pp = null,
- usefullp = null;
- particles.forEach(function(p){
- if(p.visible&p.x===x&p.y===y){
- ppp = p;
- }else if(!p.visible&usefullp===null){
- utile = p;
- }
- } );
- if(pp!==null&tt==="0"){
- pp.isDrop();
- }else if(pp===null&tt==="1"){
- usefullp.reset(x , y , color);
- }
- }
- }
- tx =xjg 4*(P_radius*2 X_J);
- }
- }
原理也不难,也是跟上面画背景差不多,遍历所有点,然后根据当前时间的数字转换成的字符串来判断,当前点是否应该有像素,如果有像素就再判断当前这个点是否已经有粒子对象在了,如果已经有粒子对象在了,就直接跳出不处理,如果没有粒子对象在,就再粒子容器中找一个没有被使用的粒子reset到这个位置。还有一种情况,就是
时间设置也写好了,就可以写舞台更新的代码了:
Code XML/HTML复制内容到剪贴板
- var timeCount_0 = 0,timeCount_1 = 0 ,particules = [];
- function initAnimate(){
- pour(var i=0;i<200;i ){
- var p = nouveau Particule();
- particles.push(p);
- }
-
- timeCount_0 = nouveau Date();
- timeCount_1 = nouveau Date();
- drawBg();
- setTime(timeCount_0)
- animate();
- }
-
- function animate(){
- ctx.clearRect(0,0,canvas.width,canvas.height);
- ctx.drawImage(bgcanvas,0,0);
-
- var timeCount_2 = nouveau Date();
-
- if(timeCount_1-timeCount_0>=1000){
- setTime(timeCount_1);
-
timeCount_0 = timeCount_1;
- }
-
- particles.forEach(function(p){
- if(p.visible){
- p.update((timeCount_2-timeCount_1)/70);
- p.paint();
- }
- });
-
-
timeCount_1 = timeCount_2
-
- RAF(animer)
-
Effectuer l'initialisation de l'animation dans initAnimate. L'initialisation signifie d'abord instancier deux cents objets de particules et les placer dans un conteneur de particules pour les enregistrer, puis mettre à jour l'horodatage, mettre en cache l'arrière-plan, définir l'heure actuelle, puis appeler le corps de la boucle d'animation animée. pour démarrer l'animation.
La logique dans animer est également très simple. Obtenez l'horodatage Si la différence de temps entre les deux horodatages est supérieure ou égale à 1 seconde, setTime est effectué. L'étape suivante consiste à parcourir et redessiner toutes les particules visualisées dans le conteneur de particules.
Alors c'est fait :
Il existe encore de nombreuses zones qui peuvent être optimisées pour cet effet, car l'horloge et les minutes bougent relativement rarement, donc ces deux éléments peuvent être mis en cache, et lorsqu'il n'y a aucune action, il suffit de dessiner directement les données mises en cache. nombre d'appels d'API de dessin pour chaque image de la scène, ce qui améliorera certainement les performances. Cependant, il n'y a pas beaucoup de particules maintenant, et deux à trois cents objets particules suffisent. Si l'optimisation n'est pas effectuée, l'animation peut toujours se dérouler sans problème. L’affiche originale était donc juste un peu paresseuse.
Adresse du code source :
https://github.com/whxaxes/canvas-test/blob/gh-pages/src/Funny-demo/coolClock/index.html