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 = $("
").addClass("grid-cell"); let $wrapper = $("
").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 = $("
").addClass("grid-cell"); // let $wrapper = $("
").addClass("element-wrapper"); // $cell.append($wrapper.append(content)); // // this.html = $("
").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 = $("
").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"; });