SO:<full-size-canvas>
by WebComponents
HTML
<full-size-canvas width="200"></full-size-canvas>
<script>
customElements.define("full-size-canvas", class extends HTMLElement {
static observedAttributes = ["width","height"];
attributeChangedCallback(name,oldValue,newValue){
if ( this.canvas && oldValue !== newValue ) {
this[name] = newValue;
this.updateCanvas();
}
}
get width(){
return ~~(this.getAttribute("width") || 100);
}
set width(v=this.width){
this.setAttribute("width",(this.canvas.width = v || 100));
}
get height(){
return ~~(this.getAttribute("height") || 100);
}
set height(v=this.height){
this.setAttribute("height",(this.canvas.height = v || 100));
}
connectedCallback() {
//this.width = 200, this.height = 80;
const createElement = (tag, props = {}) => Object.assign(document.createElement(tag), props);
Object.assign(this.style, {
display: "inline-block",
resize: "both",
border: "1px solid black",
overflow: "auto"
});
this.attachShadow({
mode: "open"
})
.append(
createElement("style", {
innerHTML: `canvas {vertical-align:top}`,
}),
this.canvas = createElement("canvas")
);
this.updateCanvas(this.width, this.height, "grey");
let observer = new ResizeObserver((mutations) => {
let {
width,
height
} = mutations[0].contentRect;
if ((this.canvas.width !== width || this.canvas.height !== height)) {
observer.unobserve(this); // do not observe on repaint
this.updateCanvas(width,height);
// Re-enable the observer after the current call stack is clear
// also prevents Observer undelivered notifications warning
setTimeout(() => observer.observe(this));
} // if
}); // observer
observer.observe(this);
} // connectedCallback
updateCanvas(width =...