1 | import { css, html, LitElement } from 'lit';
|
2 |
|
3 | class SlideList extends LitElement {
|
4 |
|
5 | static get properties() {
|
6 | return {
|
7 | slides: {
|
8 | type: Array
|
9 | }
|
10 | };
|
11 | }
|
12 |
|
13 | static get styles() {
|
14 | return css`
|
15 | :host {
|
16 | max-height: 700px;
|
17 | overflow: scroll;
|
18 | }
|
19 |
|
20 | div {
|
21 | position: relative;
|
22 | padding-left: 15px;
|
23 | }
|
24 |
|
25 | /* https://stackoverflow.com/a/20102415/417806 */
|
26 | .iframe-screen {
|
27 | position: absolute;
|
28 | top: 0;
|
29 | bottom: 0;
|
30 | right: 0;
|
31 | left: 0;
|
32 | cursor: pointer;
|
33 | z-index: 100;
|
34 | }
|
35 |
|
36 | span.num {
|
37 | float: left
|
38 | }
|
39 |
|
40 | .wrap {
|
41 | width: 100%;
|
42 | padding: 0;
|
43 | filter: drop-shadow(5px 10px 3px gray);
|
44 | height: 0;
|
45 | padding-bottom: 56.25%; /* 16:9 */
|
46 | position: relative;
|
47 | }
|
48 |
|
49 | .wrap > iframe {
|
50 | position: absolute;
|
51 | top: 0;
|
52 | left: 0;
|
53 | width: 100%;
|
54 | height: 100%;
|
55 | -moz-transform: scale(0.75);
|
56 | -moz-transform-origin: 0 0;
|
57 | -o-transform: scale(0.75);
|
58 | -o-transform-origin: 0 0;
|
59 | -webkit-transform: scale(0.75);
|
60 | -webkit-transform-origin: 0 0;
|
61 | }
|
62 | `;
|
63 | }
|
64 |
|
65 | constructor() {
|
66 | super();
|
67 | this.slides = [];
|
68 | }
|
69 |
|
70 | slideSelected(slide) {
|
71 | try {
|
72 | const { protocol, host, pathname } = window.location;
|
73 | const newurl = `${protocol}//${host}${pathname}?selectedSlideId=${slide.id}`;
|
74 |
|
75 | window.history.pushState({ path: newurl }, '', newurl);
|
76 | } catch (e) {
|
77 | console.error(e);
|
78 | }
|
79 |
|
80 | document.dispatchEvent(new CustomEvent('slide-selected', { detail: slide }));
|
81 | }
|
82 |
|
83 | slideLoaded(slide) {
|
84 | const frame = this.shadowRoot.getElementById(`slide_${slide.id}`);
|
85 | const style = document.createElement('style');
|
86 |
|
87 | style.textContent = `
|
88 | body {
|
89 | zoom: .4;
|
90 | }
|
91 | `;
|
92 |
|
93 | frame.contentDocument.head.appendChild(style);
|
94 | }
|
95 |
|
96 | render() {
|
97 | const { slides } = this;
|
98 | const list = slides.map((slide, index) => {
|
99 | const slideNum = index += 1;
|
100 |
|
101 | return html`
|
102 | <span class="num">${slideNum})</span>
|
103 | <div @click="${() => this.slideSelected(slide)}">
|
104 | <div class="wrap">
|
105 | <iframe
|
106 | id="slide_${slide.id}"
|
107 | src="${slide.route}"
|
108 | class="scaled-frame"
|
109 | @load="${() => this.slideLoaded(slide) }"
|
110 | loading="lazy">
|
111 | </iframe>
|
112 | </div>
|
113 | <div class="iframe-screen"></div>
|
114 | </div>
|
115 | `;
|
116 | });
|
117 |
|
118 | return html`
|
119 | ${list}
|
120 | `;
|
121 | }
|
122 | }
|
123 |
|
124 | customElements.define('slide-list', SlideList); |
\ | No newline at end of file |