Skip to content

Instantly share code, notes, and snippets.

@nicolasbeauvais
Created April 11, 2017 10:48
Show Gist options
  • Save nicolasbeauvais/00dd531ad3dbea90184dbeb40c165166 to your computer and use it in GitHub Desktop.
Save nicolasbeauvais/00dd531ad3dbea90184dbeb40c165166 to your computer and use it in GitHub Desktop.
Animated curves made for raisup.com, vuejs object structure
function Point(x, y) {
this.x = x;
this.y = y;
}
export default {
data() {
return {
canvas: undefined,
context: undefined,
raf: undefined,
avHeight: 0,
width: 0,
height: 0,
colors: ['rgba(1, 169, 241, 0.7)', 'rgba(25, 216, 186, 0.7)'],
curves: [],
};
},
mounted() {
this.canvas = this.$refs.canvas;
this.ctx = this.canvas.getContext('2d');
this.init();
$(window).on('resize', this.resize);
},
methods: {
init () {
this.resize();
this.curves = this.generateCurves();
this.render();
},
resize() {
this.width = this.ctx.canvas.width = this.canvas.offsetWidth;
this.height = this.ctx.canvas.height = this.canvas.offsetHeight;
this.avHeight = this.height - 220;
this.curves = this.generateCurves();
},
render() {
setTimeout(() => {
this.raf = window.requestAnimationFrame(this.render);
this.ctx.fillStyle = "#FFFFFF";
this.ctx.fillRect(0, 0, this.width, this.height);
this.curves.forEach((curve) => {
this.renderCurve(curve, this.ctx, this.width, this.height);
});
}, 1000 / 15);
},
middlePoint() {
return new Point((this.width / 100) * 50, ((this.avHeight) / 100) * 50);
},
generateCurves() {
return [
this.generateCurve(
['rgba(25, 216, 186, 0.8)', 'rgba(1, 169, 241, 0.8)'],
(this.height / 100) * 10,
(this.height / 100) * 45,
this.middlePoint,
new Point((this.width / 100) * 25, ((this.avHeight) / 100) * 5),
new Point((this.width / 100) * 76, ((this.avHeight) / 100) * 86),
),
this.generateCurve(
['rgba(1, 169, 241, 0.8)', 'rgba(25, 216, 186, 0.8)'],
((this.avHeight) / 100) * 20,
((this.avHeight) / 100) * 40,
this.middlePoint,
new Point((this.width / 100) * 23, ((this.avHeight) / 100) * 82),
new Point((this.width / 100) * 81, ((this.avHeight) / 100) * 13),
),
];
},
generateCurve(colors, yStart, yEnd, middle, point1, point2) {
const Curve = function(instance, colors, yStart, yEnd, middle, point1, point2) {
this.colors = colors;
// Origin
this.yStart = yStart;
this.yEnd = yEnd;
this.point1 = point1;
this.point2 = point2;
// Animation
this.animation = {
start: {
point: new Point(0, this.yStart),
value: Math.floor(Math.random() * 30),
direction: Math.random() > 0.5 ? 1 : -1
},
end: {
point: new Point(instance.width, this.yEnd),
value: Math.floor(Math.random() * 30),
direction: Math.random() > 0.5 ? 1 : -1
},
middle: {
point: middle,
value: Math.floor(Math.random() * 30),
direction: Math.random() > 0.5 ? 1 : -1
},
};
};
Curve.prototype.animate = function (instance) {
// Limit Animation
for (let key in this.animation) {
const realPos = this.animation[key].point.y + this.animation[key].value;
const max = key === 'middle' ? (instance.avHeight / 4) * 3 : instance.avHeight;
const min = key === 'middle' ? (instance.avHeight / 4) : 0;
// If to far change direction
if (realPos >= max || realPos <= min) {
this.animation[key].direction = this.animation[key].direction * -1;
} else {// Else, change direction randomly (1/400 frames)
if (Math.floor(Math.random() * 400) === 50) {
this.animation[key].direction = this.animation[key].direction * -1;
}
}
this.animation[key].value += this.animation[key].direction;
}
// Apply
const middlePoint = instance.middlePoint();
this.animation.start.point = new Point(0, this.yStart + this.animation.start.value);
this.animation.end.point = new Point(instance.width, this.yEnd + this.animation.end.value);
this.animation.middle.point = new Point(middlePoint.x + this.animation.middle.value, middlePoint.y + this.animation.middle.value);
};
return new Curve(this, colors, yStart, yEnd, middle, point1, point2);
},
renderCurve(curve, ctx, width, height) {
ctx.save();
// Gradient
const gradient = ctx.createLinearGradient(0, 0, width, height);
gradient.addColorStop(0, curve.colors[0]);
gradient.addColorStop(1, curve.colors[1]);
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.moveTo(curve.animation.start.point.x, curve.animation.start.point.y);
const animationCoefficient = curve.animation.middle.value;
if (width < 778) {// Small screens (render 1 curve)
ctx.quadraticCurveTo(
curve.point1.x + animationCoefficient,
curve.point1.y + animationCoefficient,
curve.animation.end.point.x,
curve.animation.end.point.y
);
} else {// Big screens (render 2 curves)
ctx.quadraticCurveTo(
curve.point1.x + animationCoefficient,
curve.point1.y + animationCoefficient,
curve.animation.middle.point.x,
curve.animation.middle.point.y
);
ctx.quadraticCurveTo(
curve.point2.x + animationCoefficient,
curve.point2.y + animationCoefficient,
curve.animation.end.point.x,
curve.animation.end.point.y
);
}
ctx.lineTo(width, height);
ctx.lineTo(0, height);
ctx.fill();
ctx.restore();
// Animate next frame
curve.animate(this);
},
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment