Compare commits

...

15 Commits

Author SHA1 Message Date
Brent Gardner 64a8e7a99c Add resources to readme 7 years ago
Brent Gardner ee1ebd4d7c Load png 7 years ago
Brent Gardner b729be165b Add sprite 7 years ago
rachel.koldenhoven 5cbbbc70b7 Hold to draw 7 years ago
rachel.koldenhoven 307079543c style 7 years ago
rachel.koldenhoven 8f162092f4 colors 7 years ago
rachel.koldenhoven 330690f972 expand canvas 7 years ago
rachel.koldenhoven 6433be1b3b brush color 7 years ago
rachel.koldenhoven 7ff3bbd0e1 Color swatches 7 years ago
rachel.koldenhoven 21bea1f92a eventlistener turns pixels red 7 years ago
rachel.koldenhoven 6de40658a0 Pixel grid 7 years ago
Brent Gardner fe80bf0448 Fix for InteliJ web server 7 years ago
Brent Gardner f6f51aaedd gitignore 7 years ago
rachel.koldenhoven 9ea669d3ba Scaffolding 7 years ago
rachel.koldenhoven 58da59c8a9 Hello world 7 years ago
  1. 9
      README.md
  2. 8
      index.html
  3. 107
      index.js
  4. BIN
      sprite.png
  5. 55
      style.css

@ -43,6 +43,15 @@ Research [LocalStorage](https://developer.mozilla.org/en-US/docs/Web/API/Storage
Create a fill tool that will [flood fill](https://en.wikipedia.org/wiki/Flood_fill) boundaries with a chosen paint color.
### Bonus 5
Load a PNG file directly onto the canvas using these resources:
- [FileReader.readAsDataUrl](https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL)
- [Canvas.drawImage](https://stackoverflow.com/questions/8751020/how-to-get-a-pixels-x-y-coordinate-color-from-an-image?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa)
- [Image.onload](https://stackoverflow.com/questions/12354865/image-onload-event-and-browser-cache?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa)
- [FileReader example](https://stackoverflow.com/questions/3146483/html5-file-api-read-as-text-and-binary?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa)
- [Get pixel color from Canvas](https://stackoverflow.com/questions/6735470/get-pixel-color-from-canvas-on-mouseover?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa)
### Deployment

@ -0,0 +1,8 @@
<html>
<title>Pixel Art Maker</title>
<head>
<link rel="stylesheet" href="style.css">
<script defer type="module" src="index.js"></script>
</head>
<body></body>
</html>

@ -0,0 +1,107 @@
const WIDTH = 48;
const HEIGHT = 24;
// State
let brushColor = '';
let mouseDown = false;
document.body.addEventListener('mouseup', () => mouseDown = false);
document.body.addEventListener('mouseenter', () => mouseDown = false);
// Container
const container = document.createElement('div');
container.className = 'container';
container.style.width = `${WIDTH * 16}px`;
// Canvas
const canvas = document.createElement('div');
canvas.className = 'canvas';
canvas.addEventListener('mousedown', () => mouseDown = true);
const pixels = [];
for(let y = 0; y < HEIGHT; y++) {
const pxRow = [];
const row = document.createElement('div');
row.className = 'row';
for(let x = 0; x < WIDTH; x++) {
const pixel = document.createElement('div');
pixel.className = 'pixel';
pixel.addEventListener('click', () => pixel.style.backgroundColor = brushColor);
pixel.addEventListener('mouseover', () => {
if(!mouseDown) return;
pixel.style.backgroundColor = brushColor;
});
row.appendChild(pixel);
pxRow.push(pixel);
}
canvas.appendChild(row);
pixels.push(pxRow);
}
container.appendChild(canvas);
// Palette
const colors = ['#b23232', '#ff4848', '#ff6c6c', '#e59b40', '#ffad48', '#ffc57e', '#e5de40', '#fff748', '#fffa91', '#39cc4b', '#48ff5e', '#91ff9e', '#3248b2', '#4867ff', '#91a3ff', '#6432b2', '#8f48ff', '#bb91ff', '#7c2b99', '#cf48ff', '#e291ff', '#000000', '#323232', '#666666', '#999999', '#cccccc', '#ffffff', '#3a2119', '#512e23', '#754233', '#90675b', '#ac8d84'];
const palette = document.createElement('div');
palette.className = 'palette';
for(let color of colors) {
const swatch = document.createElement('div');
swatch.className = 'swatch';
swatch.style.backgroundColor = color;
swatch.addEventListener('click', () => {
brushColor = color;
title.style.backgroundColor = color;
});
palette.appendChild(swatch);
}
const title = document.createElement('h2');
title.innerText = 'BRUSH COLOR';
palette.appendChild(title);
container.appendChild(palette);
// File reader
/*
<input type='file' id='fileinput'>
<input type='button' id='btnLoad' value='Load' onclick='loadFile();'>
*/
const fileDiv = document.createElement('div');
const fileInput = document.createElement('input');
fileInput.setAttribute('type', 'file');
fileDiv.appendChild(fileInput);
const btnLoad = document.createElement('input');
btnLoad.setAttribute('type', 'button');
btnLoad.setAttribute('value', 'Load');
btnLoad.addEventListener('click', () => {
const reader = new FileReader();
reader.addEventListener('load', () => {
const img = new Image();
img.onload = () => {
const canvas = document.createElement('canvas');
canvas.setAttribute('visibility', 'hidden');
canvas.width = img.width;
canvas.height = img.height;
document.body.appendChild(canvas);
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, img.width, img.height);
for(let y = 0; y < img.height / 16; y++) {
for(let x = 0; x < img.width / 16; x++) {
const p = ctx.getImageData(x * 16 + 8, y * 16 + 8, 1, 1).data;
const hex = "#" + ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);
if(y >= pixels.length) continue;
if(x >= pixels[y].length) continue;
pixels[y][x].style.backgroundColor = hex;
}
}
document.body.removeChild(canvas);
};
img.src = reader.result;
}, false);
reader.readAsDataURL(fileInput.files[0]);
});
fileDiv.appendChild(btnLoad);
function rgbToHex(r, g, b) {
if (r > 255 || g > 255 || b > 255)
throw "Invalid color component";
return ((r << 16) | (g << 8) | b).toString(16);
}
document.body.appendChild(container);
document.body.appendChild(fileDiv);

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

@ -0,0 +1,55 @@
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
h2 {
font-family: "Gill Sans";
font-size: 24px;
font-weight: 400;
color: rgb(153, 153, 153);
margin: 0;
}
.container {
display: flex;
flex-direction: column;
padding: 20px;
border-radius: 15px;
background-color: rgb(229, 229, 229);
}
.row {
display: flex;
}
.pixel {
width: 14px;
height: 14px;
border: 1px solid rgb(229, 229, 229);
background-color: white;
}
.palette {
display: flex;
flex-wrap: wrap;
background-color: rgb(229, 229, 229);
align-items: center;
}
.swatch {
width: 35px;
height: 35px;
border: 1px solid rgb(187, 187, 187);
border-radius: 50%;
display: flex;
margin: 2px;
}
.currentSwatch {
width: 50px;
height: 35px;
display: flex;
}
Loading…
Cancel
Save