mirror of
https://github.com/kevinveenbirkenbach/roulette-wheel.git
synced 2024-11-24 03:01:04 +01:00
add wheel & colors change & delete items fix & add item animation
This commit is contained in:
parent
9649216920
commit
0f955e3ce2
120
app.css
120
app.css
@ -1,60 +1,42 @@
|
|||||||
html {
|
body {
|
||||||
font-family: 'Courier New', Courier, monospace;
|
background-color: #121212;
|
||||||
|
color: snow;
|
||||||
|
transition-duration: 3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
canvas{
|
||||||
|
margin-left: 5rem;
|
||||||
|
height: 50rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
font-family: "Courier New", Courier, monospace;
|
||||||
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
height: 1.5rem;
|
height: 1.5rem;
|
||||||
width: 15rem;
|
width: 15rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul {
|
|
||||||
list-style-type: none;
|
|
||||||
padding: 0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
li {
|
li {
|
||||||
padding: 0.75rem;
|
padding: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.open-close-menu{
|
ul {
|
||||||
display: flex;
|
padding: 0;
|
||||||
justify-content: right;
|
list-style-type: none;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.open-close-arrow {
|
.add-item-button {
|
||||||
width: 1rem;
|
|
||||||
height: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item-delete {
|
|
||||||
width: 1rem;
|
|
||||||
height: 1rem;
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.decreasing {
|
|
||||||
width: 0.1rem;
|
|
||||||
transition-duration: 3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.normal {
|
|
||||||
width: 20rem;
|
|
||||||
transition-duration: 3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu {
|
|
||||||
height: 100vh;
|
|
||||||
width: 20rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.new-item-button {
|
|
||||||
height: 2rem;
|
height: 2rem;
|
||||||
width: 10rem;
|
width: 15.5rem;
|
||||||
margin-top: 0.5rem;
|
margin-top: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
#menu-item {
|
.close-arrow {
|
||||||
text-align: center;
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.counter {
|
.counter {
|
||||||
@ -62,4 +44,60 @@ li {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.light-dark-mode {
|
||||||
|
float: right;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remove-all-items-button {
|
||||||
|
width: 5.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.roulette-wheel {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu {
|
||||||
|
width: 24rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item-list {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.moon-sun {
|
||||||
|
width: 3rem;
|
||||||
|
height: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.item-delete {
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.open-close-menu {
|
||||||
|
display: flex;
|
||||||
|
justify-content: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 940px) {
|
||||||
|
canvas{
|
||||||
|
margin-top: 5rem;
|
||||||
|
height: 30rem;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.roulette-wheel {
|
||||||
|
position: relative;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
transform: translate(0, 0);
|
||||||
|
}
|
||||||
|
}
|
19
index.html
19
index.html
@ -9,17 +9,22 @@
|
|||||||
<link rel="stylesheet" href="app.css" />
|
<link rel="stylesheet" href="app.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<div class="light-dark-mode">
|
||||||
|
<img class="moon-sun" src='static/moon.png' alt="mode">
|
||||||
|
</div>
|
||||||
<div class="menu">
|
<div class="menu">
|
||||||
<div class="open-close-menu">
|
<!-- <div class="open-close-menu">
|
||||||
</div>
|
<img class="close-arrow" src="static/right-arrow.png" alt="close menu" />
|
||||||
<div class="counter">
|
</div> -->
|
||||||
</div>
|
<p class="counter"></p>
|
||||||
<div class="item-menu">
|
|
||||||
<label for="new-item">Item name</label>
|
<label for="new-item">Item name</label>
|
||||||
<input name="new-item" minlength="1" maxlength="32">
|
<input name="new-item" minlength="1" maxlength="32" />
|
||||||
<button class="new-item-button">Add</button>
|
<button class="add-item-button">Add</button>
|
||||||
<button class="remove-all-items-button">Remove all</button>
|
<button class="remove-all-items-button">Remove all</button>
|
||||||
|
<ul class="menu-item-list"></ul>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="roulette-wheel">
|
||||||
|
<canvas></canvas>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
485
src/app.ts
485
src/app.ts
@ -1,202 +1,377 @@
|
|||||||
// import { MenuItem } from "./components/menu-item";
|
|
||||||
import { CounterItem } from "./components/counter-item";
|
|
||||||
import { MenuItem } from "./components/menu-item";
|
import { MenuItem } from "./components/menu-item";
|
||||||
import { MenuItemList } from "./components/menu-item-list";
|
|
||||||
import { OpenCloseArrow } from "./components/open-close-arrow";
|
|
||||||
import { Counter } from "./model/counter";
|
|
||||||
import { Item } from "./model/item";
|
import { Item } from "./model/item";
|
||||||
import { avaliableIds, initializeIdsPool } from "./utils/item-id-pool";
|
import { ItemList } from "./model/item-list";
|
||||||
|
import { IdPool } from "./utils/item-id-pool";
|
||||||
|
import { LightDarkMode } from "./utils/light-dark-mode";
|
||||||
import { avaliableRGBs } from "./utils/utils";
|
import { avaliableRGBs } from "./utils/utils";
|
||||||
// import { OpenCloseArrow } from "./components/open-close-arrow";
|
|
||||||
|
|
||||||
|
const addButtonEl = document.getElementsByClassName(
|
||||||
|
"add-item-button"
|
||||||
|
)[0]! as HTMLButtonElement;
|
||||||
|
const inputEl = document.querySelector("input")! as HTMLInputElement;
|
||||||
|
const itemListEl = document.getElementsByClassName(
|
||||||
|
"menu-item-list"
|
||||||
|
)[0]! as HTMLUListElement;
|
||||||
const counterEl = document.getElementsByClassName(
|
const counterEl = document.getElementsByClassName(
|
||||||
"counter"
|
"counter"
|
||||||
)[0]! as HTMLDivElement;
|
)[0]! as HTMLParagraphElement;
|
||||||
const itemMenuEl = document.getElementsByClassName(
|
|
||||||
"item-menu"
|
|
||||||
)[0]! as HTMLDivElement;
|
|
||||||
const openCloseMenuEl = document.getElementsByClassName(
|
|
||||||
"open-close-menu"
|
|
||||||
)[0]! as HTMLDivElement;
|
|
||||||
const inputEl = document.querySelector("input")! as HTMLInputElement;
|
|
||||||
const addButtonEl = document.getElementsByClassName(
|
|
||||||
"new-item-button"
|
|
||||||
)[0]! as HTMLButtonElement;
|
|
||||||
const removeAllItemsButtonEl = document.getElementsByClassName(
|
const removeAllItemsButtonEl = document.getElementsByClassName(
|
||||||
"remove-all-items-button"
|
"remove-all-items-button"
|
||||||
)[0]! as HTMLButtonElement;
|
)[0]! as HTMLButtonElement;
|
||||||
HTMLUL
|
const lightDarkModeEl = document.getElementsByClassName('light-dark-mode')[0]! as HTMLDivElement;
|
||||||
|
const canvasEl = document.querySelector('canvas')! as HTMLCanvasElement;
|
||||||
|
const ctx = canvasEl.getContext('2d')!;
|
||||||
|
const bodyEl = document.querySelector('body')! as HTMLBodyElement;
|
||||||
|
const modeEl = lightDarkModeEl.querySelector('img')! as HTMLImageElement;
|
||||||
|
const canvasWrapper = document.getElementsByClassName('roulette-wheel')[0]! as HTMLDivElement;
|
||||||
|
|
||||||
const MIN_ITEMS = 0;
|
const MAXIMUM_SIZE = 16;
|
||||||
const MAX_ITEMS = 16;
|
|
||||||
|
|
||||||
const openCloseItem = new OpenCloseArrow();
|
|
||||||
openCloseMenuEl.appendChild(openCloseItem.el);
|
|
||||||
|
|
||||||
const counterItem = new CounterItem(MIN_ITEMS, MAX_ITEMS);
|
|
||||||
counterEl.appendChild(counterItem.el);
|
|
||||||
|
|
||||||
const counter = counterItem.getCounter;
|
|
||||||
|
|
||||||
const items: MenuItemList = new MenuItemList();
|
|
||||||
itemMenuEl.appendChild(items.el);
|
|
||||||
|
|
||||||
|
counterEl.textContent = `0/${MAXIMUM_SIZE}`;
|
||||||
|
|
||||||
|
const itemsList = new ItemList(MAXIMUM_SIZE);
|
||||||
|
const items: MenuItem[] = [];
|
||||||
|
|
||||||
configure();
|
configure();
|
||||||
|
|
||||||
function configure() {
|
function configure() {
|
||||||
initializeIdsPool(MAX_ITEMS);
|
LightDarkMode.currentMode = 'dark';
|
||||||
|
IdPool.initializeIdsPool(MAXIMUM_SIZE);
|
||||||
|
addRemoveItem();
|
||||||
|
addItemByEnter();
|
||||||
|
removeAllItems();
|
||||||
|
lightDarkMode();
|
||||||
|
drawRouletteWheel();
|
||||||
}
|
}
|
||||||
|
|
||||||
addButtonEl.addEventListener("click", () => {
|
function addRemoveItem() {
|
||||||
const id = avaliableIds.pop();
|
addButtonEl.addEventListener("click", () => {
|
||||||
const name = inputEl.value;
|
const name = inputEl.value;
|
||||||
if (id) {
|
const id = IdPool.getAnId();
|
||||||
if (name) {
|
if (name && id) {
|
||||||
if (counter.increment()) {
|
const color = avaliableRGBs[id % avaliableRGBs.length];
|
||||||
const item = new MenuItem(id, name, avaliableRGBs[MAX_ITEMS % Counter.value]);
|
|
||||||
console.log(item.deleteItem);
|
const item = new Item(id, name, color);
|
||||||
item.deleteItem.el.addEventListener('click', () => {
|
const menuItem = new MenuItem(id, name, color);
|
||||||
if(counter.decrement()){
|
|
||||||
avaliableIds.push(item.el.id)
|
menuItem.deleteItem.el.addEventListener("click", () => {
|
||||||
items.removeItem(item);
|
menuItem.el.remove();
|
||||||
counterItem.updateContent();
|
items.splice(items.indexOf(menuItem), 1);
|
||||||
|
itemsList.remove(item);
|
||||||
|
IdPool.addId(item.id);
|
||||||
|
updateCounter();
|
||||||
|
drawRouletteWheel();
|
||||||
|
});
|
||||||
|
|
||||||
|
registerChangeColorByClick(item, menuItem);
|
||||||
|
|
||||||
|
itemsList.add(item);
|
||||||
|
items.push(menuItem);
|
||||||
|
itemListEl.appendChild(menuItem.el);
|
||||||
|
updateCounter();
|
||||||
|
drawRouletteWheel();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function addItemByEnter(){
|
||||||
|
bodyEl.addEventListener('keyup', (event: KeyboardEvent) => {
|
||||||
|
if(event.key !== 'Enter'){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
addButtonEl.click();
|
||||||
})
|
})
|
||||||
items.addItem(item);
|
}
|
||||||
counterItem.updateContent();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
alert("Item name cannot be empty!");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
alert("Maxium number of elements!");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
removeAllItemsButtonEl.addEventListener("click", () => {
|
function registerChangeColorByClick(item: Item, menuItem: MenuItem) {
|
||||||
initializeIdsPool(MAX_ITEMS);
|
menuItem.el.addEventListener('click', () => {
|
||||||
items.clear();
|
const actualColorIndex = avaliableRGBs.indexOf(menuItem.el.style.backgroundColor);
|
||||||
counter.clear();
|
if(actualColorIndex !== -1){
|
||||||
counterItem.updateContent();
|
const color = avaliableRGBs[(actualColorIndex + 1) % avaliableRGBs.length];
|
||||||
});
|
menuItem.el.style.backgroundColor = color;
|
||||||
|
item.color = color;
|
||||||
|
drawRouletteWheel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeAllItems() {
|
||||||
|
removeAllItemsButtonEl.addEventListener("click", () => {
|
||||||
|
if (items.length > 0) {
|
||||||
|
items.forEach((menuItem) => menuItem.el.remove());
|
||||||
|
items.length = 0;
|
||||||
|
itemsList.clear();
|
||||||
|
IdPool.initializeIdsPool(MAXIMUM_SIZE);
|
||||||
|
updateCounter();
|
||||||
|
drawRouletteWheel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCounter() {
|
||||||
|
counterEl.textContent = `${itemsList.items.length}/${MAXIMUM_SIZE}`;
|
||||||
|
animateCounter();
|
||||||
|
}
|
||||||
|
|
||||||
|
function animateCounter() {
|
||||||
|
counterEl.animate(
|
||||||
|
[{ transform: "scale(1.25)" }, { transform: "scale(1.00)" }],
|
||||||
|
{
|
||||||
|
duration: 500,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function lightDarkMode(){
|
||||||
|
lightDarkModeEl.addEventListener('click', () => {
|
||||||
|
modeEl.animate(
|
||||||
|
[
|
||||||
|
{ transform: 'rotate(360deg)' }
|
||||||
|
],
|
||||||
|
{
|
||||||
|
duration: 500
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if(LightDarkMode.currentMode == 'dark'){
|
||||||
|
modeEl.src = 'static/sun.png';
|
||||||
|
bodyEl.style.backgroundColor = 'snow';
|
||||||
|
bodyEl.style.color = 'black';
|
||||||
|
}else{
|
||||||
|
modeEl.src = 'static/moon.png';
|
||||||
|
bodyEl.style.backgroundColor = '#121212';
|
||||||
|
bodyEl.style.color = 'white';
|
||||||
|
}
|
||||||
|
|
||||||
|
LightDarkMode.changeMode();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawRouletteWheel(){
|
||||||
|
ctx.clearRect(0, 0, canvasEl.width, canvasEl.height);
|
||||||
|
canvasEl.width = canvasWrapper.offsetWidth;
|
||||||
|
canvasEl.height = canvasWrapper.offsetHeight;
|
||||||
|
const x = canvasEl.width / 2;
|
||||||
|
const y = canvasEl.height / 2;
|
||||||
|
const radius = canvasEl.height / 2;
|
||||||
|
let startAngle = 0;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(x, y, radius, 0, Math.PI * 2, true);
|
||||||
|
ctx.stroke();
|
||||||
|
const segmentWidth = 360 / items.length;
|
||||||
|
let endAngle = segmentWidth;
|
||||||
|
console.log(items.length);
|
||||||
|
for(let i = 0; i < items.length; i++){
|
||||||
|
ctx.beginPath();
|
||||||
|
if(i === 1){
|
||||||
|
ctx.lineTo(x, y);
|
||||||
|
}
|
||||||
|
ctx.arc(x, y, radius, (startAngle * Math.PI / 180), (endAngle * Math.PI / 180), false);
|
||||||
|
ctx.lineTo(x, y);
|
||||||
|
ctx.fillStyle = itemsList.items[i].color;
|
||||||
|
ctx.fill();
|
||||||
|
ctx.stroke();
|
||||||
|
startAngle += segmentWidth;
|
||||||
|
endAngle += segmentWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// // import { MenuItem } from "./components/menu-item";
|
||||||
|
// import { CounterItem } from "./components/counter-item";
|
||||||
|
// import { MenuItem } from "./components/menu-item";
|
||||||
|
// import { MenuItemList } from "./components/menu-item-list";
|
||||||
|
// import { OpenCloseArrow } from "./components/open-close-arrow";
|
||||||
|
// import { Counter } from "./model/counter";
|
||||||
|
// import { Item } from "./model/item";
|
||||||
|
// import { avaliableIds, initializeIdsPool } from "./utils/item-id-pool";
|
||||||
|
// import { avaliableRGBs } from "./utils/utils";
|
||||||
|
// // import { OpenCloseArrow } from "./components/open-close-arrow";
|
||||||
|
|
||||||
|
// const counterEl = document.getElementsByClassName(
|
||||||
|
// "counter"
|
||||||
|
// )[0]! as HTMLDivElement;
|
||||||
|
// const itemMenuEl = document.getElementsByClassName(
|
||||||
|
// "item-menu"
|
||||||
|
// )[0]! as HTMLDivElement;
|
||||||
// const openCloseMenuEl = document.getElementsByClassName(
|
// const openCloseMenuEl = document.getElementsByClassName(
|
||||||
// "open-close-menu"
|
// "open-close-menu"
|
||||||
// )[0]! as HTMLDivElement;
|
// )[0]! as HTMLDivElement;
|
||||||
|
// const inputEl = document.querySelector("input")! as HTMLInputElement;
|
||||||
|
// const addButtonEl = document.getElementsByClassName(
|
||||||
|
// "new-item-button"
|
||||||
|
// )[0]! as HTMLButtonElement;
|
||||||
|
// const removeAllItemsButtonEl = document.getElementsByClassName(
|
||||||
|
// "remove-all-items-button"
|
||||||
|
// )[0]! as HTMLButtonElement;
|
||||||
|
|
||||||
// const itemNameInput = document.querySelector("input")! as HTMLInputElement;
|
// const MIN_ITEMS = 0;
|
||||||
|
// const MAX_ITEMS = 16;
|
||||||
|
|
||||||
// const newItemButtonEl = document.getElementById(
|
// const openCloseItem = new OpenCloseArrow();
|
||||||
// "newItemButton"
|
// openCloseMenuEl.appendChild(openCloseItem.el);
|
||||||
// )! as HTMLButtonElement;
|
|
||||||
|
|
||||||
// const removeAllItemsButtonEl = document.getElementById(
|
// const counterItem = new CounterItem(MIN_ITEMS, MAX_ITEMS);
|
||||||
// "removeAllItemsButton"
|
// counterEl.appendChild(counterItem.el);canvasEl
|
||||||
// )! as HTMLButtonElement;
|
|
||||||
|
|
||||||
// // const newItemMenu = document.getElementById('new-item-menu')! as HTMLDivElement;
|
// const counter = counterItem.getCounter;
|
||||||
|
|
||||||
// menuEl.appendChild(items.el);
|
// const items: MenuItemList = new MenuItemList();
|
||||||
// openCloseMenuEl.appendChild(new OpenCloseArrow().el);
|
// itemMenuEl.appendChild(items.el);
|
||||||
|
|
||||||
// const avaliableRGBs = ["255, 0, 0", "0, 255, 0", "0, 0, 255"];
|
// configure();
|
||||||
// const bgOpacity = 0.5;
|
|
||||||
// let nextColor = avaliableRGBs[0];
|
|
||||||
|
|
||||||
// const idsPool: number[] = [];
|
// function configure() {
|
||||||
// initalizeIdsPool();
|
// initializeIdsPool(MAX_ITEMS);
|
||||||
|
// }
|
||||||
|
|
||||||
// function addNewItem() {
|
// addButtonEl.addEventListener("click", () => {
|
||||||
// if (itemNameInput.value.length > 0 && itemNameInput.value.length <= 32) {
|
// const id = avaliableIds.pop();
|
||||||
// if (counter < maxItems && idsPool.length > 0) {
|
// const name = inputEl.value;
|
||||||
// const item = new MenuItem(
|
// if (id) {
|
||||||
// idsPool.pop()!,
|
// if (name) {
|
||||||
// itemNameInput.value,
|
// if (counter.increment()) {
|
||||||
// `rgba(${nextColor}, ${bgOpacity})`
|
// const item = new MenuItem(id, name, avaliableRGBs[MAX_ITEMS % Counter.value]);
|
||||||
// );
|
// console.log(item.deleteItem);
|
||||||
|
// item.deleteItem.el.addEventListener('click', () => {
|
||||||
// item.deleteItem.el.addEventListener("click", () => {
|
// if(counter.decrement()){
|
||||||
// const itemElId = calculateItemElId(item);
|
// avaliableIds.push(item.el.id)
|
||||||
// idsPool.push(itemElId);
|
|
||||||
// setNextColor();
|
|
||||||
// items.removeItem(item);
|
// items.removeItem(item);
|
||||||
// counter--;
|
// counterItem.updateContent();
|
||||||
// updateCounter();
|
// }
|
||||||
|
// })
|
||||||
|
// items.addItem(item);
|
||||||
|
// counterItem.updateContent();
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// alert("Item name cannot be empty!");
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// alert("Maxium number of elements!");
|
||||||
|
// }
|
||||||
// });
|
// });
|
||||||
|
|
||||||
// items.addItem(item);
|
// removeAllItemsButtonEl.addEventListener("click", () => {
|
||||||
// counter++;
|
// initializeIdsPool(MAX_ITEMS);
|
||||||
// updateCounter();
|
|
||||||
// setNextColor();
|
|
||||||
// } else {
|
|
||||||
// alert("Maximum number of items!");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function removeAllItems() {
|
|
||||||
// if (items.itemsLength > 0) {
|
|
||||||
// items.clear();
|
// items.clear();
|
||||||
// counter = 0;
|
// counter.clear();
|
||||||
// initalizeIdsPool();
|
// counterItem.updateContent();
|
||||||
// nextColor = avaliableRGBs[0];
|
// });
|
||||||
// updateCounter();
|
|
||||||
// } else {
|
|
||||||
// alert("Nothing to clear!");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function updateCounter() {
|
// // const openCloseMenuEl = document.getElementsByClassName(
|
||||||
// counterEl.textContent = `${counter}/${maxItems}`;
|
// // "open-close-menu"
|
||||||
// counterEl.animate([
|
// // )[0]! as HTMLDivElement;
|
||||||
// { transform: 'scale(1.25)'},
|
|
||||||
// { transform: 'scale(1.00)'}
|
|
||||||
// ],
|
|
||||||
// {
|
|
||||||
// duration: 500
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function setNextColor() {
|
// // const itemNameInput = document.querySelector("input")! as HTMLInputElement;
|
||||||
// nextColor = avaliableRGBs[counter % avaliableRGBs.length];
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function calculateItemElId(item: MenuItem) {
|
// // const newItemButtonEl = document.getElementById(
|
||||||
// return +item.el.id.slice(0, item.el.id.indexOf("-"));
|
// // "newItemButton"
|
||||||
// }
|
// // )! as HTMLButtonElement;
|
||||||
|
|
||||||
// const openCloseArrow = document.getElementById("open-close-arrow")!;
|
// // const removeAllItemsButtonEl = document.getElementById(
|
||||||
// let open = true;
|
// // "removeAllItemsButton"
|
||||||
|
// // )! as HTMLButtonElement;
|
||||||
|
|
||||||
// function rotateOpenCloseArrow() {
|
// // // const newItemMenu = document.getElementById('new-item-menu')! as HTMLDivElement;
|
||||||
// openCloseArrow.animate([
|
|
||||||
// { transform: 'rotate(180deg)' }
|
|
||||||
// ],
|
|
||||||
// {
|
|
||||||
// duration: 500,
|
|
||||||
|
|
||||||
// }
|
// // menuEl.appendChild(items.el);
|
||||||
// );
|
// // openCloseMenuEl.appendChild(new OpenCloseArrow().el);
|
||||||
// if(open){
|
|
||||||
// menuEl.className = 'decreasing';
|
|
||||||
// open = false;
|
|
||||||
// }else{
|
|
||||||
// menuEl.className = 'normal';
|
|
||||||
// open = true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// }
|
// // const avaliableRGBs = ["255, 0, 0", "0, 255, 0", "0, 0, 255"];
|
||||||
|
// // const bgOpacity = 0.5;
|
||||||
|
// // let nextColor = avaliableRGBs[0];
|
||||||
|
|
||||||
// function initalizeIdsPool() {
|
// // const idsPool: number[] = [];
|
||||||
// idsPool.length = 0;
|
// // initalizeIdsPool();
|
||||||
// for (let i = 0; i < maxItems; i++) {
|
|
||||||
// idsPool.push(i);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// newItemButtonEl.addEventListener("click", addNewItem);
|
// // function addNewItem() {
|
||||||
// removeAllItemsButtonEl.addEventListener("click", removeAllItems);
|
// // if (itemNameInput.value.length > 0 && itemNameInput.value.length <= 32) {
|
||||||
// openCloseArrow.addEventListener("click", rotateOpenCloseArrow);
|
// // if (counter < maxItems && idsPool.length > 0) {
|
||||||
|
// // const item = new MenuItem(
|
||||||
|
// // idsPool.pop()!,
|
||||||
|
// // itemNameInput.value,
|
||||||
|
// // `rgba(${nextColor}, ${bgOpacity})`
|
||||||
|
// // );
|
||||||
|
|
||||||
|
// // item.deleteItem.el.addEventListener("click", () => {
|
||||||
|
// // const itemElId = calculateItemElId(item);
|
||||||
|
// // idsPool.push(itemElId);
|
||||||
|
// // setNextColor();
|
||||||
|
// // items.removeItem(item);
|
||||||
|
// // counter--;
|
||||||
|
// // updateCounter();
|
||||||
|
// // });
|
||||||
|
|
||||||
|
// // items.addItem(item);
|
||||||
|
// // counter++;
|
||||||
|
// // updateCounter();
|
||||||
|
// // setNextColor();
|
||||||
|
// // } else {
|
||||||
|
// // alert("Maximum number of items!");
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // function removeAllItems() {
|
||||||
|
// // if (items.itemsLength > 0) {
|
||||||
|
// // items.clear();
|
||||||
|
// // counter = 0;
|
||||||
|
// // initalizeIdsPool();
|
||||||
|
// // nextColor = avaliableRGBs[0];
|
||||||
|
// // updateCounter();
|
||||||
|
// // } else {
|
||||||
|
// // alert("Nothing to clear!");
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // function updateCounter() {
|
||||||
|
// // counterEl.textContent = `${counter}/${maxItems}`;
|
||||||
|
// // counterEl.animate([
|
||||||
|
// // { transform: 'scale(1.25)'},
|
||||||
|
// // { transform: 'scale(1.00)'}
|
||||||
|
// // ],
|
||||||
|
// // {
|
||||||
|
// // duration: 500
|
||||||
|
// // }
|
||||||
|
// // );
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // function setNextColor() {
|
||||||
|
// // nextColor = avaliableRGBs[counter % avaliableRGBs.length];
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // function calculateItemElId(item: MenuItem) {
|
||||||
|
// // return +item.el.id.slice(0, item.el.id.indexOf("-"));
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // const openCloseArrow = document.getElementById("open-close-arrow")!;
|
||||||
|
// // let open = true;
|
||||||
|
|
||||||
|
// // function rotateOpenCloseArrow() {
|
||||||
|
// // openCloseArrow.animate([
|
||||||
|
// // { transform: 'rotate(180deg)' }
|
||||||
|
// // ],
|
||||||
|
// // {
|
||||||
|
// // duration: 500,
|
||||||
|
|
||||||
|
// // }
|
||||||
|
// // );
|
||||||
|
// // if(open){
|
||||||
|
// // menuEl.className = 'decreasing';
|
||||||
|
// // open = false;
|
||||||
|
// // }else{
|
||||||
|
// // menuEl.className = 'normal';
|
||||||
|
// // open = true;
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // function initalizeIdsPool() {
|
||||||
|
// // idsPool.length = 0;
|
||||||
|
// // for (let i = 0; i < maxItems; i++) {
|
||||||
|
// // idsPool.push(i);
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // newItemButtonEl.addEventListener("click", addNewItem);
|
||||||
|
// // removeAllItemsButtonEl.addEventListener("click", removeAllItems);
|
||||||
|
// // openCloseArrow.addEventListener("click", rotateOpenCloseArrow);
|
||||||
|
@ -1,35 +1,35 @@
|
|||||||
import { Counter } from "../model/counter";
|
|
||||||
import { Component } from "./base-component";
|
|
||||||
|
|
||||||
export class CounterItem extends Component<HTMLElement>{
|
// import { Component } from "./base-component";
|
||||||
private counter: Counter;
|
|
||||||
|
|
||||||
constructor(min: number, max: number){
|
// export class CounterItem extends Component<HTMLElement>{
|
||||||
const counterEl = document.createElement('p');
|
// private counter: Counter;
|
||||||
counterEl.textContent = `${min}/${max}`;
|
|
||||||
counterEl.className = 'counter-item';
|
|
||||||
super(counterEl);
|
|
||||||
this.counter = new Counter(min, max);
|
|
||||||
}
|
|
||||||
|
|
||||||
get getCounter(){
|
// constructor(min: number, max: number){
|
||||||
return this.counter;
|
// const counterEl = document.createElement('p');
|
||||||
}
|
// counterEl.textContent = `${min}/${max}`;
|
||||||
|
// counterEl.className = 'counter-item';
|
||||||
|
// super(counterEl);
|
||||||
|
// this.counter = new Counter(min, max);
|
||||||
|
// }
|
||||||
|
|
||||||
updateContent(){
|
// get getCounter(){
|
||||||
this.el.textContent = `${Counter.value}/${this.counter.max}`
|
// return this.counter;
|
||||||
this.animate();
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
private animate(): void{
|
// updateContent(){
|
||||||
this.el.animate(
|
// this.el.textContent = `${Counter.value}/${this.counter.max}`
|
||||||
[
|
// this.animate();
|
||||||
{ transform: 'scale(1.25)'},
|
// }
|
||||||
{ transform: 'scale(1.00)'}
|
|
||||||
],
|
// private animate(): void{
|
||||||
{
|
// this.el.animate(
|
||||||
duration: 500
|
// [
|
||||||
}
|
// { transform: 'scale(1.25)'},
|
||||||
);
|
// { transform: 'scale(1.00)'}
|
||||||
}
|
// ],
|
||||||
}
|
// {
|
||||||
|
// duration: 500
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
@ -5,15 +5,35 @@ export class MenuItem extends Component<HTMLLIElement> {
|
|||||||
|
|
||||||
deleteItem: ItemRemoval;
|
deleteItem: ItemRemoval;
|
||||||
|
|
||||||
constructor(id: number, value: string, color: string){
|
constructor(id: number, name: string, color: string){
|
||||||
const deleteItem = new ItemRemoval(id);
|
const deleteItem = new ItemRemoval(id);
|
||||||
const el = document.createElement('li');
|
const el = document.createElement('li');
|
||||||
el.className = 'menu-item';
|
el.className = 'menu-item';
|
||||||
el.id = `${id}-item`;
|
el.id = `${id}-item`;
|
||||||
el.textContent = value;
|
el.textContent = name;
|
||||||
el.style.backgroundColor = color;
|
el.style.backgroundColor = color;
|
||||||
el.appendChild(deleteItem.el);
|
el.appendChild(deleteItem.el);
|
||||||
super(el);
|
super(el);
|
||||||
this.deleteItem = deleteItem;
|
this.deleteItem = deleteItem;
|
||||||
|
this.appearAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
// registerChangeColorListener(){
|
||||||
|
// this.el.addEventListener('click', () => {
|
||||||
|
// const actualColorIndex = avaliableRGBs.indexOf(this.el.style.backgroundColor);
|
||||||
|
// if(actualColorIndex !== -1){
|
||||||
|
// const color = avaliableRGBs[(actualColorIndex + 1) % avaliableRGBs.length];
|
||||||
|
// this.el.style.backgroundColor = color;
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
appearAnimation(){
|
||||||
|
this.el.animate(
|
||||||
|
[{ transform: "scale(1.25)" }, { transform: "scale(1.00)" }],
|
||||||
|
{
|
||||||
|
duration: 500,
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,39 +0,0 @@
|
|||||||
export class Counter {
|
|
||||||
static value: number;
|
|
||||||
min: number;
|
|
||||||
max: number;
|
|
||||||
|
|
||||||
constructor(min: number, max: number){
|
|
||||||
Counter.value = min;
|
|
||||||
this.min = min;
|
|
||||||
this.max = max;
|
|
||||||
}
|
|
||||||
|
|
||||||
increment(){
|
|
||||||
if(!this.isMax()){
|
|
||||||
Counter.value++;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
decrement(){
|
|
||||||
if(!this.isMin()){
|
|
||||||
Counter.value--;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
clear(){
|
|
||||||
Counter.value = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private isMax(){
|
|
||||||
return this.max === Counter.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private isMin(){
|
|
||||||
return this.min === Counter.value;
|
|
||||||
}
|
|
||||||
}
|
|
32
src/model/item-list.ts
Normal file
32
src/model/item-list.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { Item } from "./item";
|
||||||
|
import { List } from "./list";
|
||||||
|
|
||||||
|
export class ItemList implements List<Item> {
|
||||||
|
items: Item[];
|
||||||
|
maximumSize: number;
|
||||||
|
|
||||||
|
constructor(maxSize: number){
|
||||||
|
this.items = [];
|
||||||
|
this.maximumSize = maxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
add(item: Item){
|
||||||
|
if(this.items.length < this.maximumSize)
|
||||||
|
this.items.push(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeById(id: number){
|
||||||
|
const toRemove = this.items.find(e => e.id === id);
|
||||||
|
if(toRemove){
|
||||||
|
this.remove(toRemove);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(item: Item){
|
||||||
|
this.items.splice(this.items.indexOf(item), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
clear(){
|
||||||
|
this.items = [];
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,7 @@ export class Item {
|
|||||||
name: string;
|
name: string;
|
||||||
color: string;
|
color: string;
|
||||||
|
|
||||||
constructor(id: number, name: string, color: string){
|
constructor(id: number, name: string, color: string) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.color = color;
|
this.color = color;
|
||||||
|
5
src/model/list.ts
Normal file
5
src/model/list.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export interface List<T> {
|
||||||
|
items: T[];
|
||||||
|
|
||||||
|
add(item: T): void;
|
||||||
|
}
|
@ -1,7 +1,22 @@
|
|||||||
export const avaliableIds: number[] = [];
|
export abstract class IdPool {
|
||||||
|
static avaliableIds: number[] = [];
|
||||||
|
|
||||||
export function initializeIdsPool(numberOfElements: number){
|
static initializeIdsPool(numberOfElements: number) {
|
||||||
for(let i = 1; i <= numberOfElements; i++){
|
for (let i = 1; i <= numberOfElements; i++) {
|
||||||
avaliableIds[i] = i;
|
IdPool.avaliableIds[i] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static getAnId() {
|
||||||
|
const id = this.avaliableIds.pop();
|
||||||
|
if (!id) {
|
||||||
|
alert("Maxiumum number of items!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static addId(id: number){
|
||||||
|
this.avaliableIds.push(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
13
src/utils/light-dark-mode.ts
Normal file
13
src/utils/light-dark-mode.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
type mode = 'dark' | 'light';
|
||||||
|
|
||||||
|
export abstract class LightDarkMode{
|
||||||
|
static currentMode: mode;
|
||||||
|
|
||||||
|
static changeMode(){
|
||||||
|
if(this.currentMode == 'light'){
|
||||||
|
this.currentMode = 'dark';
|
||||||
|
}else{
|
||||||
|
this.currentMode = 'light';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,2 +1 @@
|
|||||||
export const avaliableRGBs = ["255, 0, 0", "0, 255, 0", "0, 0, 255"];
|
export const avaliableRGBs = ["rgba(255, 0, 0, 0.5)", "rgba(0, 255, 0, 0.5)", "rgba(0, 0, 255, 0.5)", "rgba(255, 255, 0, 0.5)"];
|
||||||
|
|
BIN
static/moon.png
Normal file
BIN
static/moon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
BIN
static/sun.png
Normal file
BIN
static/sun.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
Loading…
Reference in New Issue
Block a user