Affichage des articles dont le libellé est js. Afficher tous les articles
Affichage des articles dont le libellé est js. Afficher tous les articles

vendredi 15 novembre 2024

workshop - Intro to Creative Coding & Generative Art, by Ahmad Moussa (links)

 https://slides.com/ahmadmoussa-3/creative-coding-generative-art

by https://x.com/gorillasu


https://timeline.lerandom.art Generative Art Timeline


https://editor.p5js.org 


https://x.com/gorillasu/status/1857444190910664749 example with p5js


https://openprocessing.org/sketch/2320206


example on fxHash https://www.fxhash.xyz/marketplace/generative/15063

colors palette : https://ronikaufman.github.io/color_pals/

colors manipulation js library : https://gka.github.io/chroma.js/

+ https://encycolorpedia.com/2b3c00


https://iquilezles.org/articles/distfunctions/ shapes and math



doc on fxHash : https://docs.fxhash.xyz/


Tricks : 

- when playing with RGB, start from the median value 127.5 and move around +/- 127.5

- RGB + 2 chars => 2 chars of transparency

- cos/sin/tan [0..1] with frameCount native variable of p5js : use pi to divide values and have the last frame coincide with the first frame of the loop.




--- first example

let a = 1;

var b;

const windowWidth = 800;

const windowHeitgh = 800;


function setup() {

  // attach a canvas element to the dom

  createCanvas(windowWidth, windowHeitgh);

  

}


// runs continously for each frame of the video, unless noLoop() inside

function draw() {

  // "#efface"

  // "#decede"

  background("#decede");

  ellipse(100, 150, 100)


  fill ("#efface")

  rect (300, 200, 200)

  noStroke()

  stroke("blue")

  

}



-- animated


let a = 1;

var b;

const windowWidth = 400;

const windowHeitgh = windowWidth;


function setup() {

  // attach a canvas element to the dom

  createCanvas(windowWidth, windowHeitgh);

  

}


// runs continously for each frame of the video, unless noLoop() inside

function draw() {

  // "#efface"

  // "#decede"

  background("#decede");

  noStroke()

  let t = frameCount 

  // for (let y = 0; y < 400; y=y+1){

  //   ellipse (200, y, 5)

  // }

  

  // console.log(frameCount/50)


  for (let y = 0; y < 400; y=y+1){

    fill(127.5 + sin (-frameCount/50 + y/20) * 127.5, 

         127.5 + sin (-frameCount/50 + y/20) * 127.5, 

         127.5 + sin (-frameCount/50 + y/20) * 127.5)

    

    ellipse (200 + sin (-frameCount/50 + y/20) * 20, 

             y,

             20 + cos (frameCount/30 + y/10) * 10)

  }  

  

}

--- moving, and colors changing (by me, inspired by GorillaSun)

let a = 1;

var b;

const windowWidth = 400;

const windowHeitgh = windowWidth;


let variation = 0

let variation2 = 2


function setup() {

  // attach a canvas element to the dom

  createCanvas(windowWidth, windowHeitgh);

  frameRate(50) // frame / s

  

  randomSeed(0) // so that random always does the same

  variation = random(0, 80)

  variation2 = random(100, 80)

}


let loopLength = 75



// runs continously for each frame of the video, unless noLoop() inside

function draw() {

  // "#efface"

  // "#decede"

  background("#decede");

  

  // trick to 

  let t = ( frameCount % loopLength ) / loopLength  * 2 * PI;

  

  // console.log(sin(PI))

  

  // noStroke()


  

  // for (let y = 0; y < 400; y=y+1){

  //   ellipse (200, y, 5)

  // }

  

  // console.log(frameCount/50)


  for (let y = 0; y < 400; y=y+1){

    stroke (127.5 + sin (-t + y/variation) * 127.5, 

            127.5 + sin (-t + y/20) * 127.5, 

            127.5 + sin (-t + y/variation2) * 127.5)

    

    // fill(127.5 + sin (-t/50 + y/20) * 127.5, 

    //      127.5 + sin (-t/50 + y/20), 

    //      127.5 + sin (-t/50 + y/20) * 127.5)

    noFill()

    

    square (200 + sin (-t/50 + y/variation) * 20, 

            200 + tan (-t/50 + y/variation) * variation*variation/3,

             20 + cos (t/30 + y/variation) * variation)

  }  

  

}


function keyPressed(){

  console.log(keyCode)

  if (keyCode == 56){

  saveGif('annimation', 4)

  }

}




--- other links and code from the presentation




other code from the presentation :

Sinus Wave by Ahmad Moussa || Gorilla Sun  https://openprocessing.org/sketch/1784279

function setup() {
createCanvas(400, 400);

}

function draw() {
background(0);
noStroke();
let t = millis()/500

for(let y = 20; y < 380; y++){
  fill(
    127.5 + 127.5 * sin(t + y/40),
    127.5 - 127.5 * cos(t + y/40),
    127.5 + 127.5 * cos(t + y/40)
  )
  ellipse(
    200 + sin(t + y/80 +
              sin(t + y/400) +
              cos(t + y/100)*2
             ) * 30, 
    y + sin(t + y/80 +
              sin(t + y/400))*15,
    20 + sin(t + y/10) * 15)
}
}

variation square by Ahmad Moussa || Gorilla Sun 
function setup() {
createCanvas(400, 400);
}

function draw() {
background(0);
noStroke();
let t = millis()/500

for(let y = 20; y < 380; y++){
  fill(
    127.5 + 127.5 * sin(t + y/40),
    127.5 + 127.5 * cos(t + y/40),
    127.5 - 127.5 * sin(t + y/80)
  )
  ellipse(
    200 + sin(t + y/80 +
              sin(t + y/400) +
              cos(t + y/50)*2
             ) * 30, 
    y + sin(t + y/80 +
              sin(t + y/400))*15,
    20 + sin(t + y/30) * 15)
}
}




LINKS

Zach Lieberman, Talk: Poetic Computation + atlas of blobs




https://openprocessing.org/sketch/2320206 simple circles packing by Ahmad Moussa || Gorilla Sun 

(with : <script src="https://openprocessing.org/openprocessing_sketch.js"></script>
<script src="https://cdn.jsdelivr.net/npm/p5@1.9.4/lib/p5.js"></script>
<script src="https://cdn.jsdelivr.net/npm/p5@1.9.4/lib/addons/p5.sound.min.js"></script> )


let circles = []
let numAttempts = 20000

let canvas_width = 800
let canvas_height = 800
let padding = 50

function setup() {
  createCanvas(canvas_width, canvas_height);
  pixelDensity(4)
  
  background(0)
  stroke(255)
  
  for(let n = 0; n < numAttempts; n++){
    
    let randX = random(padding, canvas_width-padding)
    let randY = random(padding, canvas_height-padding)
    let randR = random(5, 120)
    
    let placeable = true
    for(let circle of circles){
      let d = dist(
        randX, randY, circle.x, circle.y
      )
      
      if(d < randR + circle.r + 5){
        placeable = false
      }
    }
    
    if(
      (randX + randR > canvas_width-padding) ||
      (randX - randR < padding) ||
      (randY + randR > canvas_height-padding) ||
      (randY - randR < padding)
    ){
        placeable = false
    }
    
    if(placeable){
      circles.push(
        {
          x: randX, y: randY, r: randR
        }
      )
    }
  }
  
  strokeWeight(2)
noFill()
  for(let circle of circles){
    ellipse(
      circle.x,
      circle.y ,
      circle.r*2
    )
  }
  
  noLoop()
}




 Particle System with Grid Lookup
by Ahmad Moussa || Gorilla Sun 
<script src="https://cdn.jsdelivr.net/npm/p5@1.6.0/lib/p5.min.js"></script> 
p5.disableFriendlyErrors = true;
let N_PARTICLES = 50;
let particles = [];
let grid;

function setup() {
  createCanvas(windowWidth, windowHeight);

  grid = new Grid(windowWidth, windowHeight, 22);

  for (let n = 0; n < N_PARTICLES; n++) {
    let particle = new Particle(new createVector(random(windowWidth), random(windowHeight)))
    particles.push(particle);
    grid.addParticle(particle);
  }
}

function draw() {
  background(220);

  if (mouseIsPressed) {
    for(let n = 0; n < 5; n++){
let particle = new Particle(new createVector(mouseX+random(-1,1), mouseY+random(-1,1)))
    particles.push(particle);
    grid.addParticle(particle);
}
  }

  textSize(30)
  textAlign(LEFT, TOP)
  let numCollisionChecks = 0
  let startneigh = performance.now();
  for (let p of particles) {
    let neighbors = grid.getNeighbors(p)
    numCollisionChecks += p.checkCollision(neighbors)
p.updateState();
  }
  let endneigh = performance.now();
  let coll = `${numCollisionChecks} collisions computed in ${ endneigh - startneigh} ms`

  let startup = Date.now();
  for (let p of particles) {
p.checkEdges();
    grid.removeParticle(p)
    grid.addParticle(p)
  }
  let endup = Date.now();
  let up = 'Grid updated in ' + round(endup - startup, 2) + ' ms'

noFill()
  let startd = Date.now();
  for (let p of particles) {
    p.display();
  }
  let endd = Date.now();
  let dr = 'Draw in ' + round(endd - startd, 2) + ' ms'


  fill(0)
  text('Particles: ' + particles.length, 10, 10)
  text(coll, 10, 50);
  text(up, 10, 90);
  text(dr, 10, 130);
}

class Particle {
  constructor(pos) {
    this.pos = pos;
    this.velocity = createVector(random(-1.25, 1.25), random(-1.25, 1.25));
    this.acceleration = createVector(0, 0);

    this.mass = random(3, 10)
    this.radius = this.mass;
    this.maxSpeed = 10;
  }

  updateState(newPos) {
    this.velocity.add(this.acceleration);
    this.velocity.limit(this.maxSpeed); // Limit the particle's speed
    this.pos.add(this.velocity);
  }

  checkEdges() {
    if (this.pos.x - this.radius < 0) {
      this.pos.x = this.radius; // Prevent from leaving the canvas from the left side
      this.velocity.x *= -1;
    } else if (this.pos.x + this.radius > width) {
      this.pos.x = width - this.radius; // Prevent from leaving the canvas from the right side
      this.velocity.x *= -1;
    }

    if (this.pos.y - this.radius < 0) {
      this.pos.y = this.radius; // Prevent from leaving the canvas from the top
      this.velocity.y *= -1;
    } else if (this.pos.y + this.radius > height) {
      this.pos.y = height - this.radius; // Prevent from leaving the canvas from the bottom
      this.velocity.y *= -1;
    }
  }

  checkCollision(otherParticles) {
let counter = 0
    for (let other of otherParticles) {
      if (this != other) {
        let distance = this.pos.dist(other.pos);
        let minDistance = this.radius + other.radius + 1;

        if (distance <= minDistance) {
          // Calculate collision response
          let normal = p5.Vector.sub(other.pos, this.pos).normalize();
          let relativeVelocity = p5.Vector.sub(other.velocity, this.velocity);
          let impulse = p5.Vector.mult(normal, 2 * p5.Vector.dot(relativeVelocity, normal) / 2);

          // Apply repulsion force to prevent sticking
          let repulsion = p5.Vector.mult(normal, minDistance - distance + 2).mult(1);

          // Update velocities
          this.velocity.add(p5.Vector.div(impulse, this.mass));
          other.velocity.sub(p5.Vector.div(impulse, other.mass));

          // Apply repulsion force
          this.pos.sub(p5.Vector.div(repulsion, this.mass));
          other.pos.add(p5.Vector.div(repulsion, other.mass));
        }
counter++
      }
    }
return counter
  }

  display() {
    ellipse(this.pos.x, this.pos.y, this.radius * 2);
  }
}

/*
  The lookup grid
*/
class Grid {
  constructor(i, t, s) {
    (this.cellSize = s),
    (this.numCols = Math.ceil(i / s)),
    (this.numRows = Math.ceil(t / s)),
    (this.cells = []);
    for (let e = 0; e < this.numCols; e++) {
      this.cells[e] = [];
      for (let l = 0; l < this.numRows; l++) {
        this.cells[e][l] = [];
      }
    }
  }

  addParticle(i) {
    let t = Math.floor(i.pos.x / this.cellSize);
    let s = Math.floor(i.pos.y / this.cellSize);

    this.cells[t][s].push(i)
    i.gridCell = {
      col: t,
      row: s
    }
  }

  removeParticle(i) {
    let {
      col: t,
      row: s
    } = i.gridCell
    let e = this.cells[t][s];
    let l = e.indexOf(i);
    e.splice(l, 1);
  }

  determineCell(i) {
    let t = Math.floor(i.pos.x / this.cellSize);
    let s = Math.floor(i.pos.y / this.cellSize);
    return {
      col: t,
      row: s
    }
  }

  getNeighbors(particle) {
    let top_left = [
      floor((particle.pos.x - particle.radius) / this.cellSize),
      floor((particle.pos.y - particle.radius) / this.cellSize),
    ]

    let bottom_right = [
      floor((particle.pos.x + particle.radius) / this.cellSize),
      floor((particle.pos.y + particle.radius) / this.cellSize),
    ]

    let neighbors = []
    for (let i = top_left[0]; i <= bottom_right[0]; i++) {
      for (let j = top_left[1]; j <= bottom_right[1]; j++) {
        if (i < 0 || j < 0 || i >= this.numCols || j >= this.numRows) continue
        let c = this.cells[i][j]
        for (let p of c) {
          // don't add the particle itself
          if (p != particle) neighbors.push(p)
        }
      }
    }

    return neighbors
  }
}

mercredi 25 mai 2022

common regexp

 https://owasp.org/www-community/OWASP_Validation_Regex_Repository


common regexp use-cases

vendredi 6 janvier 2017

JIRA Server - redirect to full issue view after creation

 (note : this works with most version of JIRA available as of now,  Janvier 2017)

Instead of staying in the current view, you can use the following tricks to make your JIRA SERVER / DATACENTER redirect directly to the recently created issue.


JavaScript (in banner)

The trick here is to disable the "popup" with the create screen, hence going to the "full create screen" which opens the page afterward.

<script type="text/javascript">
AJS.$("#create_link").removeClass("create-issue");
$("#announcement-banner").hide()</script>

cf. : https://confluence.atlassian.com/jirakb/how-to-disable-create-issue-popup-300813780.html

 

Plugin "Issue Quick Start" (and JS source)


The following plugin aims at the same :


Excerpt from the source :

AJS.$(document).on('DOMNodeInserted', function(event) {
    if (event.target.id == 'aui-flag-container') {
        console.log('issue-quick-start: Got post-it note!');
        AJS.$(event.target).on('DOMNodeInserted', function(event) {
            console.log('issue-quick-start: Post-it HTML: ' + event.target.innerHTML);
            var postItLink = AJS.$(event.target.innerHTML).find('a');
            var postItPath = postItLink.attr('href');
            if (postItPath && postItLink.attr('data-issue-key')) {
                console.log('issue-quick-start: Going to new issue path ' + postItPath);
                window.location = postItPath;
            }
        })
    }
});


[TODO] Script Runner : redirect with script fragment (??)

  • Is there some cleaner way to do it with SR "Script Fragments" to perform the redirect ?

cf. https://scriptrunner.adaptavist.com/4.3.7/jira/fragments/WebItem.html#_redirects

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.label.LabelManager
import com.atlassian.sal.api.ApplicationProperties
import com.onresolve.scriptrunner.runner.ScriptRunnerImpl
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.transform.BaseScript
 
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response
 
@BaseScript CustomEndpointDelegate delegate
 
def labelManager = ComponentAccessor.getComponent(LabelManager)
def applicationProperties = ScriptRunnerImpl.getOsgiService(ApplicationProperties)
def issueManager = ComponentAccessor.getIssueManager()
 
labelIssue(httpMethod: "GET") { MultivaluedMap queryParams ->
 
    def issueId = queryParams.getFirst("issueId") as Long
    def issue = issueManager.getIssueObject(issueId)
 
/**    def label = labelManager.getLabels(issueId)
    if (! label) {
        labelManager.addLabel(null, issueId, "approved", false)
    }
**/
    Response.temporaryRedirect(URI.create("${applicationProperties.baseUrl}/browse/${issue.key}")).build()
}


jeudi 9 octobre 2014

JavaScript multiline code (JSON description)

It is currently not possible to store a multiline string in javascript. This is annoying since for example storing some JSON data often leads to long data to concatenate or to push into an array.
If you want to avoid this, you can use the following trick, since javascript accepts multiline comments, and returns them to the toString call on a function :

var jsonDescriptionText= function(){/*
[
    {
        "cat": "Categ1",
        "links": [
            {
                "txt": "text1",
                "url": "http://url",
                "title": "mouseover field"
            }
        ]
    }
]*/}.toString().slice(14,-3);
Note 1 : This avoids using concatenation for each line :
var longString2="string part1" + 
"string part2" 
or even escaping the new lines :
var longString2="string part1\
string part2"

Note 2 :

ECMA-262 5th Edition section 7.8.4 and called LineContinuation : "A line terminator character cannot appear in a string literal, except as part of a LineContinuation to produce the empty character sequence. The correct way to cause a line terminator character to be part of the String value of a string literal is to use an escape sequence such as \n or \u000A."

Note 3 :
 "In EcmaScript 6, you'll be able to use backticks for Template Strings, known in the spec as a NoSubstitutionTemplate:
var htmlString = `Say hello to 
multi-line
strings!`;
 "


(seen on : http://stackoverflow.com/questions/805107/creating-multiline-strings-in-javascript)