triangle

 

I am a latter day bugman ε½“δ»£ηš„θ™«δΊΊ, digital artist, and parapsychology &philosophy aficionado. This webbed site is a tomb of sorts; my digital mausoleum.

β–Ό Art

Play my latest game: trial Trial 20XX

li { position: relative; padding-inline-start: calc(1em * 5 / 4); } & > li:before { content: "✧"; font-family: sans-serif; position: absolute; top: 0; left: 0; color: var(--c-sepia2); } } .home { --bottom-height: calc(1em * 3 * var(--line-height)); position: relative; z-index: 1; pointer-events: none; container-name: layout; container-type: inline-size; max-width: var(--layout-width); margin-inline: auto; display: grid; grid-template-columns: 1fr 6fr 3fr; grid-template-rows: calc(100vh - var(--bottom-height)) var(--bottom-height); column-gap: calc(1em * 3 * var(--line-height)); padding-inline: calc(1em * 2 * var(--line-height)); p { margin-block-end: calc(1em * 1 * var(--line-height)); } .logo { width: auto; height: calc(1em * 2 * var(--line-height)); display: block; transition: opacity 0.2s ease; position: sticky; top: calc(1em * 3 / 2 * var(--line-height)); z-index: 2; &:hover { &:first-of-type { opacity: 0; } & + * { opacity: 1 !important; } } &:not(:first-of-type) { margin-block-start: calc(1em * -2 * var(--line-height)); opacity: 0; pointer-events: none; } } h2 { --scalar: calc(5 / 6); --border: calc((1em / 6) / var(--scalar)); /*--border: 1px;*/ /*--border: 0;*/ font-size: calc(1em * var(--scalar)); line-height: calc(var(--line-height) / var(--scalar)); margin-block-end: calc((1em / var(--scalar)) * var(--line-height)) !important; padding-block-start: calc((1em / var(--scalar)) * var(--line-height) - var(--border)); border-block-start: var(--border) var(--c-sepia2) solid; display: flex; align-items: center; &:not(:first-of-type) { margin-block-start: calc((1em * 3 / 2 / var(--scalar)) * var(--line-height)); /*--border: 0;*/ } svg { height: calc((1em / var(--scalar)) * var(--line-height)); width: auto; display: block; } } span { color: var(--c-sepia2); } .pages { ul.menu { columns: 2; column-gap: calc(1em * 1 * var(--line-height)); margin-block: calc(-1em / 4 * var(--line-height)); & > * { padding-inline: 0; padding-block: calc(1em / 4 * var(--line-height)); font-weight: 700; &:before { content: " "; position: absolute; top: 0; left: 0; width: 100%; border-block-end: 1px var(--c-sepia3) dotted; } } } } .wrapper { position: relative; padding-block: calc(1em * 1 * var(--line-height)) 0; &:before { content: " "; position: absolute; left: calc(1em * -3 / 2 * var(--line-height)); top: 0; width: 0; height: 100%; border-inline-start: 1px var(--c-sepia3) dotted; } } .gutter, .intro { .wrapper:before { display: none; } } .intro, .pages { h2 { border-block-start-color: transparent; } } /*.gutter, .intro, .pages { .wrapper { padding-block: calc(1em * var(--line-height) / 2) 0; } }*/ .gutter { .wrapper { height: 100%; display: flex; flex-direction: column; align-items: flex-start; } } .journal { & > * { white-space: nowrap; display: inline; padding-inline-start: 0; span { color: inherit; } &:before { position: static; content: " ⁄"; margin-inline: 0.25em 0.5em; color: var(--c-sepia2); } &:first-of-type { &:before { content: "✯"; position: static; margin-inline: 0 0.25em; } } &:not(:first-of-type) { a:before { content: "'"; } span { display: none; } } } } .journal-update { margin-block-start: calc(1em / 2 * var(--line-height)); color: var(--c-sepia2); a { font-weight: 700; text-decoration-color: var(--c-sepia3); } } .controls { display: flex; flex-direction: column; margin-block: calc(1em * 2 * var(--line-height)) calc(1em * 3 / 2 * var(--line-height)); position: sticky; bottom: calc(1em * 2 * var(--line-height)); gap: calc(1em * 1 / 4 * var(--line-height)); } .documents { margin-block: calc(1em * 0 * var(--line-height)) calc(1em * 1 * var(--line-height)); li { white-space: nowrap; counter-increment: opus-no; display: inline; padding-inline-start: 0; &:before { font-size: calc(1em * 3 / 4); margin-inline-end: 0.2em; content: "#"counter(opus-no)" "; position: static; } &:not(:last-child):after { content: ","; margin-inline-end: 0.2em; color: var(--c-sepia2); } } } & > * > * > * { pointer-events: auto; } & > * { position: relative; z-index: 1; &.gutter { grid-column: 1 / span 1; grid-row: 1 / 6; } &.intro { grid-row: 1 / span 1; grid-column: 2 / span 1; } &.pages { grid-row: 1 / span 1; grid-column: 3 / span 1; } &.hint { grid-column: 2 / span 2; grid-row: 2; } &.spacer { grid-column: 1 / 4; grid-row: 3; } &.art { grid-column: 2 / span 2; grid-row: 4; } &.articles { grid-column: 2 / span 1; grid-row: 5; } &.floater { grid-column: 3 / span 1; grid-row: 5; } & > * { margin-block-end: calc(1em * var(--line-height)); } } .spacer { position: relative; z-index: 0; opacity: 0.4; & > * { position: absolute; bottom: calc(1em * var(--line-height)); left: 0; width: 100%; height: auto; color: var(--c-bg); margin-block-end: 0; } } .hint > * { pointer-events: auto; color: inherit; } .floater { .wrapper { position: sticky; top: 0; &:before { display: none; } } } .toggle { --c-border: var(--c-sepia2); --c-fill: var(--c-sepia3); --w: 2em; --h: 0.8em; display: inline-block; position: relative; padding-inline-start: calc(var(--w) + 0.5em); color: var(--c-sepia2); margin-inline-end: calc(1em * 2 / 3 * var(--line-height)); input { display: none; } &:before { position: absolute; content: " "; display: block; top: 50%; transform: translateY(-50%); left: 0; width: var(--w); height: var(--h); border: 1px var(--c-border) solid; border-radius: 1em; } &:after { --spacing: 3px; --w2: 0.66; position: absolute; content: " "; display: block; top: 50%; transform: translateY(-50%); left: var(--spacing); width: calc(var(--w) * var(--w2) - var(--spacing) * 2); height: calc(var(--h) - var(--spacing) * 2); border: 1px var(--c-border) solid; border-radius: 1em; background: var(--c-fill); transition: left 0.15s ease; } &:has(input:checked) { color: var(--c-sepia); &:after { left: calc(var(--w) * (1 - var(--w2)) + var(--spacing)); } } } .color { --c-border: var(--c-sepia2); --c-fill: var(--c-sepia3); --w: 1.2em; --h: 0.8em; display: inline-block; position: relative; padding-inline-start: calc(var(--w) + 0.5em); color: var(--c-sepia2); input { opacity: 0; position: absolute; left: 0; top: 0; height: 100%; width: 100%; z-index: 1; } .reset { position: relative; z-index: 2; cursor: pointer; color: var(--c-sepia3); } &:before { position: absolute; content: " "; display: block; top: 50%; transform: translateY(-50%); left: 0; width: var(--w); height: var(--h); border: 1px var(--c-border) solid; border-radius: 1em; } &:after { --spacing: 3px; position: absolute; content: " "; display: block; top: 50%; transform: translateY(-50%); left: var(--spacing); width: calc(var(--w) - var(--spacing) * 2); height: calc(var(--h) - var(--spacing) * 2); border: 1px var(--c-sepia2) solid; border-radius: 1em; background: var(--c-accent);/*background: linear-gradient(to bottom, var(--c-accent), transparent)*/; } } .art { margin-block-end: calc(1em * var(--line-height) * 2); } .articles { padding-block: 0 !important; .wrapper { &:before { display: none; } } ul { display: flex; flex-direction: column-reverse; & > li { --scalar: calc(7 / 3); padding-inline-start: 0; position: relative; font-size: calc(1em * var(--scalar)); /*font-family: var(--font-alt);*/ padding-block: calc(1em * var(--line-height) / var(--scalar) * 1 / 3); &:before { content: " "; position: absolute; top: 100%; left: 0; width: 100%; height: 1px; background: linear-gradient(to right, color-mix(in oklch, var(--c-sepia4) 80%, transparent), transparent); } &:first-of-type:before { display: none; } a { text-decoration: none; } } } } footer { border-block-start: calc(1em / 6) var(--c-sepia4) solid; color: var(--c-sepia2); display: flex; align-items: flex-end; gap: calc(1em * 1 * var(--line-height)); margin-block-start: calc(1em * 3 * var(--line-height)); padding-block: calc(1em * 2 * var(--line-height)); grid-column: 2 / span 2; grid-row: 6; & > * { margin-block-end: 0; } a:has(img) { border: calc(1em / 6) var(--c-accent) solid; } img { display: block; width: auto; height: calc(1em * 3 * var(--line-height)); } ul { li { padding-inline-start: 0; display: inline; &:before { display: none; } &:not(:last-of-type):after { content: " ⁄"; margin-inline: 0.25em; color: var(--c-sepia2); } } } p { margin-block-end: 0; } } } .visual-container { --b: calc(1em * var(--line-height)); /*background: color-mix(in lch, var(--c-bg), var(--c-sepia) 8%);*/ background: hsla(60, 20%, 83%, 0.04); position: fixed; top: var(--b); left: var(--b); width: calc(100% - var(--b) * 2); height: calc(100% - var(--b) * 2); user-select: none; border-radius: calc(1em * var(--line-height) * 1 / 2); overflow: hidden; & > * { position: absolute; top: 0; left: 0; } & > img { display: block; left: 50%; top: 50%; transform: translateX(-50%) translateY(-50%); width: 10em; height: 10em; } &:has(canvas) > img { display: none; } } @media (max-width: 1200px) { .home { column-gap: calc(1em * 2 * var(--line-height)); padding-inline: calc(1em * 3 / 2 * var(--line-height)); .wrapper:before { left: calc(1em * -1 * var(--line-height)); } } } @media (max-width: 960px) { .visual-container { --b: calc(1em * var(--line-height) / 2); } .home { display: flex; flex-direction: column; pointer-events: auto; & > div:first-of-type { h2 { margin-block-start: 0; } } & > * { order: 444; } .logo { position: static; } .intro, .gutter, .pages { order: 0; } .gutter { .wrapper { align-items: center; } } .wrapper { padding-block: 0; &:before { display: none; } } .floater { display: block; margin-block: calc(1em / var(--scalar) * 1 * var(--line-height)); } .documents { margin-block: calc(1em * 1 * var(--line-height)); } .hint { margin-block: calc(1em * 1 * var(--line-height)) 0; } .hint, .art { order: 1; } .art { margin-block-end: 0; } .spacer { order: 666; & > * { bottom: calc(1em * var(--line-height) * 1 / 2); } } h2 { margin-block-start: calc(1em * 1 * var(--line-height)); } .articles ul > li { --scalar: 1.6666; padding-block: calc(1em * var(--line-height) / var(--scalar) * 1 / 4); } .controls { flex-direction: row; margin-block: calc(1em * 1 * var(--line-height)) 0; } } tml> import { Box3, Float32BufferAttribute, InstancedBufferGeometry, InstancedInterleavedBuffer, InterleavedBufferAttribute, Sphere, Vector3, WireframeGeometry } from 'three'; const _box = new Box3(); const _vector = new Vector3(); class LineSegmentsGeometry extends InstancedBufferGeometry { constructor() { super(); this.isLineSegmentsGeometry = true; this.type = 'LineSegmentsGeometry'; const positions = [ - 1, 2, 0, 1, 2, 0, - 1, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 0, - 1, - 1, 0, 1, - 1, 0 ]; const uvs = [ - 1, 2, 1, 2, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 2, 1, - 2 ]; const index = [ 0, 2, 1, 2, 3, 1, 2, 4, 3, 4, 5, 3, 4, 6, 5, 6, 7, 5 ]; this.setIndex( index ); this.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); } applyMatrix4( matrix ) { const start = this.attributes.instanceStart; const end = this.attributes.instanceEnd; if ( start !== undefined ) { start.applyMatrix4( matrix ); end.applyMatrix4( matrix ); start.needsUpdate = true; } if ( this.boundingBox !== null ) { this.computeBoundingBox(); } if ( this.boundingSphere !== null ) { this.computeBoundingSphere(); } return this; } setPositions( array ) { let lineSegments; if ( array instanceof Float32Array ) { lineSegments = array; } else if ( Array.isArray( array ) ) { lineSegments = new Float32Array( array ); } const instanceBuffer = new InstancedInterleavedBuffer( lineSegments, 6, 1 ); // xyz, xyz this.setAttribute( 'instanceStart', new InterleavedBufferAttribute( instanceBuffer, 3, 0 ) ); // xyz this.setAttribute( 'instanceEnd', new InterleavedBufferAttribute( instanceBuffer, 3, 3 ) ); // xyz this.instanceCount = this.attributes.instanceStart.count; // this.computeBoundingBox(); this.computeBoundingSphere(); return this; } setColors( array ) { let colors; if ( array instanceof Float32Array ) { colors = array; } else if ( Array.isArray( array ) ) { colors = new Float32Array( array ); } const instanceColorBuffer = new InstancedInterleavedBuffer( colors, 6, 1 ); // rgb, rgb this.setAttribute( 'instanceColorStart', new InterleavedBufferAttribute( instanceColorBuffer, 3, 0 ) ); // rgb this.setAttribute( 'instanceColorEnd', new InterleavedBufferAttribute( instanceColorBuffer, 3, 3 ) ); // rgb return this; } fromWireframeGeometry( geometry ) { this.setPositions( geometry.attributes.position.array ); return this; } fromEdgesGeometry( geometry ) { this.setPositions( geometry.attributes.position.array ); return this; } fromMesh( mesh ) { this.fromWireframeGeometry( new WireframeGeometry( mesh.geometry ) ); // set colors, maybe return this; } fromLineSegments( lineSegments ) { const geometry = lineSegments.geometry; this.setPositions( geometry.attributes.position.array ); // assumes non-indexed // set colors, maybe return this; } computeBoundingBox() { if ( this.boundingBox === null ) { this.boundingBox = new Box3(); } const start = this.attributes.instanceStart; const end = this.attributes.instanceEnd; if ( start !== undefined && end !== undefined ) { this.boundingBox.setFromBufferAttribute( start ); _box.setFromBufferAttribute( end ); this.boundingBox.union( _box ); } } computeBoundingSphere() { if ( this.boundingSphere === null ) { this.boundingSphere = new Sphere(); } if ( this.boundingBox === null ) { this.computeBoundingBox(); } const start = this.attributes.instanceStart; const end = this.attributes.instanceEnd; if ( start !== undefined && end !== undefined ) { const center = this.boundingSphere.center; this.boundingBox.getCenter( center ); let maxRadiusSq = 0; for ( let i = 0, il = start.count; i < il; i ++ ) { _vector.fromBufferAttribute( start, i ); maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) ); _vector.fromBufferAttribute( end, i ); maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) ); } this.boundingSphere.radius = Math.sqrt( maxRadiusSq ); if ( isNaN( this.boundingSphere.radius ) ) { console.error( 'THREE.LineSegmentsGeometry.computeBoundingSphere(): Computed radius is NaN. The instanced position data is likely to have NaN values.', this ); } } } toJSON() { // todo } applyMatrix( matrix ) { console.warn( 'THREE.LineSegmentsGeometry: applyMatrix() has been renamed to applyMatrix4().' ); return this.applyMatrix4( matrix ); } } export { LineSegmentsGeometry };