Draggable Mr Potato Head Parts in JavaScript π₯
permalinkWho doesn't like Mr. and Mrs. Potato Head!
Today we will recreat the iconic Mr. Potato Head in JavaScript
. Then we will learn to drag all of Mr. Potato Heads parts on the screen to his body.
Try the example code on Codepen permalink
See the Pen Vanilla JavaScript draggable Mr Potato Head π₯ by Chris Bongers (@rebelchris) on CodePen.
HTML Structure permalink
As for out HTML
, we have a fairly simple setup.
<div class="container">
<div class="parts">
<img src="https://i.imgur.com/GONNbHf.png" class="draggable" />
<img src="https://i.imgur.com/optSzq4.png" class="draggable" />
<img src="https://i.imgur.com/qJDxc4o.png" class="draggable" />
<img src="https://i.imgur.com/tIZGoeR.png" class="draggable" />
<img src="https://i.imgur.com/bKlbeXU.png" class="draggable" />
<img src="https://i.imgur.com/eUPbX3H.png" class="draggable" />
<img src="https://i.imgur.com/voJPsR5.png" class="draggable" />
<img src="https://i.imgur.com/dt2gqit.png" class="draggable" />
<img src="https://i.imgur.com/2POeyJZ.png" class="draggable" />
</div>
<div class="body">
<img src="https://i.imgur.com/kXbr8Tb.png" />
</div>
</div>
So we use the container to wrap all image tags. Then we have the Mr Potato Head parts div.It contains each of the body-parts with a class of draggable
.
And we have our body, which is Mr Potato's body. The body is where we want to drag the elements with JavaScript.
CSS Styling permalink
We use flexbox to center our two divs.
.container {
display: flex;
align-items: center;
justify-content: space-around;
min-height: 100vh;
background: #efefef;
}
The Parts container is then relative
, and we add a small border to make it look nicer.
.container .parts {
position: relative;
border: 3px dashed black;
width: 250px;
height: 100vh;
}
Each PNG will be absolute
so we can place it anywhere in the page.
.container .parts img {
position: absolute;
}
Vanilla JavaScript draggable Mr. Potato Head elements permalink
To make an actual Mr. Potato Head, we need to make sure all the HTML elements for his body parts are draggable!
I did not use the
draggable
element since that requires a dropzone, and it doesn't serve this article.
Let's start by getting our elements with the class draggable
.
const draggableElements = document.querySelectorAll('.draggable');
Then we need to define four basic variables. We will use them to store our position in. We also add a whichDown variable to see which element is dragging.
let initX, initY, firstX, firstY, whichDown;
Next on our list is to loop over each element.
draggableElements.forEach((element) => {
// Code here
});
Then we need to attach a mousedown
eventListener. This will be our starting point. We will define the current x and y position by using offsetLeft
and offsetTop
. Then we get the mouse position x and y.
And we attach an eventListener too mousemove
since that will be us, dragging a part. Once we move our mouse we call the draggable
function which we will make in a second.
draggableElements.forEach((element) => {
element.addEventListener('mousedown', function (e) {
e.preventDefault();
whichDown = this;
initX = this.offsetLeft;
initY = this.offsetTop;
firstX = e.pageX;
firstY = e.pageY;
});
});
window.addEventListener('mousemove', draggable, false);
Let's get started with our JS function to drag elements on the screen.
All this function does is change the left
and top
position of our part. And Set the z-index
higher so it's on top.
function draggable(e) {
e.preventDefault();
if (!whichDown) return;
whichDown.style.zIndex = 9;
whichDown.style.left = initX + e.pageX - firstX + 'px';
whichDown.style.top = initY + e.pageY - firstY + 'px';
}
We calculate the original position of the element + the dragged amount - the initial mouse x. And the same goes for the y position.
That's cool, but we have no way of stopping it dragging now. So let's add a mouseup
listener.
window.addEventListener(
'mouseup',
function () {
if (whichDown) {
whichDown.style.zIndex = 0;
}
whichDown = null;
},
false
);
In this section, we add a mouseup
event to our window, and once that happens, we remove the z-index
from our dragging element and remove the draggable whichDown element.
That is it. We can now drag html elements on the screen as showcased on Mr. Potato Head's body!
Thank you for reading, and let's connect! permalink
Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter