Created
September 5, 2018 15:01
-
-
Save marcolink/43e0617262addb4c166821fe8080075e to your computer and use it in GitHub Desktop.
animated-background.html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<title>Canvas - animated gradient Background</title> | |
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" | |
integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"> | |
</head> | |
<body> | |
<div class="container"> | |
<div class="row mt-5"> | |
<div class="col"> | |
<div id="background-container" class="border bg-light" style="height: 300px"> | |
<div class="align-middle" style="position:relative"> | |
<h1 class="display-4 text-center text-white mt-3">Animated Background Gradient Example</h1> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="row mt-5"> | |
<div class="col"> | |
<div id="background-container-2" class="border bg-light" style="height: 300px"> | |
<div class="align-middle" style="position:relative"> | |
<h1 class="display-4 text-center text-white mt-3">Animated Background Gradient Example</h1> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</body> | |
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" | |
crossorigin="anonymous"></script> | |
<script type="text/javascript"> | |
const randomBetween = (min, max) => Math.random() * (max - min) + min; | |
const normalize = (val, max, min) => max - min === 0 ? 1 : (val - min) / (max - min); | |
const interpolate = (a, b, fractal) => { | |
const nx = a.x + (b.x - a.x) * fractal; | |
const ny = a.y + (b.y - a.y) * fractal; | |
return {x: nx, y: ny}; | |
}; | |
class AnimatedBackground { | |
constructor(element, options) { | |
this.options = options || [{ | |
startColor: "#00ff0033", | |
endColor: "#00ff0000", | |
size: 150, | |
start: 0, | |
end: 0.5, | |
duration: 6 | |
}, { | |
startColor: "#ff000033", | |
endColor: "#ff000000", | |
size: 100, | |
start: 0.5, | |
end: 1, | |
duration: 10 | |
}, { | |
startColor: "#0000ff33", | |
endColor: "#0000ff00", | |
size: 200, | |
start: 0.4, | |
end: 0.6, | |
duration: 7 | |
}]; | |
this.init(element); | |
} | |
init(element) { | |
this.animate = this.animate.bind(this); | |
element.prepend("<canvas class='canvas-background'/>"); | |
this.$canvasElement = element.find(".canvas-background"); | |
this.$canvasElement.css({ | |
"position": "absolute", "z-index": "0", "box-sizing": "border-box" | |
}); | |
this.canvasElement = this.$canvasElement[0]; | |
this.canvasContext = this.canvasElement.getContext("2d"); | |
this.setSize($(element).width(), $(element).height()); | |
window.onresize = () => this.setSize($(element).width(), $(element).height()); | |
} | |
setSize(width, height) { | |
this.containerWidth = width; | |
this.containerHeight = height; | |
this.$canvasElement.attr("width", width); | |
this.$canvasElement.attr("height", height); | |
this.draw(); | |
} | |
start() { | |
this.animate() | |
} | |
animate(timestamp) { | |
this.draw(timestamp); | |
requestAnimationFrame(this.animate); | |
} | |
draw(timestamp) { | |
//console.debug(timestamp); | |
this.canvasContext.clearRect(0, 0, this.containerWidth, this.containerHeight); | |
this.options.forEach(option => { | |
let step = normalize(timestamp, option.startTime + option.duration * 1000, option.startTime) || 1; | |
if (!option.startPosition || step >= 1) { | |
option.startPosition = option.targetPosition || {x:randomBetween(option.start, option.end) * this.containerWidth, y:Math.random() * this.containerHeight}; | |
option.targetPosition = {x:randomBetween(option.start, option.end) * this.containerWidth, y:Math.random() * this.containerHeight}; | |
option.startTime = timestamp || 0; | |
step = 0; | |
} | |
const current = interpolate(option.startPosition, option.targetPosition, step); | |
const x = current.x; | |
const y = current.y; | |
const innerRadius = 0; | |
const outerRadius = option.size - 20; | |
let gradient = this.canvasContext.createRadialGradient(x, y, innerRadius, x, y, outerRadius); | |
gradient.addColorStop(0, option.startColor); | |
gradient.addColorStop(1, option.endColor); | |
this.canvasContext.beginPath(); | |
this.canvasContext.arc(x, y, option.size, 0, 2 * Math.PI); | |
//this.canvasContext.stroke(); | |
this.canvasContext.fillStyle = gradient; | |
this.canvasContext.fill(); | |
}); | |
} | |
} | |
// Default BG | |
new AnimatedBackground($("#background-container")).start(); | |
// Custom BG | |
new AnimatedBackground($("#background-container-2"), [{ | |
startColor: "#00ff0033", | |
endColor: "#00ff0000", | |
size: 400, | |
start: 0, | |
end: 0.5, | |
duration: 6 | |
},{ | |
startColor: "#0000ff33", | |
endColor: "#0000ff00", | |
size: 400, | |
start: 0.3, | |
end: 1, | |
duration: 11 | |
}]).start(); | |
</script> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Demo: https://jsfiddle.net/marcxolink/yz4aw57p/