Fractal curve generator

Developer
Size
13,870 Kb
Views
42,504

How do I make an fractal curve generator?

This broke my brain for an entire 2 days ...I could have not done it without the help of the following people.. What is a fractal curve generator? How do you make a fractal curve generator? This script and codes were developed by Gregor Adams on 20 June 2022, Monday.

Fractal curve generator Previews

Fractal curve generator - Script Codes HTML Codes

<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>fractal curve generator</title> <link rel='stylesheet prefetch' href='css/http___codepen_io_pixelas.css'> <link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="model"> <div class="modelMaker"> <canvas id="model"></canvas> <button id="generate" type="button">generate</button> <button id="save" type="button">save</button> </div> <div class="options"> <label>vertices <input id="vertex" type="range" value="5" min="3" max="9"/> </label> <label>iterations <input id="its" type="range" value="3" min="0" max="5"/> </label> </div> <div class="colors"> <p> <input id="three" type="checkbox" value="threeSides" checked="checked"/> <label for="three">Three sides</label> </p> <p></p> <div> <input id="rb" type="checkbox" value="rainbow"/> <label for="rb">Rainbow</label> <p class="hue">Hue <input id="color" type="range" value="100" min="0" max="360"/> </p> </div> <label>Background <input id="bg" type="color" value="#222222"/> </label> </div>
</div>
<div class="result"> <canvas id="result"> </canvas>
</div>
<div class="dialog" id="dialog">Add the following hash to the url to share the model<code id="dialogInput" readonly="readonly"></code> <button id="closeDialog">close</button>
</div> <script src="js/index.js"></script>
</body>
</html>

Fractal curve generator - Script Codes CSS Codes

@import url(http://fonts.googleapis.com/css?family=Open+Sans:300);
body { margin: 0; //overflow: hidden; //user-select: none; font-family: 'Open Sans', sans-serif; background-color: #fafafa; color: black; display: flex; flex-flow: column; justify-content: center; align-items: center;
}
* { box-sizing: border-box; font-family: inherit; font-weight: 300; text-transform: uppercase;
}
.dialog { position: fixed; z-index: 999; top: 50%; left: 50%; padding: 10px; max-width: 300px; height: auto; border: 0; box-shadow: 0 4px 12px rgba(0,0,0,0.5); transform: translate(-50%, -50%); display: none; background: #fff; &.open { display: block; } #dialogInput { display: block; width: 100%; resize: none; margin: auto; text-transform: lowercase; padding: 10px; &:focus { outline: 2px solid rgba(0,255,255,0.6); } }
}
.model { line-height: 0; display: flex; width: 100%; justify-content: center; h2 { margin: 0; font-size: 15px; line-height: 2; font-family: sans-serif; } .options, .colors { > label { padding: 10px 0; } } > div { padding: 10px; display: flex; flex-flow: column; justify-content: flex-start; align-items: flex-start; > div { //eight: 10px; //background: red; } } canvas { margin: 10px; flex: 0 0 100px; wisth: 100px; height: 100px; &.grab { cursor: grab; } &.grabbing { cursor: grabbing; } }
}
canvas { background: #fff; box-shadow: 0 2px 2px rgba(0,0,0,0.3), 0 -2px 3px rgba(0,0,0,0.1);
}
.result { height: 650px; width: 100%; padding: 10px; display: flex; justify-content: center; canvas { width: 500px; height: 500px; flex: 0 0 500px; } h2 { margin: 0; font-size: 15px; line-height: 2; font-family: sans-serif; }
}
input[type="range"] { display: block; margin: 1em 0; height: 2em; width: 100%;
}
.hue { padding-top: 10px; height: 40px; overflow: hidden; transition: all 0.5s ease-in-out; will-change: visibility, height, opacity;
}
#rb:checked { ~.hue { visibility: hidden; height: 0; opacity: 0; }
}
$base-c: #dadada;
$c: #000;
@include custom-input(checkbox, $c);
button { background: none; color: #000; border: 1px solid #000; border-radius: 2px; cursor: pointer; font-size: 1em; margin: 0 10px; width: calc(100% - 20px); &:focus { outline: none; } &:hover { color: #fff; background: #000; }
}
$base-c: #dadada;
$c: #000;
$min: 0;
$max: 32;
$n: $max - $min;
$u: .5em;
$ruler-line-w: .125em;
$ruler-line-h: 0.3em;
$ruler-gap: .375em;
$track-w: $n*$u + $ruler-line-w;
$track-h: .3em;
$track-total-h: $track-h;
$thumb-d: 0.75em;
$thumb-sf: $thumb-d/$ruler-line-w;
$thumb-m: round(1.5*$ruler-line-h/$ruler-line-w*3);
$thumb-sh: ();
$thumb-u: $ruler-line-w/$thumb-sf/4;
$thumb-sh-red: ($thumb-d - $ruler-line-w)/2/$thumb-sf;
$thumb-sh-off: 1.56*($track-h + $ruler-gap)/$thumb-sf;
$thumb-sh-n: ();
$thumb-sh-n-red: ($thumb-d - $ruler-line-w)/2;
$thumb-sh-n-off: 1.5*($track-h + $ruler-gap);
@for $i from 1 through $thumb-m { $curr: $thumb-sh-off + $i*$thumb-u; $thumb-sh: $thumb-sh, $curr $curr 0 (-$thumb-sh-red); @if $i < .56*$thumb-m { $curr-ms: $thumb-sh-n-off + $i*$ruler-line-w/2; $thumb-sh-n: $thumb-sh-n, $curr-ms $curr-ms 0 (-$thumb-sh-n-red); }
}
@mixin track($flag: null) { width: $track-w; height: $track-total-h; background: linear-gradient($base-c, $base-c) no-repeat 50% 0; background-size: $track-w - if($flag == ms, $ruler-line-w, 0) $track-h;
}
@mixin thumb($flag: null) { border: none; border-radius: 50%; background: currentColor; @if $flag == moz { width: $ruler-line-w; height: $ruler-line-w; } @else { width: $thumb-d; height: $thumb-d; }
}
input[type='range'] { &, &::-webkit-slider-runnable-track, &::-webkit-slider-thumb { -webkit-appearance: none; } align-self: center; border: solid 0 transparent; border-width: 0 $thumb-d; padding: 0; width: $track-w; height: 3*$track-total-h; background: none; font-size: 1em; cursor: pointer; overflow: visible; color: $c; &::-webkit-slider-runnable-track { position: relative; @include track(webkit); } &::-moz-range-track { @include track(); } &::-ms-track { margin-left: $thumb-d/2; border: none; @include track(ms); color: transparent; } &::-moz-range-progress { } &::-ms-fill-lower { } &::-webkit-slider-thumb { position: relative; margin-top: ($track-total-h - $thumb-d)/2; @include thumb(); } &::-moz-range-thumb { @include thumb(moz); } &::-ms-thumb { @include thumb(); } &::-ms-tooltip { display: none; } &::-webkit-slider-runnable-track, /deep/ #track { } &::-webkit-slider-thumb, /deep/ #thumb { } &:focus { outline: none; }
}
/* Chrome/ Opera */
input[type='range']:not(*:root) { $input-w: $track-w + $thumb-d - $ruler-line-w; width: $input-w;
}
/* IE */
_:-ms-input-placeholder, :root input[type='range'] { width: $track-w + $thumb-d - $ruler-line-w;
}

Fractal curve generator - Script Codes JS Codes

'use strict';
// constants
var model = document.getElementById('model');
var result = document.getElementById('result');
var resultContext = result.getContext('2d');
var modelContext = model.getContext('2d');
var its = document.getElementById('its');
var vertex = document.getElementById('vertex');
var color = document.getElementById('color');
var generate = document.getElementById('generate');
var rb = document.getElementById('rb');
var bg = document.getElementById('bg');
var three = document.getElementById('three');
var save = document.getElementById('save');
var dialog = document.getElementById('dialog');
var closeDialog = document.getElementById('closeDialog');
var dialogInput = document.getElementById('dialogInput');
var dotSize = 3;
// dimensions
var modelSize = 100;
var resultSize = 500;
// options
var iterations = its.value;
var nVertex = vertex.value;
var currentColor = color.value;
var rainbow = rb.checked;
var threeSides = three.checked;
var bgColor = bg.value;
// flag to determine if we are grabbing a point
var grab = -1;
var currentHash = '';
// array for our dots
// applies the model logic
var modelLogic = [];
resultContext.globalCompositeOperation = 'lighter';
/** * map Math to window to have easier access */
Object.getOwnPropertyNames(Math).map(function (prop) { window[prop] = Math[prop];
});
/** * convert degree to radians * @param {Number} degree degree to convert * @return {Number} returns radians */
var rad = function rad(degree) { return degree * PI / 180;
};
/** * convert radiians to degree * @param {Number} radians radians to convert * @return {Number} returns degree */
var deg = function deg(radians) { return radians * 180 / PI;
};
/** * sets the size of the canvas */
var setSize = function setSize() { model.height = modelSize; model.width = modelSize; result.height = resultSize; result.width = resultSize;
};
/** * Select text * @prop {Element} THe element which holds the text to select */
var selectText = function selectText(element) { var doc = document, text = doc.getElementById(element), range, selection; if (doc.body.createTextRange) { range = document.body.createTextRange(); range.moveToElementText(text); range.select(); } else if (window.getSelection) { selection = window.getSelection(); range = document.createRange(); range.selectNodeContents(text); selection.removeAllRanges(); selection.addRange(range); }
};
/** * initialize the model with the given points */
var initializeModel = function initializeModel(force) { var getHash = window.location.hash; var preset = []; if (!force && getHash !== '') { var dec = getHash.replace('#', '').split('a'); for (var i = 0; i < dec.length; i++) { var coords = dec[i].split('-'); var x = parseFloat(coords[0].replace('_', '.')); var y = parseFloat(coords[1].replace('_', '.')); preset.push({ x: x, y: y }); } modelLogic = preset; nVertex = vertex.value = preset.length; } else { // set initial state for model of given number of vertices for (var i = 0; i < nVertex; i++) { if (modelLogic[i + 1]) { modelLogic.pop(); } modelLogic[i] = { x: i / (nVertex - 1), y: i === 0 || i === nVertex - 1 ? 0 : modelLogic[i] ? modelLogic[i].y : (floor(random() * 5) + 1) / 6 - 1 / 6 * 2 }; } }
};
/** * grab a point on the model * @param {Event} e the event that fires the action */
var grabPoint = function grabPoint(e) { var X = e.layerX; var Y = e.layerY; for (var i in modelLogic) { // check if we are in range if (abs(X - modelLogic[i].x * model.width) < dotSize && abs(Y - (modelLogic[i].y + 0.5) * model.height) < dotSize) { // add a class to the model to indicate grabbing model.classList.add('grabbing'); // assign the point to our flag grab = i; } }
};
/** * release the point that has been grabbed * @param {Event} e the event that fires the action */
var releasePoint = function releasePoint(e) { if (grab > -1) { model.classList.add('grab'); model.classList.remove('grabbing'); } grab = -1; draw();
};
/** * while moving over the model we want to * check when we are hovering a dot. * In case we are grabbing we want to move the dot. * @param {Event} e the event that fires the action */
var handleMove = function handleMove(e) { // determine current mouse position var X = e.layerX; var Y = e.layerY; // clear classes model.classList.remove('grabbing'); model.classList.remove('grab'); // check if hovering a dot for (var i in modelLogic) { if (abs(X - modelLogic[i].x * modelSize) < dotSize && abs(Y - (modelLogic[i].y + 0.5) * modelSize) < dotSize) { // indicate grabbable model.classList.add('grab'); } } // if grabbing if (grab > -1) { // indicate grabbing model.classList.add('grabbing'); // modify dot on the model canvas modelLogic[grab] = { x: X / modelSize, y: Y / modelSize - 0.5 }; // only draw one layer to prevent performance issues draw(0); }
};
/** * draw the dots onto the model * @param {Object} points the points calculated through the model logic */
var drawDots = function drawDots(points) { for (var i = 0; i < nVertex; i++) { modelContext.lineWidth = 2; modelContext.beginPath(); // give each dot a different color modelContext.strokeStyle = 'hsla( ' + 360 / nVertex * i + ' ,100%,40%,1)'; modelContext.fillStyle = 'white'; modelContext.arc(points[i].x * modelSize, (points[i].y + 0.5) * modelSize, dotSize, 0, 2 * PI); modelContext.stroke(); modelContext.fill(); }
};
/** * draw the model to the given canvas context * and repeat for n iterations * @param {Object} ctx the Context to draw on * @param {Object} points the points calculated through the model logic * @param {Integer} n the number of iterations to apply the model */
var drawModel = function drawModel(ctx, points, n) { // stop after 0 if (n >= 0) { var dx = points[1].x - points[0].x; var dy = points[1].y - points[0].y; var mapped = []; // map the points with new coordinates for (var i = 0; i < nVertex; i++) { var pusher = 0; if (ctx === modelContext) { pusher = 0.5; } mapped[i] = { x: dx * modelLogic[i].x - dy * (modelLogic[i].y + pusher) + points[0].x, y: dy * modelLogic[i].x + dx * (modelLogic[i].y + pusher) + points[0].y }; } // repeat process for (var i = 0; i < nVertex - 1; i++) { if (rainbow) { resultContext.strokeStyle = 'hsla(' + 360 / nVertex * i + ',100%,50%,.6)'; } else { resultContext.strokeStyle = 'hsla(' + currentColor + ',100%,80%,.3)'; //currentColor; } drawModel(ctx, [mapped[i], mapped[i + 1]], n - 1); } } else { // actually draw the model resultContext.lineWidth = 1; modelContext.lineWidth = 3; modelContext.strokeStyle = '#999'; ctx.beginPath(); ctx.moveTo(points[0].x, points[0].y); ctx.lineTo(points[1].x, points[1].y); ctx.stroke(); }
};
/** * draw the model with animationFrames to redraw * @param {Integer} maxIterations flag to force iterations maximum */
var draw = function draw(maxIterations) { // clear both screens modelContext.fillStyle = 'white'; resultContext.fillStyle = bgColor; modelContext.fillRect(0, 0, model.width, model.height); resultContext.fillRect(0, 0, result.width, result.height); // draw model drawModel(modelContext, [{ x: 0, y: 0 }, { x: model.width, y: 0 }], 0); if (threeSides) { // draw result drawModel(resultContext, [{ x: result.width / 4 * 3, y: result.height / 4 + result.height / 8 }, { x: result.width / 4, y: result.height / 4 + result.height / 8 }], maxIterations === undefined ? iterations : min(maxIterations, iterations)); /* drawModel(resultContext, [{ x: result.width / 4, y: result.height / 4 }, { x: cos(rad(60)) * (result.width / 4 * 3), y: sin(rad(60)) * (result.height / 4 * 3) }], (maxIterations === undefined) ? iterations : min(maxIterations, iterations)); */ drawModel(resultContext, [{ x: cos(rad(60)) * (result.width / 2) + result.width / 4, y: sin(rad(60)) * (result.height / 4 * 3) + result.height / 8 }, { x: result.width / 2 + result.width / 4, y: result.height / 4 + result.height / 8 }], maxIterations === undefined ? iterations : min(maxIterations, iterations)); drawModel(resultContext, [{ x: result.width / 2 - result.width / 4, y: result.height / 4 + result.height / 8 }, { x: cos(rad(-60)) * (result.width / 2) + result.width / 4, y: sin(rad(-60)) * (result.height / 4 * 3) + result.height * sqrt(3) / (1 / 3 * 4) + result.height / 8 }], maxIterations === undefined ? iterations : min(maxIterations, iterations)); } else { // draw result drawModel(resultContext, [{ x: result.width / 4, y: result.height / 4 }, { x: result.width / 4 * 3, y: result.height / 4 }], maxIterations === undefined ? iterations : min(maxIterations, iterations)); } // draw the dots drawDots(modelLogic);
};
// add event listeners
model.addEventListener('mousemove', handleMove);
model.addEventListener('mousedown', grabPoint);
window.addEventListener('mouseup', releasePoint);
// change the iterations
its.addEventListener('change', function () { iterations = its.value; draw();
});
// change the color
color.addEventListener('change', function () { currentColor = color.value; draw();
});
// enable rainbow mode
rb.addEventListener('change', function () { rainbow = rb.checked; draw();
});
// toggle three sides
three.addEventListener('change', function () { threeSides = three.checked; draw();
});
// background color changes
bg.addEventListener('change', function () { bgColor = bg.value; draw();
});
// change the number of segemnts (vertices)
vertex.addEventListener('change', function () { nVertex = vertex.value; initializeModel(true); draw();
});
// generate a random model
generate.addEventListener('click', function () { vertex.value = floor(random() * 9) + 3; nVertex = vertex.value; //its.value = floor(random() * 5); //iterations = its.value; modelLogic = []; initializeModel(true); draw();
});
// save model
save.addEventListener('click', function () { var points = []; for (var _iterator = modelLogic, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { var _ref; if (_isArray) { if (_i >= _iterator.length) break; _ref = _iterator[_i++]; } else { _i = _iterator.next(); if (_i.done) break; _ref = _i.value; } var point = _ref; var coord = point.x.toString().replace('.', '_') + '-'; coord += point.y.toString().replace('.', '_'); points.push(coord); } currentHash = points.join('a'); dialogInput.innerHTML = '#' + currentHash; dialog.classList.add('open'); selectText('dialogInput');
});
// save model
closeDialog.addEventListener('click', function () { dialog.classList.remove('open');
});
// initial run
initializeModel();
setSize();
draw();
Fractal curve generator - Script Codes
Fractal curve generator - Script Codes
Home Page Home
Developer Gregor Adams
Username pixelass
Uploaded June 20, 2022
Rating 4.5
Size 13,870 Kb
Views 42,504
Do you need developer help for Fractal curve generator?

Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!

Gregor Adams (pixelass) Script Codes
Create amazing love letters with AI!

Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!