Published
Edited
Jan 23, 2019
3 forks
Importers
22 stars
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
generateBlobs = {
return numBlobs => {
return Array.apply(null, Array(numBlobs)).map((_, i) => {
const color = randomColor()
let backgroundColor = randomColor()
while (backgroundColor === color) {
backgroundColor = randomColor()
}
return {
xPosition: (i%Math.floor(numColumns))*(canvasWidth/numColumns),
yPosition: Math.floor(i/numColumns)*canvasHeight/numRows,
size: canvasHeight/(numBlobs/numColumns)/3,
amplitude: Math.random() * 0.4,
numPoints: 4,
speed: Math.random() * 0.1,
rotationSpeed: Math.random() * 0.3,
period: Math.PI * Math.ceil(Math.random() * 20) * 2,
color,
backgroundColor
}
})
}
}
Insert cell
blob = {
return ({
xPosition=canvasWidth/2,
yPosition=canvasHeight/2,
size=10,
amplitude=0.1,
numPoints=4,
speed=0.01,
period=Math.PI*2,
rotationSpeed=0.05,
color='#ffffff',
backgroundColor='#000000',
className=''}) => {
const controlPointDist = (4/3)*Math.tan(Math.PI/(numPoints*2))
const time = frame * speed
const rotation = frame * rotationSpeed
const points = [
{
x: 1 + Math.sin(time) * amplitude,
y: 0,
controlPoints: [
{
x: 1+Math.sin(time)*amplitude-Math.sin(time+(period/12)*1)*amplitude,
y: -controlPointDist-Math.sin(time+(period/12)*1)*amplitude
},
{
x: 1+Math.sin(time)*amplitude+Math.sin(time+(period/12)*1)*amplitude,
y: controlPointDist+Math.sin(time+(period/12)*1)*amplitude
}
]
},
{
x: 0,
y: 1+Math.sin(time+(period/12)*3) * amplitude,
controlPoints: [
{
x: controlPointDist+Math.sin(time+(period/12)*2)*amplitude,
y: 1+Math.sin(time+(period/12)*2)*amplitude
},
{
x: -controlPointDist+Math.sin(time+(period/12)*3)*amplitude,
y: 1+Math.sin(time+(period/12)*3)*amplitude
}
]
},
{
x: -1+Math.sin(time+(period/12)*6) * amplitude,
y: 0,
controlPoints: [
{
x: -1+Math.sin(time+(period/12)*5)*amplitude,
y: controlPointDist+Math.sin(time+(period/12)*5)*amplitude
},
{
x: -1+Math.sin(time+(period/12)*7)*amplitude,
y: -controlPointDist+Math.sin(time+(period/12)*7)*amplitude
}
]
},
{
x: 0,
y: -1+Math.sin(time+(period/12)*9) * amplitude,
controlPoints: [
{
x: -controlPointDist+Math.sin(time+(period/12)*8)*amplitude,
y: -1+Math.sin(time+(period/12)*8)*amplitude
},
{
x: controlPointDist+Math.sin(time+(period/12)*10)*amplitude,
y: -1+Math.sin(time+(period/12)*10)*amplitude
}
]
},
]
return `
${backgroundColor && `
<rect x="${xPosition}"
y="${yPosition}"
width="${canvasWidth/numColumns}"
height="${canvasHeight/numRows}"
fill="${backgroundColor}" />
`}
<g transform="translate(${xPosition+canvasWidth/numColumns/2} ${yPosition+canvasHeight/numRows/2})
scale(${size} ${size})
rotate(${rotation})">
<path
class="${className}"
d="
M ${points[0].x} ${points[0].y}
C ${points[0].controlPoints[1].x} ${points[0].controlPoints[1].y}
${points[1].controlPoints[0].x} ${points[1].controlPoints[0].y}
${points[1].x} ${points[1].y}
S ${points[2].controlPoints[0].x} ${points[2].controlPoints[0].y}
${points[2].x} ${points[2].y}
S ${points[3].controlPoints[0].x} ${points[3].controlPoints[0].y}
${points[3].x} ${points[3].y}
S ${points[0].controlPoints[0].x} ${points[0].controlPoints[0].y}
${points[0].x} ${points[0].y}
Z"
fill="${color}"/>
${showGuides && `
${points.map((point, i) => `
<line x1="${point.x}" y1="${point.y}"
x2="${point.controlPoints[0].x}" y2="${point.controlPoints[0].y}"
stroke="#ff0000"
stroke-width="0.02" />
<circle cx="${point.controlPoints[0].x}" cy="${point.controlPoints[0].y}"
r="0.05"
fill="#ff0000" />
${i == 0 && `
<line x1="${point.x}" y1="${point.y}"
x2="${point.controlPoints[1].x}" y2="${point.controlPoints[1].y}"
stroke="#0000ff"
stroke-width="0.02" />
<circle cx="${point.controlPoints[1].x}" cy="${point.controlPoints[1].y}"
r="0.05"
fill="#0000ff" />
`
}
<circle cx="${point.x}" cy="${point.y}"
r="0.05"
fill="#ff0000" />
`)}
`
}
</g>
`
}
}
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