Repository: stared/interactive-machine-learning-list
Branch: master
Commit: a2357ca50904
Files: 10
Total size: 88.0 KB
Directory structure:
gitextract_j6txg211/
├── .github/
│ └── FUNDING.yml
├── .gitignore
├── LICENSE
├── README.md
├── index.html
├── src/
│ ├── main.js
│ ├── particles.js
│ ├── particlesjs-config.json
│ └── style.css
└── websites.yaml
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: [stared]
================================================
FILE: .gitignore
================================================
.idea
.config
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2018 Piotr Migdał
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# interactive-machine-learning-list
A collaborative list of interactive Machine Learning, Deep Learning and Statistics websites.
Started by [Piotr Migdał](https://p.migdal.pl/), but anyone is encouraged to contribute!
It is a simple no-build Vue.js website:
* [p.migdal.pl/interactive-machine-learning-list/](https://p.migdal.pl/interactive-machine-learning-list/)
Feel invited to Pull Request other interactive visualizations (check [websites.yaml](https://github.com/stared/interactive-machine-learning-list/blob/master/websites.yaml))! :)
...aaand if you want to create such visualizations by yourself, see [In Browser AI](https://inbrowser.ai/).
## What goes there?
Still I am thinking what is the best criterion.
For sure things that are front-end (i.e. JavaScript within browser).
For things using backend (when you can see solution, but it uses some PyTorch/TF/etc code on a server) I am still debating, but I lean on being more inclusive. In this context:
* make sure it has some didactic value (otherwise ALL services using ML would qualify)
* add `backend-dependent` in `uses`
Strong preference for open-source solutions (so people can reuse it and learn from code), though it is not a requirement. Though, mention repo and open source license only when it is directly relevant (vs additional materials such as exercises for a book, or Python algorithm).
## Other lists
* [Explorable Explanations](http://explorabl.es/)
* [Distill](https://distill.pub/)
* [Explained Visually](http://setosa.io/ev/)
* [AI Experiments with Google](https://experiments.withgoogle.com/collection/ai)
## Inspirations
Read [Explorable Explanations](http://worrydream.com/ExplorableExplanations/) by Bret Victor.
Inspirations for collecting and displaying content:
* [Science-based games - a collaborative list](https://github.com/stared/science-based-games-list) - a list I started (maybe I will turn it int something interactive as well)
* [Kaggle Past Solutions](http://ndres.me/kaggle-past-solutions/) - a searchable compilation of Kaggle past solutions
* source: [EliotAndres/kaggle-past-solutions](https://github.com/EliotAndres/kaggle-past-solutions)
* [D3 Discovery](https://d3-discovery.net/) - finding D3 plugins with ease
* source: [https://github.com/wbkd/d3-discovery](https://github.com/wbkd/d3-discovery)
## Design
Main layout and styling developed by [Jakub Fogel](https://github.com/fogelkuba)
## TO DO
(You are invited to constribute)
* Descriptions of sites
* Write-up in a different way
* Some sorting (alphabetical?)
* Share button
* Code refactoring :)
================================================
FILE: index.html
================================================
Interactive Machine Learning List
================================================
FILE: src/main.js
================================================
document.addEventListener('DOMContentLoaded', function () {
/* particlesJS.load(@dom-id, @path-json, @callback (optional)); */
particlesJS.load('particles-js', 'src/particlesjs-config.json', function () {
console.log('callback - particles.js config loaded');
});
});
Vue.component('tag-selector', {
props: ['all-tags'],
template: document.getElementById('tag-selector'),
});
const app = new Vue({
el: '#app',
data: {
websites: [],
allTags: [],
filters: []
},
computed: {
filteredWebsites: function() {
return this.websites.filter((website) =>
this.filters.every((tag) =>
website.allTags.includes(tag)
)
);
}
},
created: function() {
const that = this;
fetch("websites.yaml")
.then(response => response.text())
.then(text => {
that.websites = jsyaml.load(text);
that.websites.forEach((website) => {
website.allTags = website.tags.concat(website.uses);
if (!!website.license) {
website.allTags.push(website.license);
}
});
that.websites.forEach((website) => {
website.allTags.forEach((tag) => {
if (that.allTags.indexOf(tag) === -1) {
that.allTags.push(tag);
}
});
});
that.allTags.sort((a, b) =>
a.toLowerCase() < b.toLowerCase() ? -1 : 1
);
});
},
methods: {
etAl: (authors) => {
if (authors.length < 3) {
return authors.join(", ");
} else {
return authors.slice(0, 3).join(", ") + " et al.";
}
},
addRemoveToFilters: function(tag) {
if (this.filters.indexOf(tag) === -1) {
this.filters.push(tag);
} else {
this.filters = this.filters
.filter((x) => x !== tag);
}
},
checkActive: function(tag) {
return this.filters.indexOf(tag) > -1;
},
clearAllFilters: function() {
this.filters = [];
},
getTagCount: function(tag) {
return this.filteredWebsites
.filter((website) => website.allTags.includes(tag))
.length;
}
}
});
================================================
FILE: src/particles.js
================================================
/* -----------------------------------------------
/* Author : Vincent Garreau - vincentgarreau.com
/* MIT license: http://opensource.org/licenses/MIT
/* Demo / Generator : vincentgarreau.com/particles.js
/* GitHub : github.com/VincentGarreau/particles.js
/* How to use? : Check the GitHub README
/* v2.0.0
/* ----------------------------------------------- */
var pJS = function(tag_id, params){
var canvas_el = document.querySelector('#'+tag_id+' > .particles-js-canvas-el');
/* particles.js variables with default values */
this.pJS = {
canvas: {
el: canvas_el,
w: canvas_el.offsetWidth,
h: canvas_el.offsetHeight
},
particles: {
number: {
value: 400,
density: {
enable: true,
value_area: 800
}
},
color: {
value: '#fff'
},
shape: {
type: 'circle',
stroke: {
width: 0,
color: '#ff0000'
},
polygon: {
nb_sides: 5
},
image: {
src: '',
width: 100,
height: 100
}
},
opacity: {
value: 1,
random: false,
anim: {
enable: false,
speed: 2,
opacity_min: 0,
sync: false
}
},
size: {
value: 20,
random: false,
anim: {
enable: false,
speed: 20,
size_min: 0,
sync: false
}
},
line_linked: {
enable: true,
distance: 100,
color: '#fff',
opacity: 1,
width: 1
},
move: {
enable: true,
speed: 2,
direction: 'none',
random: false,
straight: false,
out_mode: 'out',
bounce: false,
attract: {
enable: false,
rotateX: 3000,
rotateY: 3000
}
},
array: []
},
interactivity: {
detect_on: 'canvas',
events: {
onhover: {
enable: true,
mode: 'grab'
},
onclick: {
enable: true,
mode: 'push'
},
resize: true
},
modes: {
grab:{
distance: 100,
line_linked:{
opacity: 1
}
},
bubble:{
distance: 200,
size: 80,
duration: 0.4
},
repulse:{
distance: 200,
duration: 0.4
},
push:{
particles_nb: 4
},
remove:{
particles_nb: 2
}
},
mouse:{}
},
retina_detect: false,
fn: {
interact: {},
modes: {},
vendors:{}
},
tmp: {}
};
var pJS = this.pJS;
/* params settings */
if(params){
Object.deepExtend(pJS, params);
}
pJS.tmp.obj = {
size_value: pJS.particles.size.value,
size_anim_speed: pJS.particles.size.anim.speed,
move_speed: pJS.particles.move.speed,
line_linked_distance: pJS.particles.line_linked.distance,
line_linked_width: pJS.particles.line_linked.width,
mode_grab_distance: pJS.interactivity.modes.grab.distance,
mode_bubble_distance: pJS.interactivity.modes.bubble.distance,
mode_bubble_size: pJS.interactivity.modes.bubble.size,
mode_repulse_distance: pJS.interactivity.modes.repulse.distance
};
pJS.fn.retinaInit = function(){
if(pJS.retina_detect && window.devicePixelRatio > 1){
pJS.canvas.pxratio = window.devicePixelRatio;
pJS.tmp.retina = true;
}
else{
pJS.canvas.pxratio = 1;
pJS.tmp.retina = false;
}
pJS.canvas.w = pJS.canvas.el.offsetWidth * pJS.canvas.pxratio;
pJS.canvas.h = pJS.canvas.el.offsetHeight * pJS.canvas.pxratio;
pJS.particles.size.value = pJS.tmp.obj.size_value * pJS.canvas.pxratio;
pJS.particles.size.anim.speed = pJS.tmp.obj.size_anim_speed * pJS.canvas.pxratio;
pJS.particles.move.speed = pJS.tmp.obj.move_speed * pJS.canvas.pxratio;
pJS.particles.line_linked.distance = pJS.tmp.obj.line_linked_distance * pJS.canvas.pxratio;
pJS.interactivity.modes.grab.distance = pJS.tmp.obj.mode_grab_distance * pJS.canvas.pxratio;
pJS.interactivity.modes.bubble.distance = pJS.tmp.obj.mode_bubble_distance * pJS.canvas.pxratio;
pJS.particles.line_linked.width = pJS.tmp.obj.line_linked_width * pJS.canvas.pxratio;
pJS.interactivity.modes.bubble.size = pJS.tmp.obj.mode_bubble_size * pJS.canvas.pxratio;
pJS.interactivity.modes.repulse.distance = pJS.tmp.obj.mode_repulse_distance * pJS.canvas.pxratio;
};
/* ---------- pJS functions - canvas ------------ */
pJS.fn.canvasInit = function(){
pJS.canvas.ctx = pJS.canvas.el.getContext('2d');
};
pJS.fn.canvasSize = function(){
pJS.canvas.el.width = pJS.canvas.w;
pJS.canvas.el.height = pJS.canvas.h;
if(pJS && pJS.interactivity.events.resize){
window.addEventListener('resize', function(){
pJS.canvas.w = pJS.canvas.el.offsetWidth;
pJS.canvas.h = pJS.canvas.el.offsetHeight;
/* resize canvas */
if(pJS.tmp.retina){
pJS.canvas.w *= pJS.canvas.pxratio;
pJS.canvas.h *= pJS.canvas.pxratio;
}
pJS.canvas.el.width = pJS.canvas.w;
pJS.canvas.el.height = pJS.canvas.h;
/* repaint canvas on anim disabled */
if(!pJS.particles.move.enable){
pJS.fn.particlesEmpty();
pJS.fn.particlesCreate();
pJS.fn.particlesDraw();
pJS.fn.vendors.densityAutoParticles();
}
/* density particles enabled */
pJS.fn.vendors.densityAutoParticles();
});
}
};
pJS.fn.canvasPaint = function(){
pJS.canvas.ctx.fillRect(0, 0, pJS.canvas.w, pJS.canvas.h);
};
pJS.fn.canvasClear = function(){
pJS.canvas.ctx.clearRect(0, 0, pJS.canvas.w, pJS.canvas.h);
};
/* --------- pJS functions - particles ----------- */
pJS.fn.particle = function(color, opacity, position){
/* size */
this.radius = (pJS.particles.size.random ? Math.random() : 1) * pJS.particles.size.value;
if(pJS.particles.size.anim.enable){
this.size_status = false;
this.vs = pJS.particles.size.anim.speed / 100;
if(!pJS.particles.size.anim.sync){
this.vs = this.vs * Math.random();
}
}
/* position */
this.x = position ? position.x : Math.random() * pJS.canvas.w;
this.y = position ? position.y : Math.random() * pJS.canvas.h;
/* check position - into the canvas */
if(this.x > pJS.canvas.w - this.radius*2) this.x = this.x - this.radius;
else if(this.x < this.radius*2) this.x = this.x + this.radius;
if(this.y > pJS.canvas.h - this.radius*2) this.y = this.y - this.radius;
else if(this.y < this.radius*2) this.y = this.y + this.radius;
/* check position - avoid overlap */
if(pJS.particles.move.bounce){
pJS.fn.vendors.checkOverlap(this, position);
}
/* color */
this.color = {};
if(typeof(color.value) == 'object'){
if(color.value instanceof Array){
var color_selected = color.value[Math.floor(Math.random() * pJS.particles.color.value.length)];
this.color.rgb = hexToRgb(color_selected);
}else{
if(color.value.r != undefined && color.value.g != undefined && color.value.b != undefined){
this.color.rgb = {
r: color.value.r,
g: color.value.g,
b: color.value.b
}
}
if(color.value.h != undefined && color.value.s != undefined && color.value.l != undefined){
this.color.hsl = {
h: color.value.h,
s: color.value.s,
l: color.value.l
}
}
}
}
else if(color.value == 'random'){
this.color.rgb = {
r: (Math.floor(Math.random() * (255 - 0 + 1)) + 0),
g: (Math.floor(Math.random() * (255 - 0 + 1)) + 0),
b: (Math.floor(Math.random() * (255 - 0 + 1)) + 0)
}
}
else if(typeof(color.value) == 'string'){
this.color = color;
this.color.rgb = hexToRgb(this.color.value);
}
/* opacity */
this.opacity = (pJS.particles.opacity.random ? Math.random() : 1) * pJS.particles.opacity.value;
if(pJS.particles.opacity.anim.enable){
this.opacity_status = false;
this.vo = pJS.particles.opacity.anim.speed / 100;
if(!pJS.particles.opacity.anim.sync){
this.vo = this.vo * Math.random();
}
}
/* animation - velocity for speed */
var velbase = {}
switch(pJS.particles.move.direction){
case 'top':
velbase = { x:0, y:-1 };
break;
case 'top-right':
velbase = { x:0.5, y:-0.5 };
break;
case 'right':
velbase = { x:1, y:-0 };
break;
case 'bottom-right':
velbase = { x:0.5, y:0.5 };
break;
case 'bottom':
velbase = { x:0, y:1 };
break;
case 'bottom-left':
velbase = { x:-0.5, y:1 };
break;
case 'left':
velbase = { x:-1, y:0 };
break;
case 'top-left':
velbase = { x:-0.5, y:-0.5 };
break;
default:
velbase = { x:0, y:0 };
break;
}
if(pJS.particles.move.straight){
this.vx = velbase.x;
this.vy = velbase.y;
if(pJS.particles.move.random){
this.vx = this.vx * (Math.random());
this.vy = this.vy * (Math.random());
}
}else{
this.vx = velbase.x + Math.random()-0.5;
this.vy = velbase.y + Math.random()-0.5;
}
// var theta = 2.0 * Math.PI * Math.random();
// this.vx = Math.cos(theta);
// this.vy = Math.sin(theta);
this.vx_i = this.vx;
this.vy_i = this.vy;
/* if shape is image */
var shape_type = pJS.particles.shape.type;
if(typeof(shape_type) == 'object'){
if(shape_type instanceof Array){
var shape_selected = shape_type[Math.floor(Math.random() * shape_type.length)];
this.shape = shape_selected;
}
}else{
this.shape = shape_type;
}
if(this.shape == 'image'){
var sh = pJS.particles.shape;
this.img = {
src: sh.image.src,
ratio: sh.image.width / sh.image.height
}
if(!this.img.ratio) this.img.ratio = 1;
if(pJS.tmp.img_type == 'svg' && pJS.tmp.source_svg != undefined){
pJS.fn.vendors.createSvgImg(this);
if(pJS.tmp.pushing){
this.img.loaded = false;
}
}
}
};
pJS.fn.particle.prototype.draw = function() {
var p = this;
if(p.radius_bubble != undefined){
var radius = p.radius_bubble;
}else{
var radius = p.radius;
}
if(p.opacity_bubble != undefined){
var opacity = p.opacity_bubble;
}else{
var opacity = p.opacity;
}
if(p.color.rgb){
var color_value = 'rgba('+p.color.rgb.r+','+p.color.rgb.g+','+p.color.rgb.b+','+opacity+')';
}else{
var color_value = 'hsla('+p.color.hsl.h+','+p.color.hsl.s+'%,'+p.color.hsl.l+'%,'+opacity+')';
}
pJS.canvas.ctx.fillStyle = color_value;
pJS.canvas.ctx.beginPath();
switch(p.shape){
case 'circle':
pJS.canvas.ctx.arc(p.x, p.y, radius, 0, Math.PI * 2, false);
break;
case 'edge':
pJS.canvas.ctx.rect(p.x-radius, p.y-radius, radius*2, radius*2);
break;
case 'triangle':
pJS.fn.vendors.drawShape(pJS.canvas.ctx, p.x-radius, p.y+radius / 1.66, radius*2, 3, 2);
break;
case 'polygon':
pJS.fn.vendors.drawShape(
pJS.canvas.ctx,
p.x - radius / (pJS.particles.shape.polygon.nb_sides/3.5), // startX
p.y - radius / (2.66/3.5), // startY
radius*2.66 / (pJS.particles.shape.polygon.nb_sides/3), // sideLength
pJS.particles.shape.polygon.nb_sides, // sideCountNumerator
1 // sideCountDenominator
);
break;
case 'star':
pJS.fn.vendors.drawShape(
pJS.canvas.ctx,
p.x - radius*2 / (pJS.particles.shape.polygon.nb_sides/4), // startX
p.y - radius / (2*2.66/3.5), // startY
radius*2*2.66 / (pJS.particles.shape.polygon.nb_sides/3), // sideLength
pJS.particles.shape.polygon.nb_sides, // sideCountNumerator
2 // sideCountDenominator
);
break;
case 'image':
function draw(){
pJS.canvas.ctx.drawImage(
img_obj,
p.x-radius,
p.y-radius,
radius*2,
radius*2 / p.img.ratio
);
}
if(pJS.tmp.img_type == 'svg'){
var img_obj = p.img.obj;
}else{
var img_obj = pJS.tmp.img_obj;
}
if(img_obj){
draw();
}
break;
}
pJS.canvas.ctx.closePath();
if(pJS.particles.shape.stroke.width > 0){
pJS.canvas.ctx.strokeStyle = pJS.particles.shape.stroke.color;
pJS.canvas.ctx.lineWidth = pJS.particles.shape.stroke.width;
pJS.canvas.ctx.stroke();
}
pJS.canvas.ctx.fill();
};
pJS.fn.particlesCreate = function(){
for(var i = 0; i < pJS.particles.number.value; i++) {
pJS.particles.array.push(new pJS.fn.particle(pJS.particles.color, pJS.particles.opacity.value));
}
};
pJS.fn.particlesUpdate = function(){
for(var i = 0; i < pJS.particles.array.length; i++){
/* the particle */
var p = pJS.particles.array[i];
// var d = ( dx = pJS.interactivity.mouse.click_pos_x - p.x ) * dx + ( dy = pJS.interactivity.mouse.click_pos_y - p.y ) * dy;
// var f = -BANG_SIZE / d;
// if ( d < BANG_SIZE ) {
// var t = Math.atan2( dy, dx );
// p.vx = f * Math.cos(t);
// p.vy = f * Math.sin(t);
// }
/* move the particle */
if(pJS.particles.move.enable){
var ms = pJS.particles.move.speed/2;
p.x += p.vx * ms;
p.y += p.vy * ms;
}
/* change opacity status */
if(pJS.particles.opacity.anim.enable) {
if(p.opacity_status == true) {
if(p.opacity >= pJS.particles.opacity.value) p.opacity_status = false;
p.opacity += p.vo;
}else {
if(p.opacity <= pJS.particles.opacity.anim.opacity_min) p.opacity_status = true;
p.opacity -= p.vo;
}
if(p.opacity < 0) p.opacity = 0;
}
/* change size */
if(pJS.particles.size.anim.enable){
if(p.size_status == true){
if(p.radius >= pJS.particles.size.value) p.size_status = false;
p.radius += p.vs;
}else{
if(p.radius <= pJS.particles.size.anim.size_min) p.size_status = true;
p.radius -= p.vs;
}
if(p.radius < 0) p.radius = 0;
}
/* change particle position if it is out of canvas */
if(pJS.particles.move.out_mode == 'bounce'){
var new_pos = {
x_left: p.radius,
x_right: pJS.canvas.w,
y_top: p.radius,
y_bottom: pJS.canvas.h
}
}else{
var new_pos = {
x_left: -p.radius,
x_right: pJS.canvas.w + p.radius,
y_top: -p.radius,
y_bottom: pJS.canvas.h + p.radius
}
}
if(p.x - p.radius > pJS.canvas.w){
p.x = new_pos.x_left;
p.y = Math.random() * pJS.canvas.h;
}
else if(p.x + p.radius < 0){
p.x = new_pos.x_right;
p.y = Math.random() * pJS.canvas.h;
}
if(p.y - p.radius > pJS.canvas.h){
p.y = new_pos.y_top;
p.x = Math.random() * pJS.canvas.w;
}
else if(p.y + p.radius < 0){
p.y = new_pos.y_bottom;
p.x = Math.random() * pJS.canvas.w;
}
/* out of canvas modes */
switch(pJS.particles.move.out_mode){
case 'bounce':
if (p.x + p.radius > pJS.canvas.w) p.vx = -p.vx;
else if (p.x - p.radius < 0) p.vx = -p.vx;
if (p.y + p.radius > pJS.canvas.h) p.vy = -p.vy;
else if (p.y - p.radius < 0) p.vy = -p.vy;
break;
}
/* events */
if(isInArray('grab', pJS.interactivity.events.onhover.mode)){
pJS.fn.modes.grabParticle(p);
}
if(isInArray('bubble', pJS.interactivity.events.onhover.mode) || isInArray('bubble', pJS.interactivity.events.onclick.mode)){
pJS.fn.modes.bubbleParticle(p);
}
if(isInArray('repulse', pJS.interactivity.events.onhover.mode) || isInArray('repulse', pJS.interactivity.events.onclick.mode)){
pJS.fn.modes.repulseParticle(p);
}
/* interaction auto between particles */
if(pJS.particles.line_linked.enable || pJS.particles.move.attract.enable){
for(var j = i + 1; j < pJS.particles.array.length; j++){
var p2 = pJS.particles.array[j];
/* link particles */
if(pJS.particles.line_linked.enable){
pJS.fn.interact.linkParticles(p,p2);
}
/* attract particles */
if(pJS.particles.move.attract.enable){
pJS.fn.interact.attractParticles(p,p2);
}
/* bounce particles */
if(pJS.particles.move.bounce){
pJS.fn.interact.bounceParticles(p,p2);
}
}
}
}
};
pJS.fn.particlesDraw = function(){
/* clear canvas */
pJS.canvas.ctx.clearRect(0, 0, pJS.canvas.w, pJS.canvas.h);
/* update each particles param */
pJS.fn.particlesUpdate();
/* draw each particle */
for(var i = 0; i < pJS.particles.array.length; i++){
var p = pJS.particles.array[i];
p.draw();
}
};
pJS.fn.particlesEmpty = function(){
pJS.particles.array = [];
};
pJS.fn.particlesRefresh = function(){
/* init all */
cancelRequestAnimFrame(pJS.fn.checkAnimFrame);
cancelRequestAnimFrame(pJS.fn.drawAnimFrame);
pJS.tmp.source_svg = undefined;
pJS.tmp.img_obj = undefined;
pJS.tmp.count_svg = 0;
pJS.fn.particlesEmpty();
pJS.fn.canvasClear();
/* restart */
pJS.fn.vendors.start();
};
/* ---------- pJS functions - particles interaction ------------ */
pJS.fn.interact.linkParticles = function(p1, p2){
var dx = p1.x - p2.x,
dy = p1.y - p2.y,
dist = Math.sqrt(dx*dx + dy*dy);
/* draw a line between p1 and p2 if the distance between them is under the config distance */
if(dist <= pJS.particles.line_linked.distance){
var opacity_line = pJS.particles.line_linked.opacity - (dist / (1/pJS.particles.line_linked.opacity)) / pJS.particles.line_linked.distance;
if(opacity_line > 0){
/* style */
var color_line = pJS.particles.line_linked.color_rgb_line;
pJS.canvas.ctx.strokeStyle = 'rgba('+color_line.r+','+color_line.g+','+color_line.b+','+opacity_line+')';
pJS.canvas.ctx.lineWidth = pJS.particles.line_linked.width;
//pJS.canvas.ctx.lineCap = 'round'; /* performance issue */
/* path */
pJS.canvas.ctx.beginPath();
pJS.canvas.ctx.moveTo(p1.x, p1.y);
pJS.canvas.ctx.lineTo(p2.x, p2.y);
pJS.canvas.ctx.stroke();
pJS.canvas.ctx.closePath();
}
}
};
pJS.fn.interact.attractParticles = function(p1, p2){
/* condensed particles */
var dx = p1.x - p2.x,
dy = p1.y - p2.y,
dist = Math.sqrt(dx*dx + dy*dy);
if(dist <= pJS.particles.line_linked.distance){
var ax = dx/(pJS.particles.move.attract.rotateX*1000),
ay = dy/(pJS.particles.move.attract.rotateY*1000);
p1.vx -= ax;
p1.vy -= ay;
p2.vx += ax;
p2.vy += ay;
}
}
pJS.fn.interact.bounceParticles = function(p1, p2){
var dx = p1.x - p2.x,
dy = p1.y - p2.y,
dist = Math.sqrt(dx*dx + dy*dy),
dist_p = p1.radius+p2.radius;
if(dist <= dist_p){
p1.vx = -p1.vx;
p1.vy = -p1.vy;
p2.vx = -p2.vx;
p2.vy = -p2.vy;
}
}
/* ---------- pJS functions - modes events ------------ */
pJS.fn.modes.pushParticles = function(nb, pos){
pJS.tmp.pushing = true;
for(var i = 0; i < nb; i++){
pJS.particles.array.push(
new pJS.fn.particle(
pJS.particles.color,
pJS.particles.opacity.value,
{
'x': pos ? pos.pos_x : Math.random() * pJS.canvas.w,
'y': pos ? pos.pos_y : Math.random() * pJS.canvas.h
}
)
)
if(i == nb-1){
if(!pJS.particles.move.enable){
pJS.fn.particlesDraw();
}
pJS.tmp.pushing = false;
}
}
};
pJS.fn.modes.removeParticles = function(nb){
pJS.particles.array.splice(0, nb);
if(!pJS.particles.move.enable){
pJS.fn.particlesDraw();
}
};
pJS.fn.modes.bubbleParticle = function(p){
/* on hover event */
if(pJS.interactivity.events.onhover.enable && isInArray('bubble', pJS.interactivity.events.onhover.mode)){
var dx_mouse = p.x - pJS.interactivity.mouse.pos_x,
dy_mouse = p.y - pJS.interactivity.mouse.pos_y,
dist_mouse = Math.sqrt(dx_mouse*dx_mouse + dy_mouse*dy_mouse),
ratio = 1 - dist_mouse / pJS.interactivity.modes.bubble.distance;
function init(){
p.opacity_bubble = p.opacity;
p.radius_bubble = p.radius;
}
/* mousemove - check ratio */
if(dist_mouse <= pJS.interactivity.modes.bubble.distance){
if(ratio >= 0 && pJS.interactivity.status == 'mousemove'){
/* size */
if(pJS.interactivity.modes.bubble.size != pJS.particles.size.value){
if(pJS.interactivity.modes.bubble.size > pJS.particles.size.value){
var size = p.radius + (pJS.interactivity.modes.bubble.size*ratio);
if(size >= 0){
p.radius_bubble = size;
}
}else{
var dif = p.radius - pJS.interactivity.modes.bubble.size,
size = p.radius - (dif*ratio);
if(size > 0){
p.radius_bubble = size;
}else{
p.radius_bubble = 0;
}
}
}
/* opacity */
if(pJS.interactivity.modes.bubble.opacity != pJS.particles.opacity.value){
if(pJS.interactivity.modes.bubble.opacity > pJS.particles.opacity.value){
var opacity = pJS.interactivity.modes.bubble.opacity*ratio;
if(opacity > p.opacity && opacity <= pJS.interactivity.modes.bubble.opacity){
p.opacity_bubble = opacity;
}
}else{
var opacity = p.opacity - (pJS.particles.opacity.value-pJS.interactivity.modes.bubble.opacity)*ratio;
if(opacity < p.opacity && opacity >= pJS.interactivity.modes.bubble.opacity){
p.opacity_bubble = opacity;
}
}
}
}
}else{
init();
}
/* mouseleave */
if(pJS.interactivity.status == 'mouseleave'){
init();
}
}
/* on click event */
else if(pJS.interactivity.events.onclick.enable && isInArray('bubble', pJS.interactivity.events.onclick.mode)){
if(pJS.tmp.bubble_clicking){
var dx_mouse = p.x - pJS.interactivity.mouse.click_pos_x,
dy_mouse = p.y - pJS.interactivity.mouse.click_pos_y,
dist_mouse = Math.sqrt(dx_mouse*dx_mouse + dy_mouse*dy_mouse),
time_spent = (new Date().getTime() - pJS.interactivity.mouse.click_time)/1000;
if(time_spent > pJS.interactivity.modes.bubble.duration){
pJS.tmp.bubble_duration_end = true;
}
if(time_spent > pJS.interactivity.modes.bubble.duration*2){
pJS.tmp.bubble_clicking = false;
pJS.tmp.bubble_duration_end = false;
}
}
function process(bubble_param, particles_param, p_obj_bubble, p_obj, id){
if(bubble_param != particles_param){
if(!pJS.tmp.bubble_duration_end){
if(dist_mouse <= pJS.interactivity.modes.bubble.distance){
if(p_obj_bubble != undefined) var obj = p_obj_bubble;
else var obj = p_obj;
if(obj != bubble_param){
var value = p_obj - (time_spent * (p_obj - bubble_param) / pJS.interactivity.modes.bubble.duration);
if(id == 'size') p.radius_bubble = value;
if(id == 'opacity') p.opacity_bubble = value;
}
}else{
if(id == 'size') p.radius_bubble = undefined;
if(id == 'opacity') p.opacity_bubble = undefined;
}
}else{
if(p_obj_bubble != undefined){
var value_tmp = p_obj - (time_spent * (p_obj - bubble_param) / pJS.interactivity.modes.bubble.duration),
dif = bubble_param - value_tmp;
value = bubble_param + dif;
if(id == 'size') p.radius_bubble = value;
if(id == 'opacity') p.opacity_bubble = value;
}
}
}
}
if(pJS.tmp.bubble_clicking){
/* size */
process(pJS.interactivity.modes.bubble.size, pJS.particles.size.value, p.radius_bubble, p.radius, 'size');
/* opacity */
process(pJS.interactivity.modes.bubble.opacity, pJS.particles.opacity.value, p.opacity_bubble, p.opacity, 'opacity');
}
}
};
pJS.fn.modes.repulseParticle = function(p){
if(pJS.interactivity.events.onhover.enable && isInArray('repulse', pJS.interactivity.events.onhover.mode) && pJS.interactivity.status == 'mousemove') {
var dx_mouse = p.x - pJS.interactivity.mouse.pos_x,
dy_mouse = p.y - pJS.interactivity.mouse.pos_y,
dist_mouse = Math.sqrt(dx_mouse*dx_mouse + dy_mouse*dy_mouse);
var normVec = {x: dx_mouse/dist_mouse, y: dy_mouse/dist_mouse},
repulseRadius = pJS.interactivity.modes.repulse.distance,
velocity = 100,
repulseFactor = clamp((1/repulseRadius)*(-1*Math.pow(dist_mouse/repulseRadius,2)+1)*repulseRadius*velocity, 0, 50);
var pos = {
x: p.x + normVec.x * repulseFactor,
y: p.y + normVec.y * repulseFactor
}
if(pJS.particles.move.out_mode == 'bounce'){
if(pos.x - p.radius > 0 && pos.x + p.radius < pJS.canvas.w) p.x = pos.x;
if(pos.y - p.radius > 0 && pos.y + p.radius < pJS.canvas.h) p.y = pos.y;
}else{
p.x = pos.x;
p.y = pos.y;
}
}
else if(pJS.interactivity.events.onclick.enable && isInArray('repulse', pJS.interactivity.events.onclick.mode)) {
if(!pJS.tmp.repulse_finish){
pJS.tmp.repulse_count++;
if(pJS.tmp.repulse_count == pJS.particles.array.length){
pJS.tmp.repulse_finish = true;
}
}
if(pJS.tmp.repulse_clicking){
var repulseRadius = Math.pow(pJS.interactivity.modes.repulse.distance/6, 3);
var dx = pJS.interactivity.mouse.click_pos_x - p.x,
dy = pJS.interactivity.mouse.click_pos_y - p.y,
d = dx*dx + dy*dy;
var force = -repulseRadius / d * 1;
function process(){
var f = Math.atan2(dy,dx);
p.vx = force * Math.cos(f);
p.vy = force * Math.sin(f);
if(pJS.particles.move.out_mode == 'bounce'){
var pos = {
x: p.x + p.vx,
y: p.y + p.vy
}
if (pos.x + p.radius > pJS.canvas.w) p.vx = -p.vx;
else if (pos.x - p.radius < 0) p.vx = -p.vx;
if (pos.y + p.radius > pJS.canvas.h) p.vy = -p.vy;
else if (pos.y - p.radius < 0) p.vy = -p.vy;
}
}
// default
if(d <= repulseRadius){
process();
}
// bang - slow motion mode
// if(!pJS.tmp.repulse_finish){
// if(d <= repulseRadius){
// process();
// }
// }else{
// process();
// }
}else{
if(pJS.tmp.repulse_clicking == false){
p.vx = p.vx_i;
p.vy = p.vy_i;
}
}
}
}
pJS.fn.modes.grabParticle = function(p){
if(pJS.interactivity.events.onhover.enable && pJS.interactivity.status == 'mousemove'){
var dx_mouse = p.x - pJS.interactivity.mouse.pos_x,
dy_mouse = p.y - pJS.interactivity.mouse.pos_y,
dist_mouse = Math.sqrt(dx_mouse*dx_mouse + dy_mouse*dy_mouse);
/* draw a line between the cursor and the particle if the distance between them is under the config distance */
if(dist_mouse <= pJS.interactivity.modes.grab.distance){
var opacity_line = pJS.interactivity.modes.grab.line_linked.opacity - (dist_mouse / (1/pJS.interactivity.modes.grab.line_linked.opacity)) / pJS.interactivity.modes.grab.distance;
if(opacity_line > 0){
/* style */
var color_line = pJS.particles.line_linked.color_rgb_line;
pJS.canvas.ctx.strokeStyle = 'rgba('+color_line.r+','+color_line.g+','+color_line.b+','+opacity_line+')';
pJS.canvas.ctx.lineWidth = pJS.particles.line_linked.width;
//pJS.canvas.ctx.lineCap = 'round'; /* performance issue */
/* path */
pJS.canvas.ctx.beginPath();
pJS.canvas.ctx.moveTo(p.x, p.y);
pJS.canvas.ctx.lineTo(pJS.interactivity.mouse.pos_x, pJS.interactivity.mouse.pos_y);
pJS.canvas.ctx.stroke();
pJS.canvas.ctx.closePath();
}
}
}
};
/* ---------- pJS functions - vendors ------------ */
pJS.fn.vendors.eventsListeners = function(){
/* events target element */
if(pJS.interactivity.detect_on == 'window'){
pJS.interactivity.el = window;
}else{
pJS.interactivity.el = pJS.canvas.el;
}
/* detect mouse pos - on hover / click event */
if(pJS.interactivity.events.onhover.enable || pJS.interactivity.events.onclick.enable){
/* el on mousemove */
pJS.interactivity.el.addEventListener('mousemove', function(e){
if(pJS.interactivity.el == window){
var pos_x = e.clientX,
pos_y = e.clientY;
}
else{
var pos_x = e.offsetX || e.clientX,
pos_y = e.offsetY || e.clientY;
}
pJS.interactivity.mouse.pos_x = pos_x;
pJS.interactivity.mouse.pos_y = pos_y;
if(pJS.tmp.retina){
pJS.interactivity.mouse.pos_x *= pJS.canvas.pxratio;
pJS.interactivity.mouse.pos_y *= pJS.canvas.pxratio;
}
pJS.interactivity.status = 'mousemove';
});
/* el on onmouseleave */
pJS.interactivity.el.addEventListener('mouseleave', function(e){
pJS.interactivity.mouse.pos_x = null;
pJS.interactivity.mouse.pos_y = null;
pJS.interactivity.status = 'mouseleave';
});
}
/* on click event */
if(pJS.interactivity.events.onclick.enable){
pJS.interactivity.el.addEventListener('click', function(){
pJS.interactivity.mouse.click_pos_x = pJS.interactivity.mouse.pos_x;
pJS.interactivity.mouse.click_pos_y = pJS.interactivity.mouse.pos_y;
pJS.interactivity.mouse.click_time = new Date().getTime();
if(pJS.interactivity.events.onclick.enable){
switch(pJS.interactivity.events.onclick.mode){
case 'push':
if(pJS.particles.move.enable){
pJS.fn.modes.pushParticles(pJS.interactivity.modes.push.particles_nb, pJS.interactivity.mouse);
}else{
if(pJS.interactivity.modes.push.particles_nb == 1){
pJS.fn.modes.pushParticles(pJS.interactivity.modes.push.particles_nb, pJS.interactivity.mouse);
}
else if(pJS.interactivity.modes.push.particles_nb > 1){
pJS.fn.modes.pushParticles(pJS.interactivity.modes.push.particles_nb);
}
}
break;
case 'remove':
pJS.fn.modes.removeParticles(pJS.interactivity.modes.remove.particles_nb);
break;
case 'bubble':
pJS.tmp.bubble_clicking = true;
break;
case 'repulse':
pJS.tmp.repulse_clicking = true;
pJS.tmp.repulse_count = 0;
pJS.tmp.repulse_finish = false;
setTimeout(function(){
pJS.tmp.repulse_clicking = false;
}, pJS.interactivity.modes.repulse.duration*1000)
break;
}
}
});
}
};
pJS.fn.vendors.densityAutoParticles = function(){
if(pJS.particles.number.density.enable){
/* calc area */
var area = pJS.canvas.el.width * pJS.canvas.el.height / 1000;
if(pJS.tmp.retina){
area = area/(pJS.canvas.pxratio*2);
}
/* calc number of particles based on density area */
var nb_particles = area * pJS.particles.number.value / pJS.particles.number.density.value_area;
/* add or remove X particles */
var missing_particles = pJS.particles.array.length - nb_particles;
if(missing_particles < 0) pJS.fn.modes.pushParticles(Math.abs(missing_particles));
else pJS.fn.modes.removeParticles(missing_particles);
}
};
pJS.fn.vendors.checkOverlap = function(p1, position){
for(var i = 0; i < pJS.particles.array.length; i++){
var p2 = pJS.particles.array[i];
var dx = p1.x - p2.x,
dy = p1.y - p2.y,
dist = Math.sqrt(dx*dx + dy*dy);
if(dist <= p1.radius + p2.radius){
p1.x = position ? position.x : Math.random() * pJS.canvas.w;
p1.y = position ? position.y : Math.random() * pJS.canvas.h;
pJS.fn.vendors.checkOverlap(p1);
}
}
};
pJS.fn.vendors.createSvgImg = function(p){
/* set color to svg element */
var svgXml = pJS.tmp.source_svg,
rgbHex = /#([0-9A-F]{3,6})/gi,
coloredSvgXml = svgXml.replace(rgbHex, function (m, r, g, b) {
if(p.color.rgb){
var color_value = 'rgba('+p.color.rgb.r+','+p.color.rgb.g+','+p.color.rgb.b+','+p.opacity+')';
}else{
var color_value = 'hsla('+p.color.hsl.h+','+p.color.hsl.s+'%,'+p.color.hsl.l+'%,'+p.opacity+')';
}
return color_value;
});
/* prepare to create img with colored svg */
var svg = new Blob([coloredSvgXml], {type: 'image/svg+xml;charset=utf-8'}),
DOMURL = window.URL || window.webkitURL || window,
url = DOMURL.createObjectURL(svg);
/* create particle img obj */
var img = new Image();
img.addEventListener('load', function(){
p.img.obj = img;
p.img.loaded = true;
DOMURL.revokeObjectURL(url);
pJS.tmp.count_svg++;
});
img.src = url;
};
pJS.fn.vendors.destroypJS = function(){
cancelAnimationFrame(pJS.fn.drawAnimFrame);
canvas_el.remove();
pJSDom = null;
};
pJS.fn.vendors.drawShape = function(c, startX, startY, sideLength, sideCountNumerator, sideCountDenominator){
// By Programming Thomas - https://programmingthomas.wordpress.com/2013/04/03/n-sided-shapes/
var sideCount = sideCountNumerator * sideCountDenominator;
var decimalSides = sideCountNumerator / sideCountDenominator;
var interiorAngleDegrees = (180 * (decimalSides - 2)) / decimalSides;
var interiorAngle = Math.PI - Math.PI * interiorAngleDegrees / 180; // convert to radians
c.save();
c.beginPath();
c.translate(startX, startY);
c.moveTo(0,0);
for (var i = 0; i < sideCount; i++) {
c.lineTo(sideLength,0);
c.translate(sideLength,0);
c.rotate(interiorAngle);
}
//c.stroke();
c.fill();
c.restore();
};
pJS.fn.vendors.exportImg = function(){
window.open(pJS.canvas.el.toDataURL('image/png'), '_blank');
};
pJS.fn.vendors.loadImg = function(type){
pJS.tmp.img_error = undefined;
if(pJS.particles.shape.image.src != ''){
if(type == 'svg'){
var xhr = new XMLHttpRequest();
xhr.open('GET', pJS.particles.shape.image.src);
xhr.onreadystatechange = function (data) {
if(xhr.readyState == 4){
if(xhr.status == 200){
pJS.tmp.source_svg = data.currentTarget.response;
pJS.fn.vendors.checkBeforeDraw();
}else{
console.log('Error pJS - Image not found');
pJS.tmp.img_error = true;
}
}
}
xhr.send();
}else{
var img = new Image();
img.addEventListener('load', function(){
pJS.tmp.img_obj = img;
pJS.fn.vendors.checkBeforeDraw();
});
img.src = pJS.particles.shape.image.src;
}
}else{
console.log('Error pJS - No image.src');
pJS.tmp.img_error = true;
}
};
pJS.fn.vendors.draw = function(){
if(pJS.particles.shape.type == 'image'){
if(pJS.tmp.img_type == 'svg'){
if(pJS.tmp.count_svg >= pJS.particles.number.value){
pJS.fn.particlesDraw();
if(!pJS.particles.move.enable) cancelRequestAnimFrame(pJS.fn.drawAnimFrame);
else pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw);
}else{
//console.log('still loading...');
if(!pJS.tmp.img_error) pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw);
}
}else{
if(pJS.tmp.img_obj != undefined){
pJS.fn.particlesDraw();
if(!pJS.particles.move.enable) cancelRequestAnimFrame(pJS.fn.drawAnimFrame);
else pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw);
}else{
if(!pJS.tmp.img_error) pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw);
}
}
}else{
pJS.fn.particlesDraw();
if(!pJS.particles.move.enable) cancelRequestAnimFrame(pJS.fn.drawAnimFrame);
else pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw);
}
};
pJS.fn.vendors.checkBeforeDraw = function(){
// if shape is image
if(pJS.particles.shape.type == 'image'){
if(pJS.tmp.img_type == 'svg' && pJS.tmp.source_svg == undefined){
pJS.tmp.checkAnimFrame = requestAnimFrame(check);
}else{
//console.log('images loaded! cancel check');
cancelRequestAnimFrame(pJS.tmp.checkAnimFrame);
if(!pJS.tmp.img_error){
pJS.fn.vendors.init();
pJS.fn.vendors.draw();
}
}
}else{
pJS.fn.vendors.init();
pJS.fn.vendors.draw();
}
};
pJS.fn.vendors.init = function(){
/* init canvas + particles */
pJS.fn.retinaInit();
pJS.fn.canvasInit();
pJS.fn.canvasSize();
pJS.fn.canvasPaint();
pJS.fn.particlesCreate();
pJS.fn.vendors.densityAutoParticles();
/* particles.line_linked - convert hex colors to rgb */
pJS.particles.line_linked.color_rgb_line = hexToRgb(pJS.particles.line_linked.color);
};
pJS.fn.vendors.start = function(){
if(isInArray('image', pJS.particles.shape.type)){
pJS.tmp.img_type = pJS.particles.shape.image.src.substr(pJS.particles.shape.image.src.length - 3);
pJS.fn.vendors.loadImg(pJS.tmp.img_type);
}else{
pJS.fn.vendors.checkBeforeDraw();
}
};
/* ---------- pJS - start ------------ */
pJS.fn.vendors.eventsListeners();
pJS.fn.vendors.start();
};
/* ---------- global functions - vendors ------------ */
Object.deepExtend = function(destination, source) {
for (var property in source) {
if (source[property] && source[property].constructor &&
source[property].constructor === Object) {
destination[property] = destination[property] || {};
arguments.callee(destination[property], source[property]);
} else {
destination[property] = source[property];
}
}
return destination;
};
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback){
window.setTimeout(callback, 1000 / 60);
};
})();
window.cancelRequestAnimFrame = ( function() {
return window.cancelAnimationFrame ||
window.webkitCancelRequestAnimationFrame ||
window.mozCancelRequestAnimationFrame ||
window.oCancelRequestAnimationFrame ||
window.msCancelRequestAnimationFrame ||
clearTimeout
} )();
function hexToRgb(hex){
// By Tim Down - http://stackoverflow.com/a/5624139/3493650
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
hex = hex.replace(shorthandRegex, function(m, r, g, b) {
return r + r + g + g + b + b;
});
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
};
function clamp(number, min, max) {
return Math.min(Math.max(number, min), max);
};
function isInArray(value, array) {
return array.indexOf(value) > -1;
}
/* ---------- particles.js functions - start ------------ */
window.pJSDom = [];
window.particlesJS = function(tag_id, params){
//console.log(params);
/* no string id? so it's object params, and set the id with default id */
if(typeof(tag_id) != 'string'){
params = tag_id;
tag_id = 'particles-js';
}
/* no id? set the id to default id */
if(!tag_id){
tag_id = 'particles-js';
}
/* pJS elements */
var pJS_tag = document.getElementById(tag_id),
pJS_canvas_class = 'particles-js-canvas-el',
exist_canvas = pJS_tag.getElementsByClassName(pJS_canvas_class);
/* remove canvas if exists into the pJS target tag */
if(exist_canvas.length){
while(exist_canvas.length > 0){
pJS_tag.removeChild(exist_canvas[0]);
}
}
/* create canvas element */
var canvas_el = document.createElement('canvas');
canvas_el.className = pJS_canvas_class;
/* set size canvas */
canvas_el.style.width = "100%";
canvas_el.style.height = "100%";
/* append canvas */
var canvas = document.getElementById(tag_id).appendChild(canvas_el);
/* launch particle.js */
if(canvas != null){
pJSDom.push(new pJS(tag_id, params));
}
};
window.particlesJS.load = function(tag_id, path_config_json, callback){
/* load json config */
var xhr = new XMLHttpRequest();
xhr.open('GET', path_config_json);
xhr.onreadystatechange = function (data) {
if(xhr.readyState == 4){
if(xhr.status == 200){
var params = JSON.parse(data.currentTarget.response);
window.particlesJS(tag_id, params);
if(callback) callback();
}else{
console.log('Error pJS - XMLHttpRequest status: '+xhr.status);
console.log('Error pJS - File config not found');
}
}
};
xhr.send();
};
================================================
FILE: src/particlesjs-config.json
================================================
{
"particles": {
"number": {
"value": 30,
"density": {
"enable": true,
"value_area": 500
}
},
"color": {
"value": "#a6387b"
},
"shape": {
"type": "circle",
"stroke": {
"width": 0,
"color": "#000000"
},
"polygon": {
"nb_sides": 5
},
"image": {
"src": "img/github.svg",
"width": 100,
"height": 100
}
},
"opacity": {
"value": 0.5,
"random": false,
"anim": {
"enable": false,
"speed": 1,
"opacity_min": 0.1,
"sync": false
}
},
"size": {
"value": 3,
"random": true,
"anim": {
"enable": false,
"speed": 5,
"size_min": 0.1,
"sync": false
}
},
"line_linked": {
"enable": true,
"distance": 150,
"color": "#a6387b",
"opacity": 0.1008530152163807,
"width": 0.5
},
"move": {
"enable": true,
"speed": 2,
"direction": "none",
"random": false,
"straight": false,
"out_mode": "out",
"bounce": false,
"attract": {
"enable": false,
"rotateX": 600,
"rotateY": 1200
}
}
},
"interactivity": {
"detect_on": "window",
"events": {
"onhover": {
"enable": true,
"mode": "grab"
},
"onclick": {
"enable": false,
"mode": "push"
},
"resize": true
},
"modes": {
"grab": {
"distance": 400,
"line_linked": {
"opacity": 1
}
},
"bubble": {
"distance": 400,
"size": 40,
"duration": 2,
"opacity": 8,
"speed": 3
},
"repulse": {
"distance": 200,
"duration": 0.4
},
"push": {
"particles_nb": 4
},
"remove": {
"particles_nb": 2
}
}
},
"retina_detect": true
}
================================================
FILE: src/style.css
================================================
* {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
html {
}
body {
background: rgba(0, 0, 0, .1);
}
h2 {
color: #555;
font-weight: bold;
}
a {
/*margin-right: .5rem;*/
text-decoration: none;
cursor: pointer;
}
a:hover {
text-decoration: underline;
}
ul > li {
list-style: none;
}
.mdl-layout__container {
top: 0;
}
.mdl-navigation {
padding: 0 1rem;
}
.page-content > .mdl-grid {
padding-top: 3rem;
}
.mdl-cell {
/*overflow-y: auto;*/
}
.mdl-card {
min-height: 240px;
margin: 0 auto;
width: 100%;
position: relative;
z-index: 2;
background-size: cover;
overflow: hidden;
}
.mdl-card__title {
max-width: 80%;
padding-bottom: 0;
}
.mdl-card__title > h3 {
min-height: 60px;
display: inline-block;
font-weight: bold;
color: white;
position: relative;
z-index: 2;
text-shadow: 0 0 5px black;
}
.mdl-card__supporting-text {
color: #fff;
padding: 0 1rem;
position: relative;
z-index: 2;
}
.mdl-card__supporting-text > span {
padding-top: .5rem;
}
.mdl-card__supporting-text > span.authors {
text-shadow: 0 0 5px black;
}
.mdl-card__supporting-text .tag {
margin-bottom: .5rem;
margin-right: .5rem;
}
.mdl-card__supporting-text i.material-icons {
font-size: 20px;
position: relative;
top: 0.35rem;
}
.mdl-card__supporting-text > .mdl-grid {
padding: 0;
}
.mdl-card--bottom {
bottom: 0;
left: 0;
min-height: 75px;
padding-top: 1rem !important;
position: absolute;
}
.mdl-card__menu {
background: white;
border-radius: 2rem;
}
.mdl-card__actions {
background: rgba(0,0,0, 0.5);
font-size: 14px;
padding: .5rem 1rem;
color: white;
}
.background {
background-color: hsla(0,0%,0%,0.70);
background-blend-mode: overlay;
min-height: 300px;
padding-bottom: 75px;
background-size: cover;
color: #fff;
position: relative;
overflow: hidden;
}
.background:before {
content: '';
left: 0;
top: 0;
z-index: 0;
position: absolute;
width: 100%;
height: 100%;
background: linear-gradient(to bottom right, rgba(0,0,0,.1), transparent);
}
.right {
text-align: right;
}
.particles-js-canvas-el {
position: fixed;
pointer-events: none;
top: 0;
left: 0;
z-index: -1;
}
.illustration {
background: url(./illustration.svg);
min-width: 100%;
height: 100%;
max-height: 370px;
background-repeat: no-repeat;
background-position-x: right;
}
.tags-wrapper {
margin: 2rem auto;
max-width: 70vw;
position: relative;
z-index: 3;
text-align: left;
}
.tags-wrapper > .tag {
margin-bottom: .5rem;
margin-right: .5rem;
}
.tag {
font-weight: bold;
display: inline-block;
background: rgba(255, 255, 255, 1);
border: 1px solid rgb(255, 64, 129);
color: rgb(255, 64, 129);
padding: 0.15rem .75rem;
border-radius: 1rem;
text-decoration: none;
font-size: 11px;
white-space: nowrap;
margin-bottom: .5rem;
}
.tag:hover {
color: white;
background: rgba(255, 64, 129, 0.75);
text-decoration: none;
}
.tag.active {
color: white;
background: rgb(255, 64, 129);
text-decoration: none;
}
.delete {
position: relative;
top: .25rem;
font-size: 16px;
}
footer {
position: relative;
z-index: 3;
/*margin-top: 3rem;*/
}
@media screen and (max-width: 840px){
.illustration{
height: 150px;
width: 100%;
background-position-x: center;
}
}
@media screen and (max-width: 505px){
.illustration{
height: 150px;
background-position-x: center;
}
.mdl-layout__header-row{
padding: 0 16px;
}
.mdl-layout-title{
text-align: left;
}
h2{
font-size: 30px;
line-height: 30px;
}
.tags-wrapper{
text-align: center;
}
.mdl-mini-footer--link-list, .mdl-mini-footer__link-list{
flex-direction: column;
}
.mdl-mini-footer--link-list, .mdl-mini-footer__link-list > li{
margin-bottom: 1rem;
}
footer.ul>li{
display: block;
}
}
================================================
FILE: websites.yaml
================================================
- name: "CNN Explainer"
desc: "An interactive visualization system designed to help non-experts learn about Convolutional Neural Networks (CNNs)"
url: https://poloclub.github.io/cnn-explainer/
repo: https://github.com/poloclub/cnn-explainer
license: MIT
writeup: https://arxiv.org/abs/2004.15004
authors: [Zijie Jay Wang, Robert Turko, Omar Shaikh, Haekyu Park, Nilaksh Das, Fred Hohman, Minsuk Kahng, Duen Horng (Polo) Chau]
tags: [cnn, convnet]
uses: [demo, tutorial]
img: https://i.imgur.com/7FGSR7S.png
- name: "Deep Recurrent Nets character generation demo"
desc: "This demo shows usage of the recurrentjs library train RNN and LSTM networks in JavaScript."
url: https://cs.stanford.edu/people/karpathy/recurrentjs/
repo: https://github.com/karpathy/recurrentjs
license: MIT
writeup: http://karpathy.github.io/2015/05/21/rnn-effectiveness/
authors: [Andrej Karpathy]
tags: [rnn, lstm, nlp]
uses: [demo, library]
img: https://cs.stanford.edu/people/karpathy/recurrentjs/eg.png
- name: "ConvNetJS"
desc: "Various demos of deep learning in JavaScript, using ConvNetJS library."
url: https://cs.stanford.edu/people/karpathy/convnetjs/
repo: https://github.com/karpathy/convnetjs
license: MIT
writeup: ""
authors: [Andrej Karpathy]
tags: [convnet]
uses: [demo, library]
img: https://cs.stanford.edu/people/karpathy/convnetjs/cifar10.jpeg
- name: "Support Vector Machine in JavaScript"
desc: "A lightweight implementation of the sequential minimal optimization algorithm to train a binary SVM model in JavaScript."
url: https://cs.stanford.edu/~karpathy/svmjs/demo/
repo: https://github.com/karpathy/svmjs
license: MIT
writeup: ""
authors: [Andrej Karpathy]
tags: [svm]
uses: [demo, library, npm]
img: imgs/svmjs.png
- name: "tSNEJS demo"
desc: "tSNE used for clustering the 500 most-followed accounts on Twitter."
url: https://cs.stanford.edu/people/karpathy/tsnejs/
repo: https://github.com/karpathy/tsnejs
license: MIT
writeup: http://karpathy.github.io/2014/07/02/visualizing-top-tweeps-with-t-sne-in-Javascript/
authors: [Andrej Karpathy]
tags: [tsne]
uses: [demo, library]
img: https://karpathy.github.io/assets/tsne_preview.jpeg
- name: "Random Forest demo in JavaScript"
desc: "Random Forest implementation for JavaScript. Supports arbitrary weak learners."
url: https://cs.stanford.edu/~karpathy/svmjs/demo/demoforest.html
repo: https://github.com/karpathy/forestjs
license: MIT
writeup: ""
authors: [Andrej Karpathy]
tags: [tsne]
uses: [demo, library]
img: imgs/forestjs.png
- name: "Keras.js"
desc: "Keras.js is a library enabling running Keras models in the browser, with GPU support provided by WebGL 2."
url: https://transcranial.github.io/keras-js/#/
repo: https://github.com/transcranial/keras-js
license: MIT
writeup: ""
authors: [Leon Chen]
tags: [convnet, rnn]
uses: [demo, library]
img: https://transcranial.github.io/keras-js/demos/assets/resnet50.png
- name: "Interactive visualization of word analogies in GloVe"
desc: "king - man + woman is queen; but why? Explore word vectors interactively."
url: https://lamyiowce.github.io/word2viz/
repo: https://github.com/lamyiowce/word2viz
license: MIT
writeup: http://p.migdal.pl/2017/01/06/king-man-woman-queen-why.html
authors: [Julia Bazińska, Piotr Migdał]
tags: [nlp, word2vec]
uses: [demo]
img: https://lamyiowce.github.io/word2viz/word2viz_screenshot.png
- name: "A Neural Network Playground"
desc: "Interactive visualization of simple neural networks, written in typescript using d3.js."
url: http://playground.tensorflow.org/
repo: https://github.com/tensorflow/playground
license: Apache
writeup: ""
authors: [Daniel Smilkov, Shan Carter]
tags: [mlp]
uses: [demo]
img: https://playground.tensorflow.org/preview.png
- name: "A visual introduction to machine learning (Part 1)"
url: http://www.r2d3.us/visual-intro-to-machine-learning-part-1/
desc: "A demo of using a decision tree algorithm to distinguish houses in New York from houses in San Francisco"
repo: ""
license: ""
writeup: ""
authors: [Stephanie Yee, Tony Chu]
tags: [decision-tree]
uses: [demo, tutorial]
img: https://www.r2d3.us/static/pages/decision-trees-part-1/preview-en.png
- name: "A visual introduction to machine learning (Part 2)"
desc: Model Tuning and the Bias-Variance Tradeoff
url: http://www.r2d3.us/visual-intro-to-machine-learning-part-2/
repo: ""
license: ""
writeup: ""
authors: [Stephanie Yee, Tony Chu]
tags: [decision-tree, overfitting]
uses: [demo, tutorial]
img: https://www.r2d3.us/static/pages/decision-trees-part2-v2/part2-preview-en.png
- name: "D3 Graph Theory"
desc: "Learn graph theory using interactive visualizations made in D3.js."
url: https://mrpandey.github.io/d3graphTheory/index.html
repo: https://github.com/mrpandey/d3graphTheory
license: GPL
writeup: ""
authors: [Avinash Pandey]
tags: [graph]
uses: [demo, tutorial]
img: https://i.imgur.com/MAvlQgj.png
- name: "Immersive linear algebra"
desc: "The world's first linear algebra book with fully interactive figures."
url: http://immersivemath.com/ila/index.html
repo: ""
license: ""
writeup: ""
authors: [J. Ström, K. Åström, and T. Akenine-Mölle]
tags: [math, linear-algebra]
uses: [book]
img: imgs/immersivemath.png
- name: "Seeing Theory"
desc: "A visual introduction to probability and statistics"
url: http://students.brown.edu/seeing-theory/
repo: https://github.com/seeingtheory/Seeing-Theory
license: Apache
writeup: ""
authors: [Daniel Kunin, Jingru Guo, Tyler Dae Devlin, Daniel Xiang]
tags: [statistics]
uses: [tutorial]
img: https://students.brown.edu/seeing-theory/img/share/home.png
- name: "tSNE for the Web"
desc: "TensorFlow.js Powered tSNE Implementation"
url: https://nicola17.github.io/tfjs-tsne-demo/
repo: https://github.com/tensorflow/tfjs-tsne
license: Apache
writeup: https://ai.googleblog.com/2018/06/realtime-tsne-visualizations-with.html
authors: [Nicola Pezzotti, Alexander Mordvintsev, Thomas Hollt, Boudewijn P. F. Lelieveldt, Elmar Eisemann, Anna Vilanova]
tags: [tsne]
uses: [demo, tensorflow.js, npm]
img: https://3.bp.blogspot.com/-NE01azL_JxU/Wxli17oYNzI/AAAAAAAACxQ/axOI2yy-Ft0QbqaekOyemm5Xn0wAFvRUwCLcBGAs/s1600/image2.gif
- name: "GRAIL Text Recognizer"
desc: "An active essay revisiting Gabriel Groner's GRAIL handwriting recognizer from the 1960s"
url: https://jackschaedler.github.io/handwriting-recognition/
repo: https://github.com/jackschaedler/handwriting-recognition
license: MIT
writeup: ""
authors: [Jack Schaedler]
tags: [handwriting]
uses: [demo, tutorial]
img: imgs/handwriting-recognition.png
- name: "pix2pix: Image-to-Image Demo"
desc: "Tensorflow port of Image-to-Image Translation with Conditional Adversarial Nets"
url: https://affinelayer.com/pixsrv/
repo: https://github.com/affinelayer/pix2pix-tensorflow
license: MIT
writeup: ""
authors: [Christopher Hesse]
tags: [gan, deep-learning]
uses: [demo, backend-dependent]
img: https://raw.githubusercontent.com/affinelayer/pix2pix-tensorflow/master/docs/examples.jpg
- name: "nlp-compromise"
desc: "Modest natural-language processing in JavaScript"
url: http://compromise.cool/
repo: https://github.com/spencermountain/compromise
license: MIT
writeup: ""
authors: [Spencer Kelly]
tags: [nlp]
uses: [demo, library]
img: imgs/compromise.png
- name: "NeuroJS"
desc: "A JavaScript deep learning and reinforcement learning library"
url: https://janhuenermann.com/projects/learning-to-drive
repo: https://github.com/janhuenermann/neurojs
license: MIT
writeup: ""
authors: [Jan Hünermann]
tags: [deep-learning, reinforcement-learning]
uses: [demo, library]
img: https://raw.githubusercontent.com/janhuenermann/neurojs/experimental/images/logo-with-demo.png
- name: "DeepForge"
desc: "A modern development environment for deep learning"
url: http://deepforge.org/
repo: https://github.com/deepforge-dev/deepforge
license: Apache
writeup: ""
authors: [Brian Broll]
tags: [deep-learning]
uses: [demo, library]
img: https://raw.githubusercontent.com/deepforge-dev/deepforge/master/images/overview.png
- name: "synaptic"
desc: "The javascript architecture-free neural network library for node.js and the browser"
url: http://caza.la/synaptic/
repo: https://github.com/cazala/synaptic
license: MIT
writeup: ""
authors: [Brian Broll]
tags: [deep-learning]
uses: [demo, library]
img: imgs/synaptic.png
- name: "Machine learning library for Node.js"
desc: "Logistic regression, SVM linear and radial, kNN"
url: http://joonku.com/project/machine_learning
repo: https://github.com/junku901/machine_learning
license: MIT
writeup: ""
authors: [Joon-Ku Kang]
tags: [machine-learning]
uses: [demo, library, npm]
img: ""
- name: "Neural Slime Volleyball"
desc: "HTML5-JS Slime Volleyball clone created using ConvNetJS."
url: http://otoro.net/slimevolley/
repo: https://github.com/hardmaru/neuralslimevolley
license: GPL
writeup: http://blog.otoro.net/2015/03/28/neural-slime-volleyball/
authors: [hardmaru]
tags: [deep-learning]
uses: [demo]
img: imgs/slimevolley.png
- name: "Quick, draw!"
desc: "Can a neural network learn to recognize your doodling? The game uses the world’s largest doodling dataset."
url: https://quickdraw.withgoogle.com/
repo: ""
license: ""
writeup: https://ai.googleblog.com/2017/04/teaching-machines-to-draw.html
authors: [hardmaru]
tags: [deep-learning]
uses: [game, backend-dependent]
img: https://1.bp.blogspot.com/-X0o-v6SQXtI/WO6R8X22wlI/AAAAAAAABts/Qbvu5QoVwZIfKB-zEV7Po_Juh9AqEb28gCLcB/s1600/twitter_cover.png
- name: "SegNet"
desc: "A Deep Convolutional Encoder-Decoder Architecture for Robust Semantic Pixel-Wise Labelling"
url: https://mi.eng.cam.ac.uk/projects/segnet/#demo
repo: https://github.com/alexgkendall/caffe-segnet
license: CC BY NC
writeup: https://mi.eng.cam.ac.uk/projects/segnet/#research
authors: [Alex Kendall, Vijay Badrinarayanan, Roberto Cipolla]
tags: [deep-learning, cnn, segmentation]
uses: [demo, backend-dependent]
img: imgs/segnet.png
- name: "Caffe Demos"
desc: "Web image classification demo"
url: http://demo.caffe.berkeleyvision.org/
repo: ""
license: BSD 2-Clause license
writeup: http://caffe.berkeleyvision.org/
authors: [Yangqing Jia]
tags: [deep-learning, cnn, classification, image-classification]
uses: [demo, backend-dependent]
img: imgs/caffe-demos.png
- name: "LSTM Music Maker"
desc: "How evlolved LSTMs improvise on a melody you specify?"
url: https://www.sentient.ai/sentient-labs/ea/lstm-music/
repo: ""
license: ""
writeup: https://arxiv.org/abs/1803.04439
authors: [Aditya Rawal, Risto Miikkulainen]
tags: [deep-learning, lstm, music]
uses: [demo]
img: imgs/lstm-music-maker.png
- name: "OMNI Draw"
desc: "How do the learned models perceive the characters you draw?"
url: https://www.sentient.ai/sentient-labs/ea/omni-draw/
repo: ""
license: ""
writeup: https://arxiv.org/abs/1803.03745
authors: [Jason Liang, Elliot Meyerson, Risto Miikkulainen]
tags: [deep-learning, cmtr, omniglot]
uses: [demo]
img: imgs/omni-draw.png
- name: "Celeb Match"
desc: "Which celebrity faces match best the attribute values you specify?"
url: https://www.sentient.ai/sentient-labs/ea/celeb-match/
repo: ""
license: ""
writeup: https://arxiv.org/abs/1803.04062
authors: [Elliot Meyerson, Risto Miikkulainen]
tags: [deep-learning, pta]
uses: [demo]
img: imgs/celeb-match.png
- name: "Neural Titanic"
desc: "This visualization uses TensorFlow.js to train a neural network on the titanic dataset"
url: https://andrewnetwork.github.io/NeuralTitanic/dist/
repo: https://github.com/Andrewnetwork/NeuralTitanic
license: MIT
writeup: http://kexp.io/intro_tensorflowjs/
authors: [Andrew Ribeiro]
tags: [mlp, titanic]
uses: [demo, tensorflowjs]
img: imgs/neural-titanic.png
- name: "Backpropagation algorithm"
desc: "The backpropagation algorithm is essential for training large neural networks quickly. This article explains how the algorithm works."
url: https://google-developers.appspot.com/machine-learning/crash-course/backprop-scroll/
repo: ""
license: ""
writeup: ""
authors: [Daniel Smilkov]
tags: [neural-networks, math]
uses: [tutorial]
img: imgs/backpropagation-algorithm.png
- name: "Visual Search"
desc: "This website uses deep neural networks to compute a fingerprint of a query image and retrieves images with similar visual features."
url: https://thomasdelteil.github.io/VisualSearch_MXNet/
repo: "https://github.com/ThomasDelteil/VisualSearch_MXNet"
license: ""
writeup: ""
authors: [Thomas Delteil]
tags: [neural-networks, deep-learning, search, mxnet]
uses: [tutorial, demo, backend-dependent]
img: imgs/visual-search.png
- name: bayes.js
desc: "An implementation of a small MCMC framework and some likelihood functions for doing Bayes stats in the browser."
url: https://github.com/rasmusab/bayes.js
repo: https://github.com/rasmusab/bayes.js
license: MIT
writeup: ""
authors: [Rasmus Bååth]
tags: [bayesian, mcmc, statistics]
uses: [demo, library]
img: https://raw.githubusercontent.com/rasmusab/bayes.js/master/media/normal_model_plotly.png
- name: Basic Neural Network Math
desc: "A Visual And Interactive Look at Basic Neural Network Math"
url: https://jalammar.github.io/feedforward-neural-networks-visual-interactive/
repo: https://github.com/jalammar/jalammar.github.io/blob/master/_posts/2018-03-23-feedforward-neural-networks-visual-interactive.md
license: ""
writeup: ""
authors: [Jay Alammar]
tags: [neural-networks]
uses: [tutorial]
img: https://jalammar.github.io/images/two-input-one-output-sigmoid-network.png
- name: Seedbank
desc: "Collection of Interactive Machine Learning Examples"
url: http://tools.google.com/seedbank/
repo: ""
license: ""
writeup: https://medium.com/tensorflow/seedbank-discover-machine-learning-examples-2ff894542b57
authors: [Mike Tyka, Sures Kumar Thoddu Srinivasan, Chris Boudreaux, Simon Doury, Harini Krishnamurthy, Mike Dory, Gabriel Schubiner, Kyle Pedersen, Artists & Machine Intelligence, Colaboratory teams]
tags: [neural-networks, deep-learning]
uses: [collection, backend-dependent]
img: https://tools.google.com/seedbank/static/images/quick-start.gif
- name: "The Beginner's Guide to Dimensionality Reduction"
desc: "Explore the methods that data scientists use to visualize high-dimensional data."
url: https://idyll.pub/post/dimensionality-reduction-293e465c2a3443e8941b016d/
repo: https://github.com/mathisonian/dimensionality-reduction
license: MIT
writeup: ""
authors: [Matthew Conlen, Fred Hohman]
tags: [pca, tsne]
uses: [tutorial]
img: https://idyll.pub/post/dimensionality-reduction-293e465c2a3443e8941b016d/static/images/share.png
- name: "Visualizing K-Means Clustering"
desc: "The k-means algorithm captures the insight that each point in a cluster should be near to the center of that cluster."
url: https://www.naftaliharris.com/blog/visualizing-k-means-clustering/
repo: ""
license: ""
writeup: ""
authors: [Naftali Harris]
tags: [kmeans]
uses: [tutorial]
img: imgs/visualizing-k-means-clustering.png
date: "2014-01-19"
- name: "Matrix factorization visualized"
desc: "Matrix factorization implemented in pure JavaScript. Also for sparse data and logistic regression."
url: https://p.migdal.pl/matrix-decomposition-viz/
repo: https://github.com/stared/matrix-decomposition-viz
license: MIT
writeup: ""
authors: [Piotr Migdał]
tags: [matrix-factorization]
uses: [demo]
img: imgs/matrix-decomposition-viz.png
date: "2017-10-17"
- name: "AI Experiments - Experiments with Google"
desc: "AI Experiments is a showcase for simple experiments that make it easier for anyone to start exploring machine learning, through pictures, drawings, language, music, and more."
url: https://experiments.withgoogle.com/collection/ai
repo: ""
license: ""
writeup: ""
authors: [Google]
tags: [matrix-factorization]
uses: [collection]
img: imgs/experiments-with-google.png
- name: "A New Angle on L2 Regularization"
desc: "An explorable explanation on the phenomenon of adversarial examples in linear classification and its relation to L2 regularization."
url: https://thomas-tanay.github.io/post--L2-regularization/
repo: https://github.com/thomas-tanay/post--L2-regularization
license: ""
writeup: ""
authors: [Thomas Tanay, Lewis D Griffin]
tags: [svm, overfitting, adversarial-examples]
uses: [tutorial, paper]
img: "imgs/a-new-angle-on-l2-reg.png"
date: "2018-06-21"
- name: "Support Vector Machine Explorer"
desc: "This is a demo of the Dash interactive Python framework developed by Plotly."
url: https://dash-svm.plot.ly/
repo: https://github.com/plotly/dash-svm
license: MIT
writeup: ""
authors: [Xing Han Lu]
tags: [svm]
uses: [demo, backend-dependent, plotly, scikit-learn]
img: imgs/dash-svm-plot-ly.png
date: "2018-08-09"
- name: "GAN lab"
desc: "Play with Generative Adversarial Networks (GANs) in your browser!"
url: https://poloclub.github.io/ganlab/
repo: https://github.com/poloclub/ganlab
license: Apache
writeup: ""
authors: [Minsuk Kahng, Nikhil Thorat, Polo Chau, Fernanda Viégas, and Martin Wattenberg]
tags: [GAN, deep-learning, tensorflowjs]
uses: [demo]
img: imgs/ganlab.png
date: "2018-09-04"
- name: "Semantic Calculator"
desc: "Do math with word embeddings!"
url: https://semantic.a9.io/
repo: ""
license: ""
writeup: ""
authors: [Max Krieger]
tags: [word2vec, glove, word-embeddings]
uses: [demo, backend-dependent]
img: imgs/semantic-calculator.png
date: "2018-09-29"
- name: "ml5.js"
desc: "ml5.js aims to make machine learning approachable for a broad audience of artists, creative coders, and students. The library provides access to machine learning algorithms and models in the browser, building on top of TensorFlow.js with no other external dependencies."
url: https://ml5js.org/
repo: https://github.com/ml5js/ml5-library
license: MIT
writeup: https://towardsdatascience.com/introduction-to-ml5-js-3fe51d6a4661
authors: [NYU ITP teachers, residents and students]
tags: [machine-learning, tensorflowjs]
uses: [tutorial, demo, library]
img: imgs/ml5.png
- name: "Drum Patterns from Latent Space"
desc: "A latent explorable space with some recognizable genre areas."
url: http://altsoph.com/pp/dsp/map.html#
repo: https://github.com/altsoph/drum_space
license: MIT
writeup: https://towardsdatascience.com/drum-patterns-from-latent-space-23d59dd9d827
authors: [Aleksey Tikhonov]
tags: [music, latent]
uses: [demo]
img: imgs/drum_space.png
date: "2019-03-10"