├── LICENSE
├── README.md
├── index.html
├── itens
├── apple.gif
├── cobblestone.png
├── diamond-pickaxe.png
├── diamond-sword.png
├── diamond.png
├── iron.png
├── steak.png
└── wood.png
├── script.js
└── styles.css
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 lavininhamelo
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | Minecraft Inventory in Javascript
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | ## 💻 Project
24 |
25 | An implementation of the interface and the functionalities of the minecraft inventory, developed in javascript vanilla and CSS as a personal challenge.
26 |
27 | [](https://codepen.io/lavininhamelo/full/NWxPKLJ)
28 |
29 | ## 🤔 How to contribute
30 |
31 | - Make a fork;
32 | - Create a branck with your feature: `git checkout -b my-feature`;
33 | - Commit changes: `git commit -m 'feat: My new feature'`;
34 | - Make a push to your branch: `git push origin my-feature`.
35 |
36 | After merging your receipt request to done, you can delete a branch from yours.
37 |
38 | ## :memo: License
39 |
40 | This project is under the MIT license. See the [LICENSE](https://github.com/lavininhamelo/minecraft-inventory-in-javascript/blob/master/LICENSE) for details.
41 |
42 | Made by Lavínia Melo :wave: [Get in touch!](https://www.linkedin.com/in/laviniamelo/)
43 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Minecraft Inventory
8 |
9 |
10 |
11 |
12 |
13 |
Inventory
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | 33
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | 3
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | 14
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
1
69 |
70 |
71 |
72 |
73 |
74 |
12
75 |
76 |
77 |
78 |
79 |
80 |
81 | 33
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | 8
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 | 12
98 |
99 |
100 |
101 |
102 |
103 |
104 |
1
105 |
106 |
107 |
108 |
109 |
110 |
111 | 32
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
124 |
125 |
126 |
127 |
128 |
--------------------------------------------------------------------------------
/itens/apple.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lavininhamelo/minecraft-inventory-in-javascript/3256e2df0b4c7a850eee824e92ba02ac0a053302/itens/apple.gif
--------------------------------------------------------------------------------
/itens/cobblestone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lavininhamelo/minecraft-inventory-in-javascript/3256e2df0b4c7a850eee824e92ba02ac0a053302/itens/cobblestone.png
--------------------------------------------------------------------------------
/itens/diamond-pickaxe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lavininhamelo/minecraft-inventory-in-javascript/3256e2df0b4c7a850eee824e92ba02ac0a053302/itens/diamond-pickaxe.png
--------------------------------------------------------------------------------
/itens/diamond-sword.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lavininhamelo/minecraft-inventory-in-javascript/3256e2df0b4c7a850eee824e92ba02ac0a053302/itens/diamond-sword.png
--------------------------------------------------------------------------------
/itens/diamond.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lavininhamelo/minecraft-inventory-in-javascript/3256e2df0b4c7a850eee824e92ba02ac0a053302/itens/diamond.png
--------------------------------------------------------------------------------
/itens/iron.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lavininhamelo/minecraft-inventory-in-javascript/3256e2df0b4c7a850eee824e92ba02ac0a053302/itens/iron.png
--------------------------------------------------------------------------------
/itens/steak.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lavininhamelo/minecraft-inventory-in-javascript/3256e2df0b4c7a850eee824e92ba02ac0a053302/itens/steak.png
--------------------------------------------------------------------------------
/itens/wood.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lavininhamelo/minecraft-inventory-in-javascript/3256e2df0b4c7a850eee824e92ba02ac0a053302/itens/wood.png
--------------------------------------------------------------------------------
/script.js:
--------------------------------------------------------------------------------
1 | let current_slot = null;
2 | let status_click = false;
3 | let current_itemId = null;
4 | let current_itemType = null;
5 | let current_itemValue = null;
6 |
7 | let body = document.getElementsByTagName('body');
8 |
9 | const items = document.querySelectorAll('.item');
10 |
11 | items.forEach((item) => {
12 | item.addEventListener('click', moveItem);
13 | item.addEventListener('contextmenu', moveItem);
14 | item.setAttribute('draggable', false);
15 | });
16 |
17 | function moveItem() {
18 | event.preventDefault();
19 |
20 | const item = this;
21 |
22 | let ghostItem = item.cloneNode(true);
23 | ghostItem.setAttribute('class', 'ghostItem');
24 | item.classList.add('invisible');
25 |
26 | let shiftX = ghostItem.getBoundingClientRect().left + 20;
27 | let shiftY = ghostItem.getBoundingClientRect().top + 20;
28 |
29 | ghostItem.style.position = 'absolute';
30 | ghostItem.style.zIndex = 1000;
31 | document.body.append(ghostItem);
32 |
33 | ghostItem.onclick = function (event) {
34 | if (current_itemId && current_itemId != item.parentNode.id) {
35 | let area = document.getElementById(current_itemId);
36 | let free_space = !!!area.firstElementChild;
37 |
38 | if (free_space) {
39 | area.append(item);
40 | } else if (current_itemType == item.id) {
41 | let destiny = area.firstElementChild.lastElementChild.innerHTML;
42 | let origin = item.lastElementChild.innerHTML;
43 | let total = parseInt(destiny) + parseInt(origin);
44 | area.firstElementChild.lastElementChild.innerHTML = total;
45 | item.remove();
46 | } else {
47 | item.parentNode.append(area.firstElementChild);
48 | area.append(item);
49 | }
50 | }
51 | item && item.classList.remove('invisible');
52 | ghostItem.remove();
53 | status_click = !status_click;
54 | };
55 |
56 | ghostItem.oncontextmenu = function (event) {
57 | event.preventDefault();
58 | if (current_itemId && current_itemId != item.parentNode.id) {
59 | let area = document.getElementById(current_itemId);
60 | let free_space = !!!area.firstElementChild;
61 | if (free_space) {
62 | let newItem = item.cloneNode(true);
63 | newItem.addEventListener('click', moveItem);
64 | newItem.addEventListener('contextmenu', moveItem);
65 | newItem.setAttribute('draggable', false);
66 | if (parseInt(item.lastElementChild.innerHTML) == 1) {
67 | ghostItem.remove();
68 | status_click = !status_click;
69 | item.remove();
70 | } else {
71 | item.lastElementChild.innerHTML =
72 | parseInt(item.lastElementChild.innerHTML) - 1;
73 | ghostItem.lastElementChild.innerHTML =
74 | parseInt(ghostItem.lastElementChild.innerHTML) - 1;
75 | }
76 | newItem.lastElementChild.innerHTML = 1;
77 | area.append(newItem);
78 | newItem.classList.remove('invisible');
79 | } else if (current_itemType == item.id) {
80 | if (parseInt(item.lastElementChild.innerHTML) == 1) {
81 | ghostItem.remove();
82 | status_click = !status_click;
83 | item.remove();
84 | }
85 | let destiny = parseInt(
86 | area.firstElementChild.lastElementChild.innerHTML
87 | );
88 | let origin = parseInt(item.lastElementChild.innerHTML);
89 | let ghost = parseInt(ghostItem.lastElementChild.innerHTML);
90 |
91 | area.firstElementChild.lastElementChild.innerHTML = destiny + 1;
92 | item.lastElementChild.innerHTML = origin - 1;
93 | ghostItem.lastElementChild.innerHTML = ghost - 1;
94 | }
95 | }
96 | };
97 |
98 | status_click = !status_click;
99 |
100 | if (status_click) {
101 | moveAt(event.pageX, event.pageY);
102 | }
103 |
104 | function moveAt(pageX, pageY) {
105 | ghostItem.style.left = pageX - shiftX + 'px';
106 | ghostItem.style.top = pageY - shiftY + 'px';
107 | }
108 |
109 | function onMouseMove(event) {
110 | if (status_click) {
111 | moveAt(event.pageX, event.pageY);
112 | }
113 | ghostItem.hidden = true;
114 | let elemBelow = document.elementFromPoint(event.clientX, event.clientY);
115 | ghostItem.hidden = false;
116 |
117 | if (!elemBelow) return;
118 | let droppableBelow = elemBelow.closest('.slot');
119 | if (current_slot != droppableBelow) {
120 | if (current_slot) {
121 | leaveDroppable(current_slot);
122 | }
123 | current_slot = droppableBelow;
124 | if (current_slot) {
125 | enterDroppable(current_slot);
126 | }
127 | }
128 | }
129 |
130 | document.addEventListener('mousemove', onMouseMove);
131 | }
132 |
133 | function enterDroppable(elem) {
134 | current_itemId = elem.id;
135 | if (elem.firstElementChild) {
136 | current_itemType = elem.firstElementChild.id;
137 | child = elem.firstElementChild;
138 | current_itemValue = child.lastElementChild.innerHTML;
139 | }
140 | }
141 |
142 | function leaveDroppable(elem) {
143 | current_itemId = null;
144 | current_itemType = null;
145 | current_itemValue = null;
146 | free_space = false;
147 | }
148 |
--------------------------------------------------------------------------------
/styles.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=VT323&display=swap');
2 |
3 | @import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
4 |
5 | body {
6 | background: #ccc;
7 | box-sizing: border-box;
8 | width: 100%;
9 | height: 80vh;
10 | }
11 |
12 | .content {
13 | width: 100%;
14 | height: 100%;
15 | display: flex;
16 | justify-content: center;
17 | align-items: center;
18 | flex-direction: column;
19 | }
20 |
21 | .inventory {
22 | width: 335px;
23 | height: 200px;
24 | background: #c6c6c6;
25 | border-radius: 3px;
26 | box-shadow: 5px 5px 0px #555555, inset 4px 4px 0px #fefefe;
27 | padding-top: 5px;
28 | padding-left: 5px;
29 | margin-bottom: 10px;
30 | }
31 |
32 | h1 {
33 | margin: 5px 10px;
34 | font-family: 'VT323', monospace;
35 | font-size: 24px;
36 | color: #404040;
37 | }
38 |
39 | .number {
40 | font-family: 'VT323', monospace;
41 | font-size: 24px;
42 | color: #fefefe;
43 | position: relative;
44 | text-shadow: #333 1px 2px 1px;
45 | top: -16px;
46 | right: -8px;
47 | cursor: default;
48 | }
49 |
50 | .slot {
51 | width: 35px;
52 | height: 35px;
53 | display: flex;
54 | justify-content: center;
55 | background: #8b8b8b;
56 | box-shadow: inset 1.5px 1.5px 0px rgba(55, 55, 55, 0.8),
57 | inset -2px -2px 0px #ffffff;
58 | }
59 |
60 | .slotSpace {
61 | margin: 10px 10px;
62 | display: flex;
63 | flex-wrap: wrap;
64 | }
65 |
66 | .invisible {
67 | visibility: hidden;
68 | }
69 |
70 | .item {
71 | margin: 2px;
72 | display: flex;
73 | flex-direction: column;
74 | align-items: center;
75 | width: 30px;
76 | height: 30px;
77 | }
78 |
79 | .item img {
80 | width: 28px;
81 | }
82 |
83 | .ghostItem img {
84 | width: 28px;
85 | }
86 | .ghostItem .number {
87 | top: -20px;
88 | right: -13px;
89 | }
90 |
91 | ::selection {
92 | background: transparent;
93 | }
94 |
95 | ::-moz-selection {
96 | background: transparent;
97 | }
98 |
99 | .copy {
100 | font-family: 'VT323', monospace;
101 | font-size: 18px;
102 | width: 350px;
103 | display: flex;
104 | justify-content: flex-end;
105 | color: #333;
106 | }
107 |
108 | a {
109 | color: inherit;
110 | text-decoration: inherit;
111 | }
112 |
--------------------------------------------------------------------------------