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

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more