Template:Freiburg/landingpage js

var ctx, antibodies_mid_front, images, preloaded_images_count, textElements, start_time, time_paused, pause_start_time, pause_end_time; var red_ab_images, diachip_logo, antigen_array, hiv_antigen_image; var glass_alpha, antigen_alpha, skipButton, skipButton_alpha, skipButtonText, skipButtonSubtext, diaChip; var AB_IMAGE_WIDTH, AB_IMAGE_HEIGHT, MIN_AB_SCALE, MAX_AB_SCALE,SCALE_CUTOFF_BACKGROUND, DIACHIP_WIDTH,DIACHIP_HEIGHT, RENDERSPEED, ANTIGEN_RADIUS, AMOUNT_ANTIGENS, FONTSIZE_SCALING_FACTOR, DIACHIP_FADE_IN_TIME, GLASS_FADE_IN_TIME, ANTIGEN_FADE_IN_TIME, SKIP_BUTTON_FADE_IN_TIME, SKIP_BUTTON_ALTERNATIVE_MESSAGE_TIME, DRAW_TEXT_MIN_WINDOW_WIDTH, DRAW_TEXT_MIN_WINDOW_HEIGHT, MOBILE_PHONE_VERSION;


function initVariables(){ console.log("Variables initiated");

//RENDERSPEED = 40; //25 RENDERSPEED = 25;

DIACHIP_FADE_IN_TIME = 100; GLASS_FADE_IN_TIME = 1500; ANTIGEN_FADE_IN_TIME = 2000; SKIP_BUTTON_FADE_IN_TIME = 3000; SKIP_BUTTON_ALTERNATIVE_MESSAGE_TIME = 34000;

glass_alpha = antigen_alpha = skipButton_alpha = 0;


AMOUNT_ANTIBODIES = 5; AB_IMAGE_WIDTH = 200; AB_IMAGE_HEIGHT = 256; MIN_AB_SCALE = .09; MAX_AB_SCALE = .55; ANTIGEN_RADIUS = 38; FONTSIZE_SCALING_FACTOR = 28;

SCALE_CUTOFF_BACKGROUND = MAX_AB_SCALE*4/7;

DRAW_TEXT_MIN_WINDOW_WIDTH = 400; DRAW_TEXT_MIN_WINDOW_HEIGHT = 200;

skipButtonText = "Click here to skip"; skipButtonSubtext = "(This is an infinite animation)";

var iOS = /iPhone|iPod/.test(navigator.platform); if(iOS){ skipButtonText = "Client is iPhone"; window.location = "https://2015.igem.org/Team:Freiburg/Home"; }

if(window.screen.width<window.screen.height) MOBILE_PHONE_VERSION = true; else MOBILE_PHONE_VERSION = false; console.log("Device is a smartphone="+MOBILE_PHONE_VERSION);

PRELOADING_MAINPAGE_IMAGES = false;

console.log("Preloading font"); ctx.font = "1px Roboto-light-slim"; ctx.fillText("preloading font", -900, -900);

diachip_logo = images[0]; red_ab_images = [images[1],images[2],images[3],images[4], images[5],images[6],images[7],images[8]];


hiv_antigen_image= images[9]; var date = new Date(); start_time = date.getTime(); absolute_start_time = date.getTime(); time_paused = 0;

}

function preload(){ ctx= document.getElementById('canvasObject').getContext('2d'); ctx.canvas.width = window.innerWidth; ctx.canvas.height = window.innerHeight; var metrics = ctx.measureText("Loading page, please wait...");

ctx.fillText("Loading page, please wait...", (window.innerWidth/2)-metrics.width/2, window.innerHeight/2); console.log("Preloading images"); preloaded_images_count = 0; images = []; var imageURLS = []; imageURLS.push("Freiburg_DiaChip_Landingpage.png"); //0 imageURLS.push("Freiburg_landingpage_ab_red.png"); imageURLS.push("Freiburg_landingpage_ab_red_blur1.png"); imageURLS.push("Freiburg_landingpage_ab_red_blur2.png"); imageURLS.push("Freiburg_landingpage_ab_red_blur3.png"); imageURLS.push("Freiburg_landingpage_ab_red_blur4.png"); //5 imageURLS.push("Freiburg_landingpage_ab_red_blur5.png"); imageURLS.push("Freiburg_landingpage_ab_red_blur6.png"); imageURLS.push("Freiburg_landingpage_ab_red_blur7.png"); imageURLS.push("Freiburg_landingpage_HIV_Antigen.png"); imageURLS.push("Freiburg_landingpage_antigen_1.png"); //10 imageURLS.push("Freiburg_landingpage_antigen_2.png"); imageURLS.push("Freiburg_landingpage_antigen_3.png"); imageURLS.push("Freiburg_landingpage_antigen_4.png");

for (var i = 0; i < imageURLS.length; i++) { var img = new Image(); img.src = imageURLS[i]; images.push(img); img.onload = function () { console.log("Preloaded image: "+preloaded_images_count); preloaded_images_count++; if (preloaded_images_count >= imageURLS.length) { // preloadMainSiteImages(); init(); } }; } }

function initDiaChip(){

var DIAChip = function(){ this. x = 0; this. y = 0; this. width = 0; this. height = 0; this.alpha = 0; this.fadeInTime = DIACHIP_FADE_IN_TIME; this.scale = 1; } diaChip = new DIAChip();

}

function initEvents(){ window.onresize = function(event){ // console.log("Event: window was resized: "+window.innerWidth+":"+window.innerHeight); if(window.innerWidth < window.innerHeight) MOBILE_PHONE_VERSION = true; else MOBILE_PHONE_VERSION = false; ctx.canvas.width = window.innerWidth; ctx.canvas.height = window.innerHeight;

//update antigen position in case window was scaled for (var i = 0; i < antigen_array.length; i++) { var antigen = antigen_array[i]; antigen.x = ((i*window.innerWidth)/AMOUNT_ANTIGENS) + (window.innerWidth/(2*AMOUNT_ANTIGENS)); antigen.y = (window.innerHeight-hiv_antigen_image.height/2) -5; //ypos };


//change size of floating text elements updateTextElements();

};

window.onclick = function(event){ if(skipButton.isHovered){ var date = new Date(); var currentTime = date.getTime(); if(currentTime>start_time+SKIP_BUTTON_FADE_IN_TIME){ window.location = "https://2015.igem.org/Team:Freiburg/Home_Intro"; } }

}

window.onmousemove = function(event){ var dx = event.clientX - skipButton.x; var dy = event.clientY - skipButton.y + skipButton.height/2; dx = Math.abs(dx); dy = Math.abs(dy);

if(dx <= skipButton.width/2 & dy <= skipButton.height/2 ){ skipButton.isHovered = true; }else skipButton.isHovered = false;

}

window.onfocus = function(){

for (var i = 0; i < textElements.length; i++) { var textElement = textElements[i]; textElement.hasNeverFaded = true; textElement.alpha = 0; textElement.isVisible = false; textElement.timeOfLastToggle = 0; textElement.isFadingIn = false; textElement.isFadingOut= false; }; var tmp_date = new Date(); start_time = tmp_date.getTime() - 3000; }

window.onblur = function(){ for (var i = 0; i < textElements.length; i++) { var textElement = textElements[i]; textElement.hasNeverFaded = true; textElement.alpha = 0; textElement.isVisible = false; textElement.timeOfLastToggle = 0; textElement.isFadingIn = false; textElement.isFadingOut= false; }; var tmp_date = new Date(); start_time = tmp_date.getTime() - 3000; } }



function init(){ initVariables();

antibodies_back = new Array(30);

antibodies_mid_back= new Array(Math.round(AMOUNT_ANTIBODIES/2)); antibodies_mid_front = new Array(Math.round(AMOUNT_ANTIBODIES/2)); antibodies_front = new Array(1);

// scale, blur, alpha, speed, inFrontOfAntigen initAntibodies(antibodies_back, [.1, .2], [4, 6], [.1, .5], [5,8], false); initAntibodies(antibodies_mid_back, [.3, .35], [0,1], [1, 1], [6, 8], false); initAntibodies(antibodies_mid_front,[.3, .35], [0, 1], [1,1], [6, 8], true); initAntibodies(antibodies_front, [2, 2], [6,6], [1, 1], [4,7], true);

antibodies_front[0].x = window.innerWidth*3; antibodies_front[0].y = window.innerHeight*2;


bound_ab_foreground = new Array(0);//for antibodies that bound to antigen bound_ab_background = new Array(0); initDiaChip();

bubbleSortScale(antibodies_back); bubbleSortScale(antibodies_mid_back); bubbleSortScale(antibodies_mid_front); bubbleSortScale(antibodies_front);

initAntigens(); initTextElements(); initEvents(); initSkipButton();


//make one antibody fly directly to the left-most antigen for demonstration var target_antigen_idx = 0; var antigen = antigen_array[target_antigen_idx]; var directed_antibody = antibodies_mid_front[0]; directed_antibody.x = window.innerWidth+window.innerWidth/4; directed_antibody.y = Math.random()*window.innerHeight/4; aimAntibodyToTarget(directed_antibody, antigen.x, antigen.y);

if(antigen_array.length > 1){ //if more than one antigen is present fly to one of the right ones too target_antigen_idx = Math.round(antigen_array.length-1-(Math.random()*1)); antigen = antigen_array[target_antigen_idx]; directed_antibody = antibodies_mid_front[1]; directed_antibody.x = window.innerWidth+window.innerWidth/4; directed_antibody.y = Math.random()*window.innerHeight/2; aimAntibodyToTarget(directed_antibody, antigen.x, antigen.y); }


tick(); }

function aimAntibodyToTarget(antibody, target_x, target_y){

var dx = target_x- antibody.x; var dy = target_y - antibody.y; var angle = Math.atan2(dy,dx); antibody.rotation = angle+-Math.PI/2.1; antibody.speedX = (Math.cos(angle)*antibody.undirectedSpeed*antibody.scale); antibody.speedY = Math.sin(angle)*antibody.undirectedSpeed*antibody.scale; if(antibody.speedX>0) antibody.speedX*=-1; if(antibody.speedY<0) antibody.speedY*=-1;

}

function initSkipButton(){ var SkipButton = function(){ this.x = 0; this.y = 0; this.alpha = 0; this.width = 0; this.height = 0; this.fontsize = 40; this.isHovered = false; } skipButton = new SkipButton();

}

function initAntigens(){ var Antigen = function(x,y){ this.x = x; this.y = y; this.radius = ANTIGEN_RADIUS; this.boundAntibodyCount = 0; }

AMOUNT_ANTIGENS = Math.round(window.innerWidth/266);

console.log("Initializing "+AMOUNT_ANTIGENS+" Antigens");

antigen_array = new Array(); for (var i = 0; i < AMOUNT_ANTIGENS; i++) { var antigenX = (i*window.innerWidth)/AMOUNT_ANTIGENS + window.innerWidth/(2*AMOUNT_ANTIGENS); var antigenY = (window.innerHeight-hiv_antigen_image.height/2) -5; // var antigenX = (i*window.screen.width)/AMOUNT_ANTIGENS + window.screen.width/(2*AMOUNT_ANTIGENS); // var antigenY = (window.innerHeight-hiv_antigen_image.height/2) -5; antigen_array.push(new Antigen(antigenX, antigenY));

} }


function tick(){ calcNextABArrayStep(antibodies_back); calcNextABArrayStep(antibodies_mid_back); calcNextABArrayStep(antibodies_mid_front); calcNextABArrayStep(antibodies_front); setTimeout(function(){tick();}, RENDERSPEED); draw();

calcBindingToAntigen(antigen_array, antibodies_mid_front); calcBindingToAntigen(antigen_array, antibodies_mid_back); }


function draw(){

ctx.clearRect(0,0,window.innerWidth,window.innerHeight);

drawAntibodies(antibodies_back, red_ab_images); drawFloor(); drawBoundAntibodies(bound_ab_background, red_ab_images); drawAntibodies(antibodies_mid_back, red_ab_images);

drawDIAChip(); drawAntigen(); drawSkipButton();

//draw the foreground drawBoundAntibodies(bound_ab_foreground, red_ab_images); drawAntibodies(antibodies_mid_front, red_ab_images); drawAntibodies(antibodies_front, red_ab_images); drawTextElements();

}

function drawFloor(){ //start of routine concerning fade-in if(glass_alpha<1){ var date = new Date(); var currentTime = date.getTime();

if(currentTime-start_time > GLASS_FADE_IN_TIME){ glass_alpha+=0.05; if(glass_alpha>=1){ glass_alpha = 1; } } else{ return; } } //end of routine concerning fade-in


ctx.globalAlpha = glass_alpha;

ctx.fillStyle="#7DD0DE"; ctx.fillRect(0, window.innerHeight-40, window.innerWidth, 40);

ctx.fillStyle = '#8be8f8'; ctx.fillRect(0, window.innerHeight-45, window.innerWidth, 5);


ctx.beginPath(); ctx.moveTo(240, window.innerHeight-40); ctx.lineTo(100, window.innerHeight); ctx.lineTo(200, window.innerHeight); ctx.lineTo(290, window.innerHeight-40); ctx.closePath(); ctx.fill();

ctx.beginPath(); ctx.moveTo(620, window.innerHeight-40); ctx.lineTo(500, window.innerHeight); ctx.lineTo(700, window.innerHeight); ctx.lineTo(690, window.innerHeight-40); ctx.closePath(); ctx.fill();

ctx.globalAlpha = 1; }

function drawDIAChip(){

//start of routine concerning fade-in

if(diaChip.alpha<1){ var date = new Date(); var currentTime = date.getTime();

if(currentTime-start_time > diaChip.fadeInTime){ diaChip.alpha+=0.01; if(diaChip.alpha>=1){ diaChip.alpha = 1; } } else{ return; } } //end of routine concerning fade-in

if(MOBILE_PHONE_VERSION){ diaChip.scale = window.innerWidth/(diachip_logo.width*2) ; diaChip.width = diachip_logo.width*diaChip.scale; diaChip.height = diachip_logo.height*diaChip.scale;

diaChip.x = window.innerWidth/2 - diaChip.width/2; diaChip.y = -(diaChip.height)/100; }else{

diaChip.scale = window.screen.width/(diachip_logo.width*3) ; diaChip.width = diachip_logo.width*diaChip.scale; diaChip.height = diachip_logo.height*diaChip.scale; diaChip.x = window.innerWidth/2 - diaChip.width/2; // var xpos = 0-(diachip_logo.width*logo_scale)/10; diaChip.y = 0-(diaChip.height)/10; diaChip.y = -(diaChip.height)/20; }

ctx.globalAlpha = diaChip.alpha;

ctx.drawImage(diachip_logo, diaChip.x, diaChip.y, diaChip.width, diaChip.height);

ctx.globalAlpha = 1;

}

function drawSkipButton(){ //start of routine concerning fade-in var date = new Date(); var currentTime = date.getTime(); if(skipButton.alpha<1){

if(currentTime-start_time > SKIP_BUTTON_FADE_IN_TIME){ skipButton.alpha+=0.015; if(skipButton.alpha>=1){ skipButton.alpha = 1; } }else{ return; } } //end of routine concerning fade-in ctx.save(); ctx.textAlign = "center"; var skipButtonFontsize = 50; ctx.font = skipButtonFontsize+"px Roboto-light-slim";

console.log(currentTime-start_time);

var metrics = ctx.measureText(skipButtonText);


var widthRelativeToLogo = metrics.width / diaChip.width;

skipButton.fontsize = skipButtonFontsize/ (widthRelativeToLogo*1.1);

if(skipButton.isHovered) ctx.font = skipButton.fontsize*1.05+"px Roboto-light-slim"; else ctx.font = skipButton.fontsize+"px Roboto-light-slim";


metrics = ctx.measureText(skipButtonText); skipButton.width = metrics.width; skipButton.height = skipButton.fontsize;

ctx.globalAlpha = skipButton.alpha; ctx.fillStyle = "#C30824";

skipButton.x = diaChip.x +diaChip.width/2; skipButton.y = diaChip.y + diaChip.height;


if(MOBILE_PHONE_VERSION){ skipButton.x = window.innerWidth/2; if(skipButton.y < 100) skipButton.y = window.innerHeight/2; }

ctx.fillText(skipButtonText, skipButton.x, skipButton.y); if( (currentTime - absolute_start_time) > SKIP_BUTTON_ALTERNATIVE_MESSAGE_TIME){

ctx.font = (skipButton.fontsize/2)+"px Roboto-light-slim"; ctx.fillText(skipButtonSubtext, skipButton.x, skipButton.y + skipButton.fontsize/2); }

ctx.restore(); }

function drawAntigen(){ //start of routine concerning fade-in if(antigen_alpha<1){ var date = new Date(); var currentTime = date.getTime();

if(currentTime-start_time > ANTIGEN_FADE_IN_TIME){ antigen_alpha+=0.015; if(antigen_alpha>=1){ antigen_alpha = 1; } }else{ return; } } //end of routine concerning fade-in

ctx.globalAlpha = antigen_alpha;

for (var i = 0; i < AMOUNT_ANTIGENS; i++){ var antigen = antigen_array[i];

var antigen_image; if(antigen.boundAntibodyCount == 0 ) antigen_image = images[10]; if(antigen.boundAntibodyCount == 1 ) antigen_image = images[11]; if(antigen.boundAntibodyCount == 2 ) antigen_image = images[12]; if(antigen.boundAntibodyCount >2 ) antigen_image = images[13];


ctx.drawImage( antigen_image, antigen.x-hiv_antigen_image.width/2, antigen.y-hiv_antigen_image.height/2, hiv_antigen_image.width, hiv_antigen_image.height);

     			}
     			ctx.globalAlpha = 1;

}

function initTextElements(){ //creating TextElement pseudo-class var TextElement = function(text, relative_x, relative_y, fadeInStart, onTime, offTime){ this.text = text; this.initialRelative_x = this.relative_x = relative_x; this.initialRelative_y = this.relative_y = relative_y; this.x = window.innerWidth*relative_x; this.y = window.innerHeight*relative_y; this.fontsize = window.innerWidth/FONTSIZE_SCALING_FACTOR; this.fadeInStart = fadeInStart*1000; this.onTime = onTime*1000; this.offTime = offTime*1000; this.isFadingIn = false; this.isFadingOut= false; this.hasNeverFaded = true; this.isVisible = false; this.timeOfLastToggle = 0; this.scale = 1; this.alpha = 0; this.hasParent = false; this.parent = -1; this.color = "#004a99"; }


textElements = []; //text, x, y, fadeInStart, onTime, offTime textElements.push(new TextElement("Fast detection", 0.07, 0.35, 4, 1, 34)); textElements.push(new TextElement("of diseases", 0.14, 0.44, 4, 1, 34)); linkTextElements(textElements[textElements.length-2], textElements[textElements.length-1]);


textElements.push(new TextElement("Label-free", 0.31, 0.6, 9, 1, 34)); textElements.push(new TextElement(" Cell-free", 0.31, 0.7, 9, 1, 34)); linkTextElements(textElements[textElements.length-2], textElements[textElements.length-1]);


textElements.push(new TextElement("100 diseases", 0.1, 0.5, 14, 1, 34)); textElements.push(new TextElement("in one hour", 0.17, 0.59, 14, 1, 34)); linkTextElements(textElements[textElements.length-2], textElements[textElements.length-1]);


textElements.push(new TextElement("Only a few", 0.60 , 0.32, 19, 1, 34)); textElements.push(new TextElement("drops of blood", 0.66 , 0.41, 19, 1, 34)); linkTextElements(textElements[textElements.length-2], textElements[textElements.length-1]);


textElements.push(new TextElement("Affordable", 0.7, 0.2, 24, 1, 35));


textElements.push(new TextElement("Simultaneous", 0.6, 0.6, 28, 1, 34)); textElements.push(new TextElement("screening", 0.73, 0.67, 28, 1, 34)); linkTextElements(textElements[textElements.length-2], textElements[textElements.length-1]);

textElements.push(new TextElement("Easy storage", 0.26, 0.4, 33, 1, 34));


}

function linkTextElements(parent, child){ child.hasParent = true; child.parent = parent; }

function updateTextElements(){

for (var i = 0; i < textElements.length; i++) { textElements[i].relative_x = textElements[i].initialRelative_x; textElements[i].relative_y = textElements[i].initialRelative_y;

textElements[i].x = textElements[i].relative_x * window.innerWidth; textElements[i].y = textElements[i].relative_y * window.innerHeight;

var newFontsize = window.innerWidth/FONTSIZE_SCALING_FACTOR;

textElements[i].fontsize = newFontsize>20?newFontsize:30; }; }


function drawTextElements(){

var date = new Date(); var currentTime = date.getTime();


for (var i = 0; i < textElements.length; i++) { te = textElements[i];


if( te.isFadingIn == false && te.isFadingOut ==false ){ //currently not fading -> check if it has to start a fade

if(te.hasNeverFaded){

if(currentTime > start_time + te.fadeInStart){ fadeTextIn(te); } }else{ // text has faded before if(te.isVisible){ if( (currentTime - te.timeOfLastToggle) >= te.onTime){ fadeTextOut(te); }else{ te.scale+=0.0001; drawTextElement(te); }

}else{ if( (currentTime - te.timeOfLastToggle) >= te.offTime){ fadeTextIn(te); } }

}

} else if(te.isFadingIn){ fadeTextIn(te); } else if(te.isFadingOut){ fadeTextOut(te); } };

}

function fadeTextIn(textElement){

if(textElement.alpha>=1){ drawTextElement(textElement); textElement.hasNeverFaded = false; textElement.alpha = 1; textElement.isFadingIn = false; textElement.isVisible = true;


var date = new Date(); textElement.timeOfLastToggle = date.getTime(); return; }

textElement.isFadingIn = true; drawTextElement(textElement); textElement.alpha +=0.02; }


function fadeTextOut(textElement){

if(textElement.alpha<=0){ textElement.hasNeverFaded = false; textElement.alpha = 0; textElement.isFadingOut = false; textElement.isVisible = false; textElement.scale = 1; var date = new Date(); textElement.timeOfLastToggle = date.getTime(); return; } textElement.isFadingOut = true; drawTextElement(textElement); textElement.alpha -=0.02; }

function drawTextElement(textElement){ if(window.innerWidth<DRAW_TEXT_MIN_WINDOW_WIDTH){ return;} if(window.innerHeight<DRAW_TEXT_MIN_WINDOW_HEIGHT){ return;}

ctx.save();

ctx.font = textElement.fontsize+"px Roboto-light-slim";

ctx.globalAlpha = textElement.alpha; ctx.fillStyle = textElement.color;

var xpos = textElement.x; var ypos = textElement.y; var textmetric = ctx.measureText(textElement.text);

if(textElement.hasParent==false){ while(checkForOverlapWithDiachip(textElement.x, textElement.y-textElement.fontsize, textmetric.width, textElement.fontsize)){ textElement.relative_y +=0.05; textElement.y = textElement.relative_y*window.innerHeight; ypos = textElement.y; } }

if(textElement.hasParent){ ypos = textElement.parent.y + textElement.parent.fontsize; }

if(MOBILE_PHONE_VERSION){ xpos = window.innerWidth/2; if(ypos < 100) ypos = window.innerHeight/2; }


ctx.fillText(textElement.text, xpos, ypos); ctx.restore(); }

function calcBindingToAntigen(antigen_array, ab_array){ //check if the antigen is actually close enough for detailed calculations

for (var i = 0; i < ab_array.length; i++) {

var antibody = ab_array[i];

for (var j = 0; j < antigen_array.length; j++) { antigen = antigen_array[j];


var radius = antigen.radius; var dist = distance(antibody.x, antibody.y, antigen.x, antigen.y);

if(dist < (radius + AB_IMAGE_HEIGHT*antibody.scale) ){ //detailed collision calculations var ab_domains = calculateABDomainPositions(antibody);

var distFcDomain = distance(antigen.x, antigen.y, ab_domains[0][0],ab_domains[0][1]); var distLeftDomain = distance(antigen.x, antigen.y, ab_domains[1][0],ab_domains[1][1]); var distRightDomain = distance(antigen.x, antigen.y, ab_domains[2][0],ab_domains[2][1]);

//variable domains are inside radius if( (distRightDomain<=radius) || (distLeftDomain<=radius)){ //the domains are not allowed to be to far inside the antigen though if( (distRightDomain>=radius-10) && (distLeftDomain>=radius-10)){ //variable domains have to be closer to antigen than FC-Domain if(distRightDomain<distFcDomain && distLeftDomain<distFcDomain){ //only one domain in radius if((distRightDomain<=radius && distLeftDomain>radius && distFcDomain>1.1*radius)||(distLeftDomain<=radius && distRightDomain>radius && distFcDomain>1.1*radius)){

//for each bound AB a new free ab should be added var newAB = antibody.clone(); newAB.calculateNewInitialPosition(); newAB.setNewRotationValues();

//then the current antibody is frozen antibody.speedX = 0; antibody.speedY = 0; antibody.rotationspeed = 0; antibody.rotationdirection = 0;

//make positions of antibody relative to antigen antibody.x -= antigen.x; antibody.y -= antigen.y; antibody.boundAntigenID = j;

//remove the antibody from the antibody array to minimize further calculations if(antibody.inFrontOfAntigen){ bound_ab_foreground.push(antibody); }else{ bound_ab_background.push(antibody); } antigen.boundAntibodyCount +=1; //increase the counter for bound antibodies //ab_array = ab_array.splice(i,1); //for each bound AB a new free ab should be added ab_array[i] = newAB; } } } } } } //end antigen_loop }


}

function updateBoundABPosition(antigen, boundAB_array){ for (var i = 0; i < boundAB_array.length; i++) { var antibody = boundAB_array[i];

var dx = antigen.x - antibody.x; var dy = antigen.y - antibody.y;

antibody.x = antigen.x-dx; antibody.y = antigen.y-dy; } }


function calculateABDomainPositions(antibody){ var scale = antibody.scale; var x = antibody.x; var y = antibody.y;

var rotation = antibody.rotation ;

var left = [0,0]; var left_offset_x = x-65*scale; var left_offset_y = y+90*scale;

var right = [0,0]; var right_offset_x = x+65*scale; var right_offset_y = y+90*scale;

var fc = [0,0]; var fc_offset_x = x+0; var fc_offset_y = y-110*scale;


left[0] = x+(left_offset_x-x)*Math.cos(rotation) - (left_offset_y-y)*Math.sin(rotation); left[1] = y+(left_offset_x-x)*Math.sin(rotation) + (left_offset_y-y)*Math.cos(rotation);

right[0] = x+(right_offset_x-x)*Math.cos(rotation) - (right_offset_y-y)*Math.sin(rotation); right[1] = y+(right_offset_x-x)*Math.sin(rotation) + (right_offset_y-y)*Math.cos(rotation);

fc[0] = x+(fc_offset_x-x)*Math.cos(rotation) - (fc_offset_y-y)*Math.sin(rotation); fc[1] = y+(fc_offset_x-x)*Math.sin(rotation) + (fc_offset_y-y)*Math.cos(rotation);

return [ fc, left, right]; }


function distance(x1,y1,x2,y2){ return Math.sqrt( Math.pow(x1-x2,2) + Math.pow(y1-y2,2)); }


function initAntibodies(a, scale, blur, alpha, speed, inFrontOfAntigen){ var Antibody = function(scale, blur, alpha, speed, inFrontOfAntigen){ //assigning Antibodies [X-Pos, Y-Pos, Rotation, SpeedX, SpeedY, Rotationspeed, RotationDirection] this.undirectedSpeed = Math.random()*(speed[1] - speed[0]) + speed[0];

this.x = (Math.random()*window.innerWidth) + 1.2*window.innerWidth; this.y = Math.random()*window.innerHeight;

this.scale = Math.random()*(scale[1] - scale[0]) + scale[0]; this.rotation = Math.random()*2*Math.PI;

var movemenDirectionAngle = Math.random()*(30-10)+10; movemenDirectionAngle *= Math.PI / 180;

this.speedX = -(Math.cos(movemenDirectionAngle)*this.undirectedSpeed*this.scale); this.speedY = Math.sin(movemenDirectionAngle)*this.undirectedSpeed*this.scale;

this.setNewRotationValues(); this.boundAntigenID = -1; this.blurryness = Math.round(Math.random()*(blur[1] - blur[0]) + blur[0]); this.inFrontOfAntigen = inFrontOfAntigen; this.alpha = Math.random()*(alpha[1] - alpha[0]) + alpha[0]; }

Antibody.prototype.calculateNewInitialPosition = function(){ if(this.scale<=1){ this.x = (Math.random()*window.innerWidth) + window.innerWidth+AB_IMAGE_WIDTH; } else{ this.x = (Math.random()*window.innerWidth) + window.innerWidth*10; } this.y = Math.random()*window.innerHeight - window.innerHeight/2; };

Antibody.prototype.setNewRotationValues = function() { this.rotationspeed = this.undirectedSpeed/10 * Math.random()*0.005- 0.0025; this.rotationdirection = Math.random()-0.5; };

Antibody.prototype.clone = function(){ var ab = new Antibody([0,0],[0,0],[0,0],[0,0],true); ab.alpha = this.alpha; ab.x = this.x; ab.y = this.y; ab.scale = this.scale; ab.rotation = this.rotation; ab.speedX = this.speedX; ab.speedY = this.speedY; ab.undirectedSpeed = this.undirectedSpeed; ab.boundAntigenID = this.boundAntigenID; ab.blurryness = this.blurryness; ab.inFrontOfAntigen = this.inFrontOfAntigen; return ab; };


for (var i = 0; i <a.length; i++) { a[i] = new Antibody(scale, blur, alpha, speed, inFrontOfAntigen); } }


function calcNextABArrayStep(a){ //control for AB running out of the window for (var i = 0; i <a.length; i++){ var antibody = a[i]; if(antibody.x<-AB_IMAGE_WIDTH){ antibody.calculateNewInitialPosition(); antibody.setNewRotationValues(); } if(antibody.y>window.innerHeight+AB_IMAGE_HEIGHT){ antibody.calculateNewInitialPosition(); antibody.setNewRotationValues(); }

antibody.x+= antibody.speedX; antibody.y+=antibody.speedY;


//add rotation offset to rotation antibody.rotation+=antibody.rotationspeed; } }


function drawAntibodies(a, imageArray){ for (var i = 0; i <a.length; i++){ var antibody = a[i];

// save the current co-ordinate system ctx.save(); // move to the middle of where we want to draw our image ctx.translate(antibody.x, antibody.y); // rotate around that point, converting our // angle from degrees to radians ctx.rotate(antibody.rotation);

//set transparancy of the AB depending on its scale ctx.globalAlpha = antibody.alpha;


var image = imageArray[antibody.blurryness];


// draw it up and to the left by half the width // and height of the image

ctx.drawImage(image, -AB_IMAGE_WIDTH*antibody.scale/2, //translate for pivot point -AB_IMAGE_HEIGHT*antibody.scale/2, //translate for pivot point AB_IMAGE_WIDTH*antibody.scale, //scaled width AB_IMAGE_HEIGHT*antibody.scale); //scaled height

ctx.globalAlpha = 1; // and restore the co-ords to how they were when we began ctx.restore();

} }

function drawBoundAntibodies(bound_antibodies, imageArray){ for (var i = 0; i <bound_antibodies.length; i++) { var antibody = bound_antibodies[i];

var antigen = antigen_array[antibody.boundAntigenID]; // save the current co-ordinate system ctx.save(); // move to the middle of where we want to draw our image ctx.translate(antigen.x+antibody.x, antigen.y+antibody.y); // rotate around that point, converting our // angle from degrees to radians ctx.rotate(antibody.rotation);

//set transparancy of the AB depending on its scale ctx.globalAlpha = antibody.alpha;

var image = imageArray[antibody.blurryness];


// draw it up and to the left by half the width // and height of the image

ctx.drawImage(image, -AB_IMAGE_WIDTH*antibody.scale/2, //translate for pivot point -AB_IMAGE_HEIGHT*antibody.scale/2, //translate for pivot point AB_IMAGE_WIDTH*antibody.scale, //scaled width AB_IMAGE_HEIGHT*antibody.scale); //scaled height

ctx.globalAlpha = 1; // and restore the co-ords to how they were when we began ctx.restore();

} }


//used to assure that antibodys are drawn in the right order function bubbleSortScale(array){ for (var i = 0; i < array.length-1; i++) { if(array[i]>array[i+1]){ var tmp = array[i]; array[i]=array[i+1]; array[i+1] = tmp; }

} }

function checkForOverlapWithDiachip(x,y,w,h){ var chip_center_x = diaChip.x+ (diaChip.width/2); var chip_center_y = diaChip.y+ (diaChip.height/2);

var obj_center_x = x+ (w/2); var obj_center_y = y+(h/2);

dx = chip_center_x - obj_center_x; dy = chip_center_y - obj_center_y;

dx = Math.abs(dx); dy = Math.abs(dy);

var minDistX = (diaChip.width/2) + (w/2); var minDistY = (diaChip.height/2) + (h/2);

if(dx >= minDistX || dy >= minDistY){ return false; }else{ return true;}

}

function preloadMainSiteImages(){ console.log("Preloading MainSite Images in background"); var imageURLS = []; var images_loaded = 0; //menu icons imageURLS.push("Freiburg_icon_home_active.png"); imageURLS.push("Freiburg_icon_project.png"); imageURLS.push("Freiburg_icon_team.png"); imageURLS.push("Freiburg_icon_results.png"); imageURLS.push("Freiburg_icon_policy.png"); imageURLS.push("Freiburg_icon_notebook.png"); //active menu items imageURLS.push("Freiburg_icon_home.png"); imageURLS.push("Freiburg_icon_project_active_yellow.png"); imageURLS.push("Freiburg_icon_team_active_yellow.png"); imageURLS.push("Freiburg_icon_results_active_yellow.png"); imageURLS.push("Freiburg_icon_notebook_active_yellow.png"); imageURLS.push("Freiburg_icon_policy_active_yellow.png");

//background images and footer imageURLS.push("Freiburg_upwards_blob.png"); imageURLS.push("Freiburg_wiki_background_2_parted_left.png"); imageURLS.push("Freiburg_wiki_background_2_parted_right.png"); imageURLS.push("Freiburg_footer_uni.png"); imageURLS.push("Freiburg_Zbsa-logo.png"); imageURLS.push("Freiburg_footer_bioss.png"); imageURLS.push("Freiburg_facebook_footer.png"); imageURLS.push("Freiburg_footer_email.png"); imageURLS.push("Freiburg_footer_uni.png");

imageURLS.push("Freiburg_lightbulb_slider_30.png"); imageURLS.push("Freiburg_lightbulb_slider_27.png");

//wiki images imageURLS.push("bullet.gif"); imageURLS.push("mail_icon.gif"); imageURLS.push("lock_icon.gif"); imageURLS.push("IGEM_white_letters.png");

// images Home imageURLS.push("Freiburg_Home_Julias_Hand.jpg"); imageURLS.push("Freiburg_diachip_centcoin_home.png"); imageURLS.push("Freiburg_iRiF_home.jpg"); imageURLS.push("Freiburg_Own_Device_Foto_home.jpg"); imageURLS.push("Freiburg_pOP_home_scaled.png"); imageURLS.push("Freiburg_Home_ScienceFair_Interview.png"); imageURLS.push("Freiburg_Modeling_Home2.png"); imageURLS.push("Freiburg_tetanus_home2.png");

//images project page imageURLS.push("Freiburg_DiaCHIP_Sabi.png"); imageURLS.push("Freiburg_DiaCHIP_overview_scaled.jpg"); imageURLS.push("Freiburg_ELISA_slider.png"); imageURLS.push("Freiburg_DNAengineering_slider.png"); imageURLS.push("Freiburg_cellfreeexpressioninchamber.jpeg"); imageURLS.push("Freiburg_ProtPur_slider.png"); imageURLS.push("Freiburg_specific_surface_RJ_preview.jpg"); imageURLS.push("Freiburg_iRiF_slider.png"); imageURLS.push("Freiburg_furture_slider.png");

//overview page imageURLS.push("Freiburg_homepage_chip_blood.png"); imageURLS.push("Freiburg_generaloverview_RJ_preview.jpeg"); imageURLS.push("Freiburg_overviewcellfree_RJ_preview.jpg"); imageURLS.push("Freiburg_specific_surface_RJ_preview.jpg"); imageURLS.push("Freiburg_iRiF_overview_RJ_preview.jpg"); imageURLS.push("Freiburg_changeperspective_preview.jpg");


//Big Images imageURLS.push("FreiburgTeam2015.jpg"); //first two rows of team profile pics imageURLS.push("Freiburg_Julian_Bender.jpg"); imageURLS.push("Freiburg_Sabine_Bognar.jpg"); imageURLS.push("Freiburg_Maurizio_Camagna.jpg"); imageURLS.push("Freiburg_Julia_Donauer.jpg"); imageURLS.push("Freiburg_Julian_Eble.jpg"); imageURLS.push("Freiburg_Ramona_Emig.jpg"); imageURLS.push("Freiburg_Sabrina_Fischer.jpg"); imageURLS.push("Freiburg_Rabea_Jesser.jpg");

//Results page imageURLS.push("Freiburg_Own_Device_Foto_preview.jpg"); imageURLS.push("Freiburg_GFP_CF_NiNTA_preview.png"); imageURLS.push("Freiburg_comparison_cellfree_mixes_preview.png"); imageURLS.push("Freiburg_150912_Resultsoverviewgrafik_quer_DNAonPDMS_CF_Surface_RJ.png"); imageURLS.push("Freiburg_150912_Resultsoverviewgrafik_Tet_Sal_GFP_RJ.png");

imageURLS.push("Freiburg_tetanus_westernblot_protpur.png"); imageURLS.push("Freiburg_results-result_device_20150818_preview.jpg");


for (var i = 0; i < imageURLS.length; i++) { var img = new Image(); img.src = imageURLS[i]; images.push(img); img.onload = function () { console.log("Image loaded"); images_loaded++; if (images_loaded >= imageURLS.length) { console.log("all images have been preloaded"); } }; }

}