Skip to content

Instantly share code, notes, and snippets.

@tyfkda
Last active January 28, 2024 09:26
Show Gist options
  • Save tyfkda/3dc133d81a5b2696bf4bd2bb34109b5c to your computer and use it in GitHub Desktop.
Save tyfkda/3dc133d81a5b2696bf4bd2bb34109b5c to your computer and use it in GitHub Desktop.
Rose screen saver (p5.js)
const WIDTH = 600, HEIGHT = 600
const DIV = 64
const TWO_PI = 2 * Math.PI
const MIN_TIME = 60
const MAX_TIME = 300
const TRANSITION_RATIO = 1.0 / 100
function randi(min, max) {
return Math.floor(random(min, max + 1))
}
function sign(x) {
return x < 0 ? -1 : 1
}
let canvas
let canvasScale = 1.0
function setObjectFitContain(canvas) {
canvas.style.width = canvas.style.height = '100%'
canvas.style.objectFit = 'contain'
}
function setup() {
canvas = createCanvas(windowWidth, windowHeight, WEBGL)
const w = min(windowWidth, windowHeight)
canvasScale = w / WIDTH
setObjectFitContain(canvas.canvas)
noStroke()
colorMode(HSB, 100)
frameRate(60)
}
let counter = 0
let nextCounter = 0
let hueStart = 0
let angleStart = 0
let radius = 0
let radiusTarget = 0
let innerRadius = 0
let innerRadiusTarget = 0
let innerRadiusFrequency = 1
let innerRadiusFrequencyTarget = 1
function draw() {
fill(0, 20)
rect(-width * 0.5, -height * 0.5, width, height)
scale(canvasScale)
++counter
if (counter >= nextCounter) {
counter = 0
nextCounter = randi(MIN_TIME, MAX_TIME)
const flip1 = random(5) < 1 ? -1 : 1
const flip2 = random(3) < 1 ? -1 : 1
radiusTarget = flip1 * sign(radiusTarget) * random(WIDTH / 6, WIDTH / 4)
innerRadiusTarget = random(-radiusTarget, radiusTarget)
innerRadiusFrequencyTarget = flip2 * sign(innerRadiusFrequencyTarget) * randi(3, 20)
}
radius += (radiusTarget - radius) * TRANSITION_RATIO
innerRadius += (innerRadiusTarget - innerRadius) * TRANSITION_RATIO
innerRadiusFrequency += (innerRadiusFrequencyTarget - innerRadiusFrequency) * TRANSITION_RATIO
const dotRadius = 8
const r = radius
const r2 = innerRadius
const hStep = 1 * (100 / DIV)
let h = hueStart
for (let i = 0; i < DIV; ++i) {
const t = (i / DIV) * TWO_PI
const t2 = t * innerRadiusFrequency
const x = r * Math.cos(t + angleStart) + r2 * Math.cos(t2)
const y = r * Math.sin(t + angleStart) + r2 * Math.sin(t2)
fill(h, 100, 100)
ellipse(x, y, dotRadius, dotRadius)
h = (h + hStep) % 100
}
hueStart = (hueStart + 1) % 100
angleStart = (angleStart + radians(1)) % TWO_PI
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight)
const w = min(windowWidth, windowHeight)
canvasScale = w / WIDTH
setObjectFitContain(canvas.canvas)
}
function mousePressed() {
let fs = fullscreen();
fullscreen(!fs);
}
@tyfkda
Copy link
Author

tyfkda commented Jan 27, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment