about
Hideable PhotoSizer
04/24/2024
Hide-able PhotoSizer Element
Implements W3C/Google webcomponent
This is how this page uses the Hideable PhotoSizer Element:
<hidephotosizer-block src="Pictures/ThreadPool.JPG" width="200" class="photoSizerBlock left">
<span style="font-family:'Comic Sans MS';">Figure 1. ThreadPool</span>
</photosizer-block>
And this is how this pages styles the PhotoSizer Element:
#github hidephotosizer-block {
--border:1px solid black;
--box-shadow: 3px 3px 5px #999;
--wrapperPadding: 5px 10px 10px 10px;
--margin: 20px;
--captionPadding: 0px 0px 5px 0px;
}
/* uncomment .photoBlock to use this class */
/*#github .photoSizerBlock {
--background-color: #efe;
--font-family:Comic Sans MS;
--font-weight: Bold;
--border: 3px solid darkgreen;
--captionPadding: 0px 0px 5px 0px;
--wrapperPadding: 5px;
--margin: 30px;
}*/
View page source for all the details.
<script>
/* custom webcomponent - PhotoSizerBlock*/
class PhotoSizerBlock extends HTMLElement {
constructor(...args) {
const self = super(...args);
const shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.innerHTML =
`
<style>
#cont {
display:flex;
padding: var(--padding);
}
#wrapper {
width:min-content;
padding: var(--wrapperPadding); //10px;
margin: var(--margin); //20px;
background-color: var(--background-color);
color: var(--color);
box-shadow: var(--box-shadow);
font-family: var(--font-family);
font-size: var(--font-size);
font-weight: var(--font-weight);
border: var(--border);
cursor: pointer;
user-select:none;
-webkit-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
}
#closer {
text-align:center;
font-family:'Comic Sans MS', Sans-serif;
}
#caption {
text-align:center;
padding-bottom:10px;
padding: var(--captionPadding); //0px 0px 10px 0px;
background-color:white;
}
img {
user-select:none;
-webkit-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
}
</style>
<div id="cont">
<slot></slot>
<div id="wrapper">
<div id="caption"></div>
<img />
<div id="closer">click to close</div>
</div>
</div>
`;
this.bigger = this.bigger.bind(this);
this.smaller = this.smaller.bind(this);
this.toggle = this.toggle.bind(this);
return self;
}
connectedCallback() {
this.url = this.getAttribute('src');
this.imgElem = this.shadowRoot.querySelector('img');
this.imgElem.setAttribute('src', this.url);
this.width = this.getAttribute('width');
if (isDefined(this.width))
this.imgElem.setAttribute('width', this.width);
this.height = this.getAttribute('height');
if (isDefined(this.height))
this.imgElem.setAttribute(this.height);
this.caption = this.shadowRoot.querySelector('#caption');
if (isDefined(this.caption)) {
this.captionText = this.innerHTML;
this.innerHTML = "";
this.caption.innerHTML = this.captionText;
}
this.imgElem.addEventListener('click', this.bigger);
this.caption.addEventListener('click', this.smaller);
this.closer = this.shadowRoot.querySelector('#closer');
this.closer.addEventListener('click', this.toggle);
}
bigger() {
this.imgElem.width = Number(this.imgElem.width) * 1.25;
}
smaller() {
this.imgElem.width = Number(this.imgElem.width) / 1.25;
}
toggle() {
let wrpr = this.shadowRoot.getElementById("wrapper");
if (isDefined(wrpr)) {
if (wrpr.style.display === "none") {
wrpr.style.display = "block";
this.closer.style.right = "8px";
}
else {
wrpr.style.display = "none";
this.closer.style.right = "7px";
}
}
}
}
/* register with DOM - don't need to use script block to execute */
/*---------------------------------------------------------------------------
* This listener is added because of a component lifecycle issue with chrome
* See first reference, below.
*/
document.addEventListener('DOMContentLoaded', function () {
window.customElements.define('photosizer-block', PhotoSizerBlock);
});
/*
* The listener, above, will be removed and replaced with this when chrome
* component lifecycle is fixed.
*
* window.customElements.define('photosizer-block', PhotoSizerBlock);
*/
</script>
References:
- Issue with Chrome loading innerHTML
- polyfills CDN
- customelements - google.com
- shadowdom - google.com
- webcomponents - htm5rocks.com
- attributes & properties - alligator.io
- styling webcomponent - css-tricks.com
- encapsulating style and structure - css-tricks.com
- creating custom component from scratch - css-tricks.com
- Using custom elements - mozilla.org
- introduction to webcomponents - webcomponents.org
- build web components - dev.to
- tutorial - robinwieruch.de
- introduction - grapecity.com