Custom element, Shadow DOM で作るジッパー

Shadow DOM

Shadow DOM

Custom element, Shadow DOM で作るジッパー

SVG埋め込みで持ち運ぶファイルはJavaScript1個のみ。カプセル化で記述すっきり。

JavaScriptコードは2種類用意しました。
SVGをcreateElementで構築する方式と、
SVGをテンプレートリテラルで記述する方式です。

機能をカプセル化していますのでHTML内に意識して書くのは以下の2行のみ。

<ce-zipper></ce-zipper>

<script defer src="./js/ce_zipper.js"></script>

現時点のコードは以下の通り:
/**
 * ジッパー
 *
 * <ce-zipper></ce-zipper>
 *
 * @author ao-system, Inc.
 * @date 2024-06-15
 */
(() => {
	'use strict';
	class Zipper {
		#svgHandleLeft = `
			<path d="M86.56,6.8l-14.03-.4c-5.57-3-9.09-4.22-12.24-4.92-5.53-1.23-6.77-.96-8.76.62-4.12,3.26-6.33,10.8-6.32,13.54v.76c0,2.74,2.19,10.65,6.32,13.54,2.08,1.45,3.24,1.85,8.76.62,3.15-.7,6.67-1.92,12.24-4.62l14.03-.4V6.8Z"/>
			<path d="M59.54,6.01L3.6,2.83S.44,4.9.44,16.26s3.15,12.91,3.15,12.91l55.65-2.61h0l5.29.57V5.5s-4.99.51-4.99.51ZM15.68,16.13v6.98l-9.78,1.65s-2.59-.61-2.29-8.63c-.3-8.02,2.29-8.63,2.29-8.63l9.78,1.65v6.98ZM61.59,23.22h-16.38v-13.97h16.38s0,13.97,0,13.97Z"/>
			<rect x="48.3" y="11.36" width="25.63" height="9.27"/>
		`;
		#svgHandleRight = `
			<path d="M41.96,6.8l-14.03-.4c-5.57-3-9.09-4.22-12.24-4.92-5.53-1.23-6.77-.96-8.76.62C2.81,5.36.6,12.9.61,15.64v.76c0,2.74,2.19,10.65,6.32,13.54,2.08,1.45,3.24,1.85,8.76.62,3.15-.7,6.67-1.92,12.24-4.62l14.03-.4V6.8Z"/>
			<path d="M13.3,5.5v21.63s5.29-.57,5.29-.57h0l55.65,2.61s3.15-1.55,3.15-12.91-3.16-13.43-3.16-13.43l-55.94,3.18s-4.99-.51-4.99-.51ZM62.15,9.15l9.78-1.65s2.59.61,2.29,8.63c.3,8.02-2.29,8.63-2.29,8.63l-9.78-1.65v-6.98s0-6.98,0-6.98ZM16.24,9.25h16.38v13.97h-16.38s0-13.97,0-13.97Z"/>
			<rect x="3.7" y="11.36" width="25.63" height="9.27"/>
		`;
		#svgButtLeft = `
			<rect x="12" y="1" width="7" height="8"/>
			<rect x="12" y="12" width="7" height="8"/>
		`;
		#svgButtRight = `
			<rect x="8" y="0" width="10" height="20"/>
			<rect x="0" y="10" width="7" height="6"/>
			<rect x="0" y="3" width="7" height="6"/>
		`;
		#gradation1 = `
			<linearGradient id="gradation1" x1="0" y1="0" x2="0" y2="100%" gradientUnits="userSpaceOnUse">
				<stop offset="0" stop-color="#cb0"/>
				<stop offset="0.2" stop-color="#dd7"/>
				<stop offset="0.4" stop-color="#dd4"/>
				<stop offset="0.5" stop-color="#cb2"/>
				<stop offset="0.6" stop-color="#db3"/>
				<stop offset="0.8" stop-color="#dc5"/>
				<stop offset="0.9" stop-color="#cb5"/>
				<stop offset="1" stop-color="#ddb"/>
			</linearGradient>
		`;
		#nicolascage = 'data:image/png;base64,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';
		#style = `
			:host > main {
				user-select: none;
				padding: 20px;
				background-color: #0f3083;
				max-height: 32px;
				display: grid;
				> svg {
					grid-area: 1/1/2/2;
					display: block;
					cursor: pointer;
					width: 460px;
					height: 32px;
					viewBox: '0 0 460 32';
					path,rect {
						stroke: #ff7;
						stroke-width: 0.5px;
						fill: url(#gradation1);
					}
					rect.inner {
						stroke: none;
						fill: #36a;
						width: 300px;
						height: 6px;
						transform: translate(80px,13px);
					}
					rect.toothA {
						y: 8px;
						width: 3px;
						height: 10px;
					}
					rect.toothB {
						y: 14px;
						width: 3px;
						height: 10px;
					}
					g.stopperLeft {
						transform: translate(61px,6px);
					}
					g.stopperRight {
						transform: translate(381px,7px);
					}
				}
				> img {
					grid-area: 1/1/2/2;
					display: block;
					transform: translate(120px,-184px);
					clip-path: xywh(0 200px 200px 0px);
				}
			}
		`;
		#sliderLeft;
		#sliderRight;
		#teeth = [];
		#img;
		#openFlag = false;
		#busy = false;
		constructor() {
		}
		render(elm) {
			//style
			const style = document.createElement('style');
			style.innerHTML = this.#style;
			//main
			const main = document.createElement('main');
			const svg = document.createElementNS('http://www.w3.org/2000/svg','svg');
			svg.innerHTML = this.#gradation1;
			svg.addEventListener('click',() => {this.#toggle();});
			const inner = document.createElementNS('http://www.w3.org/2000/svg','rect');
			inner.setAttribute('class','inner');
			svg.appendChild(inner);
			for (let i = 0; i < 50; i++) {
				const tooth1 = document.createElementNS('http://www.w3.org/2000/svg','rect');
				tooth1.setAttribute('class','toothA');
				tooth1.setAttribute('x',i * 6 + 80);
				const tooth2 = document.createElementNS('http://www.w3.org/2000/svg','rect');
				tooth2.setAttribute('class','toothB');
				tooth2.setAttribute('x',i * 6 + 3 + 80);
				this.#teeth.push({'tooth1':tooth1,'tooth2':tooth2});
				svg.appendChild(tooth1);
				svg.appendChild(tooth2);
			}
			const stopperLeft = document.createElementNS('http://www.w3.org/2000/svg','g');
			stopperLeft.innerHTML = this.#svgButtLeft;
			stopperLeft.setAttribute('class','stopperLeft');
			svg.appendChild(stopperLeft);
			const stopperRight = document.createElementNS('http://www.w3.org/2000/svg','g');
			stopperRight.innerHTML = this.#svgButtRight;
			stopperRight.setAttribute('class','stopperRight');
			svg.appendChild(stopperRight);
			this.#sliderLeft = document.createElementNS('http://www.w3.org/2000/svg','g');
			this.#sliderLeft.innerHTML = this.#svgHandleLeft;
			svg.appendChild(this.#sliderLeft);
			this.#sliderRight = document.createElementNS('http://www.w3.org/2000/svg','g');
			this.#sliderRight.style.opacity = 0;
			this.#sliderRight.innerHTML = this.#svgHandleRight;
			svg.appendChild(this.#sliderRight);
			main.appendChild(svg);
			this.#img = document.createElement('img');
			this.#img.src = this.#nicolascage;
			main.appendChild(this.#img);
			//attachShadow
			const shadowRoot = elm.attachShadow({mode:'closed'});
			shadowRoot.appendChild(style);
			shadowRoot.appendChild(main);
		}
		#toggle() {
			if (this.#busy) {
				return;
			}
			this.#busy = true;
			if (this.#openFlag == false) {
				for (let i = 0; i < this.#teeth.length; i++) {
					this.#teeth[i].tooth1.animate([
						{transform: 'translateY(0px)'},
						{transform: 'translateY(-4px)'},
					],{delay: i * 20, duration: 200, fill: 'forwards'});
					this.#teeth[i].tooth2.animate([
						{transform: 'translateY(0px)'},
						{transform: 'translateY(4px)'},
					],{delay: i * 20, duration: 200, fill: 'forwards'});
				}
				this.#sliderLeft.animate([
					{opacity: 1},
					{opacity: 0},
				],{delay: 0, duration: 0, fill: 'forwards'});
				this.#sliderRight.animate([
					{opacity: 0},
					{opacity: 1},
				],{delay: 0, duration: 0, fill: 'forwards'});
				this.#sliderRight.animate([
					{transform: 'translate(50px,0px)'},
					{transform: 'translate(375px,0px)'},
				],{delay: 0, duration: 1100, fill: 'forwards'}).onfinish = () => {
					this.#img.animate([
						{transform: 'translate(120px,-184px)',clipPath: 'xywh(0 200px 200px 0px)'},
						{transform: 'translate(120px,16px)',clipPath: 'xywh(0 0 200px 200px)'},
					],{delay: 0, duration: 1000, fill: 'forwards'}).onfinish = () => {
						this.#openFlag = true;
						this.#busy = false;
					}
				}
			} else {
				this.#img.animate([
					{transform: 'translate(120px,16px)',clipPath: 'xywh(0 0 200px 200px)'},
					{transform: 'translate(120px,-184px)',clipPath: 'xywh(0 200px 200px 0px)'},
				],{delay: 0, duration: 1000, fill: 'forwards'}).onfinish = () => {
					for (let i = 0; i < this.#teeth.length; i++) {
						this.#teeth[i].tooth1.animate([
							{transform: 'translateY(-4px)'},
							{transform: 'translateY(0px)'},
						],{delay: (49 - i) * 20, duration: 200, fill: 'forwards'});
						this.#teeth[i].tooth2.animate([
							{transform: 'translateY(4px)'},
							{transform: 'translateY(0px)'},
						],{delay: (49 - i) * 20, duration: 200, fill: 'forwards'});
					}
					this.#sliderRight.animate([
						{opacity: 1},
						{opacity: 0},
					],{delay: 0, duration: 0, fill: 'forwards'});
					this.#sliderLeft.animate([
						{opacity: 0},
						{opacity: 1},
					],{delay: 0, duration: 0, fill: 'forwards'});
					this.#sliderLeft.animate([
						{transform: 'translate(335px,0px)'},
						{transform: 'translate(0px,0px)'},
					],{delay: 0, duration: 1100, fill: 'forwards'}).onfinish = () => {
						this.#openFlag = false;
						this.#busy = false;
					}
				}
			}
		}
	}
	(() => {
		const zipper = new Zipper();
		customElements.define('ce-zipper1',
			class extends HTMLElement {
				constructor() {
					super();
					zipper.render(this);
				}
			}
		);
	})();
})();
現時点のコードは以下の通り:
/**
 * ジッパー
 * テンプレートリテラルで組み立てた例
 *
 * <ce-zipper></ce-zipper>
 *
 * @author ao-system, Inc.
 * @date 2024-06-15
 */
(() => {
	'use strict';
	class Zipper {
		#nicolascage = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAMAAACahl6sAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAMBQTFRFIhUQrndm5beryZWG27Gmuoh3lGZVc1ZLxot4uJKI+/r6Ri8lp25b05qJaEY318/Ni1pKlnNm6sCz3Kud1aOTx4uEuIFszaOWy5uSu66u6+bo152TroV226SUmIyN1qud4trY1aCO1aWZqn9swnh23aWbzJ+NgU09vJB9lnx91aqVmIJ43KuWn1tWuaGd8e3u37Kh4K6h0o6Gyb691JGT5uHjp5yd6eLcfTs0sWRjzoqPVD849fL0f3h3hoOC////y4A5DgAALj9JREFUeNrsXQtb2li0NYYkBEIgJS8kyCMQIgKiKKMG5f//q7vWPgGxrTP1MZ3e+91I0VrbZrH2Y+199jmc7P6PXCf/D+SnV622veJ1N2g2O50Nr+dzPJ2fnz89PVlPz5vOurled5b4dLat7XZb/OBgcHd1ta3V/iggwHB212yuce9P50/W81NRr5/gsb/q9aKwCl5Pz8AyWHc6607z7u7s7OpPAlLbbq8GzcGd4Di6/R8v/Fndej7nBSjrdROkfIqTk6/FURtcDc4Gnc25dbjfv0NjWRZ422zWsC+w8hkkJ19rVzWYPLzCOvnFq34CQ3PPOxdPG1jY2Scc5eQr+TiDTT0XRf3kXZcFYgqEgqflYPBxKCdfycfg/Om9KF5CQOE+IZQN7v5rIOCj+WydfOKqF+cMzoOr/xJIrXZ2trbqJ5+6YGKAMmh+KBCffBGOu+amOPkkEFyFtUF+3P5XQJA+kDZOvuKqu+ewru32vwFyB7M6+arLQiS+29b+EyDbztM/J4y///2xeT09dc62u9pvB1I7a57/DYC6PMln9buT8lsSdl8JsUP4Ailn70TyeSC1u7tO8WZ+2P+SW1af5RsHWn4KpSjOO2fvM6+Tz+O4ekuR4AaLw83X94D2t75HUT59Z2yF1Wn+XiDb5vr5TX1b4KPOtL2HUD7Lr9LU6qXtfUdL/WnzLk4+DeRsfV7/OR1CSMFHUVJS7J/5Ld59UX9lbPVXvmVtrra/DUht29k8vSWf+MAduwqKeuy/Wxxc52Bd3xkXfmj9jhLlc0BqteZm8yYhJR9uoTgofytfWuI8QhV5eYkKR56PP+7c/TKSTwK5Ou/U3yBEvf7A4db3QASGfPlibi+sKGt8CdJM85277e8AAkLeELz18qbrruvKFy6IcQ92Jcx85/uH8PUqeP2ydZ18Csd2XfwchmuRiHviwHVPXqxCnMWVR7F39yMM9fpLvjz8S5vmL8qVk8/gqA02P9UY7tRqtabTqTtVQNziHkBICWHUXcXIgZDXzv46qyCd/Jp1nXwCx1XzJ1qxXritlrlomabZIhqAaQHGAVKBytatv3KSlxSp8NSP1dgzkNT+TSC1q8F6/fS9CqwXU0IwTQcXkJjmVH1YU4KZWmTGtXD3blG85Bb524WCUD8Sabw2neZZ7d8DUru6O+s8ffefko09Cg0f/NQypw6/NwU/MDjXbVklOffKeY5YOcStV7LeWg9+oWb8IJDa2eBufVEc1IVYxAsKR9O0MMSTlmpOS0uFndLaaG/A4+496EBJ/S2BXzR/IcV/DMj2rjlYnxcHu4aFuIXVKlEAhgMchpHgKdFSA2hMzQRFqYDhx1SiAQOC6x5kysl3VnWQXYN/Ccj2qtnsPCndUfqsax3YIB3jkECqhpEHea4bgIIrd1IzdTTgcFoHcnDdu99x8kMVdv7P/v4RILW75rpjHWe0uvtiVI7QMQaMIA90PW7ojWqQAJYREE+aaibpMR2xNMXM/f1eOR4c5rWfrP8xmZx8yD8659axxNjDEAfXxloIJFXguNEb2bDRaOi6nuvVIAsNLUnT0IH3hPhJYFm0SiwKSr3+82K4OP/HvvDJB+JVswkcLypcrKokQ7ERVoGjGuggYzjMht1uYwgwDT8PDCNM8GHggz8LE1vwEigHpfWzHNs5+2ogyB+dzXHh55otTzBovDWtRAEYuBoAMhx2Mzz5+FKoqeY5zKxaHfPn5VrwAf+/f+3yrxBZnX8Iwe8GcnXWWT4dagkkarKhlUA0QSFA9BvB0ej6w67v93qTXq83zBpdYAmqwGEgPDNAhyUamJnY11vV//k/JJP3Atk2O53zonRL6AzGU60kJGSsUjhugAOGRSRDv+f7k95k3uv5+LpBn6kG+DFAUZemWHGc1tR9heT466f11d86/Ml7DavT6VhlJ0d5+T5xaLwnxUb15qZBJHD0YW/iT0a9+bwHID2/25BLv6mWrCgke1ZaB0/58Xr+e0reCeRq3UECUYUsigzLOxhWCO8YKxw0KuKgh3SHsKmZP2/PJ/P5ZIbf49LxpzdAooBoyu+Vu7Tct4D8Q7n4PiC1ZrmqJkAOODRFR1jSUYVR0dN5z71hr9duw7B40by6Eo+rN40b/mwokVjc/kGwmOTk5KdgYFxfBaS25ZJzvSxkCxV2FQyVO8aIVnBzZT8NefknbXWNwEmbSIa0OHJCHFWlyEJhRJAspj/tc6kia/tVjAyOPcRiehajEiBMH8o7aFJiVWCjN2pfX1+vVtfAct0GDAUEMBolkFDFO8cZO+IrrfsXFVn/Lr//jVJ5HyPN5UZC1oujqxAaljCIo9EQPxgiUsHHJ8SxvyY9+ROxPP4sTWus0o/S/C+hq0wpr3PJ5m/K3ncB2a47qj16yOdlKtg7iOAgHfPRvOdP5grFanW6WpGUOZNJaXdV8RFlXKW3l8HLPOT473pd9b8LXCfvEovrjVXmwsI1PWVXYlbiHvDgqhDSRZRqg4v2NQGc4rpe4dG+niAz9iQE34CPm4Nt4Z9QfISkpHW/b6p+11exBm/PR7wHyHbQ3OwdRIoop0RR8qGX/oEYReemV1xXrgXH6SlYuV4howy7JRT9ploGrjJUOMfZ5OTQxz8CUly8XWKdvCdmDdSCDgmxlNx9CbsIuoABeThhvCUQoKicVoikAigVmFfletSj66gYfFOVwCV6IBS70vZA9gXKUS9C/cedu7coeQ+Q2kDNlzBiKUKO88cN5QjukzwIG20CEcM6FVoqsK3rEaEgdInHV6t7SqoH44JYQVa8f9Vgqb8sNjTPtl/AyN0+9P6EEEmACLbt0bUAoXMAiCCQT6SFUbjnj0AJIpt+cPhSppT+vigpqe+7KkecFJu3KHkXkGZRJkNLhSyHIAxxjyqBQB0KDkQoeLcio8RwKl6CC1EAYnjYY4kiSMYlEocfQsrCnLqlpC9OXoevOvx9UPsskDNpkBLI1CyTyEGXVBs3VIhM5HBq4CjZ+Hb6clXgMBVa3WSk3ESyu4pceyyOVI6qjD8scymXl1exeHrDTU7e4SJ30iBly8FqtZxXQG5EmMBgevP2ilC+p0O5ClxegDChCJKXZCJASndHwSiUHK1n7ftOhXW+PvskkKvmeWlZTIYAIvJKVVFVEbuNBiTJvD1T6uoFwLdv8mAMQ+SiB/VYZknkUsmk9JNQlf0LOsmRm1Cj7pl5utg0rz4LxCqTyLSMWa9iLwhpdCFKrpnO23AI3PV1SYcAITcVppO2SvE9ASKElIxoYlywrb2T1A/L2/vVbdjW+d3PKHkPkMHeRVot0YtHwv2GLoKUDstqU4wAQUW8G35REU5U5FoxneDPJ5P5UExLBNcLKQrIgo27+n39FSdlbiwsd/2zEPwOZ982S3niWvAQMJIePF1vSF2LbAh5tRJ9BRi86TKFiNeX/i/6q+0zlygvCY8cnumEjYjpffGymPXKV+Alg59ox3cwsl2rf0w61fssUj1oXuk0KF+X6FvGrG/H3s6wpXTwXAQ9c+JN6e2lWCGSBTupByd5tSpX57DKzwah3hO1Oq+AEIcRGmXIKqEQCPPI6np1FHfpIt++qa8kOLd7ZYG1d5MXTxFKkNqL+5dpiVetcuSSzwHZnnWUnaq1g2MXOdSEDR9BSxTvMY5ju6KxAclkMhS9BUpeCZWyp9IiI/X7IzaKo2W5YvMTEfzrQK7uXoC0DumQDrJvxOHOGLWu5WZfIzmtiIUpmbKSUnGoCGmUpnUkVoAE+vcQtlQ38IAEn59+kkreAaTZKV+fqfIRphHjBYcvlS27V/PRaIR8saooYiplel9dnzIOnDKR8GcFRZnd93mxKmnRMadT99UAy8uqnKJk/XEgte3VpmT6xUfIiK6XVQgk1KyHNFI6iGQSxGGoq/7k+vpU+b2KafNur7FnZO8lL7ELlEwPlJRWUJTOXijp+GMD9T1Rq6OM1J2WTbnQ2OPIGiDEn83m81L3ltdq/1SRquqU0RiEzPeJXeKvXq1WXzxeCqyWcpJ6vXg1U7BfQ7Eufuxpv0c0dpSsBhCJvqV8Jx8ZLAs4ehQn1z+4upgW7Oz0eiISf9IT9TtkEpUwUX25SkZKsVUOF72swSteqBw/AWQnHa0TBi3HU4QYkgsznUDgHrM5cRDGqsyBB/FbUdYm9Qibdr3Sso5chAFMOUnYMlvu0SxR/fXcHbx92fwEkKtnBYS+LusgytWzoS/LBj69vC2pUGmT0sJWJRx+n6kSfDRUDrlh+rlhZ6jaqJZxuHQSUyRKUSI5qb/ua9etH3t17wByp1YTCldqqjTlImGu6/CObAbDmuOpR0L29400fi2B62Bo9PT5XLp0w7JvqpOJKvt1gkR1VWha0yMX+aHr+HSx/gSQtaUUA1zEc1ItlWVBuEfmD2dwkD5K8vn8df5AQYhKanUQi8BxTSCQl2V3Cw9dwEjPrqo69GDEBRB3P5nzQ/P0U0BqGzXRVzBoaZ4WJoaR63GW+ZEPIO1+n3XsIWS9RK5KX9T8HgibKKWHUNhwRagqEYNAcrUqJ1X7vVozLn4kpG49rT/sI7XBUyEynlnE87Q0JQ5EXj+Cf8SgZIaKqv8KxF5hrfqj/krl+9K0lD6pqpTI9UV55CDEMJSP3O+nB382qQ7d+HEgMsNPXzclaEHD53mu5xmuWAekOJuN2qsyc1QO6rcsqvBor2RtAbbVGO4FCikRNmhZoCQ3wEmaQsgXbvEySPD94KZ10fx+reQdQGQJpi6LbY4nHmKkBrDgSpKc/GSjffNkJTGr8tJ9EGrYRBFGhvSRl9SuyxJ2VecyKaFomtm6P4zd1H+yreF88HEfKRlhOkw9x0jyMHESIEiSNEk9j49cj/qz2d5NvpWEKBsTCX+qwtaBkCMkst5b5YJvHpIRd0/JyU+B3H0CiLQZ6SIeCUkczzMteItnUQxz8cpL7My240igVEogpYgXd/lGUqBQ5vM9kKFaL2VSbei5URVKwlRDHineJIRR6xNABs98cVxXubrZ4riSZbmW27J44dlLkzxNkywSz+bNA0TliBI8MXS15zNJJUNFDX5lUGvwEBgqLsTf1JwWqkKs/3SEwDr/uNaqQfxK11cIcSyVsDimBDgWIbmWeQmW0jTPZv1+RSkUaZ4ADR/fVEMCmng2EyXQUws/ACM4xK6MPAEOZvY3CSGQTzBSW0tvyYKne8BRWjBHLQlGLnBiCZRstpIMv+bNq+v021oaW+wJVaAvfRYwswOSBmMvDSvnyg9cpATyxvjA8yecnROl+MeJIxW7ctUatYz28rfkxGMv1fOMDIysxaZw6/1KfwmKVoJDcmMfKdT3KdA4q0J1IOlw7yNwkaMuyk93Y30ij9SaTOwFvNvxrKllTQGm2A9ykBh6imdeEEoSwYDEQyr9fn8Z24ltL3M7IihWvYhtuISUsgehw0GquQyqhIbUI0ppvbXtp7mtfdi0BhYtC0C8Kdwh9S5hycDjTjkc2ypn/S68C8/0bPXK85ajSB8hBkiExmc76gPNCkhYUoIP+nkGJAy98HSqFGHEfZsPZrPOx4HsyEjRAiGma+ET8sell5YjpQhknlzpZZJcpDEsqTSlyLaRL+E5CNYWIoWZJHE/aouXKPdg8G3I1JAwgpiVtvYu+OaMzebq44ysGaWY+Zg+EGZhBdDyHLw0HYT+VC6kSCTIjEB4wbBoVgRithjZ3JbHsEYyxLBICTwEQAQJ+UgZfd3pG8lwD+Ts40A2bOrjNvjqAg5yOoLLdComNXVbzh6JkdsjZHiFY1SJSySWKUBcoSXVs0zVZMqy1BwXH0iHodRV7t8Qgopk8HEg51wYuSQjNKEk9ICAo30J71/Db1KKFSCBUhmRkj6vCLYFKHSdcuAXuROM0iGAJCMgakbJhZznDDld6wojJ2+b1g9h6x3h9wl/3bvkvYIWI+W4uIsX9wIvuJEYIRwFyp5IDHsoQNoVooliOwYUEMnEybQjK3f4QfytzCcQvXQRBK6wVPFqivZgWj8YWXH3YSADFxqHvhEmWipWJXbSoqnAnIyEdTzyMr0HKkUSX7/NsBXHOlhJEZjL+XiknCfECBBpZCBFJxbhg4zkLHU5pv13PnJifdy0mvUTy4Kj4nVMRdWJ1GIGwSfoRSNxtIR5IEkNBtlTCVr90SjOYhuCEEHAE4dXCdRCwIaR5ihoCCTnkLBBSuDtKBALV6n4t4A8f9zZO/AQWBbvVP4rFAzWU2EV1vPmyXJNVCSwbVBDpHlGTXJaifrtLAYhuQ2jYzzz4FgleNpXa2pC+yscuVQ4LBBDmK1i5Ie5wPpL+P1wZt/ULbg6y1sKbcct7ouLJ8uCRnl+eto8W2ZgGJ4G20KpkkdQKCKzYj3WdRvgbBCJDIEo7SmB4ypDm5pEQrMSIJx11DRnP2n+Ylvf7fTpfFhrDS4ofPH6MX3wv7qfti6erSdLNtduOuctj4PwCV95ihHp9FbasCqyYdviRJI9QwZwkf6QBQjenqGXQMqPkOu6rvtqE+l3aIoPNx9q61ZBr2b8z/GacRw8Sc4tntXw/Py8Xi9txGLcshEwkcxEM8LTczCSJHZu54jQU2QdpLoWeFEJ0pJREPXqsFoXGNLXKocf6scmVT/WWh8Fcrax6i5lLWJlzqoa5aiXbHj4zPn5c6fZXC8vWotqrMO24MB9VX607RweAobsPJH1bMRmVPpmywwl+yQX3LxgpraErFRN0HJkgCm2OBqs+WH/woeBNC8KZBEtl9RlhLnE24tguXl+Pn/eAMe6b49Mcx7pOl2EdRWkbyb2jyswHDM0uAEjYaiFvkVcYKZEKUYkwMFgnKbwedluYqp2/H5n8pcBuet4bJWGuprXhxXkma0bzIadJa8ObsqpNnKIREPPoU/ISF8IMfB65+wVS5ci1aGH7SB3WrDAJRKlSYXAEMFQACOTpZ4WGTksHx6tKOyH/u8+uNDTjD0qeOnI4aJR51k3toME/o1X1kbaG+Geo9N+Bn+o0LQQfekhgAFZxv5hQqmPmsVmhoQ0gG9Iym9ZLZocxE1IE4PWcl5M62WT9ettGB8DUuvkU/h6yHU2JjDBovt+1I0hQGKiwGMygo/P8CNRe1VhXZsZNiwLMt5G/actplQozCBPNp2CSACSfg/bQnRmAoKrcDuTyebvYbvQd+OzqIoGH1x6O4s0tw4DyBUhKFQzNhezhu+DB7zscZx1uyPUtDNwpc/6Ky6P9EsXifszv+pMzXMTQe78GVnU8iSKm7BCSZMOpWaigED9CpCjJsrr6bO6VXQ+uDxda9oOaqrUoGVJ0wACiQKPFR0H9tl+BhEQ78zS2WjWZ7NkFkN/xPno9LSxWEzNeIlQXTydPz1Zl5aF20ZAThQQiGkb4Y4ljgLiHJvWdxtGn6zNR9fZa5XUrLvmJUkYZii2ubSDW66G5Ti5UdWz2YglCBjRG/N+uw1SZrqdRVGG4j0NG1rQ7zw9P0kH2tpsIFBSZshqkqgyRhxJgDC4I2MWB1c/qb/aofiJyQdY1sItzJTt3aE/n83m0joYzsp2IRdH4BVsKpCpxqg96rf7owxxOIqj/mll3sANxxFyJ+wKvHQ6S6+w8BqYGsNuLpnGUEDIiSMdur1pfefqF+vBB6eDas0oNVHlhsIIYPSJRFrrgEAM1OxsxfX7wKEPfaBo9+hHICTqr05X7fg2sKPlpaTP5826szlvcXU4dVAVQFIyQucpgFBwcbzRtOruwS9eh6zO3d3HgGw7caDBtKClAMSfo+ybsZ+zYme0IjCQ/lanp/3VbKYb1YY/b3Mulh0FwMhY87bjhh7ky8pyszl/PgchtofXfAogKRUNkOg6GGGjkSWi5qnF0P0k45EQrhc/HzT9BSB3y8AITf6vADLsjmD/XPNs91eqWV0uP5/2o5nfICGc+0VI4NaLbLSKCGQUAUhsxPayg2sZLWOoE4h4WFaIvGNTweUChM4uQPZN7JPXybD+3PzoKGAzCauGWW850HWNIbKFjGSt2ivaTOWwCF2Z4eZBiD7k7ENPrUFlo4pqqMDOgiCOkDyReB7tW3vsOSKFwxS0MSaw9mJVEtJHvNarNYUjSoo3tiD/ApA1CvIxSicxLWQO2YDAEYbVfoBJ5vxmtKVqWG3MuQwyGXIFSoCoojeL9QCkMOWwrRKgPglCB5Qgvc5mmVBilKUVg1b9uGPKyZqSlvM3Dkg6+QUXScKx1nJNLQ1lfkaAlANZa4Bosll9uqItsX07VOsHPW6JaWQztRIK3QUkIAU4Rv2YQiAGgEYVWZytIVn4grezi4LSi7Xuy0Eqx4Grfnf20QHm7RJhctEqTLYWgCTuysD4y3JnSYjgACNDtaQ+lNHTIdLJtVrmQXGiy6bXaDQa9ftxNhMq2IDPkDhnMMtUtl0haKFWKeqv1xX2n986EO2fgVzZhjN2UJnC2XNObDR67f4rHFTsfRLCcTq9J6sivaFiZNReiRIm2NUo00EZXotoFGXlhcg2lFA+yyT2svcA9SUt0+LHA2yKzoeBnKGY0BwJ+gb3eza6XZki3bMhSyBzEqJzvPymJzOlvZsq7Gg49GGGFQWWP0gJw3+Fkk1XQJRYWAGIwYQY0thMNvqL+tH+05fh+LNPAAmr6dQCkFAY6fYmx37OkNWeyUiGQV/v8vsrRFtIZW5QapeMqB9tt0eNrEGPyCKfPfmMna1svprPGyxFZA9vCrG/P3AI1/09h7dKodWpfYaR0HEtbnvhDRCHmiMr12oh3f1yF0VYrd5MZEGhccPXXfZazVd7RpSBcUYIOZVTH8yrlDtAAkaQQRICMT1FSLmX6969J5QSSLP2cR8JqmGLy+taghe5O/HVPNxhAbrCySVp3yJo3XS5a+S0R1wyyNXozSqne1dSS7tqEo3yoN8XmQNiZvOhLrOF1PCaVRTllBZw3E/5KIF0Bh/e0XMVB6EhQETGd3u9AxDJg9d9mQ7XJfbCRTgTfz3hEFNDgAx78xfbUlPyaqCA80N4nhGKj1AM1assi9J3f3DBveCo37fuVexa330KSMJekImEKJtv22oqS/L5tQzsD7mNmLVJ9XYiOLpdQFPrON0ZMuTBtl5G0dTcJpCokJUNqzIliVoELlICcd1payouMr0vd4N/fI/V1TIINNkmzWGgYVd25R0mYLmJgoE3DIygagRBo3v97XQ0mfRkCwbnZ3pDJJPTV5R8OwxFiOoEKzNQZ5Q44CMKRwE+eFbMPfx9Uf97F/k1IIbHtruZwH27Q06XkZHrcs693WsgrAWlZZWMTMCJz0Vb7q6Eu1eOretlMFvNdM3bc5acYblD1PH2S9/u/ZRHENC8FsqyOp/Yh1gCMdkSBSOo0tvXpZOo3Z4NA9Klqwc8ruK2W5rWpBv75fhSt8fZs28/XKdqzkZCGPI6y032Yh1PhgV4EtR0Ol3w+IHpw4MixDr7BJBtJzBM9j6gfmXAVyYXS90Ir74xAu75hiY0gpvb7jXuj3z0GkMoEnyz2hiWYzbfA5Gh5tWqPZuPWISF5WbwVnlIktsijgeHG6sVISfrz+zVra2D1OEYuZMGwbALkxldtxWU9mTSQJIJINC7jTg3xLKQWOjsXZBkcF/72Ggon/r2IxBOl1/PYYEUzqnaYKUGTFGNTFs814Lbw7Ww9fNlqnfWI7bmyMKMkQdx6SQTtXnC71a1MXDoiFJ88W+6BEIcEpENHV8ZGoX9kRI4IgRVjRT/GcOFJvvEHDW9UfClAwweofAwLoGcbz8FZBCHAsTTgrzRgJeMuIW1LR4dIPYDSBc+cRvwC+4DJR/dbszyo+s3grGhX59+O/0JDuZ48sFaUlXqDk/jcUX5TgFEtu9qD1qoTOuT+9mvImOsQWuxCFKVlY9cMhlNuo1q6IRjgy5ORqoBCfm2B6LrceTDxMaG0dj7yOkxEA5zzue+HJpSlU0KJjfzqKPd6lOzde/I/vKHhxuJvuefPGFgG0H+Ss88RF3U6AIGUEy6vl4d81yacfCI+yYht122fCUdshTsjnz+QZhohn8teuZIcwkSjm7JxkquSssusdZ+LsgFN/cttVX+oerUf7Ym8t52UMcea87UZGWl5zFuzpfjNIKqZj6EhgISN4LghiFLgNze6t0YYMnIraEhPk9e12EChB7S80U2i1Z0zIV5GJ1zWwtnOnW4FWP8MNbA0fnZZ4GscS8aUpPGVf4GA9cIFnNT1ZwHZEL4YvXxVhFyLSISQFBHduFD+LnuTeAEiaEzch37u3L13gjyBg7CSZDyVKRCZZHpwtTMxQM3MoCRB9d67nz6gJdBFDgap2RTI+BCQUwCbqrhwkHxFDwgQMJPDLqKbPmuTMBH14+7YmNAqBlBSPfZA9kPnTN+8/SaXC83JPFIpKLOvkMBbeIkGoHgfxpXnafzzuDTQK7WgfbA7bmkJIj1m1hXOMBHNQgR7KcLKvCbyTW3r09GjVt4EhmZwMYQ2ALoZ31CXfOyaYx687rtcz94nrMsdNSklJJZKEgXmmEsHCNocF+yuez8w8lUv9T7HXS47KeA8OwfBCh4zQK+j+QBIAj40wdNC24nSmXhB/RbCV03+MmxjR8LjQbqytXLHmQ5lwOxlzndKA+p4glVpextOQstsLWHcSCMXKwH2y84BKnWjLWWx7FlI4HqQKFFHBor+KoBsljB3S+0FHmjG8GWDMN41CFXHh+D8RgA7RhegGS53/EqTTEgGc2QCyH/VS7kiW4tS40X4mUDI3HyEAayT+ay+SVAdttmYvJUGo2TDeAj1BbAwfYCGNEWqBmm09aDBpSPdoCsMw7HfMB5Hh4eNLbldBiXr+oYSrTrCif+OUPXMLhu75TH7amBs8KdcstQHhsPFHLw983d3decr1VbXzie48G24NSUd4oPHjGVIHgtqO849ESnBwcPcrgcnOfhYeGM7ZjRGXz5av/rimda0LJG/lDPg5IQOZOupU6idE1oEzCSa9Vb7jNJOn9dfRGQZgocTirr5IgxCFi5OAvsO4H4fqCjQMSkCWEswNBiKhbXWsA69GjUjZFMUHUBgmypbHMBxc8agfx7JoHACa2WOu6w3C0fBVrATXGBsT77p3MBf3mdHTdJRtQyn2aGlOicS0mSMR6a98DX1PMegFedxCZAwIo2tm/jYdTVkUyGbFxU1KEQwEFCDA6f0EEWLRncENNqiXwM40RDLYcQn5x92WF6A06bgRH6SNVwNKCgt5SNZ0DxNABBZn4AjgWtiof94ZOmJfCRqB01cjhLdzSRAzq4NDEaqZlMTpUuhBBmw9KyTJhWqEM1QEBUg+XVlx1vOODWFxDCRSvdcLjQvh8WsxUWkFLaOctT1hLA9eCNk4BAoPh1iM7GaDQCAgKJRlxRlYUdiVhcALXUkJaraS3ZDJwinqCCTppfd+DkQM1ehjmn3dIEqoKrSwFQ5HRwwEmSiwdPYCDAeQvN87SLlIYHpYnbh2MHWlWPkTkiVAKjYeTHspQgc6otGRxqKRyFFbIOQQFvBFwyNoyzrzvLdMBxTFoW+zZOzuEZtZgBHWXndsBVmgSsyEj5hXahcc4MxS+e7DhQSDLULvEw87M4ozhucCOQyEXxdECx5GjTot6SZoq23/YfdrZfB+TOkXHSXM/8YdWMWaHLUJNAycFHgDsGKdrFhcdxJ9u2H22u5xg2TUuPYEqxkQYNHTC6GcfRKBZlmlOWrsS01PwffR3yh0AC5BBj/AuW9etAZLIUloUXNDRhEwFdXJDAugLcsUzFgobxRZLEgiPmdw185gVKojiUqRzyofOQUwbAhAMbLXWKiKVGgu6ZDbm30uABONXQvvrC837P8DonXO/zZ8PQ4Z3IlGLIeWUjsHWbS2r20lZXvLy1ZUoW39QFRxT38Yy8IEzoebnQlnCE29kfdKwYgc6Cd8CkNO4ErhpJs/aVQFKNMwr50J8P2QPWOQXDrYiQ9rK4jNtc8sOWj3h/6YIEj2gURSM9NWSbniKD67eie8uDUB3Z/1BMPZ5Ma4AKrvRVjfXVVx4lfUUXASPD2SoLczX/qiWhxtk/xBb7MY54q8t+xLVnfESxzPvGUclIRPOKDU1vyJSvwqGl7Ml5Tnm+Lve/TK2W7J41uGLfaORB5+xLTynfqsFxAJn5qRpwRbh54NG+hPKox7fRaCSbXjp9Ti0Dl4xA6WJgRCUTXdQcXPukk6t9AQxaByDIJC0nlbOCG7LMly/Pvva49dpGo6aqZqNZFCJ2xTbqN6pC1IfaGGW7/ti9HY0mS5kPiPpwbSEhpvfYYlv8Rjc1hlyiylPhI5UJWjCiHVoPrdZ+TId7+gK7uf3iA/A7SOupY8Sj1Qw+Cl93KKkEyphQUO2ico/iCTBMRjQzELC/MuFEhsuTxsjn6A2HaWQ4gE7i7Y9lZWklp1DLEoauJ+tffS+oXwbSJBCIDH/VZ8AiIVJPTYUX8+FhjGoOUGI+4ttu3N1TgRCV2SpyRZmexrPM96W85TgmLbbE4XBQcNpahHI4aPWGvcvl2Ze/t8Kdp3H8SPev25yS40D1vRxdYnoaJQnQsKJKHu1HFIbBGCFgzCig80O3lWlFup3q0cyPMsWIIdPQLHRMTdXsU9c0Ara5bhqQvctff/ukXwayTUT+5v51fxbldpIn44cFV/a8JbJHnC4eIOEXY9qYgaeEX40ZDUKWYqBmmcX0/ySPZsq0WKXJriAkEjbizQUNy6TAMkKW6r/uIO8CYrMiSfN4terjhc11G/X4w/19fdHpdCrr02RZ6cTaw8MFPoDpAYLecRYPLBIfnARQdFu8JE9Qqc8Qt1IqGUYvYUTVutOW3ZFcaPD42aR59uvvbfOO3QooED0tz2aVVRRlSCSBQmLJG0w2O/jVrHBOzg4gg23D474ypeZRW6Q58j7jlp704SQwLUd2xHNwWfNUdw6ubt41bZmS1FFNvetN396xEebCgVsm+qgP29K56SOoPo4fHu5t4mjyPUwJZ92srGN7/a1iX0ZL2/S8BVf8F7AYe9aP+mCk3Z4BiMwx5mJah/Y1CNluOxxYCahM3vVGae/YvmebjmeGue/LIIk/yuDR4GSxiDeCo/nXoPltQDzrtcK03lxcXt5zvfx+aiZQwP1RpgPIHLUZzTSXabNUQq/M9beuuNRHwZwsB1f/1ts/NVkxpQaCZwQpHg3j3Bizwby4L0ogQDL4azBQ5Kyb39abS/tC5hYQprVEByMjPV71+wxaDqpNWzb6yGH4Uuivd3JE3HK5bl5t/7V3Ftuys+UZuZrqiTM/DoUSBi/znHf/F1nh84C0gJTLywup3x8QwEyHG8T9ZLZi/A5lsDCTdytQhKDG99S9b7dX23e/a917Tqo5F0o4XW0TyKzBOAtKiMSy1+SBMOQT9y+skwLhC9fjo7Qf7Zgqa3Xd93VDzZuRkvL4PAJp7j5+vQfImudlppzRBQxIJmhZAQIk05bV8i6X599oYgO+u2xn2bFNSSaPN7e3gX5rcwjdSGbt/szPE80xAEMSvOmUbx5zsftNQHYEwulvO8ujbAjHLYGMx4uFeXHped7lpT3rRF6SttxF8Cg4bm9vAh4jL12XLKq0+5yVcxy2w1H6y0S/8pC73wZkw+MdLpM8k3NdfL+bOgIEUXhhJjnuP/Eu5cNswX0I5LHb1YMblO3yd6IZN/RBcDliWZLgVehFyLJ3vw3IldUyLS9JuAlGHN5whA9epjb2xtypy4KLy3EE8nh7c3Oro7yFISKLIpn2qQtyh1tR9kUNIy/4sK5+H5DdJbeB0kskakXdHJpE4eCrz7zCnsQ4uL29fXy8ebypAgavIfcxgI8Vay495z4LOU9FVnhkOWHqrne/EUiTszWeAJENw7pGSm4UlJcLTNziiWyQjsawPZtF2RLRF6oAOQTiCkkEIYz9cFkXmbre7ncC2XmyMxdOO4x1mArLK/rI4y3v//ZWmBg/qs83NxwhkHF6AoFp9WezfmaDEDOV43pkb6Is70ynZ78XyHqqjj/JqFI4Bq4tyEmACDvpTuRsisrp5LZLKFx1MHKUHyNEXOCYRYST5QnP6Uikdyxn0ohhNXe/F0jNYpfjMol9mXaFSjG5cCC14S1XPyuTSVcxg8qKCw/RjJ13glhmSziKbKpiCBfBKClkarmd3W8GsltaLjJfrpfTx8gDC44h0dOVaZXmFeIjNxDc+v12ZURClmRxiTqEuYi6lzmkxJHsfjuQK1DiwUtibjEAENvgxIImnZTg8dF4ZOhCUB2zbNKzkQ/Vf92fw9eh0ZaspzyqA8QLCF/iAAzLq/1+ILvEcmHiNj3El12fCVd3TM0bsxM8TjRpdWnMKAgHfn80a69mDFrkhEc/8bCkshKR/e3TL8HxfiBNvoKw8TiS+Bsb9pgHOS087YKV+sVYS8cXGupxtkpH/qztQ+364uYIWILjMiUf5GYKGO6X4PjA2z+Z+K95ABXy9GgoXXWw4D2YD4CC7A5qgCOhRodd+W0U6HLBruAgl56oNW5xS1Pw4Vru5Zfg+ACQNffEpDY0+WgU6TEXrAKDp7p4DxqgAEQSGHoMBoY+r2g2n/cjxivlIB7PTmE7yZNDoL6Gj48A2fKIIKGEmycaYIRd7AD+cZFyhReFKuxu5PuZP+RqSsadZRKv8uRS5DOR7Pn4KhwfeYs0G05ySS0fRaMMQpxIbGislEsoXPLRuYYwifo8hwZ5cCYCBW6RKMOSE0lSdUzK5Vfh+AiQAW1L9FYWQZ3LTKyc6UA+VFcxjlDXjzJfEjqH+W21dx3a2ZMlPM+T5anNl+H40LvvwbjTS2EklqSI8ASvoKPYYARIdB9Vl8+dIREMC9pEBSx1Zh1bvp7HpZDPCt5PA1nDtnhABSwLVyNuNDiJifsPFBvdYbnxyKe64lrJUoddpV5L4fCIAw4y2P3HQODuHhjRuQQCJ+nqje6ky5WcUddH7uAsgC+i0leHB83sLLH3hHgpm96WVZhnu/8aCNzdvGT9jZskFzdxF0T4Ubs96o9GFW6dxsVEo4BkUIiX6aWcgUgvFz6+zs0/AeQvUMI9nrhtP27oencUc09eNOTGPMC4BiTubemvUBDSP/JEEUJGFI7lbvcHAEHJSwEbkxIAuR36XU6YRH48HLWvgSPy8Xs5cHYWLYHjkqdtsLgkDAqs5u7PALK2zMskjWN6g0wq4/4hSLjkNqpcVyZcfZO9+RWpQBJ4umlKM8njoRuX290fAmQnzRTb7jMlwtVHdAbOm0z6PKm4zd/wXZNWs6XNU2oS5g2edMbhMrNT2/0xQDqkJOHSDR19gjunk+CqwEkq1wKkgu9C7AOIHBlimfJheX/tdn8OkJqnSndow2Hck823uPc+z0jgBQwV/IokYtk2HcRtWWJcy9ruTwICncL6iFVJDBeRm+9HCoX6HY+gAx80LRqWK0ejWZf/Dh2fALKzLRHznPSJEKTk7iPCKXfi90WaQGEll5fEwXPBvOZu98cB2ZqKk0z2iUR9dQagOgxQDgSMVClFPkw5n8ba1HZ/IJBd05WyRGYC1CK6UNIfRSqfR5kcG4TA23IL1sd/7XZ/JJDdxpXQlSO8yqgJpzYUIKLgEjbjVeqpYyY7td2fCqSGWGqiSjI4Cii0QPxmavYks0s6PMFheWe73R8LZDdwVXM+kSrclmkNOZMxi2yVzgVH8e/T8Ukgu467P2c2ldML2XazZY0x57wzErmclXl5tdv92UBY9Vrluf4cI7M54Zgz5LJ4EhxFYa53uz8eyK52LudHyzmtXEJMVIdEqVyeJns52O3+NwABKU/0FHm/BU+dO0sq5BxG87yz3e3+twABlHMJTBwmtyx5IojN+mz3O6+TL/lXrtad8yfv6Ym9KvPyfLm+2v3u62T3f+T6fyB/2vU/AgwAruuHZHYE8DwAAAAASUVORK5CYII=';
		#sliderLeft;
		#sliderRight;
		#teeth = [];
		#img;
		#openFlag = false;
		#busy = false;
		constructor() {
		}
		render(elm) {
			//template literal
			const html = `
				<style>
				:host > main {
					user-select: none;
					padding: 20px;
					background-color: #5f0f83;
					max-height: 32px;
					display: grid;
					> svg {
						grid-area: 1/1/2/2;
						display: block;
						cursor: pointer;
						path,rect {
							stroke: #ff7;
							stroke-width: 0.5px;
							fill: url(#gradation1);
						}
						rect.inner {
							stroke: none;
							fill: #85b;
						}
						g#sliderLeft {
						}
						g#sliderRight {
							opacity: 0;
						}
					}
					> img {
						grid-area: 1/1/2/2;
						display: block;
						transform: translate(120px,-184px);
						clip-path: xywh(0 200px 200px 0px);
					}
				}
				</style>
				<main>
					<svg xmlns="http://www.w3.org/2000/svg" width="460" height="32" viewbox="0 0 460 32">
						<linearGradient id="gradation1" x1="0" y1="0" x2="0" y2="100%" gradientUnits="userSpaceOnUse">
							<stop offset="0" stop-color="#cb0"/>
							<stop offset="0.2" stop-color="#dd7"/>
							<stop offset="0.4" stop-color="#dd4"/>
							<stop offset="0.5" stop-color="#cb2"/>
							<stop offset="0.6" stop-color="#db3"/>
							<stop offset="0.8" stop-color="#dc5"/>
							<stop offset="0.9" stop-color="#cb5"/>
							<stop offset="1" stop-color="#ddb"/>
						</linearGradient>
						<g transform="translate(80,13)">
							<rect class="inner" width="300" height="6"/>
						</g>
						${
							Array.from({length:50}, (_, i) => `
								<rect id="toothA${i}" x="${i * 6 + 80}" y="8" width="3" height="10"/>
								<rect id="toothB${i}" x="${i * 6 + 3 + 80}" y="14" width="3" height="10"/>
							`).join('')
						}
						<g transform="translate(61,6)">
							<rect x="12" y="1" width="7" height="8"/>
							<rect x="12" y="12" width="7" height="8"/>
						</g>
						<g transform="translate(381,7)">
							<rect x="8" y="0" width="10" height="20"/>
							<rect x="0" y="10" width="7" height="6"/>
							<rect x="0" y="3" width="7" height="6"/>
						</g>
						<g id="sliderLeft">
							<path d="M86.56,6.8l-14.03-.4c-5.57-3-9.09-4.22-12.24-4.92-5.53-1.23-6.77-.96-8.76.62-4.12,3.26-6.33,10.8-6.32,13.54v.76c0,2.74,2.19,10.65,6.32,13.54,2.08,1.45,3.24,1.85,8.76.62,3.15-.7,6.67-1.92,12.24-4.62l14.03-.4V6.8Z"/>
							<path d="M59.54,6.01L3.6,2.83S.44,4.9.44,16.26s3.15,12.91,3.15,12.91l55.65-2.61h0l5.29.57V5.5s-4.99.51-4.99.51ZM15.68,16.13v6.98l-9.78,1.65s-2.59-.61-2.29-8.63c-.3-8.02,2.29-8.63,2.29-8.63l9.78,1.65v6.98ZM61.59,23.22h-16.38v-13.97h16.38s0,13.97,0,13.97Z"/>
							<rect x="48.3" y="11.36" width="25.63" height="9.27"/>
						</g>
						<g id="sliderRight">
							<path d="M41.96,6.8l-14.03-.4c-5.57-3-9.09-4.22-12.24-4.92-5.53-1.23-6.77-.96-8.76.62C2.81,5.36.6,12.9.61,15.64v.76c0,2.74,2.19,10.65,6.32,13.54,2.08,1.45,3.24,1.85,8.76.62,3.15-.7,6.67-1.92,12.24-4.62l14.03-.4V6.8Z"/>
							<path d="M13.3,5.5v21.63s5.29-.57,5.29-.57h0l55.65,2.61s3.15-1.55,3.15-12.91-3.16-13.43-3.16-13.43l-55.94,3.18s-4.99-.51-4.99-.51ZM62.15,9.15l9.78-1.65s2.59.61,2.29,8.63c.3,8.02-2.29,8.63-2.29,8.63l-9.78-1.65v-6.98s0-6.98,0-6.98ZM16.24,9.25h16.38v13.97h-16.38s0-13.97,0-13.97Z"/>
							<rect x="3.7" y="11.36" width="25.63" height="9.27"/>
						</g>
					</svg>
					<img src="${this.#nicolascage}">
				</main>
			`;
			//attachShadow
			const shadowRoot = elm.attachShadow({mode:'closed'});
			const tmpElement = document.createElement('div');
			tmpElement.innerHTML = html;
			while (tmpElement.firstChild) {
				shadowRoot.appendChild(tmpElement.firstChild);
			}
			//initial
			this.#sliderLeft = shadowRoot.querySelector('#sliderLeft');
			this.#sliderRight = shadowRoot.querySelector('#sliderRight');
			for (let i = 0; i < 50; i++) {
				this.#teeth.push({'tooth1':shadowRoot.querySelector(`#toothA${i}`),'tooth2':shadowRoot.querySelector(`#toothB${i}`)});
			}
			this.#img = shadowRoot.querySelector('img');
			shadowRoot.querySelector('svg').addEventListener('click',() => {this.#toggle();});
		}
		#toggle() {
			if (this.#busy) {
				return;
			}
			this.#busy = true;
			if (this.#openFlag == false) {
				for (let i = 0; i < this.#teeth.length; i++) {
					this.#teeth[i].tooth1.animate([
						{transform: 'translateY(0px)'},
						{transform: 'translateY(-4px)'},
					],{delay: i * 20, duration: 200, fill: 'forwards'});
					this.#teeth[i].tooth2.animate([
						{transform: 'translateY(0px)'},
						{transform: 'translateY(4px)'},
					],{delay: i * 20, duration: 200, fill: 'forwards'});
				}
				this.#sliderLeft.animate([
					{opacity: 1},
					{opacity: 0},
				],{delay: 0, duration: 0, fill: 'forwards'});
				this.#sliderRight.animate([
					{opacity: 0},
					{opacity: 1},
				],{delay: 0, duration: 0, fill: 'forwards'});
				this.#sliderRight.animate([
					{transform: 'translate(50px,0px)'},
					{transform: 'translate(375px,0px)'},
				],{delay: 0, duration: 1100, fill: 'forwards'}).onfinish = () => {
					this.#img.animate([
						{transform: 'translate(120px,-184px)',clipPath: 'xywh(0 200px 200px 0px)'},
						{transform: 'translate(120px,16px)',clipPath: 'xywh(0 0 200px 200px)'},
					],{delay: 0, duration: 1000, fill: 'forwards'}).onfinish = () => {
						this.#openFlag = true;
						this.#busy = false;
					}
				}
			} else {
				this.#img.animate([
					{transform: 'translate(120px,16px)',clipPath: 'xywh(0 0 200px 200px)'},
					{transform: 'translate(120px,-184px)',clipPath: 'xywh(0 200px 200px 0px)'},
				],{delay: 0, duration: 1000, fill: 'forwards'}).onfinish = () => {
					for (let i = 0; i < this.#teeth.length; i++) {
						this.#teeth[i].tooth1.animate([
							{transform: 'translateY(-4px)'},
							{transform: 'translateY(0px)'},
						],{delay: (49 - i) * 20, duration: 200, fill: 'forwards'});
						this.#teeth[i].tooth2.animate([
							{transform: 'translateY(4px)'},
							{transform: 'translateY(0px)'},
						],{delay: (49 - i) * 20, duration: 200, fill: 'forwards'});
					}
					this.#sliderRight.animate([
						{opacity: 1},
						{opacity: 0},
					],{delay: 0, duration: 0, fill: 'forwards'});
					this.#sliderLeft.animate([
						{opacity: 0},
						{opacity: 1},
					],{delay: 0, duration: 0, fill: 'forwards'});
					this.#sliderLeft.animate([
						{transform: 'translate(335px,0px)'},
						{transform: 'translate(0px,0px)'},
					],{delay: 0, duration: 1100, fill: 'forwards'}).onfinish = () => {
						this.#openFlag = false;
						this.#busy = false;
					}
				}
			}
		}
	}
	(() => {
		const zipper = new Zipper();
		customElements.define('ce-zipper2',
			class extends HTMLElement {
				constructor() {
					super();
					zipper.render(this);
				}
			}
		);
	})();
})();

/* JSX の書き方 */
const name = 'taro';
const element = (
	<div>
		<h1>Hello, {name}!</h1>
		<p>This is a JSX example.</p>
	</div>
);

/* JavaScriptネイティブ。テンプレートリテラルの書き方 */
const name = 'taro';
const element = `
	<div>
		<h1>Hello, ${name}!</h1>
		<p>This is a template literal example.</p>
	</div>
`;
		
テンプレートリテラルはPHPなどのヒアドキュメントに似ていますが、より柔軟性が有ります。
JavaScriptには「タグ付きテンプレートリテラル」というテンプレートリテラルにタグ付けをしてカスタム処理を行う記法も有ります。
この記事は2024年6月当時の物です。
このサイトについてのお問い合わせはエーオーシステムまでお願いいたします。
ご使用上の過失の有無を問わず、本プログラムの運用において発生した損害に対するいかなる請求があったとしても、その責任を負うものではありません。