-
Notifications
You must be signed in to change notification settings - Fork 0
/
resizer.js
104 lines (104 loc) · 2.5 KB
/
resizer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
const resizerHTML=`
<style>
:host{
--inner-width: 0;
--inner-height: 0;
}
table{
border-spacing: 0;
}
td{
padding: 0;
}
#wrapper{
display: table-cell;
}
#edgeL{
width: 1em;
height: var(--inner-height);
cursor: ew-resize;
}
#edgeB{
width: var(--inner-width);
height: 1em;
cursor: ns-resize;
}
#corner{
width: 1em;
height: 1em;
cursor: nesw-resize;
}
</style>
<table>
<tr>
<td><div id="edgeL"></div></td>
<td><div id="wrapper">
<slot></slot>
</div></td>
</tr>
<tr>
<td><div id="corner"></div></td>
<td><div id="edgeB"></div></td>
</div>
</div>
`;
class ResizerElem extends HTMLElement {
#startX;#startY;#startW;#startH;
get innerWidth(){
return getComputedStyle(this).getPropertyValue('--inner-width');
}
set innerWidth(val){
this.style.setProperty('--inner-width',val);
}
get innerHeight(){
return getComputedStyle(this).getPropertyValue('--inner-height');
}
set innerHeight(val){
this.style.setProperty('--inner-height',val);
}
setStartPos(e){
this.#startX=e.screenX;
this.#startY=e.screenY;
this.#startW=parseInt(this.innerWidth,10);
this.#startH=parseInt(this.innerHeight,10);
}
resizering(e){
console.log('resizering',e);
let bt=this.shadowRoot.elementFromPoint(e.x,e.y);
const detail={
'widthChange':!(bt==this.edgeB),
'beforeWidth':this.innerWidth,
'afterWidth':((this.#startW+this.#startX-e.screenX)+'px'),
'heightChange':!(bt==this.edgeL),
'beforeHeight':this.innerHeight,
'afterHeight':((this.#startH-this.#startY+e.screenY)+'px'),
};
const re=new CustomEvent('resizer',{'detail':detail,'cancelable':true});
if(this.dispatchEvent(re)){
console.log('resizer Event finished',detail.afterWidth,detail.afterHeight);
this.innerWidth=detail.afterWidth;
this.innerHeight=detail.afterHeight;
}
}
constructor(){
super();
this.attachShadow({mode:'open'});
this.shadowRoot.innerHTML=resizerHTML;
this.edgeL=this.shadowRoot.getElementById('edgeL');
this.edgeB=this.shadowRoot.getElementById('edgeB');
this.corner=this.shadowRoot.getElementById('corner');
this.addEventListener('mousedown',(e)=>{
let ct=e.currentTarget;
let bt=ct.shadowRoot.elementFromPoint(e.x,e.y);
ct.removeEventListener('mousemove',ct.resizering);
if(!([ct.edgeL,ct.edgeB,ct.corner].includes(bt)))return;
ct.setStartPos(e);
ct.addEventListener('mousemove',ct.resizering);
});
this.addEventListener('mouseup',(e)=>{
let ct=e.currentTarget;
ct.removeEventListener('mousemove',ct.resizering);
});
}
}
customElements.define('resize-er',ResizerElem);