Fork this turtle, write your own render function, publish!
Test using the GIF export, make sure `Draw different frames` is checked.
#pixels
Log in to post a comment.
/**
Challenge! Fork this turtle and write your own pixelart animation!
@param x 0-1 range
@param y 0-1 range
@param frame 0-1 range
@param grid total grid size
return `true` for pixel (or number > 0) / `false` for no pixel` (or number == 0)
**/
function render(x, y, frame, grid) {
return Math.sqrt((x - 0.5) ** 2 + (y - 0.5) ** 2) < (0.1+pingpong(frame*frame) * 0.75);
}
////////////////////////////////////////////////////////////////
// Pixelart GIF animation. Created by Mark Knol 2021
// https://turtletoy.net/turtle/5c567dc937
////////////////////////////////////////////////////////////////
const grid = 25; // min=10, max=100, step=5
const pixel = 175 / grid;
const drawFrame = 1; // min=0, max=1, step=1 (No, Yes)
const debug = 0; // min=0, max=1, step=1 (No, Yes)
let turtle;
function walk(i, frame) {
const x = i % grid, y = i / grid | 0;
if (i === 0) turtle = new Slowpoke();
if (drawFrame && !x && !y) {
drawRect(turtle, (-grid * 0.5) * pixel, (-grid * 0.5) * pixel, grid * pixel, grid * pixel);
}
let density;
if ((density = render(x / (grid - 1), y / (grid - 1), frame, grid)) > 0) {
if (!debug) fillRect(turtle, (x - grid * 0.5) * pixel, (y - grid * 0.5) * pixel, pixel, pixel, density);
drawRect(turtle, (x - grid * 0.5) * pixel, (y - grid * 0.5) * pixel, pixel, pixel);
}
return i < grid * grid - 1;
}
function fillRect(turtle, x, y, w, h, density = 1) {
const d = clamp(density);
if (d < 0.1) intensity = pixel;
else if (d < 0.2) intensity = pixel / 2;
else if (d < 0.3) intensity = pixel / 4;
else if (d < 0.4) intensity = pixel / 6;
else if (d < 0.5) intensity = pixel / 8;
else if (d < 0.6) intensity = pixel / 10;
else if (d < 0.7) intensity = pixel / 14;
else if (d < 0.8) intensity = pixel / 18;
else if (d < 0.9) intensity = pixel / 22;
else intensity = 0.1;
for (let ii = 0; ii < h; ii += intensity) {
turtle.jump(x, y + ii);
turtle.goto(x + w, y + ii);
}
for (let ii = 0; ii < w; ii += intensity) {
turtle.jump(x + ii, y);
turtle.goto(x + ii, y + h);
}
}
function drawRect(turtle, x, y, w, h) {
turtle.jump(x,y);
turtle.goto(x+w,y);
turtle.goto(x+w,y+h);
turtle.goto(x,y+h);
turtle.goto(x,y);
}
function pingpong(t) {
return (t > 0.5 ? 1 - t : t) * 2;
}
function clamp(v, min = 0.0, max = 1.0) {
return Math.min(Math.max(v, min), max);
}
function mix(x, y, a) {
return x * (1 - a) + y * a;
}
////////////////////////////////////////////////////////////////
// Slowpoke utility code. Created by Reinder Nijhoff 2019
// https://turtletoy.net/turtle/cfe9091ad8
////////////////////////////////////////////////////////////////
function Slowpoke(x, y) {
const linesDrawn = {};
class Slowpoke extends Turtle {
goto(x, y) {
const p = Array.isArray(x) ? [...x] : [x, y];
if (this.isdown()) {
const o = [this.x(), this.y()];
const h1 = o[0].toFixed(8)+'_'+p[0].toFixed(8)+o[1].toFixed(8)+'_'+p[1].toFixed(8);
const h2 = p[0].toFixed(8)+'_'+o[0].toFixed(8)+p[1].toFixed(8)+'_'+o[1].toFixed(8);
if (linesDrawn[h1] || linesDrawn[h2]) {
super.up();
super.goto(p);
super.down();
return;
}
linesDrawn[h1] = linesDrawn[h2] = true;
}
super.goto(p);
}
}
return new Slowpoke(x,y);
}