Je tente de personnaliser une animation effet "blobs" ou "lampe à lave" CSS Javascript (voici le code d'origine https://codepen.io/Chandrakant/pen/eYBBxPQ).
J'ai réussi à supprimer le dégradé de fond des "blobs" et leur mettre un contour blanc, seulement maintenant le scontours des "blobs" ont un problème d'affichage, une sorte de "trou" qui oscille.
Voici le code :
HTML:
Code : Tout sélectionner
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="style.css">
<style>
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@700;800;900&family=Open+Sans&display=swap');
</style>
</head>
<body>
<div class="bubblewrap">
<div class="wrap">
<div class="text-wrap">
<div class="bubblewrapText ">
<h1>Bonjour !</h1>
</div>
<div class="header-text">
<p>Je blablablabla blablabla bla bla<br>
Et blablabla bla blabla</p>
</div>
</div>
<canvas id="bubble"></canvas>
</div>
</div>
<script src="bubblewrap.js"> </script>
</body>
</html>
Code : Tout sélectionner
body{
margin: 0;
padding: 0;
}
h1{
color: #F8F7F7;
font-size: 80px;
font-family: 'Nunito', sans-serif;
font-weight: 900;
margin-bottom: 20px;
margin-top: 30px;
}
p{
}
.text-wrap{
position: absolute;
left: 10em;
z-index:1;
width: 100%;
}
.bubblewrap{
height: 650px;
position: relative;
}
.bubblewrapText,
.header-text{
width: 80%;
z-index: 1;
}
.header-text p{
color:#F8F7F7;
font-size: 30px;
font-family: 'Open Sans', sans-serif;
line-height:40px;
font-weight: 400;
}
.wrap {
overflow: hidden;
position: relative;
top: 0;
left: 0;
width: 100%;
height: 94%;
background-color: #262226;
z-index: -1;
}
.wrap canvas {
position: absolute;
top: -2%;
left: -2%;
width: 104%;
height: 104%;
}
.page-center{
max-width:1160px;
margin-left: auto;
margin-right: auto;
}
Code : Tout sélectionner
(function () {
"use strict";
var lava0;
var ge1doot = {
screen: {
elem: null,
callback: null,
ctx: null,
width: 100,
height: 100,
left: 0,
top: 0,
init: function (id, callback, initRes) {
this.elem = document.getElementById(id);
this.callback = callback || null;
if (this.elem.tagName == "CANVAS")
this.ctx = this.elem.getContext("2d");
window.addEventListener(
"resize",
function () {
this.resize();
}.bind(this),
false
);
this.elem.onselectstart = function () {
return false;
};
this.elem.ondrag = function () {
return false;
};
initRes && this.resize();
return this;
},
resize: function () {
var o = this.elem;
this.width = o.offsetWidth;
this.height = o.offsetHeight;
for (this.left = 0, this.top = 0; o != null; o = o.offsetParent) {
this.left += o.offsetLeft;
this.top += o.offsetTop;
}
if (this.ctx) {
this.elem.width = this.width;
this.elem.height = this.height;
}
this.callback && this.callback();
}
}
};
// Point constructor
var Point = function (x, y) {
this.x = x;
this.y = y;
this.magnitude = x * x + y * y;
this.computed = 0;
this.force = 0;
};
Point.prototype.add = function (p) {
return new Point(this.x + p.x, this.y + p.y);
};
// Ball constructor
var Ball = function (parent) {
var min = 0.5;
var max = 3.0;
this.vel = new Point(
(Math.random() > 0.5 ? 1 : -1) * (0.2 + Math.random() * 0.25),
(Math.random() > 0.5 ? 1 : -1) * (0.2 + Math.random())
);
this.pos = new Point(
parent.width * 0.2 + Math.random() * parent.width * 0.6,
parent.height * 0.2 + Math.random() * parent.height * 0.6
);
this.size =
parent.wh / 15 + (Math.random() * (max - min) + min) * (parent.wh / 15);
this.width = parent.width;
this.height = parent.height;
};
// move balls
Ball.prototype.move = function () {
// bounce borders
if (this.pos.x >= this.width - this.size) {
if (this.vel.x > 0) this.vel.x = -this.vel.x;
this.pos.x = this.width - this.size;
} else if (this.pos.x <= this.size) {
if (this.vel.x < 0) this.vel.x = -this.vel.x;
this.pos.x = this.size;
}
if (this.pos.y >= this.height - this.size) {
if (this.vel.y > 0) this.vel.y = -this.vel.y;
this.pos.y = this.height - this.size;
} else if (this.pos.y <= this.size) {
if (this.vel.y < 0) this.vel.y = -this.vel.y;
this.pos.y = this.size;
}
// velocity
this.pos = this.pos.add(this.vel);
};
// lavalamp constructor
var LavaLamp = function (width, height, numBalls, c0, c1) {
this.step = 5;
this.width = width;
this.height = height;
this.wh = Math.min(width, height);
this.sx = Math.floor(this.width / this.step);
this.sy = Math.floor(this.height / this.step);
this.paint = false;
this.plx = [0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0];
this.ply = [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1];
this.mscases = [0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 0, 2, 1, 1, 0];
this.ix = [1, 0, -1, 0, 0, 1, 0, -1, -1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1];
this.grid = [];
this.balls = [];
this.iter = 0;
this.sign = 1;
// init grid
for (var i = 0; i < (this.sx + 2) * (this.sy + 2); i++) {
this.grid[i] = new Point(
(i % (this.sx + 2)) * this.step,
Math.floor(i / (this.sx + 2)) * this.step
);
}
// create metaballs
for (var k = 0; k < numBalls; k++) {
this.balls[k] = new Ball(this);
}
};
// compute cell force
LavaLamp.prototype.computeForce = function (x, y, idx) {
var force;
var id = idx || x + y * (this.sx + 2);
if (x === 0 || y === 0 || x === this.sx || y === this.sy) {
force = 0.6 * this.sign;
} else {
force = 0;
var cell = this.grid[id];
var i = 0;
var ball;
while ((ball = this.balls[i++])) {
force +=
(ball.size * ball.size) /
(-2 * cell.x * ball.pos.x -
2 * cell.y * ball.pos.y +
ball.pos.magnitude +
cell.magnitude);
}
force *= this.sign;
}
this.grid[id].force = force;
return force;
};
// compute cell
LavaLamp.prototype.marchingSquares = function (next) {
var x = next[0];
var y = next[1];
var pdir = next[2];
var id = x + y * (this.sx + 2);
if (this.grid[id].computed === this.iter) {
return false;
}
var dir,
mscase = 0;
// neighbors force
for (var i = 0; i < 4; i++) {
var idn = x + this.ix[i + 12] + (y + this.ix[i + 16]) * (this.sx + 2);
var force = this.grid[idn].force;
if (
(force > 0 && this.sign < 0) ||
(force < 0 && this.sign > 0) ||
!force
) {
// compute force if not in buffer
force = this.computeForce(
x + this.ix[i + 12],
y + this.ix[i + 16],
idn
);
}
if (Math.abs(force) > 1) mscase += Math.pow(2, i);
}
if (mscase === 15) {
// inside
return [x, y - 1, false];
} else {
// ambiguous cases
if (mscase === 5) dir = pdir === 2 ? 3 : 1;
else if (mscase === 10) dir = pdir === 3 ? 0 : 2;
else {
// lookup
dir = this.mscases[mscase];
this.grid[id].computed = this.iter;
}
// draw line
var ix =
this.step /
(Math.abs(
Math.abs(
this.grid[
x +
this.plx[4 * dir + 2] +
(y + this.ply[4 * dir + 2]) * (this.sx + 2)
].force
) - 1
) /
Math.abs(
Math.abs(
this.grid[
x +
this.plx[4 * dir + 3] +
(y + this.ply[4 * dir + 3]) * (this.sx + 2)
].force
) - 1
) +
1);
ctx.lineTo(
this.grid[
x + this.plx[4 * dir] + (y + this.ply[4 * dir]) * (this.sx + 2)
].x +
this.ix[dir] * ix,
this.grid[
x +
this.plx[4 * dir + 1] +
(y + this.ply[4 * dir + 1]) * (this.sx + 2)
].y +
this.ix[dir + 4] * ix
);
this.paint = true;
// next
return [x + this.ix[dir + 4], y + this.ix[dir + 8], dir];
}
};
LavaLamp.prototype.renderMetaballs = function () {
var i = 0,
ball;
while ((ball = this.balls[i++])) ball.move();
// reset grid
this.iter++;
this.sign = -this.sign;
this.paint = false;
ctx.beginPath();
// compute metaballs
i = 0;
//ctx.shadowBlur = 50;
//ctx.shadowColor = "green";
while ((ball = this.balls[i++])) {
// first cell
var next = [
Math.round(ball.pos.x / this.step),
Math.round(ball.pos.y / this.step),
false
];
// marching squares
do {
next = this.marchingSquares(next);
} while (next);
// fill and close path
if (this.paint) {
ctx.strokeStyle = "#FFFFFF";
ctx.stroke();
ctx.closePath();
ctx.beginPath();
this.paint = false;
}
}
};
// main loop
var run = function () {
requestAnimationFrame(run);
ctx.clearRect(0, 0, screen.width, screen.height);
lava0.renderMetaballs();
};
// canvas
var screen = ge1doot.screen.init("bubble", null, true),
ctx = screen.ctx;
screen.resize();
// create LavaLamps
lava0 = new LavaLamp(
screen.width + 20,
screen.height + 20,
4,
);
run();
})();