Browse Source

New drawing

Tibo 5 months ago
parent
commit
ca8e84238f

+ 3 - 13
README.md

@@ -2,32 +2,22 @@
 
 # Intimacy
 
-## À faire
-
-- Ajouter Audio
-  - Distance
-  - Compassion
-  - Touch
-
 ## Project setup
 ```
 npm install
 ```
 
-### Compiles and hot-reloads for development
+#### Compiles and hot-reloads for development
 ```
 npm run serve
 ```
 
-### Compiles and minifies for production
+#### Compiles and minifies for production
 ```
 npm run build
 ```
 
-### Lints and fixes files
+#### Lints and fixes files
 ```
 npm run lint
 ```
-
-### Customize configuration
-See [Configuration Reference](https://cli.vuejs.org/config/).

File diff suppressed because it is too large
+ 32 - 4
pictures/observers/bundle.js


+ 19 - 0
pictures/observers/index.js

@@ -1,6 +1,18 @@
 const Tagada = require('../../tagada/tagada.js');
 const Util = require('../../tagada/util.js');
 const Vector = require('../../tagada/vector.js');
+const Tone = require("tone");
+
+var osc = new Tone.FatOscillator( {
+frequency : 0 ,
+detune : 0 ,
+type : "sine2" ,
+phase : 0,
+count:2,
+
+}
+
+).toMaster().start();
 
 const Tween = {};
 Tween.linear = function(currentTime, start, degreeOfChange, duration) {
@@ -279,9 +291,16 @@ app.update = function(dt) {
   observers.forEach(a => {
     a.avoid(observers);
   });
+  let all = 0;
   observers.forEach(o => {
     o.update(dt);
+    all += o.velocity.mag()/o.maxSpeed;
   });
+  let av = all / observers.length;
+  osc.frequency.value = Util.map(av,0,1,10,400);
+  osc.detune.value = Util.map(av,0,1,-400,10);
+  osc.spread = Util.map(av,0,1,40,100);
+
 };
 
 app.render = function() {

File diff suppressed because it is too large
+ 54 - 4
pictures/shared/bundle.js


+ 37 - 0
pictures/shared/index.js

@@ -1,6 +1,30 @@
 const Tagada = require('../../tagada/tagada.js');
 const Util = require('../../tagada/util.js');
 const Vector = require('../../tagada/vector.js');
+const Tone = require("tone");
+var osc = new Tone.FatOscillator(
+  {
+type : "sine" ,
+frequency : 400 ,
+detune : -100 ,
+phase : 0 ,
+spread : 200 ,
+partials : [] ,
+partialCount : 0,
+volume:-20,
+}
+).start();
+
+console.log(osc);
+
+var autoFilter = new Tone.AutoFilter({
+	"frequency" : "8m",
+	"min" : 600,
+	"max" : 15000
+}).connect(Tone.Master);
+
+osc.connect(autoFilter);
+autoFilter.start()
 
 let app = new Tagada();
 let shapes = [];
@@ -129,9 +153,22 @@ class Shape {
 }
 
 app.update = function(dt) {
+  let all = 0;
+
   shapes.forEach(s=>{
     s.update();
+    let p = s.points[Math.floor(s.points.length/2)],
+    old_p = p.old_position,
+    next_p = p.position;
+
+    all += old_p.dist(next_p);
+
   });
+
+  let av = all / 2;
+  osc.frequency.value =  Util.map(av,0,10,200,800);
+  osc.detune.value = Util.map(av,0,10,-800,-600);
+  osc.spread = Util.map(av,0,10,0,200);
 }
 
 app.render = function() {

+ 389 - 0
pictures/whirlwind/bundle.js

@@ -0,0 +1,389 @@
+(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
+const Tagada = require('../../tagada/tagada.js');
+const Util = require('../../tagada/util.js');
+const Vector = require('../../tagada/vector.js');
+
+
+let app = new Tagada(),
+    $ = app.ctx;
+
+let colors = ["black","white"];
+
+function whirl(x,y,radius,sides,resolution,startAngle,offset){
+
+  let lines = [];
+  for (let i = 0; i < sides; i++) {
+    lines[i] = [];
+    let a = Util.map(i,0,sides,0,Math.PI*2) + startAngle;
+    for (let ri = 0; ri < resolution; ri++) {
+      a += Util.map(ri,0,resolution,offset,0);
+      let r = Util.map(ri,0,resolution,radius,0);
+      px = x + Math.cos(a) * r,
+      py = y + Math.sin(a) * r;
+      lines[i].push({x:px,y:py});
+    }
+  }
+  let cCount = 0;
+
+  for (let r = 0; r < lines.length - 1 ; r++) {
+    $.strokeStyle = colors[Math.floor(cCount%colors.length)];
+
+    $.fillStyle = colors[Math.floor(cCount%colors.length)];
+    let l = lines[r].reverse(),
+        next_l = lines[r+1];
+    $.beginPath();
+    $.moveTo(x,y);
+    smooth(l);
+    smooth(next_l);
+    $.closePath();
+    $.fill();
+    $.stroke();
+    cCount +=1;
+  }
+
+  $.strokeStyle = colors[Math.floor(cCount%colors.length)];
+  $.fillStyle = colors[Math.floor(cCount%colors.length)];
+  let l = lines[lines.length-1].reverse(),
+      next_l = lines[0].reverse();
+  $.beginPath();
+  $.moveTo(x,y);
+  smooth(l);
+  smooth(next_l);
+  $.closePath();
+  $.stroke();
+  $.fill();
+}
+
+app.ready = function(){
+  center = new Vector(app.W/2,app.H/2);
+  $.lineWidth = 1;
+};
+
+let center;
+let actualAngle = 0;
+let v  = 0, a = 0;
+
+app.update = function(){
+
+
+};
+
+app.render = function(){
+  let minLength = Math.min(app.W,app.H);
+  let maxLength = Math.hypot(app.W,app.H);
+
+  let d = app.mouse.dist(app.pmouse)
+  d = Util.clamp(d,0,1000);
+
+  v += Util.map(d,0,1000,0,0.1);
+  v = Util.clamp(v,0,0.1);
+
+  v *= 0.96
+
+  a +=v;
+
+  var gradient = $.createRadialGradient(center.x,center.y,0, center.x,center.y,minLength);
+  var gradient2 = $.createRadialGradient(center.x,center.y,0, center.x,center.y,minLength);
+
+  // Add three color stops
+  gradient.addColorStop(1, Util.hsl(Util.map(v,0,0.1,300,340),Util.map(v,0,0.1,0,100),Util.map(v,0,0.1,40,50)));
+  gradient.addColorStop(0, Util.hsl(Util.map(v,0,0.1,300,320),Util.map(v,0,0.1,0,100),Util.map(v,0,0.1,10,40)));
+
+  gradient2.addColorStop(0, Util.hsl(Util.map(v,0,0.1,300,360),Util.map(v,0,0.1,0,100),Util.map(v,0,0.1,10,90)));
+  gradient2.addColorStop(1, Util.hsl(Util.map(v,0,0.1,280,320),Util.map(v,0,0.1,0,100),Util.map(v,0,0.1,10,70)));
+
+  colors[0] = gradient;
+  colors[1] = gradient2;
+
+  whirl(app.W/2,app.H/2,maxLength,Util.map(v,0,0.1,8,20) ,40,-app.frame * 0.001 -a*0.6,-v*0.5);
+
+};
+
+app.resize = function(){
+  center = new Vector(app.W/2,app.H/2);
+  $.lineWidth = 1;
+
+}
+
+
+
+app.run();
+app.backgroundColor = "white";
+function smooth(points) {
+
+  for (i = 1; i < points.length - 2; i++) {
+    var xc = (points[i].x + points[i + 1].x) / 2;
+    var yc = (points[i].y + points[i + 1].y) / 2;
+    $.quadraticCurveTo(points[i].x, points[i].y, xc, yc);
+  }
+
+  $.quadraticCurveTo(
+    points[i].x,
+    points[i].y,
+    points[i + 1].x,
+    points[i + 1].y
+  );
+}
+
+},{"../../tagada/tagada.js":2,"../../tagada/util.js":3,"../../tagada/vector.js":4}],2:[function(require,module,exports){
+const Util = require('./util.js');
+const Vector = require('./vector.js');
+
+class Tagada{
+  constructor(){
+    this.canvas = document.createElement("canvas");
+    this.ctx = this.canvas.getContext('2d');
+    document.body.appendChild(this.canvas);
+    this.W = 0;
+    this.H = 0;
+    this.ressources = {
+      images:[],
+      audio:[],
+    }
+    this.backgroundColor = "gray";
+    this.timeData = {
+      now : 0,
+      dt : 0,
+      last : Util.timeStamp(),
+      step : 1/60,
+    };
+    this.frame = 0;
+    window.addEventListener("resize",()=>{
+      this.setSize();
+      this.resize();
+    });
+    this.mouse = new Vector(0,0);
+    this.pmouse = new Vector(0,0);
+    window.addEventListener("pointermove",(event)=>{
+      this.pMove(event);
+    });
+  }
+  addImage(path){
+    let image = new Image();
+    image.src = path;
+    this.ressources.images.push(image);
+    return image;
+  }
+  drawImageCover(image,x,y,sizeX,sizeY){
+    if(sizeX <= 0 || sizeY <= 0) return false;
+    let scaleX,
+        scaleY,
+        ratio = image.width / image.height;
+
+    let sourceScaleX,sourceScaleY;
+
+    let cRation = sizeX / sizeY;
+
+    if(cRation > ratio){
+      scaleX = sizeX;
+      scaleY = scaleX / ratio;
+
+      sourceScaleX = image.width;
+      sourceScaleY = sourceScaleX / cRation;
+    }else{
+      scaleY = sizeY;
+      scaleX = scaleY * ratio;
+
+      sourceScaleY = image.height;
+      sourceScaleX = sourceScaleY * cRation;
+    }
+
+    let offsetX = (sizeX - scaleX);
+    let offsetY = (sizeY - scaleY);
+
+    this.ctx.drawImage(
+    image,(image.width - sourceScaleX) / 2,(image.height - sourceScaleY) / 2,sourceScaleX ,sourceScaleY,
+    x ,y,scaleX + offsetX,scaleY + offsetY
+    );
+
+
+  }
+  run(){
+    Promise.all(
+      this.ressources.images.map(image=>{
+        return new Promise(resolve=>{
+          image.onload = ()=>{
+            resolve();
+          }
+        });
+      })
+    ).then(v=>{
+      this.cap();
+      this.setSize();
+      this.ready();
+      this.loop();
+    });
+  }
+  cap(){
+    this.ctx.lineCap = "round";
+    this.ctx.lineJoin = "round";
+  }
+  resize(){
+
+  }
+  ready(){
+
+  }
+  pMove(event){
+    this.mouse.x = event.clientX - this.canvas.offsetLeft;
+    this.mouse.y = event.clientY - this.canvas.offsetTop;
+  }
+  setSize(){
+    this.W = this.canvas.width = window.innerWidth;
+    this.H = this.canvas.height = window.innerHeight;
+    this.cap();
+  }
+  update(dt){
+
+  }
+  render(){
+
+  }
+  loop(){
+    if(this.backgroundColor == "transparent"){
+      this.ctx.clearRect(0,0,this.W,this.H);
+    }else{
+      this.ctx.fillStyle = this.backgroundColor;
+      this.ctx.fillRect(0,0,this.W,this.H);
+    }
+    this.timeData.now = Util.timeStamp();
+    this.timeData.dt = this.timeData.dt + Math.min(1, (this.timeData.now - this.timeData.last) / 1000);
+    while(this.timeData.dt > this.timeData.step) {
+      this.timeData.dt = this.timeData.dt - this.timeData.step;
+      this.update(this.timeData.step);
+    }
+
+    this.render();
+    this.timeData.last = this.timeData.now;
+    this.frame += 1;
+
+    this.pmouse = this.mouse.copy();
+
+    requestAnimationFrame(()=>{
+      this.loop()
+    });
+
+  }
+}
+module.exports = Tagada;
+
+},{"./util.js":3,"./vector.js":4}],3:[function(require,module,exports){
+const Util = {};
+Util.timeStamp = function() {
+	return window.performance.now();
+};
+Util.random = function(min, max) {
+  return min + Math.random() * (max - min);
+};
+Util.randomArray = function(array){
+	return array[Math.floor(Math.random()*array.length)];
+};
+Util.map = function(a, b, c, d, e) {
+	a = this.clamp(a,b,c);
+  return (a - b) / (c - b) * (e - d) + d;
+};
+Util.lerp = function(value1, value2, amount) {
+  return value1 + (value2 - value1) * amount;
+};
+Util.clamp = function(value,min,max){
+	return Math.max(min, Math.min(max, value));
+};
+Util.threeAngle = function(p0,p1,p2){
+    var b = Math.pow(p1.x-p0.x,2) + Math.pow(p1.y-p0.y,2),
+        a = Math.pow(p1.x-p2.x,2) + Math.pow(p1.y-p2.y,2),
+        c = Math.pow(p2.x-p0.x,2) + Math.pow(p2.y-p0.y,2);
+    return Math.acos( (a+b-c) / Math.sqrt(4*a*b) );
+}
+Util.hsl = function(hue,saturation,lightness){
+	return `hsl(${hue},${saturation}%,${lightness}%)`;
+}
+
+module.exports = Util;
+
+},{}],4:[function(require,module,exports){
+class Vector{
+	constructor(x,y){
+		this.x = x || 0;
+		this.y = y || 0;
+	}
+	set(x,y){
+		this.x = x;
+		this.y = y;
+	}
+  reset(){
+		this.x = 0;
+		this.y = 0;
+  }
+	fromAngle(angle){
+		let x = Math.cos(angle),
+			y = Math.sin(angle);
+		return new Vector(x,y);
+	}
+	add(vector){
+		this.x += vector.x;
+		this.y += vector.y;
+	}
+	sub(vector){
+		this.x -= vector.x;
+		this.y -= vector.y;
+	}
+	mult(scalar){
+		this.x *= scalar;
+		this.y *= scalar;
+	}
+	div(scalar){
+		this.x /= scalar;
+		this.y /= scalar;
+	}
+	dot(vector){
+		return vector.x * this.x + vector.y * this.y;
+	}
+	limit(limit_value){
+		if(this.mag() > limit_value) this.setMag(limit_value);
+	}
+	mag(){
+		return Math.hypot(this.x,this.y);
+	}
+	setMag(new_mag){
+		if(this.mag() > 0){
+			this.normalize();
+		}else{
+			this.x = 1;
+			this.y = 0;
+		}
+		this.mult(new_mag);
+	}
+	normalize(){
+		let mag = this.mag();
+		if(mag > 0){
+			this.x /= mag;
+			this.y /= mag;
+		}
+	}
+  normalizedMag(){
+    let copy = this.copy();
+    copy.normalize();
+    return copy.mag();
+  }
+	heading(){
+		return Math.atan2(this.y,this.x);
+	}
+	setHeading(angle){
+		let mag = this.mag();
+		this.x = Math.cos(angle) * mag;
+		this.y = Math.sin(angle) * mag;
+	}
+	dist(vector){
+		return new Vector(this.x - vector.x,this.y - vector.y).mag();
+	}
+	angle(vector){
+		return Math.atan2(vector.y - this.y, vector.x - this.x);
+	}
+	copy(){
+		return new Vector(this.x,this.y);
+	}
+}
+
+module.exports = Vector;
+
+},{}]},{},[1]);

+ 18 - 0
pictures/whirlwind/index.html

@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html lang="en" dir="ltr">
+<head>
+  <meta charset="utf-8">
+  <title>Build</title>
+  <style media="screen">
+    body {
+      margin: 0;
+      overflow: hidden;
+    }
+  </style>
+</head>
+
+<body>
+  <script src="bundle.js" charset="utf-8"></script>
+</body>
+
+</html>

+ 125 - 0
pictures/whirlwind/index.js

@@ -0,0 +1,125 @@
+const Tagada = require('../../tagada/tagada.js');
+const Util = require('../../tagada/util.js');
+const Vector = require('../../tagada/vector.js');
+
+
+let app = new Tagada(),
+    $ = app.ctx;
+
+let colors = ["black","white"];
+
+function whirl(x,y,radius,sides,resolution,startAngle,offset){
+
+  let lines = [];
+  for (let i = 0; i < sides; i++) {
+    lines[i] = [];
+    let a = Util.map(i,0,sides,0,Math.PI*2) + startAngle;
+    for (let ri = 0; ri < resolution; ri++) {
+      a += Util.map(ri,0,resolution,offset,0);
+      let r = Util.map(ri,0,resolution,radius,0);
+      px = x + Math.cos(a) * r,
+      py = y + Math.sin(a) * r;
+      lines[i].push({x:px,y:py});
+    }
+  }
+  let cCount = 0;
+
+  for (let r = 0; r < lines.length - 1 ; r++) {
+    $.strokeStyle = colors[Math.floor(cCount%colors.length)];
+
+    $.fillStyle = colors[Math.floor(cCount%colors.length)];
+    let l = lines[r].reverse(),
+        next_l = lines[r+1];
+    $.beginPath();
+    $.moveTo(x,y);
+    smooth(l);
+    smooth(next_l);
+    $.closePath();
+    $.fill();
+    $.stroke();
+    cCount +=1;
+  }
+
+  $.strokeStyle = colors[Math.floor(cCount%colors.length)];
+  $.fillStyle = colors[Math.floor(cCount%colors.length)];
+  let l = lines[lines.length-1].reverse(),
+      next_l = lines[0].reverse();
+  $.beginPath();
+  $.moveTo(x,y);
+  smooth(l);
+  smooth(next_l);
+  $.closePath();
+  $.stroke();
+  $.fill();
+}
+
+app.ready = function(){
+  center = new Vector(app.W/2,app.H/2);
+  $.lineWidth = 1;
+};
+
+let center;
+let actualAngle = 0;
+let v  = 0, a = 0;
+
+app.update = function(){
+
+
+};
+
+app.render = function(){
+  let minLength = Math.min(app.W,app.H);
+  let maxLength = Math.hypot(app.W,app.H);
+
+  let d = app.mouse.dist(app.pmouse)
+  d = Util.clamp(d,0,1000);
+
+  v += Util.map(d,0,1000,0,0.1);
+  v = Util.clamp(v,0,0.1);
+
+  v *= 0.96
+
+  a +=v;
+
+  var gradient = $.createRadialGradient(center.x,center.y,0, center.x,center.y,minLength);
+  var gradient2 = $.createRadialGradient(center.x,center.y,0, center.x,center.y,minLength);
+
+  // Add three color stops
+  gradient.addColorStop(1, Util.hsl(Util.map(v,0,0.1,300,340),Util.map(v,0,0.1,0,100),Util.map(v,0,0.1,40,50)));
+  gradient.addColorStop(0, Util.hsl(Util.map(v,0,0.1,300,320),Util.map(v,0,0.1,0,100),Util.map(v,0,0.1,10,40)));
+
+  gradient2.addColorStop(0, Util.hsl(Util.map(v,0,0.1,300,360),Util.map(v,0,0.1,0,100),Util.map(v,0,0.1,10,90)));
+  gradient2.addColorStop(1, Util.hsl(Util.map(v,0,0.1,280,320),Util.map(v,0,0.1,0,100),Util.map(v,0,0.1,10,70)));
+
+  colors[0] = gradient;
+  colors[1] = gradient2;
+
+  whirl(app.W/2,app.H/2,maxLength,Util.map(v,0,0.1,8,20) ,40,-app.frame * 0.001 -a*0.6,-v*0.5);
+
+};
+
+app.resize = function(){
+  center = new Vector(app.W/2,app.H/2);
+  $.lineWidth = 1;
+
+}
+
+
+
+app.run();
+app.backgroundColor = "white";
+function smooth(points) {
+
+  for (i = 1; i < points.length - 2; i++) {
+    var xc = (points[i].x + points[i + 1].x) / 2;
+    var yc = (points[i].y + points[i + 1].y) / 2;
+    $.quadraticCurveTo(points[i].x, points[i].y, xc, yc);
+  }
+
+  $.quadraticCurveTo(
+    points[i].x,
+    points[i].y,
+    points[i + 1].x,
+    points[i + 1].y
+  );
+}

+ 4 - 0
pictures/whirlwind/info.JSON

@@ -0,0 +1,4 @@
+{
+"title":"Whirlwind",
+"description":"What make you spin"
+}

BIN
pictures/whirlwind/vignette.png


File diff suppressed because it is too large
+ 32 - 4
public/pictures/observers/bundle.js


File diff suppressed because it is too large
+ 54 - 4
public/pictures/shared/bundle.js


+ 389 - 0
public/pictures/whirlwind/bundle.js

@@ -0,0 +1,389 @@
+(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
+const Tagada = require('../../tagada/tagada.js');
+const Util = require('../../tagada/util.js');
+const Vector = require('../../tagada/vector.js');
+
+
+let app = new Tagada(),
+    $ = app.ctx;
+
+let colors = ["black","white"];
+
+function whirl(x,y,radius,sides,resolution,startAngle,offset){
+
+  let lines = [];
+  for (let i = 0; i < sides; i++) {
+    lines[i] = [];
+    let a = Util.map(i,0,sides,0,Math.PI*2) + startAngle;
+    for (let ri = 0; ri < resolution; ri++) {
+      a += Util.map(ri,0,resolution,offset,0);
+      let r = Util.map(ri,0,resolution,radius,0);
+      px = x + Math.cos(a) * r,
+      py = y + Math.sin(a) * r;
+      lines[i].push({x:px,y:py});
+    }
+  }
+  let cCount = 0;
+
+  for (let r = 0; r < lines.length - 1 ; r++) {
+    $.strokeStyle = colors[Math.floor(cCount%colors.length)];
+
+    $.fillStyle = colors[Math.floor(cCount%colors.length)];
+    let l = lines[r].reverse(),
+        next_l = lines[r+1];
+    $.beginPath();
+    $.moveTo(x,y);
+    smooth(l);
+    smooth(next_l);
+    $.closePath();
+    $.fill();
+    $.stroke();
+    cCount +=1;
+  }
+
+  $.strokeStyle = colors[Math.floor(cCount%colors.length)];
+  $.fillStyle = colors[Math.floor(cCount%colors.length)];
+  let l = lines[lines.length-1].reverse(),
+      next_l = lines[0].reverse();
+  $.beginPath();
+  $.moveTo(x,y);
+  smooth(l);
+  smooth(next_l);
+  $.closePath();
+  $.stroke();
+  $.fill();
+}
+
+app.ready = function(){
+  center = new Vector(app.W/2,app.H/2);
+  $.lineWidth = 1;
+};
+
+let center;
+let actualAngle = 0;
+let v  = 0, a = 0;
+
+app.update = function(){
+
+
+};
+
+app.render = function(){
+  let minLength = Math.min(app.W,app.H);
+  let maxLength = Math.hypot(app.W,app.H);
+
+  let d = app.mouse.dist(app.pmouse)
+  d = Util.clamp(d,0,1000);
+
+  v += Util.map(d,0,1000,0,0.1);
+  v = Util.clamp(v,0,0.1);
+
+  v *= 0.96
+
+  a +=v;
+
+  var gradient = $.createRadialGradient(center.x,center.y,0, center.x,center.y,minLength);
+  var gradient2 = $.createRadialGradient(center.x,center.y,0, center.x,center.y,minLength);
+
+  // Add three color stops
+  gradient.addColorStop(1, Util.hsl(Util.map(v,0,0.1,300,340),Util.map(v,0,0.1,0,100),Util.map(v,0,0.1,40,50)));
+  gradient.addColorStop(0, Util.hsl(Util.map(v,0,0.1,300,320),Util.map(v,0,0.1,0,100),Util.map(v,0,0.1,10,40)));
+
+  gradient2.addColorStop(0, Util.hsl(Util.map(v,0,0.1,300,360),Util.map(v,0,0.1,0,100),Util.map(v,0,0.1,10,90)));
+  gradient2.addColorStop(1, Util.hsl(Util.map(v,0,0.1,280,320),Util.map(v,0,0.1,0,100),Util.map(v,0,0.1,10,70)));
+
+  colors[0] = gradient;
+  colors[1] = gradient2;
+
+  whirl(app.W/2,app.H/2,maxLength,Util.map(v,0,0.1,8,20) ,40,-app.frame * 0.001 -a*0.6,-v*0.5);
+
+};
+
+app.resize = function(){
+  center = new Vector(app.W/2,app.H/2);
+  $.lineWidth = 1;
+
+}
+
+
+
+app.run();
+app.backgroundColor = "white";
+function smooth(points) {
+
+  for (i = 1; i < points.length - 2; i++) {
+    var xc = (points[i].x + points[i + 1].x) / 2;
+    var yc = (points[i].y + points[i + 1].y) / 2;
+    $.quadraticCurveTo(points[i].x, points[i].y, xc, yc);
+  }
+
+  $.quadraticCurveTo(
+    points[i].x,
+    points[i].y,
+    points[i + 1].x,
+    points[i + 1].y
+  );
+}
+
+},{"../../tagada/tagada.js":2,"../../tagada/util.js":3,"../../tagada/vector.js":4}],2:[function(require,module,exports){
+const Util = require('./util.js');
+const Vector = require('./vector.js');
+
+class Tagada{
+  constructor(){
+    this.canvas = document.createElement("canvas");
+    this.ctx = this.canvas.getContext('2d');
+    document.body.appendChild(this.canvas);
+    this.W = 0;
+    this.H = 0;
+    this.ressources = {
+      images:[],
+      audio:[],
+    }
+    this.backgroundColor = "gray";
+    this.timeData = {
+      now : 0,
+      dt : 0,
+      last : Util.timeStamp(),
+      step : 1/60,
+    };
+    this.frame = 0;
+    window.addEventListener("resize",()=>{
+      this.setSize();
+      this.resize();
+    });
+    this.mouse = new Vector(0,0);
+    this.pmouse = new Vector(0,0);
+    window.addEventListener("pointermove",(event)=>{
+      this.pMove(event);
+    });
+  }
+  addImage(path){
+    let image = new Image();
+    image.src = path;
+    this.ressources.images.push(image);
+    return image;
+  }
+  drawImageCover(image,x,y,sizeX,sizeY){
+    if(sizeX <= 0 || sizeY <= 0) return false;
+    let scaleX,
+        scaleY,
+        ratio = image.width / image.height;
+
+    let sourceScaleX,sourceScaleY;
+
+    let cRation = sizeX / sizeY;
+
+    if(cRation > ratio){
+      scaleX = sizeX;
+      scaleY = scaleX / ratio;
+
+      sourceScaleX = image.width;
+      sourceScaleY = sourceScaleX / cRation;
+    }else{
+      scaleY = sizeY;
+      scaleX = scaleY * ratio;
+
+      sourceScaleY = image.height;
+      sourceScaleX = sourceScaleY * cRation;
+    }
+
+    let offsetX = (sizeX - scaleX);
+    let offsetY = (sizeY - scaleY);
+
+    this.ctx.drawImage(
+    image,(image.width - sourceScaleX) / 2,(image.height - sourceScaleY) / 2,sourceScaleX ,sourceScaleY,
+    x ,y,scaleX + offsetX,scaleY + offsetY
+    );
+
+
+  }
+  run(){
+    Promise.all(
+      this.ressources.images.map(image=>{
+        return new Promise(resolve=>{
+          image.onload = ()=>{
+            resolve();
+          }
+        });
+      })
+    ).then(v=>{
+      this.cap();
+      this.setSize();
+      this.ready();
+      this.loop();
+    });
+  }
+  cap(){
+    this.ctx.lineCap = "round";
+    this.ctx.lineJoin = "round";
+  }
+  resize(){
+
+  }
+  ready(){
+
+  }
+  pMove(event){
+    this.mouse.x = event.clientX - this.canvas.offsetLeft;
+    this.mouse.y = event.clientY - this.canvas.offsetTop;
+  }
+  setSize(){
+    this.W = this.canvas.width = window.innerWidth;
+    this.H = this.canvas.height = window.innerHeight;
+    this.cap();
+  }
+  update(dt){
+
+  }
+  render(){
+
+  }
+  loop(){
+    if(this.backgroundColor == "transparent"){
+      this.ctx.clearRect(0,0,this.W,this.H);
+    }else{
+      this.ctx.fillStyle = this.backgroundColor;
+      this.ctx.fillRect(0,0,this.W,this.H);
+    }
+    this.timeData.now = Util.timeStamp();
+    this.timeData.dt = this.timeData.dt + Math.min(1, (this.timeData.now - this.timeData.last) / 1000);
+    while(this.timeData.dt > this.timeData.step) {
+      this.timeData.dt = this.timeData.dt - this.timeData.step;
+      this.update(this.timeData.step);
+    }
+
+    this.render();
+    this.timeData.last = this.timeData.now;
+    this.frame += 1;
+
+    this.pmouse = this.mouse.copy();
+
+    requestAnimationFrame(()=>{
+      this.loop()
+    });
+
+  }
+}
+module.exports = Tagada;
+
+},{"./util.js":3,"./vector.js":4}],3:[function(require,module,exports){
+const Util = {};
+Util.timeStamp = function() {
+	return window.performance.now();
+};
+Util.random = function(min, max) {
+  return min + Math.random() * (max - min);
+};
+Util.randomArray = function(array){
+	return array[Math.floor(Math.random()*array.length)];
+};
+Util.map = function(a, b, c, d, e) {
+	a = this.clamp(a,b,c);
+  return (a - b) / (c - b) * (e - d) + d;
+};
+Util.lerp = function(value1, value2, amount) {
+  return value1 + (value2 - value1) * amount;
+};
+Util.clamp = function(value,min,max){
+	return Math.max(min, Math.min(max, value));
+};
+Util.threeAngle = function(p0,p1,p2){
+    var b = Math.pow(p1.x-p0.x,2) + Math.pow(p1.y-p0.y,2),
+        a = Math.pow(p1.x-p2.x,2) + Math.pow(p1.y-p2.y,2),
+        c = Math.pow(p2.x-p0.x,2) + Math.pow(p2.y-p0.y,2);
+    return Math.acos( (a+b-c) / Math.sqrt(4*a*b) );
+}
+Util.hsl = function(hue,saturation,lightness){
+	return `hsl(${hue},${saturation}%,${lightness}%)`;
+}
+
+module.exports = Util;
+
+},{}],4:[function(require,module,exports){
+class Vector{
+	constructor(x,y){
+		this.x = x || 0;
+		this.y = y || 0;
+	}
+	set(x,y){
+		this.x = x;
+		this.y = y;
+	}
+  reset(){
+		this.x = 0;
+		this.y = 0;
+  }
+	fromAngle(angle){
+		let x = Math.cos(angle),
+			y = Math.sin(angle);
+		return new Vector(x,y);
+	}
+	add(vector){
+		this.x += vector.x;
+		this.y += vector.y;
+	}
+	sub(vector){
+		this.x -= vector.x;
+		this.y -= vector.y;
+	}
+	mult(scalar){
+		this.x *= scalar;
+		this.y *= scalar;
+	}
+	div(scalar){
+		this.x /= scalar;
+		this.y /= scalar;
+	}
+	dot(vector){
+		return vector.x * this.x + vector.y * this.y;
+	}
+	limit(limit_value){
+		if(this.mag() > limit_value) this.setMag(limit_value);
+	}
+	mag(){
+		return Math.hypot(this.x,this.y);
+	}
+	setMag(new_mag){
+		if(this.mag() > 0){
+			this.normalize();
+		}else{
+			this.x = 1;
+			this.y = 0;
+		}
+		this.mult(new_mag);
+	}
+	normalize(){
+		let mag = this.mag();
+		if(mag > 0){
+			this.x /= mag;
+			this.y /= mag;
+		}
+	}
+  normalizedMag(){
+    let copy = this.copy();
+    copy.normalize();
+    return copy.mag();
+  }
+	heading(){
+		return Math.atan2(this.y,this.x);
+	}
+	setHeading(angle){
+		let mag = this.mag();
+		this.x = Math.cos(angle) * mag;
+		this.y = Math.sin(angle) * mag;
+	}
+	dist(vector){
+		return new Vector(this.x - vector.x,this.y - vector.y).mag();
+	}
+	angle(vector){
+		return Math.atan2(vector.y - this.y, vector.x - this.x);
+	}
+	copy(){
+		return new Vector(this.x,this.y);
+	}
+}
+
+module.exports = Vector;
+
+},{}]},{},[1]);

+ 18 - 0
public/pictures/whirlwind/index.html

@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html lang="en" dir="ltr">
+<head>
+  <meta charset="utf-8">
+  <title>Build</title>
+  <style media="screen">
+    body {
+      margin: 0;
+      overflow: hidden;
+    }
+  </style>
+</head>
+
+<body>
+  <script src="bundle.js" charset="utf-8"></script>
+</body>
+
+</html>

BIN
public/pictures/whirlwind/vignette.png


+ 74 - 23
src/App.vue

@@ -1,27 +1,31 @@
 <template>
-<div id="app" class="full">
-  <iframe id="main" ref="mainframe" v-bind:class="{hidden:loading}" @load="load" width="100%" height="100%"></iframe>
-  <div id="left-pannel" class="h-sep">
-    <div class="box-fill v-sep">
-      <header id="header">
-        <h1 class="title">{{title}}</h1>
-        <vue-markdown :source="poem" class="poem"></vue-markdown>
-      </header>
-      <div id="scrollbar" class="box-fill v-sep scroll-y">
-        <card v-for="p in pictures"
-        :key="p.id" :title="p.title"
-        :description="p.description"
-        :vignettePath="p.vignette"
-        :current="current"
-        :loading="loading"
-        :id="p.id"
-        :draft="p.draft"
-        v-on:selectCurrent="currentChange" />
+<div class="full">
+  <div v-show="!ready" class="loader"/>
+  <div id="app" class="full" v-bind:class="{hidden:!ready}">
+    <iframe id="main" ref="mainframe" v-bind:class="{hidden:loading}" @load="load" width="100%" height="100%"></iframe>
+    <div id="left-pannel" class="h-sep">
+      <div class="box-fill v-sep">
+        <header id="header">
+          <h1 class="title">{{title}}</h1>
+          <vue-markdown :source="poem" class="poem"></vue-markdown>
+        </header>
+        <div id="scrollbar" class="box-fill v-sep scroll-y">
+          <card v-for="p in pictures"
+          :key="p.id" :title="p.title"
+          :description="p.description"
+          :vignettePath="p.vignette"
+          :current="current"
+          :loading="loading"
+          :id="p.id"
+          :draft="p.draft"
+          v-on:selectCurrent="currentChange" />
+        </div>
+      </div>
+      <div id="slide">
       </div>
-    </div>
-    <div id="slide">
     </div>
   </div>
+
 </div>
 </template>
 
@@ -43,6 +47,7 @@ export default {
       title: "Intimacy",
       pictures: pData.default,
       loading: true,
+      ready: false,
       current: 0,
       poem: poem,
     }
@@ -63,8 +68,10 @@ export default {
     }
   },
   mounted: function() {
+    setTimeout(()=>{
+      this.ready = true;
+    },1000);
     this.loading = true;
-
     this.$refs.mainframe.src = this.pictures[this.current].path;
   }
 
@@ -74,8 +81,9 @@ export default {
 <style>
 @font-face {
   font-family: "Quicksand";
-  src: url("fonts/Quicksand-Light.ttf");
+  src: url("./fonts/Quicksand-Light.ttf");
   font-weight: 200;
+  font-style: normal;
 }
 
 html,
@@ -91,8 +99,13 @@ body {
   user-select: none;
   font-size: 0.8rem;
   background-color: black;
-  background-image: radial-gradient(ellipse at bottom center, rgba(0, 0, 0, 0.2) 0%, rgba(0, 0, 0, 1) 60%), url("./assets/5-dots.png");
+  color:white;
+}
+
+#app{
+  transition: all 0.2s;
   perspective: 1000px;
+  background-image: radial-gradient(ellipse at bottom center, rgba(0, 0, 0, 0.2) 0%, rgba(0, 0, 0, 1) 60%), url("./assets/5-dots.png");
 }
 
 h1,
@@ -223,4 +236,42 @@ iframe {
   border-radius: 6px;
 
 }
+
+.loader{
+  position: absolute;
+  left:50%;
+  top:50%;
+  animation: spin 0.3s infinite linear;
+  perspective: 100px;
+  width:32px;
+  height: 32px;
+
+}
+.loader::after{
+  content: "";
+  position: absolute;
+  width:8px;
+  height: 8px;
+  background-color: white;
+  border-radius: 50%;
+  top: 50%;
+  left:0;
+  transform: translate(-50%,-50%);
+}
+.loader::before{
+  box-sizing: border-box;
+  content: "";
+  position: absolute;
+  border: 1.5px solid white;
+  border-radius: 50%;
+  width:100%;
+  height: 100%;
+}
+@keyframes spin {
+  from{
+  }
+  to{
+    transform: rotateZ(360deg);
+  }
+}
 </style>

File diff suppressed because it is too large
+ 1 - 1
src/assets/picturesData.JSON


+ 1 - 1
tagada/tagada.js

@@ -82,8 +82,8 @@ class Tagada{
     ).then(v=>{
       this.cap();
       this.setSize();
-      this.loop();
       this.ready();
+      this.loop();
     });
   }
   cap(){