<html>
<body>
<style>
body {
margin: 0;
}
div {
box-sizing: border-box;
width: calc(100% - 10px);
height: 150px;
margin: 5px;
padding: 5px;
background-image: -webkit-canvas(css-canvas);
}
</style>
<script>
let buttons = document.body.appendChild(document.createElement("div"));
let contexts = [
document.body.appendChild(document.createElement("canvas")).getContext("2d"),
window.OffscreenCanvas ? (new OffscreenCanvas(300, 150)).getContext("2d") : null,
document.body.appendChild(document.createElement("canvas")).getContext("webgl"),
window.OffscreenCanvas ? (new OffscreenCanvas(300, 150)).getContext("webgl") : null,
document.body.appendChild(document.createElement("canvas")).getContext("webgl2"),
window.OffscreenCanvas ? (new OffscreenCanvas(300, 150)).getContext("webgl2") : null,
].filter((context) => context);
let cssContext2D = null;
let cssNodes = [];
function applyToType(types, callback) {
for (let context of contexts) {
if (types.some((type) => type && context instanceof type))
callback(context);
}
}
function draw1_2D(context) {
context.save();
context.globalAlpha = 1;
context.globalAlpha;
context.save();
context.fillStyle = "red";
context.fillStyle;
context.fillRect(0, 0, 40, 40);
context.fillRect(0, 0, 40, 40);
context.save();
context.lineWidth = 0.5;
context.lineWidth;
context.save();
context.globalAlpha = 0.5;
context.globalAlpha;
context.save();
context.fillStyle = "blue";
context.fillStyle;
context.fillRect(20, 20, 40, 40);
context.fillRect(20, 20, 40, 40);
context.save();
context.fillStyle = undefined;
context.fillStyle;
context.restore();
context.restore();
context.restore();
context.restore();
context.restore();
}
function draw1_WebGL(context) {
context.clearColor(1, 0, 0, 1);
context.clear(context.COLOR_BUFFER_BIT);
context.clear(context.COLOR_BUFFER_BIT);
}
function draw2_2D(context) {
context.globalAlpha = 1;
context.globalAlpha;
context.fillStyle = "green";
context.fillStyle;
context.fillRect(60, 0, 40, 40);
context.fillRect(60, 0, 40, 40);
context.lineWidth = 0.5;
context.lineWidth;
context.globalAlpha = 0.5;
context.globalAlpha;
context.fillStyle = "red";
context.fillStyle;
context.fillRect(80, 20, 40, 40);
context.fillRect(80, 20, 40, 40);
context.fillStyle = undefined;
context.fillStyle;
}
function draw2_WebGL(context) {
context.clearColor(0, 0, 1, 0.5);
context.clear(context.COLOR_BUFFER_BIT);
context.clear(context.COLOR_BUFFER_BIT);
}
function draw3_2D(context) {
let gradient = context.createLinearGradient(0, 60, 40, 100);
let pattern = context.createPattern(document.querySelector("img"), "repeat");
let imageData = context.getImageData(0, 0, 300, 150);
context.setAlpha(1);
context.fillStyle = pattern;
context.fillStyle;
context.fillRect(0, 60, 40, 40);
context.setLineWidth = 0.5;
context.setLineWidth;
context.setAlpha(0.5);
context.scale(1.5, 0.5);
context.drawImage(document.querySelector("img"), 0, 0);
context.drawImage(document.querySelector("img"), 0, 0);
context.fillStyle = gradient;
context.fillStyle;
context.fill(new Path2D("M20 80L60 80L60 120L20 120Z"));
context.fill(new Path2D("M20 80L60 80L60 120L20 120Z"));
context.setFillColor(undefined);
context.clearShadow();
context.putImageData(imageData, 0, 0);
context.putImageData(imageData, 0, 0);
context.drawFocusIfNeeded(document.body);
}
function draw4_2D(context) {
context.beginPath();
context.moveTo(20, 20);
context.moveTo(NaN, NaN);
context.lineTo(200, 20);
context.moveTo(120, 120);
context.closePath();
context.lineTo(250, 75);
context.lineTo(250, -75);
context.stroke();
context.stroke();
context.fill(new Path2D("M20 80L60 80L60 120L20 120Z"));
context.fill(new Path2D("M20 80L60 80L60 120L20 120Z"));
}
function draw5_2D(context) {
context.beginPath();
context.moveTo(10, 10);
context.stroke();
context.lineTo(20, 20);
context.stroke();
context.fillStyle = "red";
context.fill();
context.fill();
}
function draw6_2D(context) {
for (let color of ["green", "blue", "red"]) {
context.save();
context.fillStyle = color;
}
}
function draw7_2D(context) {
for (let color of ["green", "blue", "red"])
context.restore();
}
let clear = buttons.appendChild(document.createElement("button"));
clear.textContent = "Clear";
clear.addEventListener("click", (event) => {
for (let context of contexts) {
if (context && context.canvas)
context.canvas.remove();
}
for (let cssNode of cssNodes)
cssNode.remove();
contexts = [];
cssContext2D = null;;
cssNodes = [];
});
let create = buttons.appendChild(document.createElement("button"));
create.textContent = "Create";
create.addEventListener("click", (event) => {
contexts.push(document.body.appendChild(document.createElement("canvas")).getContext("2d"));
});
let cssAdd = buttons.appendChild(document.createElement("button"));
cssAdd.textContent = "CSS Add";
cssAdd.addEventListener("click", (event) => {
if (!cssContext2D && document.getCSSCanvasContext)
cssContext2D = document.getCSSCanvasContext("2d", "css-canvas", 300, 150);
cssNodes.push(document.body.insertBefore(document.createElement("div"), buttons.nextElementSibling));
});
let button1 = buttons.appendChild(document.createElement("button"));
button1.textContent = "1";
button1.addEventListener("click", (event) => {
applyToType([ window.CanvasRenderingContext2D, window.OffscreenCanvasRenderingContext2D ], draw1_2D);
applyToType([ window.WebGLRenderingContext ], draw1_WebGL);
});
let button2 = buttons.appendChild(document.createElement("button"));
button2.textContent = "2";
button2.addEventListener("click", (event) => {
applyToType([ window.CanvasRenderingContext2D, window.OffscreenCanvasRenderingContext2D ], draw2_2D);
applyToType([ window.WebGLRenderingContext ], draw2_WebGL);
});
let button3 = buttons.appendChild(document.createElement("button"));
button3.textContent = "3";
button3.addEventListener("click", (event) => {
applyToType([ window.CanvasRenderingContext2D, window.OffscreenCanvasRenderingContext2D ], draw3_2D);
});
let button4 = buttons.appendChild(document.createElement("button"));
button4.textContent = "4";
button4.addEventListener("click", (event) => {
applyToType([ window.CanvasRenderingContext2D, window.OffscreenCanvasRenderingContext2D ], draw4_2D);
});
let button5 = buttons.appendChild(document.createElement("button"));
button5.textContent = "5";
button5.addEventListener("click", (event) => {
applyToType([ window.CanvasRenderingContext2D, window.OffscreenCanvasRenderingContext2D ], draw5_2D);
});
let button6 = buttons.appendChild(document.createElement("button"));
button6.textContent = "6";
button6.addEventListener("click", (event) => {
applyToType([ window.CanvasRenderingContext2D, window.OffscreenCanvasRenderingContext2D ], draw6_2D);
});
let button7 = buttons.appendChild(document.createElement("button"));
button7.textContent = "7";
button7.addEventListener("click", (event) => {
applyToType([ window.CanvasRenderingContext2D, window.OffscreenCanvasRenderingContext2D ], draw7_2D);
});
let button8 = buttons.appendChild(document.createElement("button"));
button8.textContent = "8";
button8.addEventListener("click", (event) => {
applyToType([ window.CanvasRenderingContext2D, window.OffscreenCanvasRenderingContext2D ], (context) => {
context.canvas.width = context.canvas.width / 2;
context.canvas.height = context.canvas.height / 2;
});
applyToType([ window.WebGLRenderingContext ], (context) => {
context.canvas.width = context.canvas.width / 2;
context.canvas.height = context.canvas.height / 2;
});
});
let button9 = buttons.appendChild(document.createElement("button"));
button9.textContent = "9";
button9.addEventListener("click", (event) => {
applyToType([ window.CanvasRenderingContext2D, window.OffscreenCanvasRenderingContext2D ], (context) => {
context.canvas.width = context.canvas.width * 2;
context.canvas.height = context.canvas.height * 2;
});
applyToType([ window.WebGLRenderingContext ], (context) => {
context.canvas.width = context.canvas.width * 2;
context.canvas.height = context.canvas.height * 2;
});
});
</script>
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAAAAXNSR0IArs4c6QAABBhJREFUeAHt1kFqQlEURMFncN+68yhkAw4+mD6UZKy3qx9NzvEhQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQL/SeD26TG/57z/9j/vwB9n3k8rAYGWwE8rjjQECJQFDFa5XdkIxAQMVqxQcQiUBQxWuV3ZCMQEDFasUHEIlAUMVrld2QjEBAxWrFBxCJQFDFa5XdkIxAQMVqxQcQiUBQxWuV3ZCMQEDFasUHEIlAUMVrld2QjEBAxWrFBxCJQFDFa5XdkIxAQMVqxQcQiUBQxWuV3ZCMQEDFasUHEIlAUMVrld2QjEBAxWrFBxCJQF7t8K9zzPL/304+Ifvl38fV9i8bMEBgT8hzVQkhMJEPgTMFheAgECMwIGa6YqhxIgYLC8AQIEZgQM1kxVDiVAwGB5AwQIzAgYrJmqHEqAgMHyBggQmBEwWDNVOZQAAYPlDRAgMCNgsGaqcigBAgbLGyBAYEbAYM1U5VACBAyWN0CAwIyAwZqpyqEECBgsb4AAgRkBgzVTlUMJEDBY3gABAjMCBmumKocSIGCwvAECBGYEDNZMVQ4lQMBgeQMECMwIGKyZqhxKgIDB8gYIEJgRMFgzVTmUAAGD5Q0QIDAjYLBmqnIoAQIGyxsgQGBGwGDNVOVQAgTunxLcznn/Xfl5PK/8Nt9FgEBfwH9Y/Y4lJJARMFiZKgUh0BcwWP2OJSSQETBYmSoFIdAXMFj9jiUkkBEwWJkqBSHQFzBY/Y4lJJARMFiZKgUh0BcwWP2OJSSQETBYmSoFIdAXMFj9jiUkkBEwWJkqBSHQFzBY/Y4lJJARMFiZKgUh0BcwWP2OJSSQETBYmSoFIdAXMFj9jiUkkBEwWJkqBSHQFzBY/Y4lJECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgMCLwAWFMGEbwWcYQAAAAASUVORK5CYII=">