JavaScript Canvas实现复杂酷炫的爱心表白用

简介: JavaScript Canvas实现复杂酷炫的爱心表白用

Snipaste_2022-04-24_12-29-24.jpg

👨🏻‍🎓博主介绍:大家好,我是芝士味的椒盐,一名在校大学生,热爱分享知识,很高兴在这里认识大家🌟

🌈擅长领域:Java、大数据、运维、电子

🙏🏻如果本文章各位小伙伴们有帮助的话,🍭关注+👍🏻点赞+🗣评论+📦收藏,相应的有空了我也会回访,互助!!!

🤝另本人水平有限,旨在创作简单易懂的文章,在文章描述时如有错,恳请各位大佬指正,在此感谢!!!


浏览器动态演示

源码

<!doctypehtml><html><head><metacharset="utf-8"><title>酷炫爱心表白</title><style>body {
background-color: #000;    margin: 0;
overflow: hidden;
background-repeat: no-repeat;
}</style></head><body><canvasid="canvas"width="1400"height="600"></canvas><script>varcanvas=document.getElementById("canvas");
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
// Initialize the GL contextvargl=canvas.getContext('webgl');
if(!gl){
console.error("Unable to initialize WebGL.");
}
//Timevartime=0.0;
//************** Shader sources **************varvertexSource=`attribute vec2 position;void main() {gl_Position = vec4(position, 0.0, 1.0);}`;
varfragmentSource=`precision highp float;uniform float width;uniform float height;vec2 resolution = vec2(width, height);uniform float time;#define POINT_COUNT 8vec2 points[POINT_COUNT];const float speed = -0.5;const float len = 0.25;float intensity = 1.3;float radius = 0.008;//https://www.shadertoy.com/view/MlKcDD//Signed distance to a quadratic bezierfloat sdBezier(vec2 pos, vec2 A, vec2 B, vec2 C){    vec2 a = B - A;vec2 b = A - 2.0*B + C;vec2 c = a * 2.0;vec2 d = A - pos;float kk = 1.0 / dot(b,b);float kx = kk * dot(a,b);float ky = kk * (2.0*dot(a,a)+dot(d,b)) / 3.0;float kz = kk * dot(d,a);      float res = 0.0;float p = ky - kx*kx;float p3 = p*p*p;float q = kx*(2.0*kx*kx - 3.0*ky) + kz;float h = q*q + 4.0*p3;if(h >= 0.0){ h = sqrt(h);vec2 x = (vec2(h, -h) - q) / 2.0;vec2 uv = sign(x)*pow(abs(x), vec2(1.0/3.0));float t = uv.x + uv.y - kx;t = clamp( t, 0.0, 1.0 );// 1 rootvec2 qos = d + (c + b*t)*t;res = length(qos);}else{float z = sqrt(-p);float v = acos( q/(p*z*2.0) ) / 3.0;float m = cos(v);float n = sin(v)*1.732050808;vec3 t = vec3(m + m, -n - m, n - m) * z - kx;t = clamp( t, 0.0, 1.0 );// 3 rootsvec2 qos = d + (c + b*t.x)*t.x;float dis = dot(qos,qos);res = dis;qos = d + (c + b*t.y)*t.y;dis = dot(qos,qos);res = min(res,dis);qos = d + (c + b*t.z)*t.z;dis = dot(qos,qos);res = min(res,dis);res = sqrt( res );}return res;}//http://mathworld.wolfram.com/HeartCurve.htmlvec2 getHeartPosition(float t){return vec2(16.0 * sin(t) * sin(t) * sin(t),-(13.0 * cos(t) - 5.0 * cos(2.0*t)- 2.0 * cos(3.0*t) - cos(4.0*t)));}//https://www.shadertoy.com/view/3s3GDnfloat getGlow(float dist, float radius, float intensity){return pow(radius/dist, intensity);}float getSegment(float t, vec2 pos, float offset, float scale){for(int i = 0; i < POINT_COUNT; i++){points[i] = getHeartPosition(offset + float(i)*len + fract(speed * t) * 6.28);}vec2 c = (points[0] + points[1]) / 2.0;vec2 c_prev;float dist = 10000.0;for(int i = 0; i < POINT_COUNT-1; i++){//https://tinyurl.com/y2htbwkmc_prev = c;c = (points[i] + points[i+1]) / 2.0;dist = min(dist, sdBezier(pos, scale * c_prev, scale * points[i], scale * c));}return max(0.0, dist);}void main(){vec2 uv = gl_FragCoord.xy/resolution.xy;float widthHeightRatio = resolution.x/resolution.y;vec2 centre = vec2(0.5, 0.5);vec2 pos = centre - uv;pos.y /= widthHeightRatio;//Shift upwards to centre heartpos.y += 0.02;float scale = 0.000015 * height;float t = time;//Get first segmentfloat dist = getSegment(t, pos, 0.0, scale);float glow = getGlow(dist, radius, intensity);vec3 col = vec3(0.0);//White corecol += 10.0*vec3(smoothstep(0.003, 0.001, dist));//Pink glowcol += glow * vec3(1.0,0.05,0.3);//Get second segmentdist = getSegment(t, pos, 3.4, scale);glow = getGlow(dist, radius, intensity);//White corecol += 10.0*vec3(smoothstep(0.003, 0.001, dist));//Blue glowcol += glow * vec3(0.1,0.4,1.0);//Tone mappingcol = 1.0 - exp(-col);//Gammacol = pow(col, vec3(0.4545));//Output to screengl_FragColor = vec4(col,1.0);}`;
//************** Utility functions **************window.addEventListener('resize', onWindowResize, false);
functiononWindowResize(){
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
gl.viewport(0, 0, canvas.width, canvas.height);
gl.uniform1f(widthHandle, window.innerWidth);
gl.uniform1f(heightHandle, window.innerHeight);
}
//Compile shader and combine with sourcefunctioncompileShader(shaderSource, shaderType){
varshader=gl.createShader(shaderType);
gl.shaderSource(shader, shaderSource);
gl.compileShader(shader);
if(!gl.getShaderParameter(shader, gl.COMPILE_STATUS)){
throw"Shader compile failed with: "+gl.getShaderInfoLog(shader);
  }
returnshader;
}
//From https://codepen.io/jlfwong/pen/GqmroZ//Utility to complain loudly if we fail to find the attribute/uniformfunctiongetAttribLocation(program, name) {
varattributeLocation=gl.getAttribLocation(program, name);
if (attributeLocation===-1) {
throw'Cannot find attribute '+name+'.';
  }
returnattributeLocation;
}
functiongetUniformLocation(program, name) {
varattributeLocation=gl.getUniformLocation(program, name);
if (attributeLocation===-1) {
throw'Cannot find uniform '+name+'.';
  }
returnattributeLocation;
}
//************** Create shaders **************//Create vertex and fragment shadersvarvertexShader=compileShader(vertexSource, gl.VERTEX_SHADER);
varfragmentShader=compileShader(fragmentSource, gl.FRAGMENT_SHADER);
//Create shader programsvarprogram=gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
//Set up rectangle covering entire canvas varvertexData=newFloat32Array([
-1.0,  1.0,   // top left-1.0, -1.0,   // bottom left1.0,  1.0,   // top right1.0, -1.0,   // bottom right]);
//Create vertex buffervarvertexDataBuffer=gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexDataBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertexData, gl.STATIC_DRAW);
// Layout of our data in the vertex buffervarpositionHandle=getAttribLocation(program, 'position');
gl.enableVertexAttribArray(positionHandle);
gl.vertexAttribPointer(positionHandle,
2,        // position is a vec2 (2 values per component)gl.FLOAT, // each component is a floatfalse,    // don't normalize values2*4,    // two 4 byte float components per vertex (32 bit float is 4 bytes)0// how many bytes inside the buffer to start from  );
//Set uniform handlevartimeHandle=getUniformLocation(program, 'time');
varwidthHandle=getUniformLocation(program, 'width');
varheightHandle=getUniformLocation(program, 'height');
gl.uniform1f(widthHandle, window.innerWidth);
gl.uniform1f(heightHandle, window.innerHeight);
varlastFrame=Date.now();
varthisFrame;
functiondraw(){
//Update timethisFrame=Date.now();
time+= (thisFrame-lastFrame)/1000; 
lastFrame=thisFrame;
//Send uniforms to programgl.uniform1f(timeHandle, time);
//Draw a triangle strip connecting vertices 0-4gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
requestAnimationFrame(draw);
}
draw();
</script></body></html>
相关文章
|
5月前
|
移动开发 前端开发 JavaScript
纯JavaScript实现HTML5 Canvas六种特效滤镜
纯JavaScript实现HTML5 Canvas六种特效滤镜
166 6
|
6月前
|
前端开发 JavaScript
验证码(原生js加canvas绘图)
验证码(原生js加canvas绘图)
37 0
|
6月前
|
前端开发 JavaScript
纯样式或使用JS的canvas实现图片旋转
纯样式或使用JS的canvas实现图片旋转
95 0
|
4月前
|
移动开发 前端开发 JavaScript
使用JavaScript和Canvas进行绘图
Canvas是HTML5的绘图工具,借助JavaScript实现网页上的图形、图像及动画创作。通过Canvas元素和2D渲染上下文,开发者能绘制图形、处理图像、制作动画,甚至用于游戏开发。基本步骤包括获取Canvas元素、设置绘图属性、绘制形状、处理图像以及实现动画。同时,注意性能优化,如减少不必要的重绘和使用Web Workers。Canvas结合WebGL还能实现3D效果,与Web Audio API结合则能做音频可视化。分享你的Canvas经验,探讨更多创意应用!
39 0
|
2月前
|
移动开发 前端开发 JavaScript
JS配合canvas实现贪吃蛇小游戏_升级_丝滑版本_支持PC端和移动端
本文介绍了一个使用JavaScript和HTML5 Canvas API实现的贪吃蛇游戏的升级版本,该版本支持PC端和移动端,提供了丝滑的转向效果,并允许玩家通过键盘或触摸屏控制蛇的移动。代码中包含了详细的注释,解释了游戏逻辑、食物生成、得分机制以及如何响应不同的输入设备。
58 1
JS配合canvas实现贪吃蛇小游戏_升级_丝滑版本_支持PC端和移动端
|
5月前
|
Web App开发 移动开发 前端开发
技术经验分享:canvas+howler.js解决同页面视频、音频同时播放问题
技术经验分享:canvas+howler.js解决同页面视频、音频同时播放问题
150 0
|
2月前
|
移动开发 前端开发 JavaScript
js之Canvas|2-1
js之Canvas|2-1
|
2月前
|
移动开发 前端开发 JavaScript
JS配合canvas实现贪吃蛇小游戏
本文通过详细的代码示例介绍了如何使用JavaScript和HTML5的Canvas API实现一个贪吃蛇游戏,包括蛇的移动、食物的生成、游戏的开始与结束逻辑,以及如何响应键盘事件来控制蛇的方向。
47 1
|
2月前
|
移动开发 前端开发 JavaScript
原生JavaScript+canvas实现五子棋游戏_值得一看
本文介绍了如何使用原生JavaScript和HTML5的Canvas API实现五子棋游戏,包括棋盘的绘制、棋子的生成和落子、以及判断胜负的逻辑,提供了详细的代码和注释。
36 0
原生JavaScript+canvas实现五子棋游戏_值得一看
|
6月前
|
JavaScript 前端开发
将base64格式的图片画到canvas上(js和vue两种)
将base64格式的图片画到canvas上(js和vue两种)
483 1