0


炫酷的流动爱心最近很火 来吧 代码已奉上

哈喽,大家好,我是木易巷!

爱情,是每个人都在追求的东西。身为一个IT行业人士,我也会追求爱情,我也会像心爱的人表达感情,只是我所表达的方式与他人有所不同。我的主要战场在计算机上,所以我就想到了用计算机来表达感情,在网页上做爱心,还是会动的爱心给她~

这次给大家带来炫酷的流动爱心,有三种效果,大家自行领取~

第一种效果图:

代码部分

代码如下仅供参考,可以直接拿去复制粘贴!

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
  2. <HTML>
  3. <HEAD>
  4. <TITLE> New Document </TITLE>
  5. <META NAME="Generator" CONTENT="EditPlus">
  6. <META NAME="Author" CONTENT="">
  7. <META NAME="Keywords" CONTENT="">
  8. <META NAME="Description" CONTENT="">
  9. <style>
  10. html, body {
  11. height: 100%;
  12. padding: 0;
  13. margin: 0;
  14. background: #000;
  15. }
  16. canvas {
  17. position: absolute;
  18. width: 100%;
  19. height: 100%;
  20. }
  21. </style>
  22. </HEAD>
  23. <BODY>
  24. <canvas id="pinkboard"></canvas>
  25. <script>
  26. /*
  27. * Settings
  28. */
  29. var settings = {
  30. particles: {
  31. length: 500, // maximum amount of particles
  32. duration: 2, // particle duration in sec
  33. velocity: 100, // particle velocity in pixels/sec
  34. effect: -0.75, // play with this for a nice effect
  35. size: 30, // particle size in pixels
  36. },
  37. };
  38. /*
  39. * RequestAnimationFrame polyfill by Erik Möller
  40. */
  41. (function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;a<c.length&&!window.requestAnimationFrame;++a){window.requestAnimationFrame=window[c[a]+"RequestAnimationFrame"];window.cancelAnimationFrame=window[c[a]+"CancelAnimationFrame"]||window[c[a]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(h,e){var d=new Date().getTime();var f=Math.max(0,16-(d-b));var g=window.setTimeout(function(){h(d+f)},f);b=d+f;return g}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(d){clearTimeout(d)}}}());
  42. /*
  43. * Point class
  44. */
  45. var Point = (function() {
  46. function Point(x, y) {
  47. this.x = (typeof x !== 'undefined') ? x : 0;
  48. this.y = (typeof y !== 'undefined') ? y : 0;
  49. }
  50. Point.prototype.clone = function() {
  51. return new Point(this.x, this.y);
  52. };
  53. Point.prototype.length = function(length) {
  54. if (typeof length == 'undefined')
  55. return Math.sqrt(this.x * this.x + this.y * this.y);
  56. this.normalize();
  57. this.x *= length;
  58. this.y *= length;
  59. return this;
  60. };
  61. Point.prototype.normalize = function() {
  62. var length = this.length();
  63. this.x /= length;
  64. this.y /= length;
  65. return this;
  66. };
  67. return Point;
  68. })();
  69. /*
  70. * Particle class
  71. */
  72. var Particle = (function() {
  73. function Particle() {
  74. this.position = new Point();
  75. this.velocity = new Point();
  76. this.acceleration = new Point();
  77. this.age = 0;
  78. }
  79. Particle.prototype.initialize = function(x, y, dx, dy) {
  80. this.position.x = x;
  81. this.position.y = y;
  82. this.velocity.x = dx;
  83. this.velocity.y = dy;
  84. this.acceleration.x = dx * settings.particles.effect;
  85. this.acceleration.y = dy * settings.particles.effect;
  86. this.age = 0;
  87. };
  88. Particle.prototype.update = function(deltaTime) {
  89. this.position.x += this.velocity.x * deltaTime;
  90. this.position.y += this.velocity.y * deltaTime;
  91. this.velocity.x += this.acceleration.x * deltaTime;
  92. this.velocity.y += this.acceleration.y * deltaTime;
  93. this.age += deltaTime;
  94. };
  95. Particle.prototype.draw = function(context, image) {
  96. function ease(t) {
  97. return (--t) * t * t + 1;
  98. }
  99. var size = image.width * ease(this.age / settings.particles.duration);
  100. context.globalAlpha = 1 - this.age / settings.particles.duration;
  101. context.drawImage(image, this.position.x - size / 2, this.position.y - size / 2, size, size);
  102. };
  103. return Particle;
  104. })();
  105. /*
  106. * ParticlePool class
  107. */
  108. var ParticlePool = (function() {
  109. var particles,
  110. firstActive = 0,
  111. firstFree = 0,
  112. duration = settings.particles.duration;
  113. function ParticlePool(length) {
  114. // create and populate particle pool
  115. particles = new Array(length);
  116. for (var i = 0; i < particles.length; i++)
  117. particles[i] = new Particle();
  118. }
  119. ParticlePool.prototype.add = function(x, y, dx, dy) {
  120. particles[firstFree].initialize(x, y, dx, dy);
  121. // handle circular queue
  122. firstFree++;
  123. if (firstFree == particles.length) firstFree = 0;
  124. if (firstActive == firstFree ) firstActive++;
  125. if (firstActive == particles.length) firstActive = 0;
  126. };
  127. ParticlePool.prototype.update = function(deltaTime) {
  128. var i;
  129. // update active particles
  130. if (firstActive < firstFree) {
  131. for (i = firstActive; i < firstFree; i++)
  132. particles[i].update(deltaTime);
  133. }
  134. if (firstFree < firstActive) {
  135. for (i = firstActive; i < particles.length; i++)
  136. particles[i].update(deltaTime);
  137. for (i = 0; i < firstFree; i++)
  138. particles[i].update(deltaTime);
  139. }
  140. // remove inactive particles
  141. while (particles[firstActive].age >= duration && firstActive != firstFree) {
  142. firstActive++;
  143. if (firstActive == particles.length) firstActive = 0;
  144. }
  145. };
  146. ParticlePool.prototype.draw = function(context, image) {
  147. // draw active particles
  148. if (firstActive < firstFree) {
  149. for (i = firstActive; i < firstFree; i++)
  150. particles[i].draw(context, image);
  151. }
  152. if (firstFree < firstActive) {
  153. for (i = firstActive; i < particles.length; i++)
  154. particles[i].draw(context, image);
  155. for (i = 0; i < firstFree; i++)
  156. particles[i].draw(context, image);
  157. }
  158. };
  159. return ParticlePool;
  160. })();
  161. /*
  162. * Putting it all together
  163. */
  164. (function(canvas) {
  165. var context = canvas.getContext('2d'),
  166. particles = new ParticlePool(settings.particles.length),
  167. particleRate = settings.particles.length / settings.particles.duration, // particles/sec
  168. time;
  169. // get point on heart with -PI <= t <= PI
  170. function pointOnHeart(t) {
  171. return new Point(
  172. 160 * Math.pow(Math.sin(t), 3),
  173. 130 * Math.cos(t) - 50 * Math.cos(2 * t) - 20 * Math.cos(3 * t) - 10 * Math.cos(4 * t) + 25
  174. );
  175. }
  176. // creating the particle image using a dummy canvas
  177. var image = (function() {
  178. var canvas = document.createElement('canvas'),
  179. context = canvas.getContext('2d');
  180. canvas.width = settings.particles.size;
  181. canvas.height = settings.particles.size;
  182. // helper function to create the path
  183. function to(t) {
  184. var point = pointOnHeart(t);
  185. point.x = settings.particles.size / 2 + point.x * settings.particles.size / 350;
  186. point.y = settings.particles.size / 2 - point.y * settings.particles.size / 350;
  187. return point;
  188. }
  189. // create the path
  190. context.beginPath();
  191. var t = -Math.PI;
  192. var point = to(t);
  193. context.moveTo(point.x, point.y);
  194. while (t < Math.PI) {
  195. t += 0.01; // baby steps!
  196. point = to(t);
  197. context.lineTo(point.x, point.y);
  198. }
  199. context.closePath();
  200. // create the fill
  201. context.fillStyle = '#ea80b0';
  202. context.fill();
  203. // create the image
  204. var image = new Image();
  205. image.src = canvas.toDataURL();
  206. return image;
  207. })();
  208. // render that thing!
  209. function render() {
  210. // next animation frame
  211. requestAnimationFrame(render);
  212. // update time
  213. var newTime = new Date().getTime() / 1000,
  214. deltaTime = newTime - (time || newTime);
  215. time = newTime;
  216. // clear canvas
  217. context.clearRect(0, 0, canvas.width, canvas.height);
  218. // create new particles
  219. var amount = particleRate * deltaTime;
  220. for (var i = 0; i < amount; i++) {
  221. var pos = pointOnHeart(Math.PI - 2 * Math.PI * Math.random());
  222. var dir = pos.clone().length(settings.particles.velocity);
  223. particles.add(canvas.width / 2 + pos.x, canvas.height / 2 - pos.y, dir.x, -dir.y);
  224. }
  225. // update and draw particles
  226. particles.update(deltaTime);
  227. particles.draw(context, image);
  228. }
  229. // handle (re-)sizing of the canvas
  230. function onResize() {
  231. canvas.width = canvas.clientWidth;
  232. canvas.height = canvas.clientHeight;
  233. }
  234. window.onresize = onResize;
  235. // delay rendering bootstrap
  236. setTimeout(function() {
  237. onResize();
  238. render();
  239. }, 10);
  240. })(document.getElementById('pinkboard'));
  241. </script>
  242. </BODY>
  243. </HTML>

第二种效果图(有弹幕 ):

代码部分

代码如下仅供参考,可以直接拿去复制粘贴!

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>给王总的大爱心</title>
  8. <style>
  9. html,
  10. body {
  11. height: 100%;
  12. padding: 0;
  13. margin: 0;
  14. background: #000;
  15. }
  16. canvas {
  17. position: absolute;
  18. width: 100%;
  19. height: 100%;
  20. }
  21. .down {
  22. position: absolute;
  23. top: 50%;
  24. }
  25. </style>
  26. </head>
  27. <body>
  28. <canvas id="pinkboard"></canvas>
  29. <font size="6" color="pink">
  30. <marquee direction="down" scrollamount=5 class="down"></marquee>
  31. <marquee direction="left" scrollamount=5>爱琦琦</marquee>
  32. <marquee direction="right" scrollamount=5>爱宝贝</marquee>
  33. </font>
  34. <font size="6" color="pink">
  35. <marquee direction="left" scrollamount=5>爱老婆</marquee>
  36. <marquee direction="right" scrollamount=5>爱琦琦</marquee>
  37. </font>
  38. <font size="6" color="pink">
  39. <marquee direction="left" scrollamount=5>爱宝贝</marquee>
  40. <marquee direction="right" scrollamount=5>爱老婆</marquee>
  41. </font>
  42. <font size="6" color="pink">
  43. <marquee direction="left" scrollamount=5>爱老婆</marquee>
  44. <marquee direction="right" scrollamount=5>爱琦琦</marquee>
  45. </font>
  46. <font size="6" color="pink">
  47. <marquee direction="left" scrollamount=5>爱宝贝</marquee>
  48. <marquee direction="right" scrollamount=5>爱老婆</marquee>
  49. </font>
  50. <font size="6" color="pink">
  51. <marquee direction="left" scrollamount=5>爱老婆</marquee>
  52. <marquee direction="right" scrollamount=5>爱琦琦</marquee>
  53. </font>
  54. <font size="6" color="pink">
  55. <marquee direction="left" scrollamount=5>爱宝贝</marquee>
  56. <marquee direction="right" scrollamount=5>爱老婆</marquee>
  57. </font>
  58. <script>
  59. var settings = {
  60. particles: {
  61. length: 500,
  62. duration: 2,
  63. velocity: 100,
  64. effect: -0.75,
  65. size: 30,
  66. },
  67. };
  68. (function () { var b = 0; var c = ["ms", "moz", "webkit", "o"]; for (var a = 0; a < c.length && !window.requestAnimationFrame; ++a) { window.requestAnimationFrame = window[c[a] + "RequestAnimationFrame"]; window.cancelAnimationFrame = window[c[a] + "CancelAnimationFrame"] || window[c[a] + "CancelRequestAnimationFrame"] } if (!window.requestAnimationFrame) { window.requestAnimationFrame = function (h, e) { var d = new Date().getTime(); var f = Math.max(0, 16 - (d - b)); var g = window.setTimeout(function () { h(d + f) }, f); b = d + f; return g } } if (!window.cancelAnimationFrame) { window.cancelAnimationFrame = function (d) { clearTimeout(d) } } }());
  69. var Point = (function () {
  70. undefined
  71. function Point(x, y) {
  72. undefined
  73. this.x = (typeof x !== 'undefined') ? x : 0;
  74. this.y = (typeof y !== 'undefined') ? y : 0;
  75. }
  76. Point.prototype.clone = function () {
  77. undefined
  78. return new Point(this.x, this.y);
  79. };
  80. Point.prototype.length = function (length) {
  81. undefined
  82. if (typeof length == 'undefined')
  83. return Math.sqrt(this.x * this.x + this.y * this.y);
  84. this.normalize();
  85. this.x *= length;
  86. this.y *= length;
  87. return this;
  88. };
  89. Point.prototype.normalize = function () {
  90. undefined
  91. var length = this.length();
  92. this.x /= length;
  93. this.y /= length;
  94. return this;
  95. };
  96. return Point;
  97. })();
  98. var Particle = (function () {
  99. undefined
  100. function Particle() {
  101. undefined
  102. this.position = new Point();
  103. this.velocity = new Point();
  104. this.acceleration = new Point();
  105. this.age = 0;
  106. }
  107. Particle.prototype.initialize = function (x, y, dx, dy) {
  108. undefined
  109. this.position.x = x;
  110. this.position.y = y;
  111. this.velocity.x = dx;
  112. this.velocity.y = dy;
  113. this.acceleration.x = dx * settings.particles.effect;
  114. this.acceleration.y = dy * settings.particles.effect;
  115. this.age = 0;
  116. };
  117. Particle.prototype.update = function (deltaTime) {
  118. undefined
  119. this.position.x += this.velocity.x * deltaTime;
  120. this.position.y += this.velocity.y * deltaTime;
  121. this.velocity.x += this.acceleration.x * deltaTime;
  122. this.velocity.y += this.acceleration.y * deltaTime;
  123. this.age += deltaTime;
  124. };
  125. Particle.prototype.draw = function (context, image) {
  126. undefined
  127. function ease(t) {
  128. undefined
  129. return (--t) * t * t + 1;
  130. }
  131. var size = image.width * ease(this.age / settings.particles.duration);
  132. context.globalAlpha = 1 - this.age / settings.particles.duration;
  133. context.drawImage(image, this.position.x - size / 2, this.position.y - size / 2, size, size);
  134. };
  135. return Particle;
  136. })();
  137. var ParticlePool = (function () {
  138. undefined
  139. var particles,
  140. firstActive = 0,
  141. firstFree = 0,
  142. duration = settings.particles.duration;
  143. function ParticlePool(length) {
  144. undefined
  145. particles = new Array(length);
  146. for (var i = 0; i < particles.length; i++)
  147. particles[i] = new Particle();
  148. }
  149. ParticlePool.prototype.add = function (x, y, dx, dy) {
  150. undefined
  151. particles[firstFree].initialize(x, y, dx, dy);
  152. firstFree++;
  153. if (firstFree == particles.length) firstFree = 0;
  154. if (firstActive == firstFree) firstActive++;
  155. if (firstActive == particles.length) firstActive = 0;
  156. };
  157. ParticlePool.prototype.update = function (deltaTime) {
  158. undefined
  159. var i;
  160. if (firstActive < firstFree) {
  161. undefined
  162. for (i = firstActive; i < firstFree; i++)
  163. particles[i].update(deltaTime);
  164. }
  165. if (firstFree < firstActive) {
  166. undefined
  167. for (i = firstActive; i < particles.length; i++)
  168. particles[i].update(deltaTime);
  169. for (i = 0; i < firstFree; i++)
  170. particles[i].update(deltaTime);
  171. }
  172. while (particles[firstActive].age >= duration && firstActive != firstFree) {
  173. undefined
  174. firstActive++;
  175. if (firstActive == particles.length) firstActive = 0;
  176. }
  177. };
  178. ParticlePool.prototype.draw = function (context, image) {
  179. undefined
  180. if (firstActive < firstFree) {
  181. undefined
  182. for (i = firstActive; i < firstFree; i++)
  183. particles[i].draw(context, image);
  184. }
  185. if (firstFree < firstActive) {
  186. undefined
  187. for (i = firstActive; i < particles.length; i++)
  188. particles[i].draw(context, image);
  189. for (i = 0; i < firstFree; i++)
  190. particles[i].draw(context, image);
  191. }
  192. };
  193. return ParticlePool;
  194. })();
  195. (function (canvas) {
  196. undefined
  197. var context = canvas.getContext('2d'),
  198. particles = new ParticlePool(settings.particles.length),
  199. particleRate = settings.particles.length / settings.particles.duration,
  200. time;
  201. function pointOnHeart(t) {
  202. undefined
  203. return new Point(
  204. 160 * Math.pow(Math.sin(t), 3),
  205. 130 * Math.cos(t) - 50 * Math.cos(2 * t) - 20 * Math.cos(3 * t) - 10 * Math.cos(4 * t) + 25
  206. );
  207. }
  208. var image = (function () {
  209. undefined
  210. var canvas = document.createElement('canvas'),
  211. context = canvas.getContext('2d');
  212. canvas.width = settings.particles.size;
  213. canvas.height = settings.particles.size;
  214. function to(t) {
  215. undefined
  216. var point = pointOnHeart(t);
  217. point.x = settings.particles.size / 2 + point.x * settings.particles.size / 350;
  218. point.y = settings.particles.size / 2 - point.y * settings.particles.size / 350;
  219. return point;
  220. }
  221. context.beginPath();
  222. var t = -Math.PI;
  223. var point = to(t);
  224. context.moveTo(point.x, point.y);
  225. while (t < Math.PI) {
  226. undefined
  227. t += 0.01;
  228. point = to(t);
  229. context.lineTo(point.x, point.y);
  230. }
  231. context.closePath();
  232. context.fillStyle = '#ea80b0';
  233. context.fill();
  234. var image = new Image();
  235. image.src = canvas.toDataURL();
  236. return image;
  237. })();
  238. function render() {
  239. undefined
  240. requestAnimationFrame(render);
  241. var newTime = new Date().getTime() / 1000,
  242. deltaTime = newTime - (time || newTime);
  243. time = newTime;
  244. context.clearRect(0, 0, canvas.width, canvas.height);
  245. var amount = particleRate * deltaTime;
  246. for (var i = 0; i < amount; i++) {
  247. undefined
  248. var pos = pointOnHeart(Math.PI - 2 * Math.PI * Math.random());
  249. var dir = pos.clone().length(settings.particles.velocity);
  250. particles.add(canvas.width / 2 + pos.x, canvas.height / 2 - pos.y, dir.x, -dir.y);
  251. }
  252. particles.update(deltaTime);
  253. particles.draw(context, image);
  254. }
  255. function onResize() {
  256. undefined
  257. canvas.width = canvas.clientWidth;
  258. canvas.height = canvas.clientHeight;
  259. }
  260. window.onresize = onResize;
  261. setTimeout(function () {
  262. undefined
  263. onResize();
  264. render();
  265. }, 10);
  266. })(document.getElementById('pinkboard'));
  267. </script>
  268. </body>
  269. </html>

第三种效果图:

HTML部分:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <title>流动爱心表白</title>
  6. <link rel="stylesheet" href="css/style.css" />
  7. </head>
  8. <body>
  9. <!-- 绘画爱心 -->
  10. <canvas id="canvas" width="1400" height="600"></canvas>
  11. <!-- js部分 -->
  12. <script src="js/script.js"></script>
  13. </body>
  14. </html>

JS部分:

  1. var canvas = document.getElementById("canvas");
  2. canvas.width = window.innerWidth;
  3. canvas.height = window.innerHeight;
  4. // Initialize the GL context
  5. var gl = canvas.getContext('webgl');
  6. if (!gl) {
  7. console.error("Unable to initialize WebGL.");
  8. }
  9. //Time step
  10. var dt = 0.015;
  11. //Time
  12. var time = 0.0;
  13. //************** Shader sources **************
  14. var vertexSource = `
  15. attribute vec2 position;
  16. void main() {
  17. gl_Position = vec4(position, 0.0, 1.0);
  18. }
  19. `;
  20. var fragmentSource = `
  21. precision highp float;
  22. uniform float width;
  23. uniform float height;
  24. vec2 resolution = vec2(width, height);
  25. uniform float time;
  26. #define POINT_COUNT 8
  27. vec2 points[POINT_COUNT];
  28. const float speed = -0.5;
  29. const float len = 0.25;
  30. float intensity = 0.9;
  31. float radius = 0.015;
  32. //https://www.shadertoy.com/view/MlKcDD
  33. //Signed distance to a quadratic bezier
  34. float sdBezier(vec2 pos, vec2 A, vec2 B, vec2 C){
  35. vec2 a = B - A;
  36. vec2 b = A - 2.0*B + C;
  37. vec2 c = a * 2.0;
  38. vec2 d = A - pos;
  39. float kk = 1.0 / dot(b,b);
  40. float kx = kk * dot(a,b);
  41. float ky = kk * (2.0*dot(a,a)+dot(d,b)) / 3.0;
  42. float kz = kk * dot(d,a);
  43. float res = 0.0;
  44. float p = ky - kx*kx;
  45. float p3 = p*p*p;
  46. float q = kx*(2.0*kx*kx - 3.0*ky) + kz;
  47. float h = q*q + 4.0*p3;
  48. if(h >= 0.0){
  49. h = sqrt(h);
  50. vec2 x = (vec2(h, -h) - q) / 2.0;
  51. vec2 uv = sign(x)*pow(abs(x), vec2(1.0/3.0));
  52. float t = uv.x + uv.y - kx;
  53. t = clamp( t, 0.0, 1.0 );
  54. // 1 root
  55. vec2 qos = d + (c + b*t)*t;
  56. res = length(qos);
  57. }else{
  58. float z = sqrt(-p);
  59. float v = acos( q/(p*z*2.0) ) / 3.0;
  60. float m = cos(v);
  61. float n = sin(v)*1.732050808;
  62. vec3 t = vec3(m + m, -n - m, n - m) * z - kx;
  63. t = clamp( t, 0.0, 1.0 );
  64. // 3 roots
  65. vec2 qos = d + (c + b*t.x)*t.x;
  66. float dis = dot(qos,qos);
  67. res = dis;
  68. qos = d + (c + b*t.y)*t.y;
  69. dis = dot(qos,qos);
  70. res = min(res,dis);
  71. qos = d + (c + b*t.z)*t.z;
  72. dis = dot(qos,qos);
  73. res = min(res,dis);
  74. res = sqrt( res );
  75. }
  76. return res;
  77. }
  78. //http://mathworld.wolfram.com/HeartCurve.html
  79. vec2 getHeartPosition(float t){
  80. return vec2(16.0 * sin(t) * sin(t) * sin(t),
  81. -(13.0 * cos(t) - 5.0 * cos(2.0*t)
  82. - 2.0 * cos(3.0*t) - cos(4.0*t)));
  83. }
  84. //https://www.shadertoy.com/view/3s3GDn
  85. float getGlow(float dist, float radius, float intensity){
  86. return pow(radius/dist, intensity);
  87. }
  88. float getSegment(float t, vec2 pos, float offset, float scale){
  89. for(int i = 0; i < POINT_COUNT; i++){
  90. points[i] = getHeartPosition(offset + float(i)*len + fract(speed * t) * 6.28);
  91. }
  92. vec2 c = (points[0] + points[1]) / 2.0;
  93. vec2 c_prev;
  94. float dist = 10000.0;
  95. for(int i = 0; i < POINT_COUNT-1; i++){
  96. //https://tinyurl.com/y2htbwkm
  97. c_prev = c;
  98. c = (points[i] + points[i+1]) / 2.0;
  99. dist = min(dist, sdBezier(pos, scale * c_prev, scale * points[i], scale * c));
  100. }
  101. return max(0.0, dist);
  102. }
  103. void main(){
  104. vec2 uv = gl_FragCoord.xy/resolution.xy;
  105. float widthHeightRatio = resolution.x/resolution.y;
  106. vec2 centre = vec2(0.5, 0.5);
  107. vec2 pos = centre - uv;
  108. pos.y /= widthHeightRatio;
  109. //Shift upwards to centre heart
  110. pos.y += 0.02;
  111. float scale = 0.000015 * height;
  112. float t = time;
  113. //Get first segment
  114. float dist = getSegment(t, pos, 0.0, scale);
  115. float glow = getGlow(dist, radius, intensity);
  116. vec3 col = vec3(0.0);
  117. //White core
  118. col += 10.0*vec3(smoothstep(0.003, 0.001, dist));
  119. //Pink glow
  120. col += glow * vec3(0.94,0.14,0.4);
  121. //Get second segment
  122. dist = getSegment(t, pos, 3.4, scale);
  123. glow = getGlow(dist, radius, intensity);
  124. //White core
  125. col += 10.0*vec3(smoothstep(0.003, 0.001, dist));
  126. //Blue glow
  127. col += glow * vec3(0.2,0.6,1.0);
  128. //Tone mapping
  129. col = 1.0 - exp(-col);
  130. //Output to screen
  131. gl_FragColor = vec4(col,1.0);
  132. }
  133. `;
  134. //************** Utility functions **************
  135. window.addEventListener('resize', onWindowResize, false);
  136. function onWindowResize() {
  137. canvas.width = window.innerWidth;
  138. canvas.height = window.innerHeight;
  139. gl.viewport(0, 0, canvas.width, canvas.height);
  140. gl.uniform1f(widthHandle, window.innerWidth);
  141. gl.uniform1f(heightHandle, window.innerHeight);
  142. }
  143. //Compile shader and combine with source
  144. function compileShader(shaderSource, shaderType) {
  145. var shader = gl.createShader(shaderType);
  146. gl.shaderSource(shader, shaderSource);
  147. gl.compileShader(shader);
  148. if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
  149. throw "Shader compile failed with: " + gl.getShaderInfoLog(shader);
  150. }
  151. return shader;
  152. }
  153. //From https://codepen.io/jlfwong/pen/GqmroZ
  154. //Utility to complain loudly if we fail to find the attribute/uniform
  155. function getAttribLocation(program, name) {
  156. var attributeLocation = gl.getAttribLocation(program, name);
  157. if (attributeLocation === -1) {
  158. throw 'Cannot find attribute ' + name + '.';
  159. }
  160. return attributeLocation;
  161. }
  162. function getUniformLocation(program, name) {
  163. var attributeLocation = gl.getUniformLocation(program, name);
  164. if (attributeLocation === -1) {
  165. throw 'Cannot find uniform ' + name + '.';
  166. }
  167. return attributeLocation;
  168. }
  169. //************** Create shaders **************
  170. //Create vertex and fragment shaders
  171. var vertexShader = compileShader(vertexSource, gl.VERTEX_SHADER);
  172. var fragmentShader = compileShader(fragmentSource, gl.FRAGMENT_SHADER);
  173. //Create shader programs
  174. var program = gl.createProgram();
  175. gl.attachShader(program, vertexShader);
  176. gl.attachShader(program, fragmentShader);
  177. gl.linkProgram(program);
  178. gl.useProgram(program);
  179. //Set up rectangle covering entire canvas
  180. var vertexData = new Float32Array([-1.0, 1.0, // top left
  181. -1.0, -1.0, // bottom left
  182. 1.0, 1.0, // top right
  183. 1.0, -1.0, // bottom right
  184. ]);
  185. //Create vertex buffer
  186. var vertexDataBuffer = gl.createBuffer();
  187. gl.bindBuffer(gl.ARRAY_BUFFER, vertexDataBuffer);
  188. gl.bufferData(gl.ARRAY_BUFFER, vertexData, gl.STATIC_DRAW);
  189. // Layout of our data in the vertex buffer
  190. var positionHandle = getAttribLocation(program, 'position');
  191. gl.enableVertexAttribArray(positionHandle);
  192. gl.vertexAttribPointer(positionHandle,
  193. 2, // position is a vec2 (2 values per component)
  194. gl.FLOAT, // each component is a float
  195. false, // don't normalize values
  196. 2 * 4, // two 4 byte float components per vertex (32 bit float is 4 bytes)
  197. 0 // how many bytes inside the buffer to start from
  198. );
  199. //Set uniform handle
  200. var timeHandle = getUniformLocation(program, 'time');
  201. var widthHandle = getUniformLocation(program, 'width');
  202. var heightHandle = getUniformLocation(program, 'height');
  203. gl.uniform1f(widthHandle, window.innerWidth);
  204. gl.uniform1f(heightHandle, window.innerHeight);
  205. function draw() {
  206. //Update time
  207. time += dt;
  208. //Send uniforms to program
  209. gl.uniform1f(timeHandle, time);
  210. //Draw a triangle strip connecting vertices 0-4
  211. gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  212. requestAnimationFrame(draw);
  213. }
  214. draw();

CSS部分:

  1. body {
  2. background-color: #000;
  3. margin: 0;
  4. overflow: hidden;
  5. background-repeat: no-repeat;
  6. }

好啦,本次分享就到这里,祝大家开心~


本文转载自: https://blog.csdn.net/qq_44794321/article/details/127719490
版权归原作者 木易巷 所有, 如有侵权,请联系我们删除。

“炫酷的流动爱心最近很火 来吧 代码已奉上”的评论:

还没有评论