Eduard Kuzmenko
4 years ago
6 changed files with 395 additions and 21 deletions
@ -0,0 +1,86 @@ |
|||||||
|
import { generatePathData } from "../../helpers/dom"; |
||||||
|
|
||||||
|
export default class ChatDragAndDrop { |
||||||
|
container: HTMLDivElement; |
||||||
|
svg: SVGSVGElement; |
||||||
|
outlineWrapper: HTMLDivElement; |
||||||
|
path: SVGPathElement; |
||||||
|
|
||||||
|
constructor(appendTo: HTMLElement, private options: { |
||||||
|
icon: string, |
||||||
|
header: string, |
||||||
|
subtitle: string, |
||||||
|
onDrop: (e: DragEvent) => void |
||||||
|
}) { |
||||||
|
this.container = document.createElement('div'); |
||||||
|
this.container.classList.add('drop', 'z-depth-1'); |
||||||
|
|
||||||
|
this.outlineWrapper = document.createElement('div'); |
||||||
|
this.outlineWrapper.classList.add('drop-outline-wrapper'); |
||||||
|
|
||||||
|
this.svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); |
||||||
|
this.svg.classList.add('drop-outline'); |
||||||
|
|
||||||
|
this.path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); |
||||||
|
this.path.classList.add('drop-outline-path'); |
||||||
|
|
||||||
|
const dropIcon = document.createElement('div'); |
||||||
|
dropIcon.classList.add('drop-icon', 'tgico-' + options.icon); |
||||||
|
|
||||||
|
const dropHeader = document.createElement('div'); |
||||||
|
dropHeader.classList.add('drop-header'); |
||||||
|
dropHeader.innerHTML = options.header;//'Drop files here to send them';
|
||||||
|
|
||||||
|
const dropSubtitle = document.createElement('div'); |
||||||
|
dropSubtitle.classList.add('drop-subtitle'); |
||||||
|
dropSubtitle.innerHTML = options.subtitle;//'without compression';
|
||||||
|
|
||||||
|
this.svg.append(this.path); |
||||||
|
this.outlineWrapper.append(this.svg); |
||||||
|
|
||||||
|
this.container.append(this.outlineWrapper, dropIcon, dropHeader, dropSubtitle); |
||||||
|
appendTo.append(this.container); |
||||||
|
|
||||||
|
this.container.addEventListener('dragover', this.onDragOver); |
||||||
|
this.container.addEventListener('dragleave', this.onDragLeave); |
||||||
|
this.container.addEventListener('drop', this.onDrop); |
||||||
|
} |
||||||
|
|
||||||
|
onDragOver = (e: DragEvent) => { |
||||||
|
this.container.classList.add('is-dragover'); |
||||||
|
//SetTransition(this.container, 'is-dragover', true, 500);
|
||||||
|
}; |
||||||
|
|
||||||
|
onDragLeave = (e: DragEvent) => { |
||||||
|
this.container.classList.remove('is-dragover'); |
||||||
|
//SetTransition(this.container, 'is-dragover', false, 500);
|
||||||
|
}; |
||||||
|
|
||||||
|
onDrop = (e: DragEvent) => { |
||||||
|
this.options.onDrop(e); |
||||||
|
}; |
||||||
|
|
||||||
|
destroy() { |
||||||
|
delete this.options; |
||||||
|
this.container.remove(); |
||||||
|
this.container.removeEventListener('dragover', this.onDragOver); |
||||||
|
this.container.removeEventListener('dragleave', this.onDragLeave); |
||||||
|
this.container.removeEventListener('drop', this.onDrop); |
||||||
|
} |
||||||
|
|
||||||
|
setPath() { |
||||||
|
const rect = this.outlineWrapper.getBoundingClientRect(); |
||||||
|
this.svg.setAttributeNS(null, 'preserveAspectRatio', 'none'); |
||||||
|
this.svg.setAttributeNS(null, 'viewBox', `0 0 ${rect.width} ${rect.height}`); |
||||||
|
this.svg.setAttributeNS(null, 'width', `${rect.width}`); |
||||||
|
this.svg.setAttributeNS(null, 'height', `${rect.height}`); |
||||||
|
|
||||||
|
const radius = 10; |
||||||
|
//const strokeWidth = 2;
|
||||||
|
const sizeX = rect.width - radius; |
||||||
|
const sizeY = rect.height - radius; |
||||||
|
const pos = radius / 2; |
||||||
|
const d = generatePathData(pos, pos, sizeX, sizeY, radius, radius, radius, radius); |
||||||
|
this.path.setAttributeNS(null, 'd', d); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,123 @@ |
|||||||
|
.drops-container { |
||||||
|
--padding: 20px; |
||||||
|
--pinned-floating-height: 0px; |
||||||
|
position: absolute !important; |
||||||
|
z-index: 3; |
||||||
|
top: calc(56px + var(--pinned-floating-height) + var(--padding)); |
||||||
|
right: var(--padding); |
||||||
|
bottom: var(--padding); |
||||||
|
left: var(--padding); |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
user-select: none; |
||||||
|
width: auto !important; |
||||||
|
|
||||||
|
@include respond-to(medium-screens) { |
||||||
|
//transition: transform var(--layer-transition); |
||||||
|
|
||||||
|
body.is-right-column-shown & { |
||||||
|
//left: calc(var(--right-column-width) / -2); |
||||||
|
right: calc(var(--right-column-width)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@include respond-to(handhelds) { |
||||||
|
--padding: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
&:not(.is-visible) { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
&.is-visible { |
||||||
|
animation: fade-in-opacity .2s linear forwards; |
||||||
|
|
||||||
|
&.backwards { |
||||||
|
animation: fade-in-backwards-opacity .2s linear forwards; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.drop { |
||||||
|
background-color: #fff; |
||||||
|
position: relative; |
||||||
|
//height: 100%; |
||||||
|
border-radius: $border-radius-big; |
||||||
|
width: 100%; |
||||||
|
max-width: 696px; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
color: #a2acb4; |
||||||
|
transition: color .2s ease-in-out; |
||||||
|
pointer-events: all; |
||||||
|
flex: 1 1 auto; |
||||||
|
|
||||||
|
&-outline { |
||||||
|
&-wrapper { |
||||||
|
position: absolute; |
||||||
|
top: 19px; |
||||||
|
right: 19px; |
||||||
|
bottom: 19px; |
||||||
|
left: 19px; |
||||||
|
pointer-events: none; |
||||||
|
} |
||||||
|
|
||||||
|
&-path { |
||||||
|
fill: none; |
||||||
|
stroke-dasharray: 13.5, 11; |
||||||
|
stroke: #a2acb4; |
||||||
|
stroke-width: 2; |
||||||
|
stroke-linecap: round; |
||||||
|
transition: stroke .2s ease-in-out; |
||||||
|
stroke-dashoffset: 0; |
||||||
|
|
||||||
|
.drop.is-dragover & { |
||||||
|
animation: drop-outline-move .5s linear infinite; |
||||||
|
stroke: $color-blue; |
||||||
|
} |
||||||
|
|
||||||
|
/* .drop.is-dragover.backwards & { |
||||||
|
//animation: drop-outline-backwards-move .5s linear forwards; |
||||||
|
animation-direction: reverse; |
||||||
|
animation-fill-mode: forwards; |
||||||
|
} */ |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
&-icon { |
||||||
|
font-size: 6rem; |
||||||
|
} |
||||||
|
|
||||||
|
&-header { |
||||||
|
font-weight: 500; |
||||||
|
font-size: 1.25rem; |
||||||
|
} |
||||||
|
|
||||||
|
&.is-dragover { |
||||||
|
color: $color-blue; |
||||||
|
} |
||||||
|
|
||||||
|
& + & { |
||||||
|
margin-top: 10px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@keyframes drop-outline-move { |
||||||
|
0% { |
||||||
|
stroke-dashoffset: 0; |
||||||
|
} |
||||||
|
|
||||||
|
100% { |
||||||
|
stroke-dashoffset: -24.5; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
body.is-dragging { |
||||||
|
.page-chats { |
||||||
|
pointer-events: none; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue