📝 Added sandbox (code sketchbook)
This commit is contained in:
parent
b475595f7f
commit
b5daf18b1a
142 changed files with 100702 additions and 0 deletions
1
sandbox/simulating_vines/app.css
Normal file
1
sandbox/simulating_vines/app.css
Normal file
File diff suppressed because one or more lines are too long
36683
sandbox/simulating_vines/app.js
Normal file
36683
sandbox/simulating_vines/app.js
Normal file
File diff suppressed because one or more lines are too long
342
sandbox/simulating_vines/app2.js
Normal file
342
sandbox/simulating_vines/app2.js
Normal file
|
|
@ -0,0 +1,342 @@
|
|||
(function () {
|
||||
var canvas = document.getElementById("vines");
|
||||
var context = canvas.getContext("2d");
|
||||
var canvasb = document.getElementById("leaves");
|
||||
var contextb = canvasb.getContext("2d");
|
||||
var leaves = [];
|
||||
|
||||
// Resize canvas
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
canvasb.width = window.innerWidth;
|
||||
canvasb.height = window.innerHeight;
|
||||
|
||||
// Clear canvas
|
||||
context.fillStyle = "#89f1d7";
|
||||
context.fillRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
// Calculate distance from point to line
|
||||
function distancePointToLine(point, line) {
|
||||
var L = Math.sqrt(
|
||||
Math.pow(line[1].x - line[0].x, 2) + Math.pow(line[1].y - line[0].y, 2)
|
||||
);
|
||||
var r =
|
||||
((point.x - line[0].x) * (line[1].x - line[0].x) +
|
||||
(point.y - line[0].y) * (line[1].y - line[0].y)) /
|
||||
Math.pow(L, 2);
|
||||
var s =
|
||||
((line[0].y - point.y) * (line[1].x - line[0].x) -
|
||||
(line[0].x - point.x) * (line[1].y - line[0].y)) /
|
||||
Math.pow(L, 2);
|
||||
if (r >= 0 && r <= 1) {
|
||||
return Math.abs(s) * L;
|
||||
} else {
|
||||
return Math.min(
|
||||
Math.sqrt(
|
||||
Math.pow(point.x - line[0].x, 2) + Math.pow(point.y - line[0].y, 2)
|
||||
),
|
||||
Math.sqrt(
|
||||
Math.pow(point.x - line[1].x, 2) + Math.pow(point.y - line[1].y, 2)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw leaf
|
||||
function drawLeaf(leaf) {
|
||||
leaf.size = Math.max(10, leaf.size);
|
||||
contextb.save();
|
||||
contextb.translate(leaf.x, leaf.y);
|
||||
contextb.rotate(leaf.angle);
|
||||
contextb.translate(-leaf.x, -leaf.y);
|
||||
contextb.fillStyle = "#ff0078";
|
||||
contextb.beginPath();
|
||||
contextb.moveTo(leaf.x, leaf.y);
|
||||
contextb.bezierCurveTo(
|
||||
leaf.x + leaf.size,
|
||||
leaf.y,
|
||||
leaf.x + leaf.size * 2,
|
||||
leaf.y + leaf.size,
|
||||
leaf.x,
|
||||
leaf.y + leaf.size * 4
|
||||
);
|
||||
contextb.bezierCurveTo(
|
||||
leaf.x - leaf.size * 2,
|
||||
leaf.y + leaf.size,
|
||||
leaf.x - leaf.size,
|
||||
leaf.y,
|
||||
leaf.x,
|
||||
leaf.y
|
||||
);
|
||||
contextb.closePath();
|
||||
contextb.fill();
|
||||
contextb.restore();
|
||||
}
|
||||
|
||||
// Draw vine
|
||||
function drawVinesWithLattice(
|
||||
lattice,
|
||||
seeds,
|
||||
interations,
|
||||
sort,
|
||||
prune,
|
||||
minLength,
|
||||
maxLength
|
||||
) {
|
||||
var t = 1;
|
||||
var maxLineWidth = 10;
|
||||
|
||||
// Create initial branches
|
||||
var branches = [];
|
||||
for (var i in seeds) {
|
||||
branches.push({
|
||||
points: [
|
||||
{ x: seeds[i].x, y: seeds[i].y },
|
||||
{ x: seeds[i].x, y: seeds[i].y },
|
||||
{ x: seeds[i].x, y: seeds[i].y },
|
||||
{ x: seeds[i].x, y: seeds[i].y },
|
||||
],
|
||||
angle: 0,
|
||||
distanceToLattice: 1000,
|
||||
lineWidth: 6,
|
||||
active: true,
|
||||
leaf: false,
|
||||
});
|
||||
}
|
||||
|
||||
// Animation function
|
||||
function tick() {
|
||||
// Draw branches
|
||||
contextb.clearRect(0, 0, canvasb.width, canvasb.height);
|
||||
for (var i in branches) {
|
||||
var ax =
|
||||
(-branches[i].points[0].x +
|
||||
3 * branches[i].points[1].x -
|
||||
3 * branches[i].points[2].x +
|
||||
branches[i].points[3].x) /
|
||||
6;
|
||||
var ay =
|
||||
(-branches[i].points[0].y +
|
||||
3 * branches[i].points[1].y -
|
||||
3 * branches[i].points[2].y +
|
||||
branches[i].points[3].y) /
|
||||
6;
|
||||
var bx =
|
||||
(branches[i].points[0].x -
|
||||
2 * branches[i].points[1].x +
|
||||
branches[i].points[2].x) /
|
||||
2;
|
||||
var by =
|
||||
(branches[i].points[0].y -
|
||||
2 * branches[i].points[1].y +
|
||||
branches[i].points[2].y) /
|
||||
2;
|
||||
var cx = (-branches[i].points[0].x + branches[i].points[2].x) / 2;
|
||||
var cy = (-branches[i].points[0].y + branches[i].points[2].y) / 2;
|
||||
var dx =
|
||||
(branches[i].points[0].x +
|
||||
4 * branches[i].points[1].x +
|
||||
branches[i].points[2].x) /
|
||||
6;
|
||||
var dy =
|
||||
(branches[i].points[0].y +
|
||||
4 * branches[i].points[1].y +
|
||||
branches[i].points[2].y) /
|
||||
6;
|
||||
context.lineWidth = branches[i].lineWidth;
|
||||
context.beginPath();
|
||||
context.moveTo(
|
||||
ax * Math.pow(t, 3) + bx * Math.pow(t, 2) + cx * t + dx,
|
||||
ay * Math.pow(t, 3) + by * Math.pow(t, 2) + cy * t + dy
|
||||
);
|
||||
context.lineTo(
|
||||
ax * Math.pow(t + 0.1, 3) +
|
||||
bx * Math.pow(t + 0.1, 2) +
|
||||
cx * (t + 0.1) +
|
||||
dx,
|
||||
ay * Math.pow(t + 0.1, 3) +
|
||||
by * Math.pow(t + 0.1, 2) +
|
||||
cy * (t + 0.1) +
|
||||
dy
|
||||
);
|
||||
context.stroke();
|
||||
context.closePath();
|
||||
|
||||
// Draw leaf
|
||||
if (branches[i].leaf) {
|
||||
if (branches[i].active) {
|
||||
var x1 = ax * Math.pow(t, 3) + bx * Math.pow(t, 2) + cx * t + dx;
|
||||
var y1 = ay * Math.pow(t, 3) + by * Math.pow(t, 2) + cy * t + dy;
|
||||
var x2 =
|
||||
ax * Math.pow(t + 0.1, 3) +
|
||||
bx * Math.pow(t + 0.1, 2) +
|
||||
cx * (t + 0.1) +
|
||||
dx;
|
||||
var y2 =
|
||||
ay * Math.pow(t + 0.1, 3) +
|
||||
by * Math.pow(t + 0.1, 2) +
|
||||
cy * (t + 0.1) +
|
||||
dy;
|
||||
branches[i].leaf.x = x2;
|
||||
branches[i].leaf.y = y2;
|
||||
branches[i].leaf.angle = Math.atan2(y2 - y1, x2 - x1) - Math.PI / 2;
|
||||
branches[i].leaf.size = branches[i].lineWidth * 2;
|
||||
} else {
|
||||
branches[i].leaf.size = (branches[i].lineWidth + t) * 2;
|
||||
}
|
||||
drawLeaf(branches[i].leaf);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw leaves
|
||||
for (var i in leaves) {
|
||||
drawLeaf(leaves[i]);
|
||||
}
|
||||
|
||||
// When finished drawing splines, create a new set of branches
|
||||
t += 0.02;
|
||||
if (t >= 1) {
|
||||
var new_branches = [];
|
||||
for (var j = branches.length - 1; j >= 0; j--) {
|
||||
if (branches[j].active) {
|
||||
// Split branch into two
|
||||
for (var k = 0; k < 2; k++) {
|
||||
// Generate random deviation from previous angle
|
||||
var angle = branches[j].angle - (Math.random() * 180 - 90);
|
||||
|
||||
// Determine closest lattice point
|
||||
var distance = 100000;
|
||||
for (var l in lattice) {
|
||||
var result = distancePointToLine(
|
||||
branches[j].points[3],
|
||||
lattice[l]
|
||||
);
|
||||
if (result < distance) distance = result;
|
||||
}
|
||||
|
||||
// Generate random length
|
||||
var length = Math.random() * (maxLength - minLength) + minLength;
|
||||
|
||||
// Calculate new point
|
||||
var x2 =
|
||||
branches[j].points[3].x +
|
||||
Math.sin((Math.PI * angle) / 180) * length;
|
||||
var y2 =
|
||||
branches[j].points[3].y -
|
||||
Math.cos((Math.PI * angle) / 180) * length;
|
||||
|
||||
// Add to new branch array
|
||||
new_branches.push({
|
||||
points: [
|
||||
branches[j].points[1],
|
||||
branches[j].points[2],
|
||||
branches[j].points[3],
|
||||
{ x: x2, y: y2 },
|
||||
],
|
||||
angle: angle,
|
||||
distanceToLattice: distance,
|
||||
lineWidth: 6,
|
||||
active: true,
|
||||
leaf: {
|
||||
x: x2,
|
||||
y: y2,
|
||||
angle: 0,
|
||||
},
|
||||
parent: branches[j],
|
||||
});
|
||||
|
||||
// "Deactivate" branch
|
||||
branches[j].active = false;
|
||||
}
|
||||
|
||||
// Grow branch
|
||||
} else {
|
||||
branches[j].lineWidth++;
|
||||
if (branches[j].lineWidth > maxLineWidth) {
|
||||
leaves.push(branches[j].leaf);
|
||||
branches.splice(j, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort branches by distance to lattice
|
||||
new_branches.sort(function (a, b) {
|
||||
return a.distanceToLattice - b.distanceToLattice;
|
||||
});
|
||||
|
||||
// If over 10 branches, prune the branches furthest from the lattice
|
||||
if (prune) {
|
||||
if (sort) {
|
||||
while (new_branches.length > 20) new_branches.pop();
|
||||
} else {
|
||||
while (new_branches.length > 20) {
|
||||
new_branches.splice(
|
||||
Math.floor(Math.random() * new_branches.length),
|
||||
1
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove leaves from parent
|
||||
for (var i = 0; i < new_branches.length; i++) {
|
||||
new_branches[i].parent.leaf = false;
|
||||
}
|
||||
|
||||
// Replace old branch array with new
|
||||
branches = branches.concat(new_branches);
|
||||
interations--;
|
||||
t = 0;
|
||||
}
|
||||
|
||||
// Keep on animating
|
||||
if (interations > 0) {
|
||||
requestAnimationFrame(tick);
|
||||
}
|
||||
}
|
||||
tick();
|
||||
}
|
||||
|
||||
// Setup lattice
|
||||
var space = canvas.height / 3;
|
||||
var lattice = [];
|
||||
for (var y = -space * 4; y < space * 4; y += space) {
|
||||
lattice.push([
|
||||
{ x: 0, y: y + canvas.height },
|
||||
{ x: canvas.width, y: y },
|
||||
]);
|
||||
}
|
||||
|
||||
// Draw lattice
|
||||
context.strokeStyle = "rgba(0, 0, 0, 0.1)";
|
||||
context.lineWidth = canvas.height * 0.05;
|
||||
context.lineCap = "square";
|
||||
for (var i in lattice) {
|
||||
context.beginPath();
|
||||
context.moveTo(lattice[i][0].x, lattice[i][0].y);
|
||||
context.lineTo(lattice[i][1].x, lattice[i][1].y);
|
||||
context.stroke();
|
||||
}
|
||||
context.strokeStyle = "#ff0078";
|
||||
|
||||
// Create vines
|
||||
var minLength = canvas.width * 0.05;
|
||||
var maxLength = canvas.width * 0.1;
|
||||
var iterations = 20;
|
||||
var seeds = [
|
||||
{ x: -5, y: space },
|
||||
{ x: space, y: -5 },
|
||||
{ x: -5, y: space * 3 },
|
||||
{ x: canvas.width + 5, y: space },
|
||||
{ x: space * 3, y: canvas.height + 5 },
|
||||
];
|
||||
drawVinesWithLattice(
|
||||
lattice,
|
||||
seeds,
|
||||
iterations,
|
||||
true,
|
||||
true,
|
||||
minLength,
|
||||
maxLength
|
||||
);
|
||||
})();
|
||||
204
sandbox/simulating_vines/simulating-vines.html
Normal file
204
sandbox/simulating_vines/simulating-vines.html
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="csrf-token" content="" />
|
||||
<link rel="stylesheet" href="app.css" />
|
||||
<title>Simulating Vines</title>
|
||||
</head>
|
||||
<body>
|
||||
<div
|
||||
id="app"
|
||||
v-bind:class="{ 'search--open': searchTerm, 'index--open': showIndex }"
|
||||
>
|
||||
<header class="header header--hero">
|
||||
<div class="header__navbar"> <a class="header__logo" href="/">Maissan Inc.</a>
|
||||
<div class="header__search">
|
||||
<input v-model="searchTerm" placeholder="search" />
|
||||
</div>
|
||||
<nav class="header__nav">
|
||||
<a class="index-button" href="#index" @click.prevent="toggleIndex">
|
||||
<span class="index-button__label">Index</span>
|
||||
<i @click.stop="closeAll" class="close-button"></i>
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="hero">
|
||||
<canvas id="vines"></canvas>
|
||||
<canvas id="leaves"></canvas>
|
||||
|
||||
<h1>Simulating Vines</h1>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="search">
|
||||
<div class="search__spinner" v-if="loading">
|
||||
<div class="spinner"></div>
|
||||
</div>
|
||||
<div
|
||||
class="search__no-results"
|
||||
v-if="!loading && searchResults.length == 0"
|
||||
>
|
||||
<span>No Results</span>
|
||||
</div>
|
||||
<div v-for="result in searchResults" class="search__result">
|
||||
<h2>{{ result.title }}</h2>
|
||||
<p v-html="result.snippet"></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="index">
|
||||
<div class="index__tags">
|
||||
<h1>Tags</h1>
|
||||
<div class="index__columns">
|
||||
<h2>Bluetooth</h2>
|
||||
<ul class="index__list">
|
||||
<li class="index__list__item">
|
||||
<a href="https://maissan.net/articles/dash-and-dot"
|
||||
>Controlling Dash & Dot</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
<h2>Drupal</h2>
|
||||
<ul class="index__list">
|
||||
<li class="index__list__item">
|
||||
<a
|
||||
href="https://maissan.net/articles/deploying-drupal-updates-with-gulp"
|
||||
>Deploying Drupal Updates with Gulp</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
<h2>Graphics</h2>
|
||||
<ul class="index__list">
|
||||
<li class="index__list__item">
|
||||
<a href="https://maissan.net/articles/javascript-spirograph"
|
||||
>JavaScript Spirograph</a
|
||||
>
|
||||
</li>
|
||||
<li class="index__list__item">
|
||||
<a href="https://maissan.net/articles/simulating-vines"
|
||||
>Simulating Vines</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
<h2>JavaScript</h2>
|
||||
<ul class="index__list">
|
||||
<li class="index__list__item">
|
||||
<a href="https://maissan.net/articles/javascript-spirograph"
|
||||
>JavaScript Spirograph</a
|
||||
>
|
||||
</li>
|
||||
<li class="index__list__item">
|
||||
<a href="https://maissan.net/articles/simulating-vines"
|
||||
>Simulating Vines</a
|
||||
>
|
||||
</li>
|
||||
<li class="index__list__item">
|
||||
<a href="https://maissan.net/articles/dash-and-dot"
|
||||
>Controlling Dash & Dot</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
<h2>PHP</h2>
|
||||
<ul class="index__list">
|
||||
<li class="index__list__item">
|
||||
<a href="https://maissan.net/articles/php-profiling"
|
||||
>Application Profiling with PHP</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="index__keywords">
|
||||
<h1>Keywords</h1>
|
||||
<ul class="index__list index__columns">
|
||||
<li class="index__list__item">
|
||||
Await
|
||||
<a href="https://maissan.net/articles/dash-and-dot#await">1</a>
|
||||
</li>
|
||||
<li class="index__list__item">
|
||||
B-Splines
|
||||
<a href="https://maissan.net/articles/simulating-vines#b-splines"
|
||||
>1</a
|
||||
>
|
||||
</li>
|
||||
<li class="index__list__item">
|
||||
Bezier
|
||||
<a href="https://maissan.net/articles/simulating-vines#bezier"
|
||||
>1</a
|
||||
>
|
||||
</li>
|
||||
<li class="index__list__item">
|
||||
Binary
|
||||
<a href="https://maissan.net/articles/dash-and-dot#binary">1</a>
|
||||
</li>
|
||||
<li class="index__list__item">
|
||||
Bluetooth
|
||||
<a href="https://maissan.net/articles/dash-and-dot#bluetooth"
|
||||
>1</a
|
||||
>
|
||||
</li>
|
||||
<li class="index__list__item">
|
||||
Canvas
|
||||
<a
|
||||
href="https://maissan.net/articles/javascript-spirograph#canvas"
|
||||
>1</a
|
||||
>
|
||||
<a href="https://maissan.net/articles/simulating-vines#canvas"
|
||||
>2</a
|
||||
>
|
||||
</li>
|
||||
<li class="index__list__item">
|
||||
Curves
|
||||
<a href="https://maissan.net/articles/simulating-vines#curves"
|
||||
>1</a
|
||||
>
|
||||
</li>
|
||||
<li class="index__list__item">
|
||||
Drupal
|
||||
<a
|
||||
href="https://maissan.net/articles/deploying-drupal-updates-with-gulp#drupal"
|
||||
>1</a
|
||||
>
|
||||
</li>
|
||||
<li class="index__list__item">
|
||||
Gulp
|
||||
<a
|
||||
href="https://maissan.net/articles/deploying-drupal-updates-with-gulp#gulp"
|
||||
>1</a
|
||||
>
|
||||
</li>
|
||||
<li class="index__list__item">
|
||||
JavaScript
|
||||
<a
|
||||
href="https://maissan.net/articles/javascript-spirograph#javascript"
|
||||
>1</a
|
||||
>
|
||||
<a href="https://maissan.net/articles/simulating-vines#javascript"
|
||||
>2</a
|
||||
>
|
||||
<a href="https://maissan.net/articles/dash-and-dot#javascript"
|
||||
>3</a
|
||||
>
|
||||
</li>
|
||||
<li class="index__list__item">
|
||||
PHP
|
||||
<a href="https://maissan.net/articles/php-profiling#php">1</a>
|
||||
</li>
|
||||
<li class="index__list__item">
|
||||
Promises
|
||||
<a href="https://maissan.net/articles/dash-and-dot#promises">1</a>
|
||||
</li>
|
||||
<li class="index__list__item">
|
||||
Xdebug
|
||||
<a href="https://maissan.net/articles/php-profiling#xdebug">1</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="app.js"></script>
|
||||
<script src="app2.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
1
sandbox/simulating_vines/website_to_research.txt
Normal file
1
sandbox/simulating_vines/website_to_research.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
https://maissan.net/articles/simulating-vines
|
||||
Loading…
Add table
Add a link
Reference in a new issue