Public
Edited
Dec 17, 2024
Insert cell
Insert cell
Insert cell
pluto = await FileAttachment("pluto.jpg").url()
Insert cell
<canvas id="canvas" width="300" height="300"></canvas>
Insert cell
<svg width="300" height="300">
<defs>
<filter id="shadow">
<feDropShadow style="flood-color: green" dx="5" dy="5" stdDeviation="3"/>
</filter>
<linearGradient id="grad" x1="0" y1="0" x2="100%" y2="0">
<stop offset="0%" stop-color="magenta"/>
<stop offset="100%" stop-color="yellow"/>
</linearGradient>
<clipPath id="circle">
<circle r="40" cx="175" cy="75"/>
</clipPath>
</defs>

<!-- rectangle -->
<rect x="50" y="50"
height="50" width="50"
fill="red"
stroke="blue"
stroke-width="10"
stroke-opacity="0.5"/>

<!-- dashed shape -->
<path id="path1"
d="M150,200 L150,150 L100,150 C100,200 150,250 200,250 L200,200 Z"
stroke-dasharray="5 2 1 2"
stroke-width="2"
stroke="blue"
fill="none"
style="filter:url(#shadow)"/>

<!-- gray quarter-circle -->
<path d="M0,0 L0,-100 A100,100 0 0,0 -100,0 L0,0 Z"
transform="translate(100,250) scale(0.5) "
stroke="red"
stroke-opacity=".5"
stroke-width="4"
fill-opacity=".2"/>

<text fill="url(#grad)"
font-size="20" x="200" y="100">Scalable
<tspan dy="20" x="200">Vector</tspan>
<tspan dy="20" x="200">Graphics</tspan></text>

<image x="125" y="25"
height="100" width="100"
href="${pluto}"
clip-path="url(#circle)"
opacity="0.75"/>

<!-- rainbow half-circle -->
<path d="M100,200 C100,100 250,100 250,200"
transform="scale(0.6) rotate(180,295,225) "
fill="url(#grad)"/>

</svg>
Insert cell
{
const ctx = canvas.getContext("2d");

// rectangle
ctx.save(); // save default context

ctx.fillStyle = "#ff0000";
ctx.strokeStyle = "blue";
ctx.lineWidth = 10;

ctx.fillRect(50,50,50,50);

ctx.globalAlpha = 0.5;
ctx.strokeRect(50,50,50,50);

// dashed shape
ctx.restore();
ctx.save();

ctx.strokeStyle = "blue";
ctx.lineWidth = 2;
ctx.shadowBlur = 6;
ctx.shadowColor = "green";
ctx.shadowOffsetX = ctx.shadowOffsetY = 5;
ctx.setLineDash([5,2,1,2]);

ctx.beginPath();
ctx.moveTo(150,200);
ctx.lineTo(150,150);
ctx.lineTo(100,150);
ctx.bezierCurveTo(100,200,150,250,200,250);
ctx.lineTo(200,200);
ctx.closePath();
ctx.stroke();

ctx.restore();
ctx.save();

// quarter-circle
ctx.translate(100,250);
ctx.scale(0.5, 0.5);
ctx.strokeStyle = "red";
ctx.lineWidth = 4;
ctx.globalAlpha = 0.5;

ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(0,-100);
ctx.arcTo(-100,-100,-100,0,100);
ctx.lineTo(0,0);
ctx.stroke();

ctx.globalAlpha = 0.2;

ctx.beginPath();
ctx.arc(0,0,100,3.14,-1.57,false);
ctx.lineTo(0,0);
ctx.closePath();
ctx.fill();

ctx.restore();
ctx.save();

// text and half-circle
const text = "Canvas"
ctx.translate(250,150);
ctx.font = "24px monospace";
const textWidth = ctx.measureText(text).width;
const gradient = ctx.createLinearGradient(-50,-50,-50 + textWidth,-50);
gradient.addColorStop(0,"magenta");
gradient.addColorStop(1, "yellow");

ctx.fillStyle = gradient;
ctx.shadowColor = "transparent";

ctx.fillText(text, -45, -5);

ctx.scale(1.1, 1.1)
ctx.rotate(3.14);

ctx.beginPath();
ctx.arc(0,0,40,3.14,0,false);
ctx.fill();

ctx.restore();
ctx.save();

// image and clip
ctx.beginPath();
ctx.arc(175,75,40,0,6.28,false);
ctx.clip();

const image = new Image(100,100);
image.src = pluto;
ctx.globalAlpha = 0.75;
ctx.drawImage(image, 125, 25, image.width, image.height);
}
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