JS实现调皮动态粒子背景

楼主
我是社区第485122位番薯,欢迎点我头像关注我哦~
1. 概述
1.1 预期效果

大屏场景下,给决策报表添加一个调皮的动态粒子背景,如下图所示:



1.2 实现思路

使用 JS 代码来生成动态背景。


2. 示例

2.1 报表设计

新建决策报表,选中 body 组件,添加初始化后事件,如下图所示:

JS 代码如下:

  1. $("body").prepend('<canvas id="canvas" style="position:absolute;z-index:-3;"></canvas>');
  2. let c = init("canvas").c,
  3.     canvas = init("canvas").canvas,
  4.   w = (canvas.width = window.innerWidth),
  5.   h = (canvas.height = window.innerHeight);
  6. //initiation
  7. function cc(A,B,C){
  8.   let D = 2*(A.x*(B.y-C.y)+B.x*(C.y-A.y)+C.x*(A.y-B.y));
  9.   let S = {
  10.     x: (1/D)*((A.x*A.x+A.y*A.y)*(B.y-C.y)+(B.x*B.x+B.y*B.y)*(C.y-A.y)+(C.x*C.x+C.y*C.y)*(A.y-B.y)),
  11.     y: (1/D)*((A.x*A.x+A.y*A.y)*(C.x-B.x)+(B.x*B.x+B.y*B.y)*(A.x-C.x)+(C.x*C.x+C.y*C.y)*(B.x-A.x))
  12.   }
  13.   return S;
  14. }
  15. function dist(A,B){
  16.   return Math.sqrt(Math.pow(A.x-B.x,2)+Math.pow(A.y-B.y,2));
  17. }
  18. class point{
  19.   constructor(x,y){
  20.     this.x = x;
  21.     this.y = y;
  22.   }
  23.   update(x,y){
  24.     this.x = x;
  25.     this.y = y;
  26.   }
  27. }
  28. class triangle{
  29.   constructor(A,B,C,lw){
  30.     this.a = A;
  31.     this.b = B;
  32.     this.c = C;
  33.     this.s = cc(A,B,C);
  34.     this.ty = this.c;
  35.     this.lw = lw;
  36.    
  37.     this.x = dist(this.s,this.a);
  38.     this.c1 = dist(this.a,this.b)/2;
  39.     this.c2 = dist(this.b,this.c)/2;
  40.     this.c3 = dist(this.c,this.a)/2;
  41.     this.a2ab = Math.atan2(this.a.y-this.b.y,this.a.x-this.b.x);
  42.     this.a2bc = Math.atan2(this.b.y-this.c.y,this.b.x-this.c.x);
  43.     this.a2ca = Math.atan2(this.c.y-this.a.y,this.c.x-this.a.x);
  44.     this.rab = Math.sqrt(this.x*this.x-this.c1*this.c1);
  45.     this.rbc = Math.sqrt(this.x*this.x-this.c2*this.c2);
  46.     this.rca = Math.sqrt(this.x*this.x-this.c3*this.c3);
  47.    
  48.     this.s1 = {
  49.       x:this.s.x+(this.rab/2)*Math.cos(this.a2ab+Math.PI/2),
  50.       y:this.s.y+(this.rab/2)*Math.sin(this.a2ab+Math.PI/2)
  51.     };
  52.     this.s2 = {
  53.       x:this.s.x+(this.rbc/2)*Math.cos(this.a2bc+Math.PI/2),
  54.       y:this.s.y+(this.rbc/2)*Math.sin(this.a2bc+Math.PI/2)
  55.     };
  56.     this.s3 = {
  57.       x:this.s.x+(this.rca/2)*Math.cos(this.a2ca+5*Math.PI/2),
  58.       y:this.s.y+(this.rca/2)*Math.sin(this.a2ca+5*Math.PI/2)
  59.     };
  60.   }
  61.   update(A,B,C){
  62.     this.a = A;
  63.     this.b = B;
  64.     this.c = C;
  65.     this.s = cc(A,B,C);
  66.     this.ty = this.c;
  67.    
  68.     this.x = dist(this.s,this.a);
  69.     this.c1 = dist(this.a,this.b)/2;
  70.     this.c2 = dist(this.b,this.c)/2;
  71.     this.c3 = dist(this.c,this.a)/2;
  72.     this.a2ab = Math.atan2(this.a.y-this.b.y,this.a.x-this.b.x);
  73.     this.a2bc = Math.atan2(this.b.y-this.c.y,this.b.x-this.c.x);
  74.     this.a2ca = Math.atan2(this.c.y-this.a.y,this.c.x-this.a.x);
  75.     this.rab = Math.sqrt(this.x*this.x-this.c1*this.c1);
  76.     this.rbc = Math.sqrt(this.x*this.x-this.c2*this.c2);
  77.     this.rca = Math.sqrt(this.x*this.x-this.c3*this.c3);
  78.    
  79.     this.s1 = {
  80.       x:this.s.x+(this.rab/2)*Math.cos(this.a2ab+Math.PI/2),
  81.       y:this.s.y+(this.rab/2)*Math.sin(this.a2ab+Math.PI/2)
  82.     };
  83.     this.s2 = {
  84.       x:this.s.x+(this.rbc/2)*Math.cos(this.a2bc+Math.PI/2),
  85.       y:this.s.y+(this.rbc/2)*Math.sin(this.a2bc+Math.PI/2)
  86.     };
  87.     this.s3 = {
  88.       x:this.s.x+(this.rca/2)*Math.cos(this.a2ca+5*Math.PI/2),
  89.       y:this.s.y+(this.rca/2)*Math.sin(this.a2ca+5*Math.PI/2)
  90.     };
  91.   }
  92.   move(m){
  93.     this.c = m;
  94.     this.s = cc(this.a,this.b,this.c);
  95.    
  96.     this.x = dist(this.s,this.a);
  97.     this.c1 = dist(this.a,this.b)/2;
  98.     this.c2 = dist(this.b,this.c)/2;
  99.     this.c3 = dist(this.c,this.a)/2;
  100.     this.a2ab = Math.atan2(this.a.y-this.b.y,this.a.x-this.b.x);
  101.     this.a2bc = Math.atan2(this.b.y-this.c.y,this.b.x-this.c.x);
  102.     this.a2ca = Math.atan2(this.c.y-this.a.y,this.c.x-this.a.x);
  103.     this.rab = Math.sqrt(this.x*this.x-this.c1*this.c1);
  104.     this.rbc = Math.sqrt(this.x*this.x-this.c2*this.c2);
  105.     this.rca = Math.sqrt(this.x*this.x-this.c3*this.c3);
  106.    
  107.     this.s1 = {
  108.       x:this.s.x+(this.rab/2)*Math.cos(this.a2ab+Math.PI/2),
  109.       y:this.s.y+(this.rab/2)*Math.sin(this.a2ab+Math.PI/2)
  110.     };
  111.     this.s2 = {
  112.       x:this.s.x+(this.rbc/2)*Math.cos(this.a2bc+Math.PI/2),
  113.       y:this.s.y+(this.rbc/2)*Math.sin(this.a2bc+Math.PI/2)
  114.     };
  115.     this.s3 = {
  116.       x:this.s.x+(this.rca/2)*Math.cos(this.a2ca+5*Math.PI/2),
  117.       y:this.s.y+(this.rca/2)*Math.sin(this.a2ca+5*Math.PI/2)
  118.     };
  119.   }
  120.   iterate(it){
  121.     this.it = it;
  122.     // this.t1 = new triangle(this.a,this.b,this.s1,this.lw/2);
  123.     // this.t2 = new triangle(this.a,this.s2,this.c,this.lw/2);
  124.     // this.t3 = new triangle(this.b,this.c,this.s3,this.lw/2);
  125.    
  126.     this.t4 = new triangle(this.a,this.s1,this.s3,this.lw/2);
  127.     this.t5 = new triangle(this.b,this.s2,this.s1,this.lw/2);
  128.     this.t6 = new triangle(this.c,this.s3,this.s2,this.lw/2);
  129.    
  130.     this.t7 = new triangle(this.s1,this.s2,this.s3,this.lw/2);
  131.    
  132.     if(it < 3){
  133.       // this.t1.iterate(it+1);
  134.       // this.t2.iterate(it+1);
  135.       // this.t3.iterate(it+1);
  136.       
  137.       this.t4.iterate(it+1);
  138.       this.t5.iterate(it+1);
  139.       this.t6.iterate(it+1);
  140.       
  141.       this.t7.iterate(it+1);
  142.     }
  143.    
  144.     // this.t1.show();
  145.     // this.t2.show();
  146.     // this.t3.show();
  147.    
  148.     this.t4.show();
  149.     this.t5.show();
  150.     this.t6.show();
  151.    
  152.     this.t7.show();
  153.   }
  154.   show(){
  155.     // c.beginPath();
  156.     // c.lineTo(this.a.x,this.a.y);
  157.     // c.lineTo(this.b.x,this.b.y);
  158.     // c.lineTo(this.c.x,this.c.y);
  159.     // c.strokeStyle="white";
  160.     // c.lineWidth=this.lw;
  161.     // c.lineJoin="round";
  162.     // c.closePath();
  163.     // c.stroke();
  164.    
  165.     c.fillStyle="white";
  166.     c.fillRect(this.a.x-1,this.a.y-1,2,2);
  167.     c.fillRect(this.b.x-1,this.b.y-1,2,2);
  168.     c.fillRect(this.c.x-1,this.c.y-1,2,2);
  169.    
  170.     c.fillStyle="#00ffff";
  171.     c.fillRect(this.s.x-0.5,this.s.y-0.5,1,1);
  172.     c.fillStyle="#00ffff";
  173.     c.fillRect(this.s1.x-0.5,this.s1.y-0.5,1,1);
  174.     c.fillStyle="#00ffff";
  175.     c.fillRect(this.s2.x-0.5,this.s2.y-0.5,1,1);
  176.     c.fillStyle="#00ffff";
  177.     c.fillRect(this.s3.x-0.5,this.s3.y-0.5,1,1);
  178.    
  179.   }
  180. }

  181. let s = h/3,
  182.     A = new point(
  183.       w/2+s*Math.cos(0),
  184.       h/2+s*Math.sin(0)),
  185.     B = new point(
  186.       w/2+s*Math.cos(Math.PI/3),
  187.       h/2+s*Math.sin(Math.PI/3)),
  188.     C = new point(
  189.       w/2+s*Math.cos(2*Math.PI/3),  
  190.       h/2+s*Math.sin(2*Math.PI/3)),
  191.     D = new point(
  192.       w/2+s*Math.cos(Math.PI),  
  193.       h/2+s*Math.sin(Math.PI)),
  194.     E = new point(
  195.       w/2+s*Math.cos(4*Math.PI/3),  
  196.       h/2+s*Math.sin(4*Math.PI/3)),
  197.     F = new point(
  198.       w/2+s*Math.cos(5*Math.PI/3),  
  199.       h/2+s*Math.sin(5*Math.PI/3)),
  200.     G = new point(
  201.       w/2,  
  202.       h/2),
  203.     lb = 1,
  204.     T = new triangle(A,B,G,lb),
  205.     T2 = new triangle(B,C,G,lb),
  206.     T3 = new triangle(C,D,G,lb),
  207.     T4 = new triangle(D,E,G,lb),
  208.     T5 = new triangle(E,F,G,lb),
  209.     T6 = new triangle(F,A,G,lb),
  210.     tx = w/2,
  211.     ty = h/2,
  212.     spd = 0;
  213.    

  214. function draw() {
  215.   //animation
  216.   if(mouse.x){
  217.     T.move(mouse);
  218.     T2.move(mouse);
  219.     T3.move(mouse);
  220.     T4.move(mouse);
  221.     T5.move(mouse);
  222.     T6.move(mouse);
  223.   }else{
  224.     T.move({x: tx,y: ty});
  225.     T2.move({x: tx,y: ty});
  226.     T3.move({x: tx,y: ty});
  227.     T4.move({x: tx,y: ty});
  228.     T5.move({x: tx,y: ty});
  229.     T6.move({x: tx,y: ty});
  230.     tx = w/2+(s*Math.cos(Math.PI/6)-45)*Math.cos(spd);
  231.     ty = h/2+(s*Math.cos(Math.PI/6)-70)*Math.sin(spd);
  232.     spd+=0.05;
  233.   }
  234.   
  235.   T.iterate(0);
  236.   T2.iterate(0);
  237.   T3.iterate(0);
  238.   T4.iterate(0);
  239.   T5.iterate(0);
  240.   T6.iterate(0);
  241.   T.show();
  242.   T2.show();
  243.   T3.show();
  244.   T4.show();
  245.   T5.show();
  246.   T6.show();
  247. }

  248. let mouse = {
  249.   x: false,
  250.   y: false
  251. };
  252. let last_mouse = {};

  253. canvas.addEventListener(
  254.   "mousemove",
  255.   function(e) {
  256.     last_mouse.x = mouse.x;
  257.     last_mouse.y = mouse.y;

  258.     mouse.x = e.pageX - this.offsetLeft;
  259.     mouse.y = e.pageY - this.offsetTop;
  260.   },
  261.   false
  262. );
  263.   
  264.   canvas.addEventListener("mouseleave", function(e) {
  265.   mouse.x = false;
  266. });
  267.   
  268. function init(elemid) {
  269.   let canvas = document.getElementById(elemid),
  270.     c = canvas.getContext("2d"),
  271.     w = (canvas.width = window.innerWidth),
  272.     h = (canvas.height = window.innerHeight);
  273.   c.fillStyle = "rgba(30,30,30,1)";
  274.   c.fillRect(0, 0, w, h);
  275.   return {c:c,canvas:canvas};
  276. }

  277. window.requestAnimFrame = (function() {
  278.   return (
  279.     window.requestAnimationFrame ||
  280.     window.webkitRequestAnimationFrame ||
  281.     window.mozRequestAnimationFrame ||
  282.     window.oRequestAnimationFrame ||
  283.     window.msRequestAnimationFrame ||
  284.     function(callback) {
  285.       window.setTimeout(callback);
  286.     }
  287.   );
  288. });

  289. function loop() {
  290.   window.requestAnimFrame(loop);
  291.   c.fillStyle = "rgba(30,30,30,1)";
  292.   c.fillRect(0, 0, w, h);
  293.   draw();
  294. }

  295. window.addEventListener("resize", function() {
  296.   (w = canvas.width = window.innerWidth),
  297.   (h = canvas.height = window.innerHeight);
  298.     s = h/3,
  299.     A.update(w/2+s*Math.cos(0),h/2+s*Math.sin(0));
  300.     B.update(
  301.       w/2+s*Math.cos(Math.PI/3),
  302.       h/2+s*Math.sin(Math.PI/3)),
  303.     C.update(
  304.       w/2+s*Math.cos(2*Math.PI/3),  
  305.       h/2+s*Math.sin(2*Math.PI/3)),
  306.     D.update(
  307.       w/2+s*Math.cos(Math.PI),  
  308.       h/2+s*Math.sin(Math.PI)),
  309.     E.update(
  310.       w/2+s*Math.cos(4*Math.PI/3),  
  311.       h/2+s*Math.sin(4*Math.PI/3)),
  312.     F.update(
  313.       w/2+s*Math.cos(5*Math.PI/3),  
  314.       h/2+s*Math.sin(5*Math.PI/3)),
  315.     G.update(
  316.       w/2,  
  317.       h/2),
  318.     T.update(A,B,G),
  319.     T2.update(B,C,G),
  320.     T3.update(C,D,G),
  321.     T4.update(D,E,G),
  322.     T5.update(E,F,G),
  323.     T6.update(F,A,G),
  324.     tx = w/2,
  325.     ty = h/2,
  326.   loop();
  327. });

  328. loop();
  329. setInterval(loop, 1000 / 40);
复制代码
2.2 效果预览

保存报表,点击表单预览,效果如预期效果中所示。


3. 模板下载

已完成模板可参见:%FR_HOME%\webapps\webroot\WEB-INF\reportlets\doc\JS\表单JS实例\JS实现调皮动态粒子背景.frm

点击下载模板:JS实现调皮动态粒子背景.frm



编辑于 2020-11-18 22:05  
分享扩散:

沙发
发表于 2023-5-16 10:41:36
666,楼主牛皮
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1回帖数 1关注人数 7020浏览人数
最后回复于:2023-5-16 10:41

返回顶部 返回列表