網站動態背景線條跟隨鼠標移動,吸附鼠標效果
動態背景線條,鼠標移動可以吸附,可以添加配置,代碼如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>粒子線條canvas效果</title> <style> #J_dotLine { display: block; margin: 0 auto; } </style> </head> <body> <canvas id="J_dotLine"></canvas> <script> ; (function (window) { function Dotline(option) { this.opt = this.extend({ dom: 'J_dotLine',//畫布id cw: 1000,//畫布寬 ch: 500,//畫布高 ds: 100,//點的個數 r: 0.5,//圓點半徑 cl: '#000',//顏色 dis: 100//觸發連線的距離 }, option); this.c = document.getElementById(this.opt.dom);//canvas元素id this.ctx = this.c.getContext('2d'); this.c.width = this.opt.cw;//canvas寬 this.c.height = this.opt.ch;//canvas高 this.dotSum = this.opt.ds;//點的數量 this.radius = this.opt.r;//圓點的半徑 this.disMax = this.opt.dis * this.opt.dis;//點與點觸發連線的間距 this.color = this.color2rgb(this.opt.cl);//設置粒子線顏色 this.dots = []; //requestAnimationFrame控制canvas動畫 var RAF = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) { window.setTimeout(callback, 1000 / 60); }; var _self = this; //增加鼠標效果 var mousedot = { x: null, y: null, label: 'mouse' }; this.c.onmousemove = function (e) { var e = e || window.event; mousedot.x = e.clientX - _self.c.offsetLeft; mousedot.y = e.clientY - _self.c.offsetTop; }; this.c.onmouseout = function (e) { mousedot.x = null; mousedot.y = null; } //控制動畫 this.animate = function () { _self.ctx.clearRect(0, 0, _self.c.width, _self.c.height); _self.drawLine([mousedot].concat(_self.dots)); RAF(_self.animate); }; } //合並配置項,es6直接使用obj.assign(); Dotline.prototype.extend = function (o, e) { for (var key in e) { if (e[key]) { o[key] = e[key] } } return o; }; Dotline.prototype.color2rgb = function (colorStr) { var red = null, green = null, blue = null; var cstr = colorStr.toLowerCase();//變小寫 var cReg = /^#[0-9a-fA-F]{3,6}$/;//確定是16進制顏色碼 if (cstr && cReg.test(cstr)) { if (cstr.length == 4) { var cstrnew = '#'; for (var i = 1; i < 4; i++) { cstrnew += cstr.slice(i, i + 1).concat(cstr.slice(i, i + 1)); } cstr = cstrnew; } red = parseInt('0x' + cstr.slice(1, 3)); green = parseInt('0x' + cstr.slice(3, 5)); blue = parseInt('0x' + cstr.slice(5, 7)); } return red + ',' + green + ',' + blue; } //畫點 Dotline.prototype.addDots = function () { var dot; for (var i = 0; i < this.dotSum; i++) {//參數 dot = { x: Math.floor(Math.random() * this.c.width) - this.radius, y: Math.floor(Math.random() * this.c.height) - this.radius, ax: (Math.random() * 2 - 1) / 1.5, ay: (Math.random() * 2 - 1) / 1.5 } this.dots.push(dot); } }; //點運動 Dotline.prototype.move = function (dot) { dot.x += dot.ax; dot.y += dot.ay; //點碰到邊緣返回 dot.ax *= (dot.x > (this.c.width - this.radius) || dot.x < this.radius) ? -1 : 1; dot.ay *= (dot.y > (this.c.height - this.radius) || dot.y < this.radius) ? -1 : 1; //繪制點 this.ctx.beginPath(); this.ctx.arc(dot.x, dot.y, this.radius, 0, Math.PI * 2, true); this.ctx.stroke(); }; //點之間畫線 Dotline.prototype.drawLine = function (dots) { var nowDot; var _that = this; //自己的思路:遍歷兩次所有的點,比較點之間的距離,函數的觸發放在animate里 this.dots.forEach(function (dot) { _that.move(dot); for (var j = 0; j < dots.length; j++) { nowDot = dots[j]; if (nowDot === dot || nowDot.x === null || nowDot.y === null) continue;//continue跳出當前循環開始新的循環 var dx = dot.x - nowDot.x,//別的點坐標減當前點坐標 dy = dot.y - nowDot.y; var dc = dx * dx + dy * dy; if (Math.sqrt(dc) > Math.sqrt(_that.disMax)) continue; // 如果是鼠標,則讓粒子向鼠標的位置移動 if (nowDot.label && Math.sqrt(dc) > Math.sqrt(_that.disMax) / 2) { dot.x -= dx * 0.02; dot.y -= dy * 0.02; } var ratio; ratio = (_that.disMax - dc) / _that.disMax; _that.ctx.beginPath(); _that.ctx.lineWidth = ratio / 2; _that.ctx.strokeStyle = 'rgba(' + _that.color + ',' + parseFloat(ratio + 0.2).toFixed(1) + ')'; _that.ctx.moveTo(dot.x, dot.y); _that.ctx.lineTo(nowDot.x, nowDot.y); _that.ctx.stroke();//不描邊看不出效果 //dots.splice(dots.indexOf(dot), 1); } }); }; //開始動畫 Dotline.prototype.start = function () { var _that = this; this.addDots(); setTimeout(function () { _that.animate(); }, 100); } window.Dotline = Dotline; }(window)); //調用 window.onload = function () { var dotline = new Dotline({ dom: 'J_dotLine',//畫布id cw: 1000,//畫布寬 ch: 500,//畫布高 ds: 100,//點的個數 r: 0.5,//圓點半徑 cl: '#fff',//粒子線顏色 dis: 100//觸發連線的距離 }).start(); } </script> </body> </html>
vue,react寫法,類分裝:
創建一個dotline.js
class Dotline { constructor(option) { this.opt = this.extend({ dom: 'J_dotLine',//畫布id cw: 1000,//畫布寬 ch: 500,//畫布高 ds: 100,//點的個數 r: 0.5,//圓點半徑 cl: '#000',//顏色 dis: 100//觸發連線的距離 }, option); this.c = document.getElementById(this.opt.dom);//canvas元素id this.ctx = this.c.getContext('2d'); this.c.width = this.opt.cw;//canvas寬 this.c.height = this.opt.ch;//canvas高 this.dotSum = this.opt.ds;//點的數量 this.radius = this.opt.r;//圓點的半徑 this.disMax = this.opt.dis * this.opt.dis;//點與點觸發連線的間距 this.color = this.color2rgb(this.opt.cl);//設置粒子線顏色 this.dots = []; //requestAnimationFrame控制canvas動畫 var RAF = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) { window.setTimeout(callback, 1000 / 60); }; var _self = this; //增加鼠標效果 var mousedot = { x: null, y: null, label: 'mouse' }; this.c.onmousemove = function (e) { var e = e || window.event; mousedot.x = e.clientX - _self.c.offsetLeft; mousedot.y = e.clientY - _self.c.offsetTop; }; this.c.onmouseout = function (e) { mousedot.x = null; mousedot.y = null; } //控制動畫 this.animate = function () { _self.ctx.clearRect(0, 0, _self.c.width, _self.c.height); _self.drawLine([mousedot].concat(_self.dots)); RAF(_self.animate); }; } //合並配置項,es6直接使用obj.assign(); extend(o, e) { for (var key in e) { if (e[key]) { o[key] = e[key] } } return o; } //設置線條顏色 color2rgb(colorStr) { var red = null, green = null, blue = null; var cstr = colorStr.toLowerCase();//變小寫 var cReg = /^#[0-9a-fA-F]{3,6}$/;//確定是16進制顏色碼 if (cstr && cReg.test(cstr)) { if (cstr.length == 4) { var cstrnew = '#'; for (var i = 1; i < 4; i++) { cstrnew += cstr.slice(i, i + 1).concat(cstr.slice(i, i + 1)); } cstr = cstrnew; } red = parseInt('0x' + cstr.slice(1, 3)); green = parseInt('0x' + cstr.slice(3, 5)); blue = parseInt('0x' + cstr.slice(5, 7)); } return red + ',' + green + ',' + blue; } //畫點 addDots() { var dot; for (var i = 0; i < this.dotSum; i++) {//參數 dot = { x: Math.floor(Math.random() * this.c.width) - this.radius, y: Math.floor(Math.random() * this.c.height) - this.radius, ax: (Math.random() * 2 - 1) / 1.5, ay: (Math.random() * 2 - 1) / 1.5 } this.dots.push(dot); } } //點運動 move(dot) { dot.x += dot.ax; dot.y += dot.ay; //點碰到邊緣返回 dot.ax *= (dot.x > (this.c.width - this.radius) || dot.x < this.radius) ? -1 : 1; dot.ay *= (dot.y > (this.c.height - this.radius) || dot.y < this.radius) ? -1 : 1; //繪制點 this.ctx.beginPath(); this.ctx.arc(dot.x, dot.y, this.radius, 0, Math.PI * 2, true); this.ctx.stroke(); } //點之間畫線 drawLine(dots) { var nowDot; var _that = this; //自己的思路:遍歷兩次所有的點,比較點之間的距離,函數的觸發放在animate里 this.dots.forEach(function (dot) { _that.move(dot); for (var j = 0; j < dots.length; j++) { nowDot = dots[j]; if (nowDot === dot || nowDot.x === null || nowDot.y === null) continue;//continue跳出當前循環開始新的循環 var dx = dot.x - nowDot.x,//別的點坐標減當前點坐標 dy = dot.y - nowDot.y; var dc = dx * dx + dy * dy; if (Math.sqrt(dc) > Math.sqrt(_that.disMax)) continue; // 如果是鼠標,則讓粒子向鼠標的位置移動 if (nowDot.label && Math.sqrt(dc) > Math.sqrt(_that.disMax) / 2) { dot.x -= dx * 0.02; dot.y -= dy * 0.02; } var ratio; ratio = (_that.disMax - dc) / _that.disMax; _that.ctx.beginPath(); _that.ctx.lineWidth = ratio / 2; _that.ctx.strokeStyle = 'rgba(' + _that.color + ',' + parseFloat(ratio + 0.2).toFixed(1) + ')'; _that.ctx.moveTo(dot.x, dot.y); _that.ctx.lineTo(nowDot.x, nowDot.y); _that.ctx.stroke();//不描邊看不出效果 //dots.splice(dots.indexOf(dot), 1); } }); } //開始動畫 start() { var _that = this; this.addDots(); setTimeout(function () { _that.animate(); }, 100); } } export default Dotline;
調用方法:
html:
<canvas id="J_dotLine"></canvas>
js:
import Dotline from "./dotline.js";
const option = {
dom: 'J_dotLine',//畫布id
cw: 1000,//畫布寬
ch: 500,//畫布高
ds: 250,//點的個數
r: 3,//圓點半徑
cl: '#061eb3',//粒子線顏色
dis: 120//觸發連線的距離
}
const dotline = new Dotline(option).start();
轉載:https://blog.csdn.net/weixin_44149978/article/details/98076605
-------------------------------------------------------------------------------------------------
<template> <div> <canvas id="J_dotLine"></canvas> </div> </template> <script> import Dotline from "../../assets/js/dotline.js"; export default { mounted: function () { this.swippertab(); }, methods: { swippertab() { const option = { dom: "J_dotLine", //畫布id cw: 1000, //畫布寬 ch: 500, //畫布高 ds: 250, //點的個數 r: 3, //圓點半徑 cl: "#8FDAF8", //粒子線顏色 dis: 120, //觸發連線的距離 }; new Dotline(option).start(); }, }, }; </script> <style> </style>