AI Wind Chimes - Peaceful Garden Sounds Click to make the chimes swing and play! 5 hanging tubes of

50 views Β· Dec 16, 2025

Create a simple Wind Chimes simulation! Draw 5 hanging tubes of different lengths. When you click, a

#xelsedia#xelsedai#xelsedp5flashalpha6
πŸ”€ Remix This πŸ“– View Docs β›Ά Full Screen ← Back to Gallery
πŸ“‹ Embed Code

Copy this code to embed this sketch on your website:

<iframe src="https://p5js.ai/embed/edfc6db1-63ee-4adc-9919-7650cf50f328" width="400" height="400" frameborder="0" allow="autoplay" title="AI Wind Chimes - Peaceful Garden Sounds Click to make the chimes swing and play! 5 hanging tubes of"></iframe>

Adjust width and height as needed. Preview embed β†’

❓ About This Sketch 3 questions

What visual elements does the AI Wind Chimes sketch display?

The sketch visually creates five hanging tubes of varying lengths that resemble wind chimes, swaying gently in response to user interactions.

How can users interact with the Wind Chimes simulation?

Users can click anywhere on the canvas to make the chimes swing and produce soothing musical tones.

What creative coding concept is demonstrated in this p5.js sketch?

This sketch showcases pendulum physics and sound synthesis, illustrating how physical simulations can be combined with audio generation for an interactive experience.

πŸ’¬ AI Chat History 4 messages
πŸ‘€ You
Create a simple Wind Chimes simulation! Draw 5 hanging tubes of different lengths. When you click, all chimes swing and play tones using p5.Oscillator - longer tubes make lower sounds. Show the tubes swinging with smooth animation. Peaceful garden background with soft colors. Keep it simple and working!
πŸ€– AI
Here’s a complete, simple wind chimes sketch with 5 swinging tubes and p5.Oscillator tones. Longer tubes make lower sounds. Click (or tap) to make all chimes swing and ring.

---

### index.html

Loads p5.js 1.11.3 and p5.sound, then your sketch.

```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Wind Chimes – p5.js</title>
<link rel="stylesheet" href="style.css" />

<!-- p5.js core -->
<script src="https://cdn.jsdelivr.net/npm/p5@1.11.3/lib/p5.min.js"></script>
<!-- p5.sound addon (for p5.Oscillator) -->
<script src="https://cdn.jsdelivr.net/npm/p5@1.11.3/lib/addons/p5.sound.min.js"></script>
</head>
<body>
<script src="sketch.js"></script>
</body>
</html>
```

---

### style.css

Same as before (just ensures a full-window canvas).

```css
body {
margin: 0;
padding: 0;
overflow: hidden;
background: #d0e6ff; /* soft sky blue behind the canvas */
}

canvas {
display: block;
}
```

---

### sketch.js

Wind chimes simulation with smooth swinging and gentle tones.

```js
// Wind Chimes with p5.js + p5.sound
// Uses p5.Oscillator: https://p5js.org/reference/#/p5.Oscillator

let chimes = [];
const NUM_CHIMES = 5;

class Chime {
constructor(index, total) {
this.index = index;
this.total = total;

// Pendulum physics state
this.angle = 0;
this.angleVel = 0;
this.angleAcc = 0;
this.damping = 0.995; // how quickly it slows down
this.k = 0.02; // springiness (restoring force)

// Geometry (set in updateGeometry so it recomputes on resize)
this.x0 = 0;
this.y0 = 0;
this.length = 0;
this.updateGeometry();

// Sound: longer tube = lower frequency
const freqHigh = 880; // short tube, higher pitch
const freqLow = 220; // long tube, lower pitch
const t = total > 1 ? index / (total - 1) : 0;
this.freq = lerp(freqHigh, freqLow, t);

this.osc = new p5.Oscillator('sine');
this.osc.freq(this.freq);
this.osc.amp(0); // start silent
this.osc.start();
}

updateGeometry() {
// Horizontal layout
const totalWidth = min(width * 0.6, 500);
const spacing = this.total > 1 ? totalWidth / (this.total - 1) : 0;
const startX = width / 2 - totalWidth / 2;

this.x0 = startX + this.index * spacing;
this.y0 = height * 0.2;

// Tube length increases slightly with index
const baseLen = height * 0.25;
const extra = height * 0.05 * this.index;
this.length = baseLen + extra;
}

// Give the chime a push and play its tone
strike() {
// Set an initial swing (a bit different per tube)
this.angleVel = -0.12 - 0.02 * this.index;
this.angle = this.angleVel * 15;

// Trigger sound with quick attack and gentle decay
this.osc.freq(this.freq);
this.osc.amp(0.4, 0.02); // fade up to 0.4 in 20ms
this.osc.amp(0, 1.5); // fade back to 0 over 1.5s
}

update() {
this.angleAcc = -this.k * this.angle;
this.angleVel += this.angleAcc;
this.angleVel *= this.damping;
this.angle += this.angleVel;
}

display() {
// Tube + cord
push();
translate(this.x0, this.y0);
rotate(this.angle);

// Cord
stroke(90, 80);
strokeWeight(2);
const cordLen = this.length * 0.15;
line(0, 0, 0, cordLen);

// Tube body
const tubeTop = cordLen;
const tubeBottom = this.length;
strokeWeight(12);
stroke(210);
line(0, tubeTop, 0, tubeBottom);

// Highlight stripe on the tube
strokeWeight(5);
stroke(240, 240, 255, 180);
line(0, tubeTop + 2, 0, tubeBottom - 2);

pop();

// Small pivot dot
noStroke();
fill(80);
circle(this.x0, this.y0, 6);
}
}

function setup() {
createCanvas(windowWidth, windowHeight);
// Create chimes
for (let i = 0; i < NUM_CHIMES; i++) {
chimes.push(new Chime(i, NUM_CHIMES));
}
}

function draw() {
drawBackground();
drawChimeFrame();

// Update and draw all chimes
for (let chime of chimes) {
chime.update();
chime.display();
}
}

function drawBackground() {
// Soft sky
background(206, 226, 255);

noStroke();

// Distant hills
fill(180, 215, 190);
ellipse(width * 0.2, height * 0.9, width * 0.8, height * 0.7);
fill(170, 205, 185);
ellipse(width * 0.8, height * 0.95, width * 0.9, height * 0.8);

// Ground
fill(190, 230, 200);
rect(0, height * 0.7, width, height * 0.3);

// Soft sun
fill(255, 245, 210, 240);
circle(width * 0.15, height * 0.2, min(width, height) * 0.18);

// A few simple grass tufts for extra calmness
fill(160, 210, 170, 180);
const step = width / 20;
for (let x = 0; x < width; x += step) {
const h = random(15, 30);
triangle(x, height * 0.7, x + step * 0.3, height * 0.7 - h, x + step * 0.6, height * 0.7);
}
}

function drawChimeFrame() {
// Wooden bar holding the chimes
const barY = height * 0.2;
const barWidth = min(width * 0.7, 600);
const barHeight = 12;

rectMode(CENTER);
noStroke();
fill(160, 120, 90);
rect(width / 2, barY, barWidth, barHeight, 6);
rectMode(CORNER);
}

// Click / tap to make all chimes swing and ring
function mousePressed() {
// Make sure audio context is running (required on many browsers)
userStartAudio();

for (let chime of chimes) {
chime.strike();
}
}

function windowResized() {
resizeCanvas(windowWidth, windowHeight);
// Recompute positions and lengths, keep oscillators
for (let chime of chimes) {
chime.updateGeometry();
}
}
```

---

Notes:

- Oscillator docs: [p5.Oscillator](https://p5js.org/reference/#/p5.Oscillator)
- Shapes like `circle()` are standard 2D drawing calls: [circle](https://p5js.org/reference/#/p5/circle)

Apply these three files and you should get a calm garden scene with 5 wind chimes that swing and play tones whenever you click.
πŸ‘€ You
they move way too much whenb you tuch them
πŸ€– AI
To make the chimes move less when you touch/click them, we just need to calm down the initial push in `strike()`.

Right now:

```js
strike() {
// Set an initial swing (a bit different per tube)
this.angleVel = -0.12 - 0.02 * this.index;
this.angle = this.angleVel * 15;
...
}
```

`rotate(this.angle)` uses **radians**, and `this.angleVel * 15` makes the swing very large (almost flipping the chime).

Below is a toned‑down version: small angles (about 5–10 degrees) and gentle motion.

---

```js
// sketch.js
// Wind Chimes with p5.js + p5.sound
// Uses p5.Oscillator: https://p5js.org/reference/#/p5.Oscillator

let chimes = [];
const NUM_CHIMES = 5;

class Chime {
constructor(index, total) {
this.index = index;
this.total = total;

// Pendulum physics state
this.angle = 0;
this.angleVel = 0;
this.angleAcc = 0;
this.damping = 0.995; // how quickly it slows down
this.k = 0.02; // springiness (restoring force)

// Geometry (set in updateGeometry so it recomputes on resize)
this.x0 = 0;
this.y0 = 0;
this.length = 0;
this.updateGeometry();

// Sound: longer tube = lower frequency
const freqHigh = 880; // short tube, higher pitch
const freqLow = 220; // long tube, lower pitch
const t = total > 1 ? index / (total - 1) : 0;
this.freq = lerp(freqHigh, freqLow, t);

this.osc = new p5.Oscillator('sine');
this.osc.freq(this.freq);
this.osc.amp(0); // start silent
this.osc.start();
}

updateGeometry() {
// Horizontal layout
const totalWidth = min(width * 0.6, 500);
const spacing = this.total > 1 ? totalWidth / (this.total - 1) : 0;
const startX = width / 2 - totalWidth / 2;

this.x0 = startX + this.index * spacing;
this.y0 = height * 0.2;

// Tube length increases slightly with index
const baseLen = height * 0.25;
const extra = height * 0.05 * this.index;
this.length = baseLen + extra;
}

// Give the chime a gentle push and play its tone
strike() {
// Small, gentle swing: around 5–10 degrees in radians
const minDeg = 5;
const maxDeg = 10;
const t = this.total > 1 ? this.index / (this.total - 1) : 0;

// Longer chimes can move slightly more, but still subtle
const angleDeg = lerp(minDeg, maxDeg, t);
this.angle = -radians(angleDeg);

// Start from rest at that displaced position
this.angleVel = 0;

// Trigger sound with quick attack and gentle decay
this.osc.freq(this.freq);
this.osc.amp(0.4, 0.02); // fade up to 0.4 in 20ms
this.osc.amp(0, 1.5); // fade back to 0 over 1.5s
}

update() {
this.angleAcc = -this.k * this.angle;
this.angleVel += this.angleAcc;
this.angleVel *= this.damping;
this.angle += this.angleVel;
}

display() {
// Tube + cord
push();
translate(this.x0, this.y0);
rotate(this.angle);

// Cord
stroke(90, 80);
strokeWeight(2);
const cordLen = this.length * 0.15;
line(0, 0, 0, cordLen);

// Tube body
const tubeTop = cordLen;
const tubeBottom = this.length;
strokeWeight(12);
stroke(210);
line(0, tubeTop, 0, tubeBottom);

// Highlight stripe on the tube
strokeWeight(5);
stroke(240, 240, 255, 180);
line(0, tubeTop + 2, 0, tubeBottom - 2);

pop();

// Small pivot dot
noStroke();
fill(80);
circle(this.x0, this.y0, 6);
}
}

function setup() {
createCanvas(windowWidth, windowHeight);
// Create chimes
for (let i = 0; i < NUM_CHIMES; i++) {
chimes.push(new Chime(i, NUM_CHIMES));
}
}

function draw() {
drawBackground();
drawChimeFrame();

// Update and draw all chimes
for (let chime of chimes) {
chime.update();
chime.display();
}
}

function drawBackground() {
// Soft sky
background(206, 226, 255);

noStroke();

// Distant hills
fill(180, 215, 190);
ellipse(width * 0.2, height * 0.9, width * 0.8, height * 0.7);
fill(170, 205, 185);
ellipse(width * 0.8, height * 0.95, width * 0.9, height * 0.8);

// Ground
fill(190, 230, 200);
rect(0, height * 0.7, width, height * 0.3);

// Soft sun
fill(255, 245, 210, 240);
circle(width * 0.15, height * 0.2, min(width, height) * 0.18);

// A few simple grass tufts for extra calmness
fill(160, 210, 170, 180);
const step = width / 20;
for (let x = 0; x < width; x += step) {
const h = random(15, 30);
triangle(x, height * 0.7, x + step * 0.3, height * 0.7 - h, x + step * 0.6, height * 0.7);
}
}

function drawChimeFrame() {
// Wooden bar holding the chimes
const barY = height * 0.2;
const barWidth = min(width * 0.7, 600);
const barHeight = 12;

rectMode(CENTER);
noStroke();
fill(160, 120, 90);
rect(width / 2, barY, barWidth, barHeight, 6);
rectMode(CORNER);
}

// Click / tap to make all chimes swing and ring
function mousePressed() {
// Make sure audio context is running (required on many browsers)
userStartAudio();

for (let chime of chimes) {
chime.strike();
}
}

function windowResized() {
resizeCanvas(windowWidth, windowHeight);
// Recompute positions and lengths, keep oscillators
for (let chime of chimes) {
chime.updateGeometry();
}
}
```

If you want them even calmer, reduce the degrees in `minDeg`/`maxDeg` (for example 3 and 7), or increase `this.damping` slightly (e.g. `0.997`) so they die out a bit faster.
🎬 Video Preview