Skip to content

Instantly share code, notes, and snippets.

@tzamora
Created October 2, 2020 15:54
Show Gist options
  • Save tzamora/479c7c8405d8d04848424c8c4dcb8c89 to your computer and use it in GitHub Desktop.
Save tzamora/479c7c8405d8d04848424c8c4dcb8c89 to your computer and use it in GitHub Desktop.
(function() {
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) {
return window.setTimeout(callback, 1000 / 60);
};
})();
$(function() {
var animate, canvas, context, drawMarker, rainDrop;
canvas = document.getElementById('canvas');
context = canvas.getContext('2d');
CanvasRenderingContext2D.prototype.rainDrop = function(x, y, width, height, fill, stroke) {
var center, shadow, shadowGradient;
center = {
x: x + width / 2,
y: y + height / 2
};
this.beginPath();
shadow = {
width: width / 2,
height: width / 2
};
shadow.start = {
x: center.x - shadow.width / 2,
y: y + height - shadow.height
};
shadowGradient = this.createRadialGradient(shadow.start.x + shadow.width / 2, shadow.start.y + shadow.height / 2, 0, shadow.start.x + shadow.width / 2, shadow.start.y + shadow.height / 2, shadow.width / 2);
shadowGradient.addColorStop(0, 'rgba(0,0,0,.3)');
shadowGradient.addColorStop(1, 'rgba(0,0,0,0)');
this.setTransform(1, 0, 0, 0.5, 0, 0);
this.translate(0, y + height + shadow.height / 2);
this.fillStyle = shadowGradient;
this.fillRect(shadow.start.x, shadow.start.y, shadow.width, shadow.height);
this.fill();
this.closePath();
this.setTransform(1, 0, 0, 1, 0, 0);
this.beginPath();
this.arc(center.x, y + height / 3, width / 2, Math.PI, 0, false);
this.bezierCurveTo(x + width, y + (height / 3) + height / 4, center.x + width / 3, center.y, center.x, y + height);
this.moveTo(x, y + height / 3);
this.bezierCurveTo(x, y + (height / 3) + height / 4, center.x - width / 3, center.y, center.x, y + height);
if (fill) {
this.fillStyle = fill;
this.fill();
}
if (stroke) {
this.strokeStyle = stroke;
return this.stroke();
}
};
drawMarker = function(rainDrop) {
var darkRedGradient, highlight, highlightThickness, inner, redGradient, whiteBall;
rainDrop.width = rainDrop.size;
rainDrop.height = rainDrop.size * 1.5;
redGradient = context.createLinearGradient(rainDrop.x, rainDrop.y, rainDrop.x + rainDrop.width, rainDrop.y + rainDrop.height);
redGradient.addColorStop(0, '#d00');
redGradient.addColorStop(1, '#600');
darkRedGradient = context.createLinearGradient(rainDrop.x, rainDrop.y, rainDrop.x + rainDrop.width, rainDrop.y + rainDrop.height);
darkRedGradient.addColorStop(0, '#800');
darkRedGradient.addColorStop(1, '#500');
context.lineWidth = 1.2;
context.rainDrop(rainDrop.x, rainDrop.y, rainDrop.width, rainDrop.height, redGradient, darkRedGradient);
highlightThickness = (rainDrop.width / 99.0) * rainDrop.borderWidth;
highlight = {
x: rainDrop.x + 1.5,
y: rainDrop.y,
width: rainDrop.width - 2.5,
height: rainDrop.height - highlightThickness * 2.5
};
context.rainDrop(highlight.x, highlight.y, highlight.width, highlight.height, 'rgba(255,0,0,.5)', false);
inner = {
x: highlight.x,
y: highlight.y + 1.5,
width: highlight.width,
height: highlight.height - highlightThickness
};
context.rainDrop(inner.x, inner.y, inner.width, inner.height, redGradient, false);
context.closePath();
context.beginPath();
whiteBall = {
color: '#fff',
border: '#800',
width: rainDrop.width / 4,
height: rainDrop.width / 4,
x: rainDrop.x + rainDrop.width / 2,
y: rainDrop.y + (rainDrop.height / 3)
};
context.arc(whiteBall.x, whiteBall.y, whiteBall.width / 2, Math.PI * 2, 0, false);
context.fillStyle = whiteBall.color;
return context.fill();
};
animate = function(rainDrop) {
var amplitude, centerX, centerY, date, nextX, nextY, period, time;
rainDrop.width = rainDrop.size;
rainDrop.height = rainDrop.size * 1.5;
date = new Date();
time = date.getTime();
amplitude = 150;
period = 2000;
centerX = canvas.width / 2 - rainDrop.width / 2;
centerY = canvas.height / 2 - rainDrop.height / 2;
nextX = amplitude * Math.sin(time * 2 * Math.PI / period) + centerX;
nextY = amplitude * Math.sin(time * 2.5 * Math.PI / period) + centerY;
rainDrop.x = nextX;
rainDrop.y = nextY;
if (rainDrop.grow === true) {
rainDrop.size += 0.5;
} else {
rainDrop.size -= 0.5;
}
if (rainDrop.size >= 128) {
rainDrop.grow = false;
}
if (rainDrop.size <= 24) {
rainDrop.grow = true;
}
context.clearRect(0, 0, canvas.width, canvas.height);
drawMarker(rainDrop);
return requestAnimFrame(function() {
return animate(rainDrop);
});
};
rainDrop = {
size: 24,
x: 250,
y: 250,
borderWidth: 1.5,
grow: true
};
return animate(rainDrop);
});
}).call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment