diff --git a/README.md b/README.md index 1ea09f8..e7cd75a 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,13 @@ hackrew is a framework for making character creator/dressup game applets a la [picrew](https://picrew.me/). You can check out an online demo [here](https://ksadov.github.io/hackrew/), or see a more complex version on [Neocities](https://cherrvak.neocities.org/furrycreator/index.html). To make your own character creator, fork this repo or download the files and follow the instructions below. +This builder uses hackrew as a base, and implements some accessibility improvements to allow more users to interact with it. + ## Instructions ### Step 1: start a web server -The applet won't run correctly unless it's launched from a server. To launch it from your own machine, cd into the hackrew folder, run ./serve.sh (you'll need [Python 3 installed on your machine](https://www.python.org/downloads/)) from the command line and navigate to [http://localhost:8000/](http://localhost:8000/) in your browser. Once you're done developing your character creator, you can host it on a remote server, like Neocities or Github Pages. +The applet won't run correctly unless it's launched from a server. To launch it from your own machine, cd into the hackrew folder, run `./serve.sh` (you'll need [Python 3 installed on your machine](https://www.python.org/downloads/)) from the command line and navigate to [http://localhost:8000/](http://localhost:8000/) in your browser. Once you're done developing your character creator, you can host it on a remote server, like Neocities or Github Pages. ### Step 2: specify your parts The character creator applet's visual components are comprised of "parts" (ex: "body", "ears", "tail", "accessories"), which have varieties called "items" (ex: the items for ears are "small" and "big"). Each item is represented by a .png image with a transparent background. The applet allows the user to create different characters by layering different item .pngs on top of each other. @@ -51,11 +53,10 @@ The script will take a while to run, but at the end you'll have your color varia ### Step 4: edit the UI To change the colors and graphics of the UI, edit the variables at the top of index.css. -### Step 5: host your applet +### Step 5: host your avatar builder The only files that you need to host your applet are index.html, index.css imagemaker.js, and the imagemakerAssets folder. To host on Github pages, fork this repo, customize the files, and follow the intrucutions [here](https://docs.github.com/en/pages/getting-started-with-github-pages/creating-a-github-pages-site). -To host on Neocities, make a new folder to contain your project (in my [example page](https://cherrvak.neocities.org/furrycreator/index.html), the folder is called "furrycreator"). Place the files index.html, index.css and imagemaker.js in this folder. Then place the folder imagemakerAssets in the same directory, but be careful to preserve the subfolder structure: the Neocities drag-and-drop GUI won't preserve the seperate folders for each part, which will break the code, so you're better off making a folder called imagemakerAssets and dragging-and-dropping in each part folder one-by-one. Then your completed applet will be on the page `https://your-neocities-page.neocities.org/your-folder-name/` (ex: https://cherrvak.neocities.org/furrycreator/) +Since this repo generates a static site, you can turn on Github Pages in the Settings of the Repo and it should automatically deploy for you, detecting the presence of an index.html file. It will host your builder at `yourRepoName.github.io`. You can change the name of your repository to get a URL you like. -## TODO -- Add item shift button or draggable items? \ No newline at end of file +Pushing your changes to main will trigger a deploy. diff --git a/imagemaker.js b/imagemaker.js index 237935b..ec4de6e 100644 --- a/imagemaker.js +++ b/imagemaker.js @@ -86,7 +86,6 @@ window.addEventListener('load', function(ev) { */ function initButtons() { randomButton.addEventListener('click', randomize); - infoButton.addEventListener('click', toggleInfo); paletteButton.addEventListener('click', togglePalette); itemsButton.addEventListener('click', toggleItems); return null; @@ -107,7 +106,7 @@ window.addEventListener('load', function(ev) { function initPalette() { for (let i = 0; i < parts.length; i++) { for (let j = 0; j < parts[i].colors.length; j++) { - let colorElement = document.createElement('li'); + let colorElement = document.createElement('button'); colorElement.style.backgroundColor = "#" + parts[i].colors[j]; colorElement.addEventListener('click', function() { selectColor(i, j); @@ -226,7 +225,7 @@ window.addEventListener('load', function(ev) { */ function initPartsElements() { for (let i = 0; i < parts.length; i++) { - let part = document.createElement('li'); + let part = document.createElement('button'); let partIcon = document.createElement('img'); partIcon.src = assetsPath + parts[i].folder + "/icon.png"; part.appendChild(partIcon); @@ -249,7 +248,7 @@ window.addEventListener('load', function(ev) { } for (let i = 0; i < parts.length; i++) { if (parts[i].noneAllowed) { - let noneButton = document.createElement('li'); + let noneButton = document.createElement('button'); let noneButtonIcon = document.createElement('img'); noneButtonIcon.src = assetsPath + "none_button.svg"; noneButton.appendChild(noneButtonIcon); @@ -258,7 +257,7 @@ window.addEventListener('load', function(ev) { itemsElements[i][0] = noneButton; } for (let j = 0; j < parts[i].items.length; j++) { - let item = document.createElement('li'); + let item = document.createElement('button'); let itemIcon = document.createElement('img'); itemIcon.id = "icon_" + i.toString() + "_" + j.toString(); itemIcon.src = (assetsPath + diff --git a/index.css b/index.css index 631a1f7..dcce3ba 100644 --- a/index.css +++ b/index.css @@ -3,11 +3,13 @@ --loading-bg-color: #FFFFFF; /* the color of the border around selected part and icon buttons */ --select-color: #FF0000; + /* the color of the focus ring */ + --focus-color: #0008ff; /* the color/image filepath of the background of the image display area */ - --image-background-color: hsla(0,0%,93.3%,.5); + --image-background-color: hsla(0, 0%, 93.3%, .5); --image-background-png: "none"; /* the color/image filepath of the random button */ - --random-button-color: #ffbd15; + --random-button-color: #9d05f0; --random-button-png: "none"; /* the color/image filepath of the items menu background*/ --control-panel-color: #ccc; @@ -20,15 +22,9 @@ /* the color/image filepath of the palette toggle button */ --palette-toggle-color: #fff; --palette-toggle-svg: url("imagemakerAssets/palette_toggle.svg"); - /* the color/image filepath of the info button */ - --info-toggle-color: #fff; - --info-toggle-png: "none"; - /* the color/image filepath of the info button */ - --move-toggle-color: #fff; - --move-toggle-svg: url("imagemakerAssets/move_toggle.svg"); /* the image filepath of the logo */ --logo-png: "none"; - --save-button-color: #00b33c; + --save-button-color: #008a2e; } * { @@ -38,222 +34,208 @@ box-sizing: border-box; } +button:focus-visible, +a:focus-visible { + outline: 3px solid var(--focus-color); +} + body { height: 90vh; } -.imagemaker { - height: 100%; +.sr-only { + border: 0 !important; + clip: rect(1px, 1px, 1px, 1px) !important; + /* 1 */ + -webkit-clip-path: inset(50%) !important; + clip-path: inset(50%) !important; + /* 2 */ + height: 1px !important; + margin: -1px !important; + overflow: hidden !important; + padding: 0 !important; + position: absolute !important; + width: 1px !important; + white-space: nowrap !important; + /* 3 */ } + @media (orientation: landscape) { .imagemaker_container_wrapper { - width: 800px; + width: 800px; } - + .imagemaker_container { - flex-direction: row; + flex-direction: row; } - + .imagemaker_canvas_wrapper { - max-height: 100%; + max-height: 100%; } .imagemaker_save_button { - top: 5px; - height: 36px; + top: 5px; + height: 36px; } .imagemaker_ctrl_buttons { - position: absolute; - top: 4px; - right: 4px; - bottom: auto; - left: auto; - width: 50px; - height: 50px; - z-index: 0; + position: absolute; + top: 10px; + right: 65px; + bottom: auto; + left: auto; + width: 50px; + height: 50px; + z-index: 0; } .imagemaker_control_wrapper { - position: relative; - flex: 1; - display: flex; - flex-direction: column; - min-width: 275px; - height: 100% + position: relative; + flex: 1; + display: flex; + flex-direction: column; + min-width: 275px; + height: 100% } - .imagemaker_info_show_button { - position: absolute; - top: auto; - right: auto; - bottom: 4px; - left: 4px; - width: 50px; - height: 50px; - } .imagemaker_random_button { - min-width: 60px; - font-size: 14px; + min-width: 60px; + font-size: 14px; } - .imagemaker_parts_menu ul { - margin-left: 10px; + .imagemaker_parts_menu nav { + margin-left: 10px; } - .imagemaker_itemlist ul li { - width: 33.2%; + .imagemaker_itemlist div button { + width: 33.2%; } .imagemaker_parts_menu { - height: 68px; + height: 68px; } - .imagemaker_parts_menu ul li { - width: 60px; - height: auto; + .imagemaker_parts_menu nav button { + width: 60px; + height: auto; } - .imagemaker_ctrl_buttons .button_show_itemlist { - width: 50px; - height: 50px; - line-height: 50px; + .imagemaker_ctrl_buttons button { + min-width: 50px; + height: 50px; + line-height: 50px; } - .imagemaker_ctrl_buttons .button_show_colorpalette { - align-items: center; - width: 50px; - height: 50px; - line-height: 50px; - left: -55px; - } - .imagemaker_colorpalette ul li { - width: 48px; - height: 48px; + .imagemaker_colorpalette div button{ + width: 48px; + height: 48px; } - .imagemaker_info_content { - font-size: 3vh; - } + } @media (orientation: portrait) { .loading { - font-size: 3vh; + font-size: 3vh; } - + .imagemaker_container_wrapper { - width: 95vw; - min-height: 95vh; + width: 95vw; + min-height: 95vh; } .imagemaker_container { - flex-direction: column; + flex-direction: column; } .imagemaker_canvas_wrapper { - max-height: 50vh; + max-height: 50vh; } .imagemaker_save_button { - height: 4vh; - font-size: 3vh; + height: 4vh; + font-size: 3vh; } .imagemaker_ctrl_buttons { - bottom: 4px; - right: 4px; - top: auto; - left: auto; + position:absolute; + bottom: 10px; + right: 10px; + top: auto; + left: auto; } .imagemaker_control_wrapper { - position: relative; - flex: 1; - display: flex; - flex-direction: column; - height: 100% - } - - .imagemaker_info_show_button { - position: absolute; - top: 4px; - right: 4px; - bottom: auto; - left: auto; - height: 6vh; - width: 6vh; - font-size: 5vh + position: relative; + flex: 1; + display: flex; + flex-direction: column; + height: 100% } .imagemaker_parts_menu_wrapper { - padding-left: 18.18%; + padding-left: 18.18%; } - .imagemaker_parts_menu ul { - margin-left: 0px; + .imagemaker_parts_menu nav { + margin-left: 0px; } - .imagemaker_itemlist ul li { - width: 23.75%; + .imagemaker_itemlist div button { + width: 23.75%; } .imagemaker_parts_menu_wrapper { - min-height: 10vh; + min-height: 10vh; } - + .imagemaker_parts_menu { - height: 100%; + height: 100%; } - .imagemaker_parts_menu ul { - width: auto; - height: 100%; - } - - .imagemaker_parts_menu ul li { - width: 9vh; - height: 9vh; + .imagemaker_parts_menu nav { + width: auto; + height: 100%; } - .imagemaker_parts_menu ul li img { - width: 100%; - height: 100%; - position: relative; + .imagemaker_parts_menu nav button { + width: 9vh; + height: 9vh; } - .imagemaker_random_button { - font-size: 4vw; + .imagemaker_parts_menu nav button img { + width: 100%; + height: 100%; + position: relative; } - .imagemaker_ctrl_buttons { - width: 6vh; - height: 6vh; + .imagemaker_random_button { + font-size: 4vw; } .imagemaker_ctrl_buttons .button_show_colorpalette { - width: 6vh; - height: 6vh; - line-height: 6vh; - left: -10vh; - bottom: 4px; + width: 6vh; + height: 6vh; + line-height: 6vh; + left: -10vh; + bottom: 4px; } .imagemaker_ctrl_buttons .button_show_itemlist { - width: 6vh; - height: 6vh; - bottom: 4px; - right: 4px; + width: 6vh; + height: 6vh; + bottom: 4px; + right: 4px; } - .imagemaker_colorpalette ul li { - width: 8vh; - height: 8vh; + .imagemaker_colorpalette div button { + width: 8vh; + height: 8vh; } - + } .imagemaker_container_wrapper { @@ -268,7 +250,7 @@ body { height: 100%; display: flex; overflow: hidden; - background-color: var(--image-background-color, hsla(0,0%,93.3%,.5)); + background-color: var(--image-background-color, hsla(0, 0%, 93.3%, .5)); background-image: var(--image-background-png, none); background-position: center; background-repeat: no-repeat; @@ -307,8 +289,6 @@ body { position: absolute; font-size: 3vh; background-color: var(--loading-bg-color, #FFFFFF); - //padding: 3px; - //bottom: 4px; } .imagemaker_canvas_wrapper canvas { @@ -322,10 +302,8 @@ body { .imagemaker_ctrl_buttons { - position: absolute; - width: 50px; - height: 50px; z-index: 0; + display: flex; } .imagemaker_control_wrapper { @@ -351,7 +329,7 @@ body { -ms-overflow-style: scrollbar; } -.imagemaker_parts_menu ul { +.imagemaker_parts_menu nav { margin-right: 0; margin-top: 0; margin-bottom: 0; @@ -360,7 +338,7 @@ body { list-style: "none"; } -.imagemaker_parts_menu ul li { +.imagemaker_parts_menu nav button{ position: relative; min-width: 48px; margin: 4px 2px 4px 2px; @@ -421,7 +399,7 @@ body { margin: .5%; } -.imagemaker_itemlist ul li { +.imagemaker_itemlist div button { margin: 5px; background-color: var(--item-button-color, #fff); border-radius: 4px; @@ -434,7 +412,7 @@ body { cursor: pointer; } -.imagemaker_itemlist ul li img { +.imagemaker_itemlist div button img { width: 100%; height: 100%; } @@ -451,7 +429,6 @@ body { border-radius: 50%; cursor: pointer; text-align: center; - position: absolute; } .imagemaker_ctrl_buttons .button_show_controller { @@ -489,23 +466,6 @@ body { border-radius: 50%; cursor: pointer; text-align: center; - position: absolute; -} - -.imagemaker_info_show_button { - display: inline-flex; - justify-content: center; - align-items: center; - background-color: var(--info-toggle-color, #fff); - background-image: var(--info-toggle-png, "none"); - background-position: center; - background-repeat: no-repeat; - color: #333; - border: 0 solid #aaa; - border-radius: 50%; - cursor: pointer; - text-align: center; - z-index: 20; } .imagemaker_logo { @@ -517,7 +477,7 @@ body { display: inline-block; background-size: contain; background-repeat: no-repeat; - background-color: #ff597e; + background-color: #ff597e; background-image: var(--logo-png, "none"); width: 66px; height: 20px; @@ -529,24 +489,6 @@ body { border: 3px solid var(--select-color, #ff0000); } -.imagemaker_info_wrapper { - height: 100%; - background-color: #eeeeee; - position: absolute; - top: 4px; - right: 4px; - bottom: 4px; - left: 4px; - height: calc(100% - 8px); - overflow: hidden; - z-index: 10; - display: none; -} - -.imagemaker_info_content { - margin: 10px; -} - .imagemaker_colorpalette { flex: 1; /*display: flex;*/ @@ -566,21 +508,20 @@ body { text-align: center; } -.imagemaker_colorpalette ul li { +.imagemaker_colorpalette div button { margin: 1px; border-radius: 50%; border: 2px solid #eee; box-sizing: border-box; - list-style-type: none!important; + list-style-type: none !important; cursor: pointer; } -.imagemaker_colorpalette ul > * { +.imagemaker_colorpalette ul>* { display: inline-block; list-style-type: none; margin: 0; padding: 0; vertical-align: middle; font-size: 1rem; -} - +} \ No newline at end of file diff --git a/index.html b/index.html index b1d4f72..afd11fd 100644 --- a/index.html +++ b/index.html @@ -1,67 +1,76 @@ -
- - - - - -- I made this applet using my open-source character creator - framework, hackrew. -
-- If you're interested in making your own, I suggest - checking out the linked Github repository for documentation. -
-