feat: New collection and view
- Add art collection - Move views to art - Add new view
This commit is contained in:
parent
5cd55ab2bc
commit
0f92174143
4 changed files with 199 additions and 2 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
title: 10print
|
title: 10print
|
||||||
tags:
|
tags:
|
||||||
- demoExample
|
- demoArt
|
||||||
---
|
---
|
||||||
{% layout 'hippie/simple.liquid' %}
|
{% layout 'hippie/simple.liquid' %}
|
||||||
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
title: Matrix
|
title: Matrix
|
||||||
tags:
|
tags:
|
||||||
- demoExample
|
- demoArt
|
||||||
---
|
---
|
||||||
{% layout 'hippie/simple.liquid' %}
|
{% layout 'hippie/simple.liquid' %}
|
||||||
|
|
||||||
186
source/view/demo/art/squares.liquid
Normal file
186
source/view/demo/art/squares.liquid
Normal file
|
|
@ -0,0 +1,186 @@
|
||||||
|
---
|
||||||
|
title: Squares²
|
||||||
|
tags:
|
||||||
|
- demoArt
|
||||||
|
---
|
||||||
|
{% layout 'hippie/simple.liquid' %}
|
||||||
|
|
||||||
|
{% block style %}
|
||||||
|
<style>
|
||||||
|
canvas {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block body %}{% endblock %}
|
||||||
|
|
||||||
|
{% block script %}
|
||||||
|
<script>
|
||||||
|
function fillCanvasWithSquares(maxSquareSize = 128, minSquareSize = 8, largeSquarePercentage = 40) {
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
canvas.width = window.innerWidth;
|
||||||
|
canvas.height = window.innerHeight;
|
||||||
|
document.body.appendChild(canvas);
|
||||||
|
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
const colors = [
|
||||||
|
'#fad803', '#d30a51', '#273f8b',
|
||||||
|
'#b7e0f0', '#52bed1', '#0c85ff'
|
||||||
|
];
|
||||||
|
|
||||||
|
// Verify maxSquareSize and minSquareSize are powers of 2
|
||||||
|
if (!isPowerOfTwo(maxSquareSize) || !isPowerOfTwo(minSquareSize)) {
|
||||||
|
console.error('Both maxSquareSize and minSquareSize must be powers of 2');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minSquareSize > maxSquareSize) {
|
||||||
|
console.error('minSquareSize must be <= maxSquareSize');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (largeSquarePercentage < 0 || largeSquarePercentage > 100) {
|
||||||
|
console.error('largeSquarePercentage must be between 0 and 100');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPowerOfTwo(n) {
|
||||||
|
return n > 0 && (n & (n - 1)) === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grid to track occupied cells
|
||||||
|
let grid = [];
|
||||||
|
|
||||||
|
function initializeGrid() {
|
||||||
|
grid = Array(Math.ceil(canvas.height / minSquareSize))
|
||||||
|
.fill(null)
|
||||||
|
.map(() => Array(Math.ceil(canvas.width / minSquareSize)).fill(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
function canPlaceSquare(gridX, gridY, sizeInCells) {
|
||||||
|
if (gridY + sizeInCells > grid.length || gridX + sizeInCells > grid[0].length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let y = gridY; y < gridY + sizeInCells; y++) {
|
||||||
|
for (let x = gridX; x < gridX + sizeInCells; x++) {
|
||||||
|
if (grid[y][x]) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function markSquareOccupied(gridX, gridY, sizeInCells) {
|
||||||
|
for (let y = gridY; y < gridY + sizeInCells; y++) {
|
||||||
|
for (let x = gridX; x < gridX + sizeInCells; x++) {
|
||||||
|
grid[y][x] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawSquare(gridX, gridY, sizeInPixels) {
|
||||||
|
const pixelX = gridX * minSquareSize;
|
||||||
|
const pixelY = gridY * minSquareSize;
|
||||||
|
|
||||||
|
const color = colors[Math.floor(Math.random() * colors.length)];
|
||||||
|
ctx.fillStyle = color;
|
||||||
|
ctx.fillRect(pixelX, pixelY, sizeInPixels, sizeInPixels);
|
||||||
|
|
||||||
|
ctx.strokeStyle = '#333';
|
||||||
|
ctx.lineWidth = 1;
|
||||||
|
ctx.strokeRect(pixelX, pixelY, sizeInPixels, sizeInPixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSizesInDescendingOrder() {
|
||||||
|
const sizes = [];
|
||||||
|
for (let size = maxSquareSize; size >= minSquareSize; size /= 2) {
|
||||||
|
sizes.push(size);
|
||||||
|
}
|
||||||
|
return sizes;
|
||||||
|
}
|
||||||
|
|
||||||
|
function countPossibleSquares(size) {
|
||||||
|
const sizeInCells = size / minSquareSize;
|
||||||
|
let count = 0;
|
||||||
|
|
||||||
|
for (let gridY = 0; gridY < grid.length; gridY++) {
|
||||||
|
for (let gridX = 0; gridX < grid[0].length; gridX++) {
|
||||||
|
if (canPlaceSquare(gridX, gridY, sizeInCells)) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fillCanvasWithPercentage() {
|
||||||
|
const sizes = getSizesInDescendingOrder();
|
||||||
|
|
||||||
|
// Fill the largest squares based on percentage
|
||||||
|
const largestSize = sizes[0];
|
||||||
|
const maxPossibleLargeSquares = countPossibleSquares(largestSize);
|
||||||
|
const targetLargeSquares = Math.floor((maxPossibleLargeSquares * largeSquarePercentage) / 100);
|
||||||
|
const largestSizeInCells = largestSize / minSquareSize;
|
||||||
|
|
||||||
|
// Collect all valid positions for largest squares
|
||||||
|
if (targetLargeSquares > 0) {
|
||||||
|
const positions = [];
|
||||||
|
for (let gridY = 0; gridY < grid.length; gridY++) {
|
||||||
|
for (let gridX = 0; gridX < grid[0].length; gridX++) {
|
||||||
|
if (canPlaceSquare(gridX, gridY, largestSizeInCells)) {
|
||||||
|
positions.push({gridX, gridY});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shuffle positions array
|
||||||
|
positions.sort(() => Math.random() - 0.5);
|
||||||
|
|
||||||
|
// Place squares up to target percentage
|
||||||
|
let placedCount = 0;
|
||||||
|
for (let i = 0; i < positions.length && placedCount < targetLargeSquares; i++) {
|
||||||
|
const {gridX, gridY} = positions[i];
|
||||||
|
// Double-check the position is still valid before placing
|
||||||
|
if (canPlaceSquare(gridX, gridY, largestSizeInCells)) {
|
||||||
|
markSquareOccupied(gridX, gridY, largestSizeInCells);
|
||||||
|
drawSquare(gridX, gridY, largestSize);
|
||||||
|
placedCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill remaining space with all sizes in descending order
|
||||||
|
// Skip the largest size since we already handled it
|
||||||
|
for (let i = 1; i < sizes.length; i++) {
|
||||||
|
const size = sizes[i];
|
||||||
|
const sizeInCells = size / minSquareSize;
|
||||||
|
|
||||||
|
for (let gridY = 0; gridY < grid.length; gridY++) {
|
||||||
|
for (let gridX = 0; gridX < grid[0].length; gridX++) {
|
||||||
|
if (canPlaceSquare(gridX, gridY, sizeInCells)) {
|
||||||
|
markSquareOccupied(gridX, gridY, sizeInCells);
|
||||||
|
drawSquare(gridX, gridY, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initializeGrid();
|
||||||
|
fillCanvasWithPercentage();
|
||||||
|
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
canvas.width = window.innerWidth;
|
||||||
|
canvas.height = window.innerHeight;
|
||||||
|
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
initializeGrid();
|
||||||
|
fillCanvasWithPercentage();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fillCanvasWithSquares(128, 8, 40);
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -64,6 +64,17 @@ title: Index
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
|
<section>
|
||||||
|
<h3>Art</h3>
|
||||||
|
<ul class="block link">
|
||||||
|
{% assign artByTitle = collections.demoArt | sort: 'data.title' %}
|
||||||
|
{% for link in artByTitle %}
|
||||||
|
<li>
|
||||||
|
<a href="{{ link.page.url }}">{{ link.data.title }}</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue