moves js into the asset pipeline
This commit is contained in:
30
assets/js/colorCalculator.js
Normal file
30
assets/js/colorCalculator.js
Normal file
@ -0,0 +1,30 @@
|
||||
class ColorCalculator {
|
||||
constructor() {
|
||||
// Available color families from our palette
|
||||
this.colorFamilies = ['sand', 'pink', 'red', 'rust', 'clay', 'gold', 'moss', 'pine', 'cyan', 'blue'];
|
||||
// Available shades for each color
|
||||
this.shades = ['100', '500', '900'];
|
||||
}
|
||||
|
||||
// Get color based on sigil digit and influences
|
||||
getColor(sigilDigit, influences = []) {
|
||||
// Map digit 0-9 to color family
|
||||
const colorFamily = this.colorFamilies[sigilDigit];
|
||||
|
||||
// Calculate shade based on influences
|
||||
const shade = this.calculateShade(influences);
|
||||
|
||||
return `${colorFamily}-${shade}`;
|
||||
}
|
||||
|
||||
// Calculate shade based on surrounding influences
|
||||
calculateShade(influences) {
|
||||
if (!influences.length) return '500';
|
||||
|
||||
// Average the influences and map to one of our three shades
|
||||
const avg = influences.reduce((sum, val) => sum + val, 0) / influences.length;
|
||||
if (avg < 3) return '100';
|
||||
if (avg > 6) return '900';
|
||||
return '500';
|
||||
}
|
||||
}
|
44
assets/js/sigil.js
Normal file
44
assets/js/sigil.js
Normal file
@ -0,0 +1,44 @@
|
||||
class Sigil {
|
||||
// Convert string to sigil array
|
||||
static generate(str) {
|
||||
if (!str) return [];
|
||||
|
||||
// Convert to lowercase, remove non-word characters
|
||||
const cleaned = str.toLowerCase().replace(/[^a-z]/g, '');
|
||||
|
||||
// Remove vowels
|
||||
const noVowels = cleaned.replace(/[aeiou]/g, '');
|
||||
|
||||
// Remove duplicate characters
|
||||
const deduped = [...new Set(noVowels)].join('');
|
||||
|
||||
// Convert to ASCII values and get digital roots
|
||||
return [...deduped].map(char => {
|
||||
const ascii = char.charCodeAt(0);
|
||||
return Sigil.getDigitalRoot(ascii);
|
||||
});
|
||||
}
|
||||
|
||||
// Get digital root of a number (sum digits until single digit)
|
||||
static getDigitalRoot(num) {
|
||||
if (num < 10) return num;
|
||||
return Sigil.getDigitalRoot([...num.toString()].reduce((sum, digit) => sum + parseInt(digit), 0));
|
||||
}
|
||||
|
||||
// Helper to validate and debug sigil generation
|
||||
static debug(str) {
|
||||
console.log({
|
||||
original: str,
|
||||
lowercase: str.toLowerCase(),
|
||||
cleaned: str.toLowerCase().replace(/[^a-z]/g, ''),
|
||||
noVowels: str.toLowerCase().replace(/[^a-z]/g, '').replace(/[aeiou]/g, ''),
|
||||
deduped: [...new Set(str.toLowerCase().replace(/[^a-z]/g, '').replace(/[aeiou]/g, ''))].join(''),
|
||||
sigil: Sigil.generate(str)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Export for use in other files
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = Sigil;
|
||||
}
|
270
assets/js/wompum.js
Normal file
270
assets/js/wompum.js
Normal file
@ -0,0 +1,270 @@
|
||||
class WompumGrid {
|
||||
constructor(element) {
|
||||
this.gridElement = element;
|
||||
this.gridSize = {
|
||||
columns: parseInt(element.dataset.columns) || 7,
|
||||
rows: parseInt(element.dataset.rows) || 5
|
||||
};
|
||||
|
||||
// Set grid template columns and rows
|
||||
this.gridElement.style.gridTemplateColumns = `repeat(${this.gridSize.columns}, 1fr)`;
|
||||
this.gridElement.style.gridTemplateRows = `repeat(${this.gridSize.rows}, 1fr)`;
|
||||
|
||||
// Initialize color calculator
|
||||
this.colorCalculator = new ColorCalculator();
|
||||
|
||||
// Generate sigil from text content if provided
|
||||
const text = element.dataset.text || '';
|
||||
this.sigil = Sigil.generate(text);
|
||||
this.gridElement.dataset.sigil = JSON.stringify(this.sigil);
|
||||
}
|
||||
|
||||
// Get sigil digit for a cell based on its position
|
||||
getSigilDigit(position) {
|
||||
if (!this.sigil || !this.sigil.length) return 0;
|
||||
return this.sigil[position % this.sigil.length];
|
||||
}
|
||||
|
||||
// Get influences from adjacent cells
|
||||
getInfluences(column, row) {
|
||||
const influences = [];
|
||||
|
||||
// Check adjacent cells (up, down, left, right)
|
||||
const adjacentPositions = [
|
||||
[column, row - 1], // up
|
||||
[column, row + 1], // down
|
||||
[column - 1, row], // left
|
||||
[column + 1, row] // right
|
||||
];
|
||||
|
||||
for (const [adjCol, adjRow] of adjacentPositions) {
|
||||
if (adjCol >= 0 && adjCol < this.gridSize.columns &&
|
||||
adjRow >= 0 && adjRow < this.gridSize.rows) {
|
||||
const cell = this.gridElement.querySelector(
|
||||
`[data-column="${adjCol}"][data-row="${adjRow}"]`
|
||||
);
|
||||
if (cell && cell.dataset.sigilDigit) {
|
||||
influences.push(parseInt(cell.dataset.sigilDigit));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return influences;
|
||||
}
|
||||
|
||||
// Create basic grid cells
|
||||
createGrid() {
|
||||
const totalCells = this.gridSize.columns * this.gridSize.rows;
|
||||
|
||||
for (let i = 0; i < totalCells; i++) {
|
||||
const cell = document.createElement('div');
|
||||
const column = i % this.gridSize.columns;
|
||||
const row = Math.floor(i / this.gridSize.columns);
|
||||
|
||||
cell.className = 'wompum-cell';
|
||||
cell.setAttribute('data-cell-index', i);
|
||||
cell.setAttribute('data-column', column);
|
||||
cell.setAttribute('data-row', row);
|
||||
|
||||
// Set sigil digit based on cell position
|
||||
const sigilDigit = this.getSigilDigit(i);
|
||||
cell.setAttribute('data-sigil-digit', sigilDigit);
|
||||
|
||||
this.gridElement.appendChild(cell);
|
||||
}
|
||||
}
|
||||
|
||||
applyMetadataDesign() {
|
||||
const cells = this.gridElement.querySelectorAll('.wompum-cell');
|
||||
|
||||
cells.forEach(cell => {
|
||||
const column = parseInt(cell.dataset.column);
|
||||
const row = parseInt(cell.dataset.row);
|
||||
const sigilDigit = parseInt(cell.dataset.sigilDigit);
|
||||
|
||||
// Get influences from adjacent cells
|
||||
const influences = this.getInfluences(column, row);
|
||||
|
||||
// Calculate and apply color
|
||||
const color = this.colorCalculator.getColor(sigilDigit, influences);
|
||||
cell.classList.add(`bg-${color}`);
|
||||
});
|
||||
}
|
||||
|
||||
init() {
|
||||
if (!this.gridElement) return;
|
||||
this.createGrid();
|
||||
this.applyMetadataDesign();
|
||||
}
|
||||
}
|
||||
|
||||
class ArticleGrid extends WompumGrid {
|
||||
constructor(element, metadata) {
|
||||
super(element);
|
||||
this.metadata = metadata;
|
||||
|
||||
// Generate sigils for each metadata component
|
||||
this.sigils = {
|
||||
narrator: Sigil.generate(metadata.narrator),
|
||||
subject: Sigil.generate(metadata.subject),
|
||||
facilitator: Sigil.generate(metadata.facilitator)
|
||||
};
|
||||
|
||||
// Store sigils as data attributes
|
||||
Object.entries(this.sigils).forEach(([key, value]) => {
|
||||
this.gridElement.dataset[`${key}Sigil`] = JSON.stringify(value);
|
||||
});
|
||||
}
|
||||
|
||||
getSigilDigit(position, section) {
|
||||
const sigil = this.sigils[section];
|
||||
if (!sigil || !sigil.length) return 0;
|
||||
return sigil[position % sigil.length];
|
||||
}
|
||||
|
||||
createGrid() {
|
||||
const totalCells = this.gridSize.columns * this.gridSize.rows;
|
||||
const narratorColumns = 2;
|
||||
const facilitatorColumns = 2;
|
||||
|
||||
for (let i = 0; i < totalCells; i++) {
|
||||
const cell = document.createElement('div');
|
||||
const column = i % this.gridSize.columns;
|
||||
const row = Math.floor(i / this.gridSize.columns);
|
||||
|
||||
// Determine section based on column position
|
||||
let section;
|
||||
if (column < narratorColumns) section = 'narrator';
|
||||
else if (column >= this.gridSize.columns - facilitatorColumns) section = 'facilitator';
|
||||
else section = 'subject';
|
||||
|
||||
// Use BEM modifiers for sections
|
||||
cell.className = `wompum-cell wompum-cell--${section}`;
|
||||
cell.setAttribute('data-cell-index', i);
|
||||
cell.setAttribute('data-section', section);
|
||||
cell.setAttribute('data-column', column);
|
||||
cell.setAttribute('data-row', row);
|
||||
|
||||
// Set sigil digit based on section and position
|
||||
const sigilDigit = this.getSigilDigit(row, section);
|
||||
cell.setAttribute('data-sigil-digit', sigilDigit);
|
||||
|
||||
this.gridElement.appendChild(cell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RadialWompumGrid {
|
||||
constructor(element, size = 10) {
|
||||
this.element = element; // Remove .parentElement
|
||||
this.segments = size;
|
||||
this.colorCalculator = new ColorCalculator();
|
||||
this.sigil = Sigil.generate(this.element.dataset.text || '');
|
||||
}
|
||||
|
||||
createSegment(index) {
|
||||
const angle = (360 / this.segments);
|
||||
// Add a small gap by reducing the arc angle
|
||||
const gap = 2; // degrees of gap
|
||||
const startAngle = (index * angle) + (gap / 2);
|
||||
const endAngle = ((index + 1) * angle) - (gap / 2);
|
||||
const outerRadius = 50;
|
||||
const innerRadius = 0;
|
||||
|
||||
const start = this.polarToCartesian(startAngle, outerRadius);
|
||||
const end = this.polarToCartesian(endAngle, outerRadius);
|
||||
const innerStart = this.polarToCartesian(startAngle, innerRadius);
|
||||
const innerEnd = this.polarToCartesian(endAngle, innerRadius);
|
||||
|
||||
const largeArcFlag = (angle - gap) > 180 ? 1 : 0;
|
||||
|
||||
const d = [
|
||||
`M ${start.x} ${start.y}`,
|
||||
`A ${outerRadius} ${outerRadius} 0 ${largeArcFlag} 1 ${end.x} ${end.y}`,
|
||||
`L ${innerEnd.x} ${innerEnd.y}`,
|
||||
`A ${innerRadius} ${innerRadius} 0 ${largeArcFlag} 0 ${innerStart.x} ${innerStart.y}`,
|
||||
'Z'
|
||||
].join(' ');
|
||||
|
||||
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
||||
path.setAttribute('d', d);
|
||||
|
||||
const sigilDigit = this.getSigilDigit(index);
|
||||
// Pass empty array for influences since we don't need adjacent segments
|
||||
const color = this.colorCalculator.getColor(sigilDigit, []);
|
||||
path.setAttribute('fill', `var(--color-${color})`);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
polarToCartesian(angle, radius) {
|
||||
const radian = (angle - 90) * Math.PI / 180.0;
|
||||
return {
|
||||
x: 50 + (radius * Math.cos(radian)),
|
||||
y: 50 + (radius * Math.sin(radian))
|
||||
};
|
||||
}
|
||||
|
||||
getSigilDigit(position) {
|
||||
if (!this.sigil || !this.sigil.length) return 0;
|
||||
return this.sigil[position % this.sigil.length];
|
||||
}
|
||||
|
||||
getInfluences(index) {
|
||||
const prev = (index - 1 + this.segments) % this.segments;
|
||||
const next = (index + 1) % this.segments;
|
||||
return [
|
||||
this.getSigilDigit(prev),
|
||||
this.getSigilDigit(next)
|
||||
];
|
||||
}
|
||||
|
||||
createSVG() {
|
||||
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||
svg.setAttribute('viewBox', '0 0 100 100');
|
||||
svg.setAttribute('class', 'wompum-radial-grid');
|
||||
|
||||
for (let i = 0; i < this.segments; i++) {
|
||||
svg.appendChild(this.createSegment(i));
|
||||
}
|
||||
|
||||
return svg;
|
||||
}
|
||||
|
||||
init() {
|
||||
if (!this.sigil || !this.sigil.length) {
|
||||
console.error('No sigil generated from text:', this.element.getAttribute('data-text'));
|
||||
return;
|
||||
}
|
||||
const svg = this.createSVG();
|
||||
this.element.insertBefore(svg, this.element.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize grids
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// Initialize basic grids
|
||||
document.querySelectorAll('.wompum-grid').forEach(element => {
|
||||
const grid = new WompumGrid(element);
|
||||
grid.init();
|
||||
});
|
||||
|
||||
// Initialize article grids
|
||||
document.querySelectorAll('.wompum-article-grid').forEach(element => {
|
||||
let metadata = {};
|
||||
try {
|
||||
metadata = JSON.parse(element.dataset.metadata || '{}');
|
||||
} catch (e) {
|
||||
console.error('Error parsing metadata for article grid:', e);
|
||||
}
|
||||
|
||||
const grid = new ArticleGrid(element, metadata);
|
||||
grid.init();
|
||||
});
|
||||
|
||||
// Initialize radial grids for profile images
|
||||
document.querySelectorAll('.narrator__container').forEach(element => {
|
||||
const grid = new RadialWompumGrid(element);
|
||||
grid.init();
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user