Last active
March 12, 2018 16:08
-
-
Save teddykishi/cc623d4648f26568f82ecad2dcb2d5cc to your computer and use it in GitHub Desktop.
Somme useful js tools
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
/***************** | |
ANIMATION | |
*****************/ | |
// tiny helper for jquery to know when an css animation/transition ends | |
// $(".cls").on(animationEnd, fn); | |
var animationEnd = "webkitAnimationEnd oanimationend msAnimationEnd animationend"; | |
// $(".cls").on(transitionEnd, fn); | |
var transitionEnd = "webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend"; | |
/**************** | |
RANDOM | |
****************/ | |
function rndFloatRange(min, max) { | |
return min + (Math.random() * (max - min)); | |
} | |
function rndIntRange(min, max) { | |
return Math.round(rndRange(min, max)); | |
} | |
function rndColor(){ | |
return '#' + Math.floor(Math.random() * 16777215).toString(16); | |
} | |
function rndColor(){ | |
var r = Math.floor( Math.random() * 255 ); | |
var g = Math.floor( Math.random() * 255 ); | |
var b = Math.floor( Math.random() * 255 ); | |
return 'rgb('+r+','+g+','+b+')'; | |
} | |
/**************** | |
ANGLES | |
*****************/ | |
var PI = Math.PI; | |
var RADIANS = PI / 180; | |
var DEGREES = 180 / PI; | |
// degrees to radians | |
function toRadians(degrees) { | |
return degrees * Math.PI / 180; | |
} | |
// radians to degrees | |
function toDegrees(radians) { | |
return radians * 180 / Math.PI; | |
} | |
function getAngle(x1, y1, x2, y2) { | |
/*var deltaX = x2 - x1; | |
var deltaY = y2 - y1; | |
var rad = Math.atan2(deltaY, deltaX); // In radians | |
*/ | |
return - Math.atan2(y2 - y1, x2 - x1); | |
} | |
function pointInAngleDist(offset, start, to){ | |
var angle = Math.atan2(to.y - start.y - offset, to.x - start.x - offset), | |
angleDeg = (angle * 180 / Math.PI).toFixed(2), | |
dist = distanceBetween(start.x, start.y, to.x, to.y), | |
x = (start.x - offset) + Math.cos(angle) * (dist*.5), | |
y = (start.y - offset) + Math.sin(angle) * (dist*.5); | |
return { x : x, y : y, angle : angleDeg} | |
} | |
/**************** | |
DISTANCE | |
*****************/ | |
// get distance between | |
function distanceBetween(x1, y1, x2, y2) { | |
var dx = x1 - x2, | |
dy = y1 - y2; | |
return Math.sqrt(dx * dx + dy * dy); | |
} | |
/**************** | |
COLLISIONS | |
*****************/ | |
// square collision | |
function overlapSquare(x1, y1, w1, h1, x2, y2, w2, h2) { | |
if (x1 + w1 > x2 && x1 < x2 + w2 && y1 + h1 > y2 && y1 < y2 + h2) { | |
return true; | |
} | |
return false; | |
} | |
// circle collision | |
function overlapCircle(cx1, cy1, cr1, cx2, cy2, cr2) { | |
var dx = cx1 - cx2, dy = cy1 - cy1, distance = (dx * dx + dy * dy); | |
if (distance <= (cr1 + cr2) * (cr1 + cr2)) { | |
return true; | |
} | |
return false; | |
} | |
// p1 is an object {x : 0, y:0 } | |
// p2 is an object {x : 0, y:0 } | |
// c is an object {x : 0, y:0 } | |
// r radius of the circle | |
function interceptOnCircle(p1, p2, c, r) { | |
//p1 is the first line point | |
//p2 is the second line point | |
//c is the circle's center | |
//r is the circle's radius | |
var p3 = {x:p1.x - c.x, y:p1.y - c.y}; //shifted line points | |
var p4 = {x:p2.x - c.x, y:p2.y - c.y}; | |
var m = (p4.y - p3.y) / (p4.x - p3.x); //slope of the line | |
var b = p3.y - m * p3.x; //y-intercept of line | |
var underRadical = Math.pow(r,2)*Math.pow(m,2) + Math.pow(r,2) - Math.pow(b,2); //the value under the square root sign | |
if (underRadical < 0) { | |
//line completely missed | |
return false; | |
} else { | |
var t1 = (-m*b + Math.sqrt(underRadical))/(Math.pow(m,2) + 1); //one of the intercept x's | |
var t2 = (-m*b - Math.sqrt(underRadical))/(Math.pow(m,2) + 1); //other intercept's x | |
var i1 = {x:t1+c.x, y:m*t1+b+c.y}; //intercept point 1 | |
var i2 = {x:t2+c.x, y:m*t2+b+c.y}; //intercept point 2 | |
return [i1, i2]; | |
} | |
} | |
// check isPointInCircle | |
function isPointInCircle(cx, cy, r, x, y){ | |
var dx = (cx - x)^2, | |
dy = (cy - y)^2, | |
d = Math.sqrt( dx + dy); | |
return d <= r; | |
} | |
// check if two line intersects | |
function checkLineIntersection(line1StartX, line1StartY, line1EndX, line1EndY, line2StartX, line2StartY, line2EndX, line2EndY) { | |
// if the lines intersect, the result contains the x and y of the intersection (treating the lines as infinite) and booleans for whether line segment 1 or line segment 2 contain the point | |
var denominator, a, b, numerator1, numerator2, result = { x: null, y: null, onLine1: false, onLine2: false }; | |
denominator = ((line2EndY - line2StartY) * (line1EndX - line1StartX)) - ((line2EndX - line2StartX) * (line1EndY - line1StartY)); | |
if (denominator === 0) { return result; } | |
a = line1StartY - line2StartY; | |
b = line1StartX - line2StartX; | |
numerator1 = ((line2EndX - line2StartX) * a) - ((line2EndY - line2StartY) * b); | |
numerator2 = ((line1EndX - line1StartX) * a) - ((line1EndY - line1StartY) * b); | |
a = numerator1 / denominator; | |
b = numerator2 / denominator; | |
// if we cast these lines infinitely in both directions, they intersect here: | |
result.x = line1StartX + (a * (line1EndX - line1StartX)); | |
result.y = line1StartY + (a * (line1EndY - line1StartY)); | |
// if line1 is a segment and line2 is infinite, they intersect if: | |
if (a > 0 && a < 1) { result.onLine1 = true; } | |
// if line2 is a segment and line1 is infinite, they intersect if: | |
if (b > 0 && b < 1) { result.onLine2 = true; } | |
// if line1 and line2 are segments, they intersect if both of the above are true | |
return result; | |
} | |
// var point = {x: 1, y: 2}; | |
// var rectangle = {x1: 0, x2: 10, y1: 1, y2: 7}; | |
// pointRectangleIntersection(point, rectangle); | |
function isPointInRect(point, rect) { | |
return point.x > rect.x && point.x < rect.width && point.y > rect.y && point.y < rect.height; | |
} | |
function isPointInPoly(poly, pt){ | |
for(var i = -1, l = poly.length, j = l - 1; ++i < l; j = i){ | |
if(((poly[i].y <= pt.y && pt.y < poly[j].y) || (poly[j].y <= pt.y && pt.y < poly[i].y)) && | |
(pt.x < (poly[j].x - poly[i].x) * (pt.y - poly[i].y) / (poly[j].y - poly[i].y) + poly[i].x) ){ | |
return true; | |
} | |
} | |
return false; | |
} | |
// check if two svg path eleme,nt intersects | |
function checkPathIntersection(path1, path2, accuracy, debug){ | |
var collision, line1StartX, line1StartY, line1EndX, line1EndY,l,m, | |
line1 = pathToPolyline(path1, accuracy, debug), | |
line2 = pathToPolyline(path2, accuracy, debug), | |
colisions = []; | |
if(debug){ | |
svg.appendChild(line1.polyline); | |
svg.appendChild(line2.polyline); | |
} | |
for(l = 1; l < line1.points.length; l++){ | |
line1StartX = line1.points[l-1][0]; | |
line1StartY = line1.points[l-1][1]; | |
line1EndX = line1.points[l][0]; | |
line1EndY = line1.points[l][1]; | |
for(m = 1; m < line2.points.length; m++){ | |
line2StartX = line2.points[m-1][0]; | |
line2StartY = line2.points[m-1][1]; | |
line2EndX = line2.points[m][0]; | |
line2EndY = line2.points[m][1]; | |
collision = checkLineIntersection(line1StartX, line1StartY, line1EndX, line1EndY, line2StartX, line2StartY, line2EndX, line2EndY); | |
if(collision.onLine1 && collision.onLine2){ | |
colisions.push(collision); | |
} | |
} | |
} | |
if(colisions.length){ | |
return colisions; | |
} | |
return false; | |
} | |
/* transform a svh path tag to an array of points [[x,y],[x,y],...] */ | |
function pathToPolyline(path, segments, debug){ | |
var division = Math.round(segments), | |
curveLength = path.getTotalLength(), | |
step = curveLength / segments, | |
currentPosition = curveLength, | |
point = path.getPointAtLength(currentPosition), | |
polyline = false, | |
points = []; | |
for(var i = 0; i <= segments; i++){ | |
currentPosition -= step; | |
point = path.getPointAtLength(currentPosition+step); | |
points.push([parseFloat((point.x).toFixed(2)), parseFloat((point.y).toFixed(2))]); | |
} | |
if(debug){polyline = arrayToPolyline(points); } | |
return { polyline : polyline, points : points }; | |
} | |
/*************** | |
SVG TOOLS | |
/****************/ | |
/* create and SVG element */ | |
// makeSVG(element, "circle", { cx : 10, cy : 10, r : 20 }); | |
function makeSVG(parent, tag, attrs) { | |
var el= document.createElementNS('http://www.w3.org/2000/svg', tag); | |
for (var k in attrs){ | |
if(k=="xlink:href"){ | |
el.setAttributeNS('http://www.w3.org/1999/xlink', 'href', attrs[k]); | |
} else { | |
el.setAttribute(k, attrs[k]); | |
} | |
} | |
} | |
/* TRANSFORM an array of data [[x,y],[x,y],...] to a polyline svg element */ | |
function arrayToPolyline(array){ | |
var polyline = document.createElementNS("http://www.w3.org/2000/svg","polyline"); | |
polyline.setAttribute("fill", "none"); | |
polyline.setAttribute("stroke", "greenyellow"); | |
polyline.setAttribute("stroke-width", "2"); | |
polyline.setAttribute("points", array.join(" ")); | |
return polyline; | |
} | |
/************* | |
ARRAYS | |
**************/ | |
function sortOn(array, key) { | |
array.sort(function(a, b) { | |
if (a[key] < b[key]) { | |
return -1; | |
} else if (a[key] > b[key]) { | |
return 1; | |
} | |
return 0; | |
}); | |
} | |
// https://bost.ocks.org/mike/shuffle/ | |
function shuffle(array) { | |
var m = array.length, t, i; | |
while (m) { | |
i = Math.floor(Math.random() * m--); | |
t = array[m]; | |
array[m] = array[i]; | |
array[i] = t; | |
} | |
return array; | |
} | |
function remove(array, index) { | |
var output = array.slice(0); | |
if (output[index]) { | |
output.splice(index, 1); | |
return output; | |
} | |
} | |
var getDegreeDirection = function(x1, y1, x2, y2){ | |
return Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI; | |
} | |
var removeFromArrayById = function(array, id){ | |
var output = array.slice(0); | |
for(var i=0; i<output.length; i++){ | |
if(output[i].id == id){ | |
output.splice(i, 1); | |
return output; | |
} | |
} | |
} | |
var hitTestCircle = function (ball1, ball2) { | |
var retVal = false; | |
var dx = ball1.nextX - ball2.nextX; | |
var dy = ball1.nextY - ball2.nextY; | |
var distance = (dx * dx + dy * dy); | |
if (distance <= (ball1.radius + ball2.radius) * (ball1.radius + ball2.radius) ) { | |
retVal = true; | |
} | |
return retVal; | |
} | |
var fibonacci = function (n) { | |
var i, w, u, v; | |
if(n <= 0) return 0; | |
if(n == 1) return 1; | |
u = 0; | |
v = 1; | |
for(i=2; i <= n; i++) { | |
w = u+v; u = v; v = w; | |
}; | |
return v; | |
} | |
var alphabet = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]; | |
var randomLetter = function(){ | |
return alphabet[Math.round(randomRange(0,25))]; | |
} | |
var randomColor = function(){ | |
return '#' + Math.floor(Math.random() * 16777215).toString(16); | |
} | |
/** | |
* Shuffles array in place. | |
* @param {Array} a items The array containing the items. | |
*/ | |
function shuffle(a) { | |
var j, x, i; | |
for (i = a.length; i; i -= 1) { | |
j = Math.floor(Math.random() * i); | |
x = a[i - 1]; | |
a[i - 1] = a[j]; | |
a[j] = x; | |
} | |
} | |
/* | |
isIntersecting = function(r1, r2) { | |
return !(r2.x > (r1.x + r1.width) || | |
(r2.x + r2.width) < r1.x || | |
r2.y > (r1.y + r1.height) || | |
(r2.y + r2.height) < r1.y); | |
} | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment