1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16export class LitSlicer extends HTMLElement { 17 static get observedAttributes() { 18 return ['direction']; //direction = 'horizontal'或者'vertical' 19 } 20 21 constructor() { 22 super(); 23 const shadowRoot = this.attachShadow({ mode: 'open' }); 24 shadowRoot.innerHTML = ` 25 <style> 26 :host{ 27 display: flex; 28 } 29 30 #root{ 31 display: flex; 32 width: 100%; 33 height: 100%; 34 overflow: auto; 35 } 36 </style> 37 <div id="root" style="${this.style}"> 38 <slot></slot> 39 </div> 40 `; 41 } 42 43 set direction(val: any) { 44 if (val.startsWith('h')) { 45 this.shadowRoot!.querySelector('div')!.style.flexDirection = 'row'; 46 } else if (val.startsWith('v')) { 47 this.shadowRoot!.querySelector('div')!.style.flexDirection = 'column'; 48 } 49 } 50 51 connectedCallback() {} 52 53 disconnectedCallback() {} 54 55 attributeChangedCallback(name: any, oldValue: any, newValue: any) { 56 (this as any)[name] = newValue; 57 } 58 59 set style(v: any) {} 60} 61 62if (!customElements.get('lit-slicer')) { 63 customElements.define('lit-slicer', LitSlicer); 64} 65 66export class LitSlicerTrack extends HTMLElement { 67 private line: HTMLElement | null | undefined; 68 private draging: boolean = false; 69 private normalWidth: number = 0; 70 71 static get observedAttributes() { 72 return ['range-left', 'range-right']; 73 } 74 75 get rangeLeft() { 76 return parseInt(this.getAttribute('range-left') || '200'); 77 } 78 79 set rangeLeft(val: number) { 80 this.setAttribute('range-left', `${val}`); 81 } 82 83 get rangeRight() { 84 return parseInt(this.getAttribute('range-right') || '300'); 85 } 86 87 set rangeRight(val: number) { 88 this.setAttribute('range-right', `${val}`); 89 } 90 91 constructor() { 92 super(); 93 const shadowRoot = this.attachShadow({ mode: 'open' }); 94 shadowRoot.innerHTML = ` 95 <style> 96 :host{ 97 flex 98 } 99 .rootH{ 100 width:var(--lit-slicer-track--width,5px); 101 background-color: var(--lit-slicer-track--background-color,#d1d1d1); 102 height: 100%; 103 cursor: ew-resize; 104 } 105 .rootV{ 106 height:var(--lit-slicer-track--height,5px); 107 background-color: var(--lit-slicer-track--background-color,#d1d1d1); 108 width: 100%; 109 cursor: ns-resize; 110 } 111 </style> 112 <div id="root"> 113 </div> 114 `; 115 } 116 117 //当 custom element首次被插入文档DOM时,被调用。 118 connectedCallback() { 119 this.line = this.shadowRoot?.querySelector('#root'); 120 let parentDirection = this.parentElement!.getAttribute('direction') || 'horizontal'; 121 if (parentDirection.startsWith('h')) { 122 this.line!.className = 'rootH'; 123 let previousElementSibling = this.previousElementSibling as HTMLElement; 124 let preX: number, preY: number, preWidth: number; 125 this.line!.onmousedown = (e) => { 126 this.draging = true; 127 preX = e.pageX; 128 preWidth = previousElementSibling!.clientWidth; 129 if (this.normalWidth == 0) this.normalWidth = previousElementSibling!.clientWidth; 130 previousElementSibling!.style.width = preWidth + 'px'; 131 document.body.style.userSelect = 'none'; 132 document.body.style.webkitUserSelect = 'none'; 133 // @ts-ignore 134 document.body.style.msUserSelect = 'none'; 135 document.onmousemove = (e1) => { 136 if (this.draging) { 137 if ( 138 preWidth + e1.pageX - preX >= this.normalWidth - this.rangeLeft && 139 preWidth + e1.pageX - preX <= this.normalWidth + this.rangeRight 140 ) { 141 previousElementSibling!.style.width = preWidth + e1.pageX - preX + 'px'; 142 } 143 } 144 }; 145 document.onmouseleave = (e2) => { 146 this.draging = false; 147 document.body.style.userSelect = 'auto'; 148 document.body.style.webkitUserSelect = 'auto'; 149 // @ts-ignore 150 document.body.style.msUserSelect = 'auto'; 151 }; 152 document.onmouseup = (e3) => { 153 this.draging = false; 154 document.body.style.userSelect = 'auto'; 155 document.body.style.webkitUserSelect = 'auto'; 156 // @ts-ignore 157 document.body.style.msUserSelect = 'auto'; 158 }; 159 }; 160 } else { 161 this.line!.className = 'rootV'; 162 let previousElementSibling = this.previousElementSibling as HTMLElement; 163 let preY: number, preHeight: number; 164 this.line!.onmousedown = (e) => { 165 this.draging = true; 166 preY = e.pageY; 167 preHeight = previousElementSibling?.clientHeight; 168 previousElementSibling!.style!.height = preHeight + 'px'; 169 document.onmousemove = (e1) => { 170 if (this.draging) { 171 previousElementSibling.style.height = preHeight + e1.pageY - preY + 'px'; 172 } 173 }; 174 document.onmouseleave = (e2) => { 175 this.draging = false; 176 }; 177 document.onmouseup = (e3) => { 178 this.draging = false; 179 }; 180 }; 181 } 182 } 183 184 //当 custom element从文档DOM中删除时,被调用。 185 disconnectedCallback() { 186 this.line!.onmousedown = null; 187 } 188 189 //当 custom element被移动到新的文档时,被调用。 190 adoptedCallback() {} 191 192 //当 custom element增加、删除、修改自身属性时,被调用。 193 attributeChangedCallback(name: any, oldValue: any, newValue: any) {} 194} 195 196if (!customElements.get('lit-slicer-track')) { 197 customElements.define('lit-slicer-track', LitSlicerTrack); 198} 199