1107 lines
44 KiB
HTML
1107 lines
44 KiB
HTML
<html>
|
|
<head>
|
|
<style>
|
|
@import url('https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200');
|
|
@import url("https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200");
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div style="height: 50px; width: 10000px; background-color: blue;"></div>
|
|
<button id="button"></button>
|
|
<span class="material-symbols-rounded">
|
|
close
|
|
</span>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
v
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
<p>Nice thanks man awesome</p>
|
|
|
|
|
|
<template id="x-widget-template">
|
|
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.0.0-rc.5/dist/html2canvas.min.js"></script>
|
|
|
|
<style>
|
|
@import url("https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200");
|
|
@import url("https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200");
|
|
|
|
* {
|
|
box-sizing: border-box;
|
|
--unit-spacing: 8px;
|
|
--icon-default-dim: 60px;
|
|
--form-default-width: 450px;
|
|
--form-default-height: 580px;
|
|
--side-margin: calc(var(--unit-spacing) * 2);
|
|
--site-falcon-purple-1: #AE55E7;
|
|
--site-falcon-purple-2: #a544e3;
|
|
--site-falcon-blue: #0098FF;
|
|
--site-falcon-red: #FF4031;
|
|
--site-falcon-grey-1: #ececec;
|
|
--site-falcon-grey-2: #e0e0e0;
|
|
--site-falcon-grey-3: #d3d3d3;
|
|
--site-falcon-grey-4: #5A5A5A;
|
|
--form-element-border-size: 2px;
|
|
--form-border-radius: var(--unit-spacing);
|
|
}
|
|
|
|
#icon {
|
|
width: var(--icon-default-dim);
|
|
height: var(--icon-default-dim);
|
|
position: fixed;
|
|
visibility: visible;
|
|
opacity: 1;
|
|
transition: top 0.3s ease 0s, left 0.3s ease 0s, scale 0.2s ease, transform 0.5s ease, visibility 0s linear 0.3s, opacity 0.3s linear;
|
|
}
|
|
|
|
#icon.location-top-left {
|
|
left: var(--side-margin);
|
|
top: var(--side-margin);
|
|
}
|
|
|
|
#icon.location-top-right {
|
|
left: calc(100% - var(--icon-default-dim) - var(--side-margin));
|
|
top: var(--side-margin);
|
|
}
|
|
|
|
#icon.location-bottom-left {
|
|
left: var(--side-margin);
|
|
top: calc(100% - var(--icon-default-dim) - var(--side-margin));
|
|
}
|
|
|
|
#icon.location-bottom-right {
|
|
left: calc(100% - var(--icon-default-dim) - var(--side-margin));
|
|
top: calc(100% - var(--icon-default-dim) - var(--side-margin));
|
|
}
|
|
|
|
#icon:hover {
|
|
scale: 1.05;
|
|
}
|
|
|
|
#icon > img {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
#form {
|
|
width: var(--form-default-width);
|
|
height: var(--form-default-height);
|
|
background-color: white;
|
|
border: 0px;
|
|
border-radius: var(--form-border-radius);
|
|
box-shadow: 0 calc(var(--unit-spacing) / 2) calc(var(--unit-spacing) * 2) rgb(0 0 0 / 25%);
|
|
position: fixed;
|
|
visibility: visible;
|
|
opacity: 1;
|
|
transition: transform 0.4s ease, visibility 0s linear 0.3s, opacity 0.3s linear;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
#form.location-top-left {
|
|
left: var(--side-margin);
|
|
top: var(--side-margin);
|
|
}
|
|
|
|
#form.location-top-right {
|
|
left: calc(100% - var(--form-default-width) - var(--side-margin));
|
|
top: var(--side-margin);
|
|
}
|
|
|
|
#form.location-bottom-left {
|
|
left: var(--side-margin);
|
|
top: calc(100% - var(--form-default-height) - var(--side-margin));
|
|
}
|
|
|
|
#form.location-bottom-right {
|
|
left: calc(100% - var(--form-default-width) - var(--side-margin));
|
|
top: calc(100% - var(--form-default-height) - var(--side-margin));
|
|
}
|
|
|
|
#form-header {
|
|
top: 0px;
|
|
width: 100%;
|
|
height: calc(var(--unit-spacing) * 8);
|
|
background-image: linear-gradient(var(--site-falcon-purple-2), var(--site-falcon-purple-1));
|
|
border-radius: var(--form-border-radius) var(--form-border-radius) 0px 0px;
|
|
border: 0px;
|
|
justify-content: center;
|
|
align-items: center;
|
|
display: flex;
|
|
}
|
|
|
|
.form-header-button {
|
|
cursor: pointer;
|
|
user-select: none;
|
|
color: white;
|
|
margin-left: calc(var(--unit-spacing) * 2);
|
|
font-size: 26px;
|
|
transition: scale 0.2s ease;
|
|
}
|
|
|
|
.form-header-button:hover {
|
|
scale: 1.1;
|
|
}
|
|
|
|
#form-button-help {
|
|
margin-left: calc(var(--unit-spacing) * 2);
|
|
}
|
|
|
|
#form-button-close {
|
|
margin-right: calc(var(--unit-spacing) * 2);
|
|
}
|
|
|
|
#form-title {
|
|
font-family: "Alexandria", sans-serif;
|
|
font-weight: 400;
|
|
font-size: 24px;
|
|
color: white;
|
|
text-align: center;
|
|
user-select: none;
|
|
flex-grow: 1;
|
|
}
|
|
|
|
#form-content-container {
|
|
width: 100%;
|
|
align-items: center;
|
|
padding-left: calc(var(--unit-spacing) * 4);
|
|
padding-right: calc(var(--unit-spacing) * 4);
|
|
padding: calc(var(--unit-spacing) * 4);
|
|
flex-grow: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
#input-name-container {
|
|
width: 100%;
|
|
position: relative;
|
|
}
|
|
|
|
.md-input {
|
|
width: 100%;
|
|
border: var(--form-element-border-size) solid var(--site-falcon-grey-3);
|
|
border-radius: calc(var(--unit-spacing) / 2);
|
|
padding: 16px;
|
|
}
|
|
|
|
#input-name {
|
|
height: calc(var(--unit-spacing) * 6);
|
|
}
|
|
|
|
.label-md-input {
|
|
position: absolute;
|
|
top: 0;
|
|
left: calc(var(--unit-spacing) * 2);
|
|
display: flex;
|
|
pointer-events: none;
|
|
}
|
|
|
|
#input-name + .label-md-input {
|
|
bottom: 0;
|
|
align-items: center;
|
|
}
|
|
|
|
#input-description + .label-md-input {
|
|
margin-top: calc(var(--unit-spacing) * 2);
|
|
}
|
|
|
|
#input-name:not(#input-name[value=""]), #input-description:not(#input-description[value=""]) {
|
|
font-size: 16px;
|
|
}
|
|
|
|
.md-input, .label-md-input > div {
|
|
font-family: "Alexandria", sans-serif;
|
|
font-weight: 300;
|
|
font-size: 16px;
|
|
}
|
|
|
|
.label-md-input > div {
|
|
transition: all 0.15s ease-out, visibility 0s;
|
|
color: grey;
|
|
}
|
|
|
|
.md-input:focus {
|
|
outline: none;
|
|
border: var(--form-element-border-size) solid var(--site-falcon-purple-1);
|
|
}
|
|
|
|
#input-name:focus + .label-md-input > div, #input-name:not(#input-name[value=""]) + .label-md-input > div {
|
|
font-size: 14px;
|
|
transform: translate(0, -150%);
|
|
background-color: white;
|
|
padding-left: calc(var(--unit-spacing) / 2);
|
|
padding-right: calc(var(--unit-spacing) / 2);
|
|
}
|
|
|
|
#input-description:focus + .label-md-input > div, #input-description:not(#input-description[value=""]) + .label-md-input > div {
|
|
font-size: 14px;
|
|
transform: translate(0, -150%);
|
|
background-color: white;
|
|
padding-left: calc(var(--unit-spacing) / 2);
|
|
padding-right: calc(var(--unit-spacing) / 2);
|
|
}
|
|
|
|
.md-input:focus + .label-md-input > div {
|
|
color: var(--site-falcon-purple-1);
|
|
}
|
|
|
|
#select-severity-container {
|
|
width: 100%;
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr 1fr 1fr;
|
|
grid-column-gap: 0px;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
|
|
.severity-option {
|
|
margin: 0px;
|
|
height: calc(var(--unit-spacing) * 6);
|
|
background-color: var(--site-falcon-grey-1);
|
|
border: var(--form-element-border-size) solid var(--site-falcon-grey-3);
|
|
border-left: 0px;
|
|
display: flex;
|
|
flex-direction: row;
|
|
justify-content: center;
|
|
align-items: center;
|
|
cursor: pointer;
|
|
user-select: none;
|
|
transition: background-color 0.15s ease;
|
|
}
|
|
|
|
.severity-option .material-symbols-rounded {
|
|
color: var(--site-falcon-grey-4);
|
|
font-size: 26px;
|
|
}
|
|
|
|
.severity-option .material-symbols-rounded:not(:first-child) {
|
|
margin-left: -14px;
|
|
}
|
|
|
|
.severity-option:hover:not(.selected) {
|
|
background-color: var(--site-falcon-grey-2);
|
|
}
|
|
|
|
.severity-option.selected {
|
|
background-color: var(--site-falcon-grey-3);
|
|
}
|
|
|
|
#select-severity-container > :first-child {
|
|
border-left: var(--form-element-border-size) solid var(--site-falcon-grey-3);
|
|
border-radius: calc(var(--unit-spacing) / 2) 0px 0px calc(var(--unit-spacing) / 2);
|
|
}
|
|
|
|
#select-severity-container :last-child {
|
|
border-radius: 0px calc(var(--unit-spacing) / 2) calc(var(--unit-spacing) / 2) 0px;
|
|
}
|
|
|
|
#input-description-container {
|
|
width: 100%;
|
|
position: relative;
|
|
}
|
|
|
|
#input-description {
|
|
height: calc(var(--unit-spacing) * 19);
|
|
resize: none;
|
|
}
|
|
|
|
#icon:not(.hidden), #form:not(.hidden) {
|
|
transition-delay: 0s;
|
|
}
|
|
|
|
#icon.hidden, #form.hidden {
|
|
pointer-events: none;
|
|
visibility: hidden;
|
|
opacity: 0;
|
|
}
|
|
|
|
#icon.hidden.location-bottom-left, #form.hidden.location-bottom-left,
|
|
#icon.hidden.location-bottom-right, #form.hidden.location-bottom-right {
|
|
transform: translateY(100%);
|
|
}
|
|
|
|
#icon.hidden.location-top-left, #form.hidden.location-top-left,
|
|
#icon.hidden.location-top-right, #form.hidden.location-top-right {
|
|
transform: translateY(-100%);
|
|
}
|
|
|
|
#icon.hidden {
|
|
scale: 1.05;
|
|
}
|
|
|
|
#container-snapshot {
|
|
width: 100%;
|
|
display: grid;
|
|
grid-template-columns: 1fr;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
|
|
#container-snapshot.snapshot-taken {
|
|
grid-template-columns: 7fr 1fr 1fr;
|
|
}
|
|
|
|
#container-snapshot .material-symbols-rounded.snapshot-taken {
|
|
display: block;
|
|
}
|
|
|
|
#container-snapshot .material-symbols-rounded:hover {
|
|
cursor: pointer;
|
|
}
|
|
|
|
#button-snapshot {
|
|
width: 100%;
|
|
height: calc(var(--unit-spacing) * 6);
|
|
border-radius: calc(var(--unit-spacing) / 2);
|
|
border: var(--form-element-border-size) dashed var(--site-falcon-grey-3);
|
|
background-color: var(--site-falcon-grey-1);
|
|
color: var(--site-falcon-grey-4);
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
cursor: pointer;
|
|
user-select: none;
|
|
transition: background-color 0.15s ease;
|
|
}
|
|
|
|
#button-snapshot .material-symbols-outlined {
|
|
font-size: 30px;
|
|
}
|
|
|
|
#button-snapshot:hover {
|
|
background-color: var(--site-falcon-grey-3);
|
|
}
|
|
|
|
#container-snapshot > .material-symbols-rounded {
|
|
display: none;
|
|
margin-left: auto;
|
|
font-size: 30px;
|
|
}
|
|
|
|
#button-view-snapshot {
|
|
color: var(--site-falcon-blue);
|
|
}
|
|
|
|
#button-delete-snapshot {
|
|
color: var(--site-falcon-red);
|
|
}
|
|
|
|
#name-snapshot {
|
|
margin-left: auto;
|
|
font-family: "Alexandria", sans-serif;
|
|
font-weight: 400;
|
|
font-size: 24px;
|
|
color: green;
|
|
text-align: right;
|
|
user-select: none;
|
|
}
|
|
|
|
#footer-buttons-container {
|
|
width: 100%;
|
|
display: flex;
|
|
flex-direction: row;
|
|
}
|
|
|
|
#footer-buttons-container .form-footer-button {
|
|
width: 45%;
|
|
height: calc(var(--unit-spacing) * 6);
|
|
border-radius: calc(var(--unit-spacing) / 2);
|
|
font-family: "Alexandria", sans-serif;
|
|
font-weight: 400;
|
|
font-size: 20px;
|
|
border: 0px;
|
|
cursor: pointer;
|
|
user-select: none;
|
|
transition: background-color 0.15s ease;
|
|
}
|
|
|
|
#button-clear-form {
|
|
margin-right: auto;
|
|
color: var(--site-falcon-grey-4);
|
|
background-color: var(--site-falcon-grey-1);
|
|
}
|
|
|
|
#button-clear-form:hover {
|
|
background-color: var(--site-falcon-grey-2);
|
|
}
|
|
|
|
#button-submit {
|
|
margin-left: auto;
|
|
color: white;
|
|
background-color: var(--site-falcon-purple-1);
|
|
}
|
|
|
|
#button-submit:hover {
|
|
background-color: var(--site-falcon-purple-2);
|
|
}
|
|
|
|
#canvas-snapshot {
|
|
position: fixed;
|
|
left: 0px;
|
|
top: 0px;
|
|
width: 100%;
|
|
height: 100%;
|
|
visibility: hidden;
|
|
cursor: crosshair;
|
|
}
|
|
|
|
#canvas-snapshot.visible {
|
|
visibility: visible;
|
|
}
|
|
</style>
|
|
|
|
<canvas id="canvas-snapshot">
|
|
|
|
</canvas>
|
|
|
|
<div id="icon">
|
|
<img src="icon_open.png">
|
|
</div>
|
|
|
|
<div id="form">
|
|
<div id="form-header">
|
|
<span id="form-button-help" class="material-symbols-rounded form-header-button">
|
|
help
|
|
</span>
|
|
<div id="form-title">
|
|
New Ticket
|
|
</div>
|
|
<span id="form-button-close" class="material-symbols-rounded form-header-button">
|
|
close
|
|
</span>
|
|
</div>
|
|
<div id="form-content-container">
|
|
<div id="select-severity-container">
|
|
<div title="General Comment" class="severity-option selected" id="option-no-severity">
|
|
<span class="material-symbols-rounded">
|
|
info
|
|
</span>
|
|
</div>
|
|
<div title="Low Priority" class="severity-option" id="option-low-severity">
|
|
<span class="material-symbols-rounded">
|
|
priority_high
|
|
</span>
|
|
</div>
|
|
<div title="Medium Priority" class="severity-option" id="option-medium-severity">
|
|
<span class="material-symbols-rounded">
|
|
priority_high
|
|
</span>
|
|
<span class="material-symbols-rounded">
|
|
priority_high
|
|
</span>
|
|
</div>
|
|
<div title="High Priority" class="severity-option" id="option-high-severity">
|
|
<span class="material-symbols-rounded">
|
|
priority_high
|
|
</span>
|
|
<span class="material-symbols-rounded">
|
|
priority_high
|
|
</span>
|
|
<span class="material-symbols-rounded">
|
|
priority_high
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div id="input-name-container">
|
|
<input
|
|
type="text"
|
|
id="input-name"
|
|
class="md-input"
|
|
name="name"
|
|
value=""
|
|
aria-labelledby="label-input-name"
|
|
/>
|
|
<label for="name" class="label-md-input">
|
|
<div>Name</div>
|
|
</label>
|
|
</div>
|
|
<div id="input-description-container">
|
|
<textarea
|
|
type="text"
|
|
id="input-description"
|
|
class="md-input"
|
|
name="description"
|
|
value=""
|
|
aria-labelledby="label-input-description"
|
|
></textarea>
|
|
<label for="description" class="label-md-input">
|
|
<div>Description</div>
|
|
</label>
|
|
</div>
|
|
<div id="container-snapshot">
|
|
<button id="button-snapshot" class="taken">
|
|
<span class="material-symbols-outlined">
|
|
photo_camera
|
|
</span>
|
|
</button>
|
|
<span id="button-view-snapshot" class="material-symbols-rounded">
|
|
image
|
|
</span>
|
|
<span id="button-delete-snapshot" class="material-symbols-rounded">
|
|
delete
|
|
</span>
|
|
</div>
|
|
<div id="footer-buttons-container">
|
|
<button id="button-clear-form" class="form-footer-button">
|
|
Clear
|
|
</button>
|
|
<button id="button-submit" class="form-footer-button">
|
|
Submit
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
class XWidget extends HTMLElement {
|
|
#icon;
|
|
#form;
|
|
#canvas;
|
|
#canvasCtx;
|
|
#location;
|
|
|
|
constructor() {
|
|
super();
|
|
|
|
const shadowRoot = this.attachShadow({mode: 'open'});
|
|
shadowRoot.appendChild(document.getElementById("x-widget-template").content.cloneNode(true));
|
|
|
|
this.#icon = this.#createIcon();
|
|
this.#form = this.#createForm();
|
|
this.#canvas = this.#createCanvas();
|
|
this.#canvasCtx = this.#canvas.getContext("2d");
|
|
|
|
this.#location = "bottom-right";
|
|
}
|
|
|
|
connectedCallback() {
|
|
this.#renderInitial();
|
|
}
|
|
|
|
#renderInitial() {
|
|
if (this.isConnected) {
|
|
this.#renderIcon({visibility: "visible"});
|
|
this.#renderForm({visibility: "hidden"});
|
|
}
|
|
}
|
|
|
|
#createIcon() {
|
|
let icon = this.shadowRoot.getElementById("icon");
|
|
|
|
icon.addEventListener("pointerdown", (e) => this.#onIconPointerDown(e));
|
|
icon.addEventListener("pointermove", (e) => this.#onIconPointerMove(e));
|
|
icon.addEventListener("pointerup", (e) => this.#onIconPointerUp(e));
|
|
icon.addEventListener("pointerover", (e) => this.#onIconPointerOver(e));
|
|
icon.addEventListener("pointerout", (e) => this.#onIconPointerOut(e));
|
|
|
|
icon.pointerDown = false;
|
|
icon.moving = false;
|
|
|
|
return icon;
|
|
}
|
|
|
|
#createCanvas() {
|
|
let canvas = this.shadowRoot.getElementById("canvas-snapshot");
|
|
|
|
canvas.addEventListener("pointerdown", (e) => this.#onCanvasPointerDown(e));
|
|
canvas.addEventListener("pointermove", (e) => this.#onCanvasPointerMove(e));
|
|
canvas.addEventListener("pointerup", async (e) => await this.#onCanvasPointerUpAsync(e));
|
|
|
|
canvas.pointerDown = null;
|
|
canvas.initialX = null;
|
|
canvas.initialY = null;
|
|
|
|
return canvas;
|
|
}
|
|
|
|
#createForm() {
|
|
let form = this.shadowRoot.getElementById("form");
|
|
|
|
let buttonHelp = this.shadowRoot.getElementById("form-button-help");
|
|
buttonHelp.addEventListener("click", (e) => this.#onFormHelpButtonClicked(e));
|
|
|
|
let buttonClose = this.shadowRoot.getElementById("form-button-close");
|
|
buttonClose.addEventListener("click", (e) => this.#onFormCloseButtonClicked(e));
|
|
|
|
let inputName = this.shadowRoot.getElementById("input-name");
|
|
inputName.addEventListener("input", (e) => this.#onNameInput(e));
|
|
|
|
let selectSeverityContainer = this.shadowRoot.getElementById("select-severity-container");
|
|
|
|
for (let i = 0; i < selectSeverityContainer.childElementCount; i++) {
|
|
let severityOption = selectSeverityContainer.children[i];
|
|
severityOption.addEventListener("click", (e) => this.#OnSeverityOptionClicked(e));
|
|
}
|
|
|
|
let inputDescription = this.shadowRoot.getElementById("input-description");
|
|
inputDescription.addEventListener("input", (e) => this.#onDescriptionInput(e));
|
|
|
|
let buttonSnapshot = this.shadowRoot.getElementById("button-snapshot");
|
|
buttonSnapshot.addEventListener("click", (e) => this.#onsnapshotButtonClicked(e));
|
|
|
|
let buttonViewSnapshot = this.shadowRoot.getElementById("button-view-snapshot");
|
|
buttonSnapshot.addEventListener("click", (e) => this.#onViewSnapshotButtonClicked(e));
|
|
|
|
let buttonDeleteSnapshot = this.shadowRoot.getElementById("button-delete-snapshot");
|
|
buttonDeleteSnapshot.addEventListener("click", (e) => this.#onDeleteSnapshotButtonClicked(e));
|
|
|
|
let buttonClearForm = this.shadowRoot.getElementById("button-clear-form");
|
|
buttonClearForm.addEventListener("click", (e) => this.#onClearFormButtonClicked(e));
|
|
|
|
let buttonSubmit = this.shadowRoot.getElementById("button-submit");
|
|
buttonSubmit.addEventListener("click", (e) => this.#onSubmitButtonClicked(e));
|
|
|
|
return form;
|
|
}
|
|
|
|
#renderIcon(parameters={}) {
|
|
if (this.#location == "top-left") {
|
|
removeClassByPrefix(this.#icon, "location");
|
|
this.#icon.classList.add("location-top-left");
|
|
}
|
|
else if (this.#location == "top-right") {
|
|
removeClassByPrefix(this.#icon, "location");
|
|
this.#icon.classList.add("location-top-right");
|
|
}
|
|
else if (this.#location == "bottom-left") {
|
|
removeClassByPrefix(this.#icon, "location");
|
|
this.#icon.classList.add("location-bottom-left");
|
|
}
|
|
else if (this.#location == "bottom-right") {
|
|
removeClassByPrefix(this.#icon, "location");
|
|
this.#icon.classList.add("location-bottom-right");
|
|
}
|
|
|
|
if (parameters["visibility"]) {
|
|
if (parameters["visibility"] == "visible") {
|
|
this.#icon.classList.remove("hidden");
|
|
}
|
|
else if (parameters["visibility"] == "hidden") {
|
|
this.#icon.classList.add("hidden");
|
|
}
|
|
}
|
|
}
|
|
|
|
#renderForm(parameters={}) {
|
|
if (this.#location == "top-left") {
|
|
removeClassByPrefix(this.#form, "location");
|
|
this.#form.classList.add("location-top-left");
|
|
} else if (this.#location == "top-right") {
|
|
removeClassByPrefix(this.#form, "location");
|
|
this.#form.classList.add("location-top-right");
|
|
} else if (this.#location == "bottom-left") {
|
|
removeClassByPrefix(this.#form, "location");
|
|
this.#form.classList.add("location-bottom-left");
|
|
} else if (this.#location == "bottom-right") {
|
|
removeClassByPrefix(this.#form, "location");
|
|
this.#form.classList.add("location-bottom-right");
|
|
}
|
|
|
|
if (parameters["visibility"]) {
|
|
if (parameters["visibility"] == "visible") {
|
|
this.#form.classList.remove("hidden");
|
|
}
|
|
else if (parameters["visibility"] == "hidden") {
|
|
this.#form.classList.add("hidden");
|
|
}
|
|
}
|
|
}
|
|
|
|
#onFormHelpButtonClicked(e) {
|
|
console.log("help pressed");
|
|
}
|
|
|
|
#onFormCloseButtonClicked(e) {
|
|
if (!this.#form.classList.contains("hidden")) {
|
|
this.#renderIcon({visibility: "visible"});
|
|
this.#renderForm({visibility: "hidden"});
|
|
}
|
|
}
|
|
|
|
#onNameInput(e) {
|
|
let inputName = this.shadowRoot.getElementById("input-name");
|
|
|
|
inputName.setAttribute('value', inputName.value);
|
|
}
|
|
|
|
#onDescriptionInput(e) {
|
|
let inputDescription = this.shadowRoot.getElementById("input-description");
|
|
|
|
inputDescription.setAttribute('value', inputDescription.value);
|
|
}
|
|
|
|
#OnSeverityOptionClicked(e) {
|
|
let selectedSeverityOption = e.currentTarget;
|
|
|
|
let selectSeverityContainer = this.shadowRoot.getElementById("select-severity-container");
|
|
|
|
for (let i = 0; i < selectSeverityContainer.childElementCount; i++) {
|
|
let severityOption = selectSeverityContainer.children[i];
|
|
|
|
if (severityOption == selectedSeverityOption) {
|
|
if (!severityOption.classList.contains("selected")) {
|
|
severityOption.classList.add("selected");
|
|
}
|
|
}
|
|
else {
|
|
severityOption.classList.remove("selected");
|
|
}
|
|
}
|
|
}
|
|
|
|
#onsnapshotButtonClicked(e) {
|
|
this.#renderIcon({visibility: "visible"});
|
|
this.#renderForm({visibility: "hidden"});
|
|
|
|
this.#setBlankCanvas();
|
|
this.#canvas.classList.add("visible");
|
|
}
|
|
|
|
#setBlankCanvas() {
|
|
this.#canvas.width = this.#canvas.clientWidth;
|
|
this.#canvas.height = this.#canvas.clientHeight;
|
|
|
|
this.#canvasCtx.clearRect(0, 0, this.#canvas.width, this.#canvas.height);
|
|
|
|
this.#canvasCtx.globalAlpha = 0.5;
|
|
this.#canvasCtx.fillStyle = "white";
|
|
this.#canvasCtx.beginPath();
|
|
this.#canvasCtx.rect(0, 0, this.#canvas.width, this.#canvas.height);
|
|
this.#canvasCtx.fill();
|
|
this.#canvasCtx.closePath();
|
|
|
|
this.#setCanvasBrush("red");
|
|
}
|
|
|
|
#setCanvasBrush(colour) {
|
|
this.#canvasCtx.globalAlpha = 1;
|
|
this.#canvasCtx.strokeStyle = colour;
|
|
}
|
|
|
|
#onCanvasPointerDown(e) {
|
|
if (e.button !== 0) {
|
|
return;
|
|
}
|
|
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
this.#canvas.initialX = e.offsetX;
|
|
this.#canvas.initialY = e.offsetY;
|
|
this.#canvas.pointerDown = true;
|
|
|
|
this.#renderIcon({visibility: "hidden"});
|
|
|
|
this.#canvas.setPointerCapture(e.pointerId);
|
|
}
|
|
|
|
#onCanvasPointerMove(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
if (this.#canvas.pointerDown) {
|
|
let offsetX;
|
|
let offsetY;
|
|
|
|
if (e.offsetX < 0) {
|
|
offsetX = 0;
|
|
}
|
|
else if (e.offsetX > this.#canvas.width - 1) {
|
|
offsetX = this.#canvas.width - 1;
|
|
}
|
|
else {
|
|
offsetX = e.offsetX;
|
|
}
|
|
|
|
if (e.offsetY < 0) {
|
|
offsetY = 0;
|
|
}
|
|
else if (e.offsetY > this.#canvas.height - 1) {
|
|
offsetY = this.#canvas.height - 1;
|
|
}
|
|
else {
|
|
offsetY = e.offsetY;
|
|
}
|
|
|
|
let width = offsetX - this.#canvas.initialX;
|
|
let height = offsetY - this.#canvas.initialY;
|
|
|
|
this.#setBlankCanvas();
|
|
this.#canvasCtx.beginPath();
|
|
this.#canvasCtx.clearRect(this.#canvas.initialX, this.#canvas.initialY, width, height);
|
|
this.#canvasCtx.rect(this.#canvas.initialX, this.#canvas.initialY, width, height);
|
|
this.#canvasCtx.stroke();
|
|
this.#canvasCtx.closePath();
|
|
}
|
|
}
|
|
|
|
async #onCanvasPointerUpAsync(e) {
|
|
if (e.button !== 0) {
|
|
return;
|
|
}
|
|
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
if (this.#canvas.pointerDown) {
|
|
let offsetX;
|
|
let offsetY;
|
|
|
|
if (e.offsetX < 0) {
|
|
offsetX = 0;
|
|
}
|
|
else if (e.offsetX > this.#canvas.width - 1) {
|
|
offsetX = this.#canvas.width - 1;
|
|
}
|
|
else {
|
|
offsetX = e.offsetX;
|
|
}
|
|
|
|
if (e.offsetY < 0) {
|
|
offsetY = 0;
|
|
}
|
|
else if (e.offsetY > this.#canvas.height - 1) {
|
|
offsetY = this.#canvas.height - 1;
|
|
}
|
|
else {
|
|
offsetY = e.offsetY;
|
|
}
|
|
|
|
if (Math.abs(offsetX - this.#canvas.initialX) > 10 && Math.abs(offsetY - this.#canvas.initialY) > 10) {
|
|
await this.#takeSnapshotAsync(offsetX, offsetY);
|
|
|
|
this.shadowRoot.getElementById("container-snapshot").classList.add("snapshot-taken");
|
|
this.shadowRoot.getElementById("button-view-snapshot").classList.add("snapshot-taken");
|
|
this.shadowRoot.getElementById("button-delete-snapshot").classList.add("snapshot-taken");
|
|
}
|
|
|
|
this.#canvas.initialX = null;
|
|
this.#canvas.initialY = null;
|
|
this.#canvas.pointerDown = false;
|
|
|
|
this.#canvas.classList.remove("visible");
|
|
this.#setBlankCanvas();
|
|
this.#renderForm({visibility: "visible"});
|
|
}
|
|
}
|
|
|
|
async #takeSnapshotAsync(offsetX, offsetY) {
|
|
let snapshotCanvas = await html2canvas(document.body, {
|
|
width: Math.abs(this.#canvas.initialX - offsetX),
|
|
height: Math.abs(this.#canvas.initialY - offsetY),
|
|
x: Math.min(this.#canvas.initialX, offsetX),
|
|
y: Math.min(this.#canvas.initialY, offsetY)
|
|
})
|
|
|
|
let base64image = snapshotCanvas.toDataURL("image/png");
|
|
|
|
// var image = new Image();
|
|
// image.src = base64image;
|
|
|
|
// var w = window.open("_blank");
|
|
// w.document.write(image.outerHTML);
|
|
}
|
|
|
|
#onViewSnapshotButtonClicked(e) {
|
|
|
|
}
|
|
|
|
#onDeleteSnapshotButtonClicked(e) {
|
|
this.#deleteSnapshot();
|
|
}
|
|
|
|
#deleteSnapshot() {
|
|
this.shadowRoot.getElementById("container-snapshot").classList.remove("snapshot-taken");
|
|
this.shadowRoot.getElementById("button-view-snapshot").classList.remove("snapshot-taken");
|
|
this.shadowRoot.getElementById("button-delete-snapshot").classList.remove("snapshot-taken");
|
|
}
|
|
|
|
#onClearFormButtonClicked(e){
|
|
let inputName = this.shadowRoot.getElementById("input-name");
|
|
inputName.setAttribute("value", "");
|
|
inputName.value = null;
|
|
|
|
this.#resetForm();
|
|
}
|
|
|
|
#onSubmitButtonClicked(e) {
|
|
this.#renderIcon({visibility: "visible"});
|
|
this.#renderForm({visibility: "hidden"});
|
|
this.#resetForm();
|
|
}
|
|
|
|
#resetForm() {
|
|
let selectSeverityContainer = this.shadowRoot.getElementById("select-severity-container");
|
|
|
|
selectSeverityContainer.children[0].classList.add("selected");
|
|
|
|
for (let i = 1; i < selectSeverityContainer.childElementCount; i++) {
|
|
let severityOption = selectSeverityContainer.children[i];
|
|
severityOption.classList.remove("selected");
|
|
}
|
|
|
|
let inputDescription = this.shadowRoot.getElementById("input-description");
|
|
inputDescription.setAttribute("value", "");
|
|
inputDescription.value = null;
|
|
|
|
this.#deleteSnapshot();
|
|
}
|
|
|
|
#onIconPointerOver(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
}
|
|
|
|
#onIconPointerOut(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
}
|
|
|
|
#onIconPointerDown(e) {
|
|
if (e.button !== 0) {
|
|
return;
|
|
}
|
|
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
this.#icon.pointerDown = true;
|
|
|
|
this.#icon.setPointerCapture(e.pointerId);
|
|
}
|
|
|
|
#onIconPointerMove(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
if (this.#icon.pointerDown) {
|
|
this.#icon.moving = true;
|
|
this.#icon.style.cursor = "grabbing";
|
|
this.#snapToCorner(e.clientX, e.clientY);
|
|
}
|
|
else {
|
|
this.#icon.style.cursor = "pointer";
|
|
}
|
|
}
|
|
|
|
#onIconPointerUp(e) {
|
|
if (e.button !== 0) {
|
|
return;
|
|
}
|
|
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
this.#icon.style.cursor = "pointer";
|
|
this.#canvas.classList.remove("visible");
|
|
|
|
if (this.#icon.pointerDown && !this.#icon.moving) {
|
|
if (this.#form.classList.contains("hidden")) {
|
|
this.#renderIcon({visibility: "hidden"});
|
|
this.#renderForm({visibility: "visible"});
|
|
}
|
|
}
|
|
else {
|
|
this.#icon.moving = false;
|
|
}
|
|
|
|
this.#icon.pointerDown = false;
|
|
|
|
this.#icon.releasePointerCapture(e.pointerId);
|
|
}
|
|
|
|
#snapToCorner(anchorX, anchorY) {
|
|
let locationChanged = false;
|
|
|
|
if (anchorX < window.innerWidth / 2) {
|
|
if (this.#location != "top-left" && anchorY < window.innerHeight / 2) {
|
|
this.#location = "top-left";
|
|
locationChanged = true;
|
|
}
|
|
else if (this.#location != "bottom-left" && anchorY > window.innerHeight - window.innerHeight / 2) {
|
|
this.#location = "bottom-left";
|
|
locationChanged = true;
|
|
}
|
|
}
|
|
else if (anchorX > window.innerWidth - window.innerWidth / 2) {
|
|
if (this.#location != "top-right" && anchorY < window.innerHeight / 2) {
|
|
this.#location = "top-right";
|
|
locationChanged = true;
|
|
}
|
|
else if (this.#location != "bottom-right" && anchorY > window.innerHeight - window.innerHeight / 2) {
|
|
this.#location = "bottom-right";
|
|
locationChanged = true;
|
|
}
|
|
}
|
|
|
|
if (locationChanged) {
|
|
this.#renderIcon({visibility: "visible"});
|
|
this.#renderForm({visibility: "hidden"});
|
|
}
|
|
}
|
|
}
|
|
|
|
function removeClassByPrefix(el, prefix) {
|
|
if (!el.classList) {
|
|
return;
|
|
}
|
|
|
|
let filteredClassList = [];
|
|
|
|
for (let i = 0; i < el.classList.length; i++) {
|
|
if (!el.classList[i].startsWith(prefix)) {
|
|
filteredClassList.push(el.classList[i])
|
|
}
|
|
}
|
|
|
|
el.className = "";
|
|
|
|
for (let i = 0; i < filteredClassList.length; i++) {
|
|
el.classList.add(filteredClassList[i]);
|
|
}
|
|
|
|
let dsf = el;
|
|
let dsg = "";
|
|
}
|
|
|
|
customElements.define("x-widget", XWidget);
|
|
document.body.appendChild(document.createElement("x-widget"));
|
|
</script>
|
|
</body>
|
|
</html> |