html圆点跟链接线,html5 canvas简洁的圆点线动画特效

特效描述:html5 canvas简洁的 圆点线动画特效。html5 canvas绘制简洁动画特效,圆点和线条连接的背景动画特效。

代码结构

1. HTML代码

在美国的研究

我们一起可以在学术界产生影响。

// min and max radius, radius threshold and percentage of filled circles

var radMin = 5,

radMax = 125,

filledCircle = 60, //percentage of filled circles

concentricCircle = 30, //percentage of concentric circles

radThreshold = 25; //IFF special, over this radius concentric, otherwise filled

//min and max speed to move

var speedMin = 0.3,

speedMax = 2.5;

//max reachable opacity for every circle and blur effect

var maxOpacity = 0.6;

//default palette choice

var colors = ['52,168,83', '117,95,147', '199,108,23', '194,62,55', '0,172,212', '120,120,120'],

bgColors = ['52,168,83', '117,95,147', '199,108,23', '194,62,55', '0,172,212', '120,120,120'],

circleBorder = 10,

backgroundLine = bgColors[0];

var backgroundMlt = 0.85;

//min distance for links

var linkDist = Math.min(canvas.width, canvas.height) / 2.4,

lineBorder = 2.5;

//most importantly: number of overall circles and arrays containing them

var maxCircles = 12,

points = [],

pointsBack = [];

//populating the screen

for (var i = 0; i < maxCircles * 2; i++) points.push(new Circle());

for (var i = 0; i < maxCircles; i++) pointsBack.push(new Circle(true));

//experimental vars

var circleExp = 1,

circleExpMax = 1.003,

circleExpMin = 0.997,

circleExpSp = 0.00004,

circlePulse = false;

//circle class

function Circle(background) {

//if background, it has different rules

this.background = (background || false);

this.x = randRange(-canvas.width / 2, canvas.width / 2);

this.y = randRange(-canvas.height / 2, canvas.height / 2);

this.radius = background ? hyperRange(radMin, radMax) * backgroundMlt : hyperRange(radMin, radMax);

this.filled = this.radius < radThreshold ? (randint(0, 100) > filledCircle ? false : 'full') : (randint(0, 100) > concentricCircle ? false : 'concentric');

this.color = background ? bgColors[randint(0, bgColors.length - 1)] : colors[randint(0, colors.length - 1)];

this.borderColor = background ? bgColors[randint(0, bgColors.length - 1)] : colors[randint(0, colors.length - 1)];

this.opacity = 0.05;

this.speed = (background ? randRange(speedMin, speedMax) / backgroundMlt : randRange(speedMin, speedMax)); // * (radMin / this.radius);

this.speedAngle = Math.random() * 2 * Math.PI;

this.speedx = Math.cos(this.speedAngle) * this.speed;

this.speedy = Math.sin(this.speedAngle) * this.speed;

var spacex = Math.abs((this.x - (this.speedx < 0 ? -1 : 1) * (canvas.width / 2 + this.radius)) / this.speedx),

spacey = Math.abs((this.y - (this.speedy < 0 ? -1 : 1) * (canvas.height / 2 + this.radius)) / this.speedy);

this.ttl = Math.min(spacex, spacey);

};

Circle.prototype.init = function() {

Circle.call(this, this.background);

}

//support functions

//generate random int a<=x<=b

function randint(a, b) {

return Math.floor(Math.random() * (b - a + 1) + a);

}

//generate random float

function randRange(a, b) {

return Math.random() * (b - a) + a;

}

//generate random float more likely to be close to a

function hyperRange(a, b) {

return Math.random() * Math.random() * Math.random() * (b - a) + a;

}

//rendering function

function drawCircle(ctx, circle) {

//circle.radius *= circleExp;

var radius = circle.background ? circle.radius *= circleExp : circle.radius /= circleExp;

ctx.beginPath();

ctx.arc(circle.x, circle.y, radius * circleExp, 0, 2 * Math.PI, false);

ctx.lineWidth = Math.max(1, circleBorder * (radMin - circle.radius) / (radMin - radMax));

ctx.strokeStyle = ['rgba(', circle.borderColor, ',', circle.opacity, ')'].join('');

if (circle.filled == 'full') {

ctx.fillStyle = ['rgba(', circle.borderColor, ',', circle.background ? circle.opacity * 0.8 : circle.opacity, ')'].join('');

ctx.fill();

ctx.lineWidth=0;

ctx.strokeStyle = ['rgba(', circle.borderColor, ',', 0, ')'].join('');

}

ctx.stroke();

if (circle.filled == 'concentric') {

ctx.beginPath();

ctx.arc(circle.x, circle.y, radius / 2, 0, 2 * Math.PI, false);

ctx.lineWidth = Math.max(1, circleBorder * (radMin - circle.radius) / (radMin - radMax));

ctx.strokeStyle = ['rgba(', circle.color, ',', circle.opacity, ')'].join('');

ctx.stroke();

}

circle.x += circle.speedx;

circle.y += circle.speedy;

if (circle.opacity < (circle.background ? maxOpacity : 1)) circle.opacity += 0.01;

circle.ttl--;

}

//initializing function

function init() {

window.requestAnimationFrame(draw);

}

//rendering function

function draw() {

if (circlePulse) {

if (circleExp < circleExpMin || circleExp > circleExpMax) circleExpSp *= -1;

circleExp += circleExpSp;

}

var ctxfr = document.getElementById('canvas').getContext('2d');

var ctxbg = document.getElementById('canvasbg').getContext('2d');

ctxfr.globalCompositeOperation = 'destination-over';

ctxfr.clearRect(0, 0, canvas.width, canvas.height); // clear canvas

ctxbg.globalCompositeOperation = 'destination-over';

ctxbg.clearRect(0, 0, canvas.width, canvas.height); // clear canvas

ctxfr.save();

ctxfr.translate(canvas.width / 2, canvas.height / 2);

ctxbg.save();

ctxbg.translate(canvas.width / 2, canvas.height / 2);

//function to render each single circle, its connections and to manage its out of boundaries replacement

function renderPoints(ctx, arr) {

for (var i = 0; i < arr.length; i++) {

var circle = arr[i];

//checking if out of boundaries

if (circle.ttl<0) {}

var xEscape = canvas.width / 2 + circle.radius,

yEscape = canvas.height / 2 + circle.radius;

if (circle.ttl < -20) arr[i].init(arr[i].background);

//if (Math.abs(circle.y) > yEscape || Math.abs(circle.x) > xEscape) arr[i].init(arr[i].background);

drawCircle(ctx, circle);

}

for (var i = 0; i < arr.length - 1; i++) {

for (var j = i + 1; j < arr.length; j++) {

var deltax = arr[i].x - arr[j].x;

var deltay = arr[i].y - arr[j].y;

var dist = Math.pow(Math.pow(deltax, 2) + Math.pow(deltay, 2), 0.5);

//if the circles are overlapping, no laser connecting them

if (dist <= arr[i].radius + arr[j].radius) continue;

//otherwise we connect them only if the dist is < linkDist

if (dist < linkDist) {

var xi = (arr[i].x < arr[j].x ? 1 : -1) * Math.abs(arr[i].radius * deltax / dist);

var yi = (arr[i].y < arr[j].y ? 1 : -1) * Math.abs(arr[i].radius * deltay / dist);

var xj = (arr[i].x < arr[j].x ? -1 : 1) * Math.abs(arr[j].radius * deltax / dist);

var yj = (arr[i].y < arr[j].y ? -1 : 1) * Math.abs(arr[j].radius * deltay / dist);

ctx.beginPath();

ctx.moveTo(arr[i].x + xi, arr[i].y + yi);

ctx.lineTo(arr[j].x + xj, arr[j].y + yj);

var samecolor = arr[i].color == arr[j].color;

ctx.strokeStyle = ["rgba(", arr[i].borderColor, ",", Math.min(arr[i].opacity, arr[j].opacity) * ((linkDist - dist) / linkDist), ")"].join("");

ctx.lineWidth = (arr[i].background ? lineBorder * backgroundMlt : lineBorder) * ((linkDist - dist) / linkDist); //*((linkDist-dist)/linkDist);

ctx.stroke();

}

}

}

}

var startTime = Date.now();

renderPoints(ctxfr, points);

renderPoints(ctxbg, pointsBack);

deltaT = Date.now() - startTime;

ctxfr.restore();

ctxbg.restore();

window.requestAnimationFrame(draw);

}

init();

/*Credits and aknowledgements:

Original Idea and Design by Luca Luzzatti

Optimizing tips from Benjamin K?stner

General tips from Salvatore Previti*/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值