You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

261 lines
7.0 KiB
JavaScript

class Grid{
constructor(id, cell_size, mode = "STRETCH"){
this.id = id;
this.$grid = $("#"+id);
if (Array.isArray(cell_size)){
this.cell_width = cell_size[0];
this.cell_height = cell_size[1];
} else{
this.cell_width = cell_size;
this.cell_height = cell_size;
}
this.columns = 0;
this.rows = 0;
const possible_mode = ["STRETCH", "FIXED", "SPACE"];
if(possible_mode.includes(mode)){
this.mode = mode;
}
// this.init_css();
this.elements = [];
this.distribute = function(i,j){
// default distribution if there is more than one element
let index = j;
let choose = (index+(i%this.elements.length))%this.elements.length;
return choose;
}
this.mouvements = [];
}
init_css(){
// get the new element because pagedjs changed it
this.$grid = $("#"+this.id);
// compute number of cell that can fit horizontaly and verticaly
this.columns = String(Math.floor(this.$grid.width() / this.cell_width));
this.rows = String(Math.floor(this.$grid.height() / this.cell_height));
console.log(this.$grid.width(), this.$grid.height());
console.log("col-row-size", this.columns, this.rows, "(" + this.cell_width + "px", this.cell_width + "px" + ")");
// init css grid
this.$grid.css("display", "grid");
if(this.mode == "STRETCH" || this.mode == "SPACE"){
this.$grid.css("grid-template-columns", "repeat("+ this.columns +", 1fr");
this.$grid.css("grid-template-rows", "repeat("+ this.rows +", 1fr");
} else{
this.$grid.css("grid-template-columns", "repeat("+ this.columns +", "+ this.cell_width + "px");
this.$grid.css("grid-template-rows", "repeat("+ this.rows +", "+ this.cell_height + "px");
}
}
addElement(element_template){
this.elements.push(element_template);
}
addMouvement(grid_mouvement){
this.mouvements.push(grid_mouvement);
}
draw(){
// fill all the grid with it's element
this.init_css();
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
// pick the element we are going to draw
let pick = this.distribute(i,j);
let element_html = "";
if(pick >= 0){
element_html = this.elements[pick].html;
}
// a clone
let $el = $(element_html);
// wrapp it in a cell
let $cell = $("<div>").addClass("grid-cell");
let $wrapper = $("<div>").addClass("element-wrapper");
//so we can chain transform on it
// $wrapper.css("transform-origin", "center center");
// $wrapper.css("transform", "translate(-50%, -50%)");
if(this.mode == "SPACE"){
$wrapper.css("width", this.cell_width);
$wrapper.css("height", this.cell_height);
}
$cell.append($wrapper.append($el));
// iterate over all mouvement and apply them to the clone
this.mouvements.forEach( function(mvt){
mvt.apply($cell,i,j);
});
// get a clone with mouvement applied
// let $el = this.element_template.draw(i,j);
this.$grid.append($cell);
}
}
}
}
class GridElement{
// a template of grid element to clone into the grid
constructor(id){
//get html content string
// let content = $("#"+id).html();
// wrapp it in a cell
// let $cell = $("<div>").addClass("grid-cell");
// let $wrapper = $("<div>").addClass("element-wrapper");
// $cell.append($wrapper.append(content));
//
// this.html = $("<div>").append($cell).html().trim();
this.html = $("#"+id).html();
// this.mouvements = [];
}
// addMouvement(grid_mouvement){
// this.mouvements.push(grid_mouvement);
// }
// draw(i, j){
// // return the DOM element according to it's template and an i,j parameter
//
// // a clone
// let $new_el = $(this.html);
//
// // iterate over all mouvement and apply them to the clone
// this.mouvements.forEach( function(mvt){
// mvt.apply($new_el,i,j);
// });
//
// return $new_el;
// }
}
class GridMouvement{
constructor(css_property, eval_function, selector=".element-wrapper"){
this.selector = selector;
this.property = css_property;
this.evaluate = eval_function;
}
apply($element, i, j){
// apply the mouvement to an element according to it's i, j position
// on the grid
let $search = $("<div>").append($element);
let $affected_by_mvt = $search.find(this.selector);
let css = this.evaluate(i,j);
if(this.property == "transform"){
let current_transform = $affected_by_mvt.css("transform");
css = current_transform + " " + css;
}
$affected_by_mvt.css(this.property, css);
}
}
// default mouvements
function map_range(value, in_min, in_max, out_min, out_max) {
return (value - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
const sym2HH = new GridMouvement("transform", function(i,j){
let scaleY = 1;
if(j%2==1){ scaleY = -1; }
let transform = "scaleY("+scaleY+")";
return transform;
});
const sym2VV = new GridMouvement("transform", function(i,j){
let scaleX = 1;
if(i%2==1){ scaleX = -1; }
let transform = "scaleX("+scaleX+")";
return transform;
});
const sym4 = new GridMouvement("transform", function(i,j){
let scaleX = 1;
let scaleY = 1;
if(i%2==1){ scaleX = -1; }
if(j%2==1){ scaleY = -1; }
let transform = "scaleX("+scaleX+") scaleY("+scaleY+")";
return transform;
});
const sym4alt = new GridMouvement("transform", function(i,j){
let scaleX = 1;
let scaleY = 1;
if(i%2==1){ scaleY = -1; }
if(j%2==1){ scaleX = -1; }
let transform = "scaleX("+scaleX+") scaleY("+scaleY+")";
return transform;
});
const line_shift = new GridMouvement("transform", function(i,j){
let translate = "";
if(i%2==1){
translate = "translateX(-25%)";
}
if(i%2==0){
translate = "translateX(+25%)";
}
return translate;
});
const shrink = new GridMouvement("transform", function(i,j){
let factor = j/(mygrid.columns);
return "scale("+factor+")";
});
const rotation = new GridMouvement("transform", function(i,j){
let angle = String((j/(mygrid.columns-1))*360)+"deg";
let rotate = "rotate("+angle+")";
return rotate;
});
const random_rot = new GridMouvement("transform", function(i,j){
let angle = Math.random()*360;
let rotate = "rotate("+angle+"deg)";
return rotate;
});
const random_color = new GridMouvement("background", function(i,j){
let hue = map_range(Math.random(),0,1,30,100);
let color = "hsl("+hue+",70%,50%)";
return color;
}, ".leaves");
const scattered = new GridMouvement("transform", function(i,j){
let maxdecal = 120;
let decalx = (Math.random()*maxdecal) - (maxdecal/2);
let decaly = (Math.random()*maxdecal) - (maxdecal/2);
let transform = "translate("+decalx+"%, "+decaly+"%)";
return transform;
});
const diagonal_fontsize = new GridMouvement("font-size", function(i,j){
let x = j/(mygrid.columns-1);
let y = i/(mygrid.rows-1);
let fontsize = Math.max(Math.abs(x-y) * 10, 1);
return fontsize+"em";
});