粒子连线效果(业余学习"/>
粒子连线效果(业余学习
看到很多这个效果,所以试着实现下
1、从网上一个博客看到的(找不到网址了。。)
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Starry</title>
</head>
<body><div style="position: fixed;top: 0;left:0;bottom: 0;right: 0;z-index: 0"><canvas id="canvas" style="background-color: rgb(255,255,255);"></canvas></div><script type="text/javascript">const canvas = document.getElementById('canvas')const ctx = canvas.getContext('2d')let width = window.innerWidthlet height = window.innerHeightlet dotsNum = 80 // 点的数量let radius = 1 // 圆的半径,连接线宽度的一半let fillStyle = 'rgba(255,255,255,0.5)' // 点的颜色let lineWidth = radius * 2let connection = 120 // 连线最大距离let followLength = 80 // 鼠标跟随距离let dots = []let animationFrame = nulllet mouseX = nulllet mouseY = nullfunction addCanvasSize () { // 改变画布尺寸width = window.innerWidthheight = window.innerHeightcanvas.width = widthcanvas.height = heightctx.clearRect(0, 0, width, height)dots = []if (animationFrame) window.cancelAnimationFrame(animationFrame)initDots(dotsNum)moveDots()}function mouseMove (e) {mouseX = e.clientXmouseY = e.clientY}function mouseOut (e) {mouseX = nullmouseY = null}function mouseClick () {for (const dot of dots) dot.elastic()}class Dot {constructor(x, y) {this.x = xthis.y = ythis.speedX = Math.random() * 2 - 1this.speedY = Math.random() * 2 - 1this.follow = false}draw () {ctx.beginPath()ctx.arc(this.x, this.y, radius, 0, 2 * Math.PI)ctx.fill()ctx.closePath()}move () {if (this.x >= width || this.x <= 0) this.speedX = -this.speedXif (this.y >= height || this.y <= 0) this.speedY = -this.speedYthis.x += this.speedXthis.y += this.speedYif (this.speedX >= 1) this.speedX--if (this.speedX <= -1) this.speedX++if (this.speedY >= 1) this.speedY--if (this.speedY <= -1) this.speedY++this.correct()this.connectMouse()this.draw()}correct () { // 根据鼠标的位置修正if (!mouseX || !mouseY) returnlet lengthX = mouseX - this.xlet lengthY = mouseY - this.yconst distance = Math.sqrt(lengthX ** 2 + lengthY ** 2)if (distance <= followLength) this.follow = trueelse if (this.follow === true && distance > followLength && distance <= followLength + 8) {let proportion = followLength / distancelengthX *= proportionlengthY *= proportionthis.x = mouseX - lengthXthis.y = mouseY - lengthY} else this.follow = false}connectMouse () { // 点与鼠标连线if (mouseX && mouseY) {let lengthX = mouseX - this.xlet lengthY = mouseY - this.yconst distance = Math.sqrt(lengthX ** 2 + lengthY ** 2)if (distance <= connection) {opacity = (1 - distance / connection) * 0.5ctx.strokeStyle = `rgba(0,0,0,${opacity})`ctx.beginPath()ctx.moveTo(this.x, this.y)ctx.lineTo(mouseX, mouseY);ctx.stroke();ctx.closePath()}}}elastic () { // 鼠标点击后的弹射let lengthX = mouseX - this.xlet lengthY = mouseY - this.yconst distance = Math.sqrt(lengthX ** 2 + lengthY ** 2)if (distance >= connection) returnconst rate = 1 - distance / connection // 距离越小此值约接近1this.speedX = 40 * rate * -lengthX / distancethis.speedY = 40 * rate * -lengthY / distance}}function initDots (num) { // 初始化粒子ctx.fillStyle = fillStylectx.lineWidth = lineWidthfor (let i = 0; i < num; i++) {const x = Math.floor(Math.random() * width)const y = Math.floor(Math.random() * height)const dot = new Dot(x, y)dot.draw()dots.push(dot)}}function moveDots () { // 移动并建立点与点之间的连接线ctx.clearRect(0, 0, width, height)for (const dot of dots) {dot.move()}for (let i = 0; i < dots.length; i++) {for (let j = i; j < dots.length; j++) {const distance = Math.sqrt((dots[i].x - dots[j].x) ** 2 + (dots[i].y - dots[j].y) ** 2)if (distance <= connection) {opacity = (1 - distance / connection) * 0.5ctx.strokeStyle = `rgba(110, 106, 106,${opacity})`ctx.beginPath()ctx.moveTo(dots[i].x, dots[i].y)ctx.lineTo(dots[j].x, dots[j].y);ctx.stroke();ctx.closePath()}}}animationFrame = window.requestAnimationFrame(moveDots)}addCanvasSize()initDots(dotsNum)moveDots()document.onmousemove = mouseMovedocument.onmouseout = mouseOutdocument.onclick = mouseClickwindow.onresize = addCanvasSize
</script>
</body>
</html>
2、后来知道了particles.js
简单引用这样,源文件官网能下
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>smart-line</title><meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"><link rel="stylesheet" media="screen" href="css/style.css">
</head>
<body><div id="particles-js"></div>
<script src="js/particles.min.js"></script>
<script src="js/app.js"></script></body>
</html>
app.js
/* -----------------------------------------------
/* How to use? : Check the GitHub README
/* ----------------------------------------------- *//* To load a config file (particles.json) you need to host this demo (MAMP/WAMP/local)... */
/*
particlesJS.load('particles-js', 'particles.json', function() {console.log('particles.js loaded - callback');
});
*//* Otherwise just put the config content (json): */particlesJS('particles-js',{"particles": {"number": {"value": 30,"density": {"enable": true,"value_area": 800}},"color": {"value": "#ffffff"},"shape": {"type": "circle","stroke": {"width": 0,"color": "#000000"},"polygon": {"nb_sides": 5},"image": {"src": "img/github.svg","width": 100,"height": 100}},"opacity": {"value": 0.5,"random": false,"anim": {"enable": false,"speed": 1,"opacity_min": 0.1,"sync": false}},"size": {"value": 5,"random": true,"anim": {"enable": false,"speed": 40,"size_min": 0.1,"sync": false}},"line_linked": {"enable": true,"distance": 150,"color": "#ffffff","opacity": 0.4,"width": 1},"move": {"enable": true,"speed": 6,"direction": "none","random": false,"straight": false,"out_mode": "out","attract": {"enable": false,"rotateX": 600,"rotateY": 1200}}},"interactivity": {"detect_on": "canvas","events": {"onhover": {"enable": true,"mode": "repulse"},"onclick": {"enable": true,"mode": "push"},"resize": true},"modes": {"grab": {"distance": 400,"line_linked": {"opacity": 1}},"bubble": {"distance": 400,"size": 40,"duration": 2,"opacity": 8,"speed": 3},"repulse": {"distance": 200},"push": {"particles_nb": 4},"remove": {"particles_nb": 2}}},"retina_detect": true,"config_demo": {"hide_card": false,"background_color": "#4B0082","background_image": "","background_position": "50% 50%","background_repeat": "no-repeat","background_size": "cover"}}// {// "particles": {// "number": {// "value": 160,// "density": {// "enable": true,// "value_area": 800// }// },// "color": {// "value": "#ffffff"// },// "shape": {// "type": "circle",// "stroke": {// "width": 0,// "color": "#000000"// },// "polygon": {// "nb_sides": 5// },// "image": {// "src": "img/github.svg",// "width": 100,// "height": 100// }// },// "opacity": {// "value": 1,// "random": true,// "anim": {// "enable": true,// "speed": 1,// "opacity_min": 0,// "sync": false// }// },// "size": {// "value": 3,// "random": true,// "anim": {// "enable": false,// "speed": 4,// "size_min": 0.3,// "sync": false// }// },// "line_linked": {// "enable": false,// "distance": 150,// "color": "#ffffff",// "opacity": 0.4,// "width": 1// },// "move": {// "enable": true,// "speed": 1,// "direction": "none",// "random": true,// "straight": false,// "out_mode": "out",// "bounce": false,// "attract": {// "enable": false,// "rotateX": 600,// "rotateY": 600// }// }// },// "interactivity": {// "detect_on": "canvas",// "events": {// "onhover": {// "enable": true,// "mode": "bubble"// },// "onclick": {// "enable": true,// "mode": "repulse"// },// "resize": true// },// "modes": {// "grab": {// "distance": 400,// "line_linked": {// "opacity": 1// }// },// "bubble": {// "distance": 250,// "size": 0,// "duration": 2,// "opacity": 0,// "speed": 3// },// "repulse": {// "distance": 400,// "duration": 0.4// },// "push": {// "particles_nb": 4// },// "remove": {// "particles_nb": 2// }// }// },// "retina_detect": true// });
style.css
/* =============================================================================HTML5 CSS Reset Minified - Eric Meyer========================================================================== */html,body,div,span,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,abbr,address,cite,code,del,dfn,em,img,ins,kbd,q,samp,small,strong,sub,sup,var,b,i,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,figcaption,figure,footer,header,hgroup,menu,nav,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent}
body{line-height:1}
article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}
nav ul{list-style:none}
blockquote,q{quotes:none}
blockquote:before,blockquote:after,q:before,q:after{content:none}
a{margin:0;padding:0;font-size:100%;vertical-align:baseline;background:transparent;text-decoration:none}
mark{background-color:#ff9;color:#000;font-style:italic;font-weight:bold}
del{text-decoration:line-through}
abbr[title],dfn[title]{border-bottom:1px dotted;cursor:help}
table{border-collapse:collapse;border-spacing:0}
hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0}
input,select{vertical-align:middle}
li{list-style:none}/* =============================================================================My CSS========================================================================== *//* ---- base ---- */html,body{ width:100%;height:100%;background:#111;
}html{-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}body{font:normal 75% Arial, Helvetica, sans-serif;
}canvas{display:block;vertical-align:bottom;
}/* ---- particles.js container ---- */#particles-js{width: 100%;height: 100%;background-color: #000;background-image: url('');background-size: cover;background-position: 50% 50%;background-repeat: no-repeat;
}
3、当你在vue项目里面怎么引用呢
这是按照组件引用的效果
particlesJS在Vue中怎么使用?怎么引入?_fengzideshijie2的博客-CSDN博客
4、还有别人写的这个,还没有尝试
vue.js 实现粒子特效之插件( vue-particles ) - Gordon-Guo - 博客园
更多推荐
粒子连线效果(业余学习
发布评论