10/10/2018, 00:12

Giải thuật "Tuyết rơi" - Java Script

Bác nào giỏi thuật toán nghiên cứu giùm tớ cái code Java Script này tý.

Đây là 1 script tạo hiệu ứng một bầu trời bão tuyết Tớ có tham khảo thuật toán quỹ tích điểm trong code "Autumn leaves", nhưng xây dựng theo cấu trúc DOM và chuyển thành một class.

Nó chạy tốt. Chỉ có điều là sau một khoảng thời gian thì chương trình càng nặng thêm ! Mặc dù về sau không append thêm phần tử (phương thức Commencer chỉ được gọi 1 lần đầu tiên). Tớ nghĩ là do chỗ tính tập hợp điểm random.

Các bác xem demo ở đây : http://linhlan.justfree.com/. Nếu bỏ hiệu ứng này đi thì trang web chạy bình thường, nhưng mất một nửa vẻ đẹp của nó

Giúp tớ chút nha. Code dưới đây. Sau khi hoàn chỉnh rồi bạn nào thích thì lấy mà dùng

PHP Code:
/*----------------------------------------------------------------
Class LaNeige - Tuyết rơi, viết bởi Sacroyant Nguyen
Dựa tren giải thuật  tìm tập hợp trong "Autumn leaves" của Kurt Grigg (kurt.grigg@virgin.net)
 // Xem code "Autumn leaves"  : 
http://www.dynamicdrive.com/dynamicindex3/leaves.htm
----------------------------------------------------------------*/
function LaNeige(){
  
this.grphcs=new Array(5);
  
this.gouttes=60;
  
this.Xpos=***91;***93;;
  
this.Ypos=***91;***93;;
  
this.Speed=***91;***93;;
  
this.Step=***91;***93;;
  
this.Cstep=***91;***93;;
  
this.timer=***91;40,80,120,150,180,200,250,180,120,150,100***93;;
  
this.Commencer=function(){
      for(var 
i=0;i<this.gouttes;i++){
      var 
P=Math.floor(Math.random()*this.grphcs.length);
        var 
elm=document.createElement('span');
            
elm.innerHTML='.';
            
elm.name='sn'+i;
            
elm.id='sn'+i;
            
elm.style.position='absolute';
        
document.body.appendChild(elm);
    }
    
this.tomber();
  }
  
this.tomber=function(){
    
getWinSize();
      var 
hscrll=(window.pageYOffset)||(document.body.scrollTop);
      var 
wscrll=(window.pageXOffset)||(document.body.scrollLeft);
        for (var 
j=0;j<this.gouttes;j++){                                                                
            
this.Ypos***91;j***93; = Math.round(Math.random()*(winsize.h-60));
            
this.Xpos***91;j***93; = Math.round(Math.random()*(winsize.w-50));
            
this.Speed***91;j***93;= Math.random()*8+5;
            
this.Cstep***91;j***93;=0;
            
this.Step***91;j***93;=Math.random()*0.1+0.05;
        }
        for(var 
i=0;i<this.gouttes;i++){
            
sy this.Speed***91;i***93;*Math.sin(90*Math.PI/180);
            
sx this.Speed***91;i***93;*Math.cos(this.Cstep***91;i***93;);
            
this.Ypos***91;i***93;+=sy;
            
this.Xpos***91;i***93;+=sx
              if(
this.Ypos***91;i***93;>winsize.h){
                
this.Ypos***91;i***93;=-60;
                
this.Xpos***91;i***93;=Math.round(Math.random()*(winsize.w));
                  if(
this.Xpos***91;i***93;>winsize.wthis.Xpos***91;i***93;=-50;
                
this.Speed***91;i***93;=Math.random()*5+1;
              }
            
size=***91;4,5,6,7,8,9,10,20,18,16,12,9,7,5***93;;
            
color=***91;'#ffffff','#f6f3f6','#f6fef1','#fff1f1','#aff4f5','#f1f5f1','#cccccc'***93;;
            
asize=Math.floor(Math.random()*size.length);
            
acolor=Math.floor(Math.random()*color.length);
            var 
oLeft=Math.min(winsize.w,this.Xpos***91;i***93;);
            var 
oTop=this.Ypos***91;i***93;+hscrll;
                if(
oLeft>=winsize.woLeft=winsize.w-50;
                if(
oTop>=winsize.hoTop=winsize.h-60;
            
rel("sn"+i).style.color=color***91;acolor***93;;
            
rel("sn"+i).style.fontSize=size***91;asize***93;+'px';
            
rel("sn"+i).style.left=oLeft+'px';
            
rel("sn"+i).style.top=oTop+'px';
            
this.Cstep***91;i***93;+=this.Step***91;i***93;;
        }
        var 
self=this;    
                  
window.setTimeout(
                    function(){
self.tomber();},
                     
this.timer***91;Math.ceil(Math.random()*this.timer.length)***93;
                  );
    }
}
/* /////////////////////////////////////
-------- End Class LaNeige
/////////////////////////////////////// */ 
* Ghi chú :

- getWinSize() là hàm bên ngoài dùng để tính kích thước cửa sổ. Nó trả về winsize{width, height}

- rel(id) là hàm bên ngoài, trả về phần tử dựa trên ID.
zoejoe viết 02:14 ngày 10/10/2018
Đúng là sau một thời gian thì nó lại nặng hơn, chạy không muợt bằng lúc đầu. Có thể do thuật tóan anh đệ qui ở timeout, có thể thay bằng set interval sẽ nhẹ hơn, vì với set timeout nó sẽ phải lưu lại các thông số cũ truớc đó và tiếp tục gọi lại chính nó !
sacroyant viết 02:25 ngày 10/10/2018
Được gửi bởi zoejoe
Đúng là sau một thời gian thì nó lại nặng hơn, chạy không muợt bằng lúc đầu. Có thể do thuật tóan anh đệ qui ở timeout, có thể thay bằng set interval sẽ nhẹ hơn, vì với set timeout nó sẽ phải lưu lại các thông số cũ truớc đó và tiếp tục gọi lại chính nó !
Ừ nhỉ, để tớ thử ngay xem sao. Cảm ơn bạn nhé

Nếu bạn nghe nhạc mới thấy rõ điều này. Nghe một hồi có cảm giác bản nhạc bị ngập ngừng (rất nhẹ thôi !).



Hay thật, tớ chuyển đoạn mã này vào trong định nghĩa phương thức Commencer()

PHP Code:
var self=this;
window.setInterval(
   function(){
self.tomber();},
   
this.timer***91;Math.ceil(Math.random()*this.timer.length)***93;
); 
Đúng là mượt mà hơn hẳn Cảm ơn zoejoe nha
zoejoe viết 02:20 ngày 10/10/2018
Không có gì, do làm việc nhiều với cái này nên có để ý đôi chút tới tốc độ thực thi. Với những hàm nhỏ thì không sao, nhưng nếu công việc cứ chồng chất vô 1 hàm, thì tự nó sẽ nặng hơn do phải lưu trữ tốn bộ nhớ theo quy tắc đệ qui nếu cứ lạm dụng việc dùng hàm setTimeout(). Khi dùng hàm setInterval, đơn giản là nó chỉ gọi lại hàm đó sau 1 khỏan thời gian nào đó, các biến cũ của hàm đó đuợc thực thi truớc đó sẽ tự huỷ sau khi hàm đó thực thi xong với vai trò là các biến cục bộ .
sacroyant viết 02:23 ngày 10/10/2018
Hai phương thức này trước giờ mình cũng chỉ hiểu sơ lược. Giờ bạn nói mới rõ thêm về bản chất của mỗi cái

Hiện giờ bản mô phỏng hệ điều hành nầy mới chỉ có giao diện thử nghiệm, chưa cá nhân hóa. Để tớ bổ sung thêm vài ứng dụng nữa, thế nào cũng phải thỉnh giáo thêm ở bạn và các bác khác
zoejoe viết 02:24 ngày 10/10/2018
Được gửi bởi sacroyant
Hai phương thức này trước giờ mình cũng chỉ hiểu sơ lược. Giờ bạn nói mới rõ thêm về bản chất của mỗi cái

Hiện giờ bản mô phỏng hệ điều hành nầy mới chỉ có giao diện thử nghiệm, chưa cá nhân hóa. Để tớ bổ sung thêm vài ứng dụng nữa, thế nào cũng phải thỉnh giáo thêm ở bạn và các bác khác
Anh tính giả lập 1 hệ điều hành như Fanbox à Việc code js lại từ đầu theo cách cổ điển thì chắc là hơi lâu và phức tạp Có thể anh nên dùng thêm framework js như jQuery chẳng hạn thì công việc sẽ đơn giản hơn nhiều, và giao diên nó cũng mang phong cách vista với các hiệu ứng đựoc viết sẵn trong đó với UI của jQuery Để làm xong một số việc mình cũng phải làm một cái mới đựoc (nhưng mà nhỏ hơn )
sacroyant viết 02:27 ngày 10/10/2018

Hà hà, tớ vừa làm vừa chơi ấy mà. Tự code mới vui. Giờ cứ viết mã tràn lan rồi tinh giản sau
Bài liên quan
0