Just search for the nice values / curves.
Log in to post a comment.
console.clear(); const turtle = new Turtle(); const PI2 = Math.PI*2; const depth = 5; // min=2, max=100, step=1 const useOddEven = 1; // min=0, max=1, step=1 const innerRadius = 3; // min=0, max=100, step=0.01 const outerRadius = 80; // min=0, max=100, step=0.01 const radiusEasing = 2; // min=0, max=40, step=1 const radiusEase = getEasing(radiusEasing); console.log("radiusEase: " + radiusEase.name); const innerAmount = 1; // min=0, max=100, step=0.1 const outerAmount = 16.7; // min=0, max=100, step=0.1 const amountEasing = 0; // min=0, max=40, step=1 const amountEase = getEasing(amountEasing); console.log("amountEase: " + amountEase.name); const innerCircleRadius = 1; // min=0, max=50, step=0.01 const outerCircleRadius = 15.4; // min=0, max=50, step=0.01 const circleRadiusEasing = 0; // min=0, max=40, step=1 const circleRadiusEase = getEasing(circleRadiusEasing); console.log("circleRadiusEase: " + circleRadiusEase.name); function walk(i) { let r = i/depth; circles( i, lerp(innerRadius, outerRadius, radiusEase.fn(r)), lerp(innerAmount, outerAmount, amountEase.fn(r))|0, lerp(innerCircleRadius, outerCircleRadius, circleRadiusEase.fn(r))); return i < depth; } function lerp(a, b, r) { return a + (b - a) * r; } function circles(idx, radius, amount, circleRadius) { let f = 1 / amount; for (let i = 0; i<amount; i++) { let t = f * i; let a = PI2 * t; if (useOddEven && idx & 1) a += PI2 * f * 0.5; let pos = [Math.sin(a) * radius, Math.cos(a) * radius - circleRadius]; turtle.jump(pos); turtle.circle(circleRadius); } } function getEasing(idx) { return [ {name: "linear", fn: t => t}, {name: "smoothstep", fn: t => t * t * (3.0 - 2.0 * t)}, {name: "quad in", fn: t => t * t}, {name: "quad out", fn: t => t * (2.0 - t)}, {name: "quad in/out", fn: t => t <= 0.5 ? t * t * 2.0 : 1.0 - (--t) * t * 2.0}, {name: "quad out/in", fn: t => (t < 0.5) ? -0.5 * (t = (t * 2.0)) * (t - 2.0) : 0.5 * (t = (t * 2.0 - 1.0)) * t + 0.5}, {name: "pow in", fn: t => Math.pow(t, 5)}, {name: "pow out", fn: t => 1 - Math.pow(1 - t, 5)}, {name: "sine in", fn: t => 1 - Math.cos((Math.PI * 0.5) * t)}, {name: "sine out", fn: t => Math.sin(Math.PI * 0.5 * t)}, {name: "sine in/out", fn: t => .5 - Math.cos(Math.PI * t) / 2.0}, {name: "sine out/in", fn: t => { if (t == 0.0) return 0.0 else if (t == 1.0) return 1.0 else return (t < 0.5) ? 0.5 * Math.sin((t * 2.0) * Math.PI*0.5) : -0.5 * Math.cos((t * 2.0 - 1.0) * Math.PI*0.5) + 1.0 }}, {name: "circ in", fn: t => 1.0 - Math.sqrt(1.0 - t * t)}, {name: "circ out", fn: t => { --t; return Math.sqrt(1.0 - t * t) }}, {name: "circ in/out", fn: t => t <= 0.5 ? (Math.sqrt(1.0 - t * t * 4.0) - 1.0) / -2.0 : (Math.sqrt(1.0 - (t * 2.0 - 2.0) * (t * 2.0 - 2.0)) + 1.0) / 2.0}, {name: "circ out/in", fn: t => (t < 0.5) ? 0.5 * Math.sqrt(1.0 - (t = t * 2.0 - 1.0) * t) : -0.5 * ((Math.sqrt(1.0 - (t = t * 2.0 - 1.0) * t) - 1.0) - 1.0)}, {name: "cube in", fn: t => t * t * t}, {name: "cube out", fn: t => 1.0 + (--t) * t * t}, {name: "cube in/out", fn: t => t <= 0.5 ? t * t * t * 4.0 : 1.0 + (--t) * t * t * 4.0}, {name: "cube out/in", fn: t => 0.5 * ((t = t * 2.0 - 1.0) * t * t + 1.0)}, {name: "quart in", fn: t => t * t * t * t}, {name: "quart out", fn: t => 1.0 - (--t) * t * t * t}, {name: "quart in/out", fn: t => t <= 0.5 ? t * t * t * t * 8.0 : (1.0 - (t = t * 2.0 - 2.0) * t * t * t) * 0.5 + 0.5}, {name: "quart out/in", fn: t => (t < 0.5) ? -0.5 * (t = t * 2.0 - 1.0) * t * t * t + 0.5 : 0.5 * (t = t * 2.0 - 1.0) * t * t * t + 0.5}, {name: "quint in", fn: t => t * t * t * t * t}, {name: "quint out", fn: t => (t = t - 1) * t * t * t * t + 1.0}, {name: "quint in/out", fn: t => ((t *= 2.0) < 1.0) ? (t * t * t * t * t) / 2.0 : ((t -= 2.0) * t * t * t * t + 2.0) / 2.0}, {name: "quint out/in", fn: t => 0.5 * ((t = t * 2.0 - 1.0) * t * t * t * t + 1.0)}, {name: "expo in", fn: t => Math.pow(2, 10.0 * (t - 1.0))}, {name: "expo out", fn: t => -Math.pow(2, -10.0 * t) + 1.0}, {name: "expo in/out", fn: t => t < .5 ? Math.pow(2, 10.0 * (t * 2.0 - 1.0)) / 2.0 : (-Math.pow(2, -10.0 * (t * 2.0 - 1.0)) + 2.0) / 2.0}, {name: "expo out/in", fn: t => (t < 0.5) ? 0.5 * (1.0 - Math.pow(2, -20.0 * t)) : (t == 0.5) ? 0.5 : 0.5 * (Math.pow(2, 20.0 * (t - 1.0)) + 1.0)}, {name: "back in", fn: t => t * t * (5.0 * t - 4.0)}, {name: "back out", fn: t => 1 - --t * t * (-5.0 * t - 4.0)}, {name: "back in/out", fn: t => { t *= 2.0 if (t < 1.0) return t * t * (5.0 * t - 4.0) / 2.0 t -= 2.0 return (1 - t * t * (-5.0 * t - 4.0)) / 2.0 + 0.5 }}, {name: "elastic in", fn: t => {const ELASTIC_AMPLITUDE=1, ELASTIC_PERIOD=0.4; return -(ELASTIC_AMPLITUDE * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - (ELASTIC_PERIOD / (Math.PI / 2) * Math.asin(1 / ELASTIC_AMPLITUDE))) * (Math.PI * 2) / ELASTIC_PERIOD))}}, {name: "elastic out", fn: t => {const ELASTIC_AMPLITUDE=1, ELASTIC_PERIOD=0.4; return (ELASTIC_AMPLITUDE * Math.pow(2, -10 * t) * Math.sin((t - (ELASTIC_PERIOD / (Math.PI * 2) * Math.asin(1 / ELASTIC_AMPLITUDE))) * (Math.PI * 2) / ELASTIC_PERIOD) +1)}}, {name: "elastic in/out", fn: t => {const ELASTIC_AMPLITUDE=1, ELASTIC_PERIOD=0.4; if (t < 0.5) return -0.5 * (Math.pow(2, 10.0 * (t -= 0.5)) * Math.sin((t - (ELASTIC_PERIOD / 4.0)) * (Math.PI * 2) / ELASTIC_PERIOD)); return Math.pow(2, -10 * (t -= 0.5)) * Math.sin((t - (ELASTIC_PERIOD / 4)) * (Math.PI * 2.0) / ELASTIC_PERIOD) * 0.5 + 1.0;}}, {name: "steps", fn: t => Math.floor(t * 10.0) / 10.0}, {name: "array", fn: t => [0.0, 0.4, 0.7, 0.2, 1.0][Math.floor(t * 5.0)]}, {name: "randomish", fn: t => t + -0.03 + Math.random() * 0.06} ][idx]; }