Published
Edited
Dec 29, 2020
1 fork
9 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// thi.ng enumerates a matrix in column-major order
shiftL = m.mat33to44([],[0,0,1,1,0,0,0,1,0]);
Insert cell
Insert cell
function rotateDegrees(deg,dir,origin) {
const or = origin || [0,0,0];
const trans = m.translation44([],or);
return m.concat([],trans,m.rotationAroundAxis44([],dir,Math.PI * deg/180),m.invert44([],trans));
}
Insert cell
Insert cell
function prepost(a,x,e) {
if (e==0)
return a;
if (e==1)
return m.concat([],m.invert44([],x),a,x);
const xxx = m.concat([],...range(e).map(()=>x));
return m.concat([],m.invert44([],xxx),a,xxx);
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
squareToFace0 = m.concat([],m.translation44([],[thickness,-1,-1-thickness]),m.scale44([],[1,thickness,1]))
Insert cell
Insert cell
function rotation(faceNr) {
if (faceNr==0)
return m.IDENT44;
const mv = [-thickness,0,thickness,0][faceNr%4];
const origin = [mv,-mv,0];
const shiftAndTranslate = m.concat([],m.translation44([],[0,0,-2]),shiftL);
return prepost(rotateDegrees(90,zdir,origin),shiftAndTranslate,faceNr-1);
}
Insert cell
Insert cell
function faceTransformation3D(i) {
return m.concat([],...range(i+1).map(rotation).reverse(),squareToFace0);
}
Insert cell
Insert cell
function faceTransformation2D(i) {
const divToSquare = m.scale44([],[2/divWidth,2/divHeight,1]);
const view = m.lookAt([],[1,1,1],[0,0,0],[0,1,-1]) // look at the origin along the x=y=z line
const project = m.ortho([],0,3,-1,2,-1,1);
const toScreen = m.mat23to44([],m.viewport([],0,300,300,0));
return m.concat([],toScreen,project,view,faceTransformation3D(i),divToSquare);
}
Insert cell
Insert cell
Insert cell
function htmlFace(nr) {
const innerDiv = [
html`<div>you don't see with your eye</div>`,
html`<div>you perceive with your mind</div>`
][nr%2];
const innerStyle = {
fontFamily: 'Bebas Neue',
whiteSpace: 'nowrap',
animation: '12s infinite linear scroll',
animationDelay: `${12-nr}s`,
transform: 'translate(100%,0%)'
}
const outerDiv = html`<div>${withStyle(innerStyle)(innerDiv)}</div>`;
const clippct = (1-thickness)*100;
const outerStyle = {
position: 'absolute',
height: `${divHeight}px`,
width: `${divWidth}px`,
overflow: 'hidden',
clipPath: (nr%4==3) ? `polygon(0% 0%, 0% 100%, 100% 100%, ${clippct}% 0%)` : undefined,
backgroundColor: (nr%4>1) ? ['#ff33cc99','#ffff6699','#33993399'][(Math.floor(nr/2))%3] : '#99999933',
color: (nr%4>1) ?'#000000':'#00000055',
transformOrigin: 'center',
transform: `matrix3d(${faceTransformation2D(nr).join(',')})`
}
return withStyle(outerStyle)(outerDiv);
}
Insert cell
// import font and define "scroll" animation
html`<style>
@import url('https://fonts.googleapis.com/css2?family=Bebas+Neue&display=swap');
@keyframes scroll {
from { transform: translate(100%,0%) }
33% { transform: translate(-250%,0%) }
to { transform: translate(-250%,0%) }
}
</style>`
Insert cell
Insert cell
withStyle({height:'300px'})(html`<div>${range(12).map(htmlFace)}</div>`)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more