├── CNAME ├── images └── icon.png ├── rainbow-draw.png ├── .editorconfig ├── README.md ├── index.html ├── style.css └── script.js /CNAME: -------------------------------------------------------------------------------- 1 | rainbow.b5n.sh -------------------------------------------------------------------------------- /images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sesh/rainbow-draw/main/images/icon.png -------------------------------------------------------------------------------- /rainbow-draw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sesh/rainbow-draw/main/rainbow-draw.png -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | 2 | [*] 3 | indent_style = space 4 | indent_size = 2 5 | max_line_length = 120 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Rainbow Draw](./rainbow-draw.png) 2 | 3 | A simple drawing app that supports multitouch and fun colours. 4 | 5 | All games as part of this series are: 6 | 7 | - Ad free 8 | - Tracker free 9 | - Have no timers or high scores 10 | 11 | Originally developed on [Glitch](https://glitch.com), migrated to Github for safe keeping. 12 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Rainbow, Draw! 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | /* CSS files add styling rules to your content */ 2 | 3 | html, 4 | body { 5 | touch-action: none; 6 | -webkit-touch-callout: none; 7 | -webkit-user-select: none; 8 | -khtml-user-select: none; 9 | -moz-user-select: none; 10 | -ms-user-select: none; 11 | user-select: none; 12 | } 13 | 14 | body { 15 | font-family: helvetica, arial, sans-serif; 16 | width: 100%; 17 | height: 100vh; 18 | background-color: #eeefee; 19 | overflow: hidden; 20 | } 21 | 22 | .box { 23 | width: 10px; 24 | height: 10px; 25 | position: absolute; 26 | top: 20px; 27 | left: 100px; 28 | } 29 | 30 | .colour-picker, 31 | .trash { 32 | border: 3px solid white; 33 | width: 32px; 34 | height: 32px; 35 | border-radius: 50%; 36 | -webkit-box-shadow: 3px 3px 8px 0px rgba(0, 0, 0, 0.15); 37 | -moz-box-shadow: 3px 3px 8px 0px rgba(0, 0, 0, 0.15); 38 | box-shadow: 3px 3px 8px 0px rgba(0, 0, 0, 0.15); 39 | position: absolute; 40 | bottom: 20px; 41 | right: 20px; 42 | cursor: pointer; 43 | z-index: 10; 44 | } 45 | 46 | .trash { 47 | left: 20px !important; 48 | display: flex; 49 | align-items: center; 50 | justify-content: center; 51 | } 52 | 53 | .rainbow { 54 | transform: rotate(11deg); 55 | background-size: cover; 56 | background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAwIDgwMDAiPgogICAgPHJlY3QgZmlsbD0iI2YwM2UzZSIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwMCIgeT0iMCIgeD0iMCIvPgogICAgPHJlY3QgZmlsbD0iI2ZkN2UxNCIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwMCIgeT0iMTAwMCIgeD0iMCIvPgogICAgPHJlY3QgZmlsbD0iI2ZmZTA2NiIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwMCIgeT0iMjAwMCIgeD0iMCIvPgogICAgPHJlY3QgZmlsbD0iIzUxY2Y2NiIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwMCIgeT0iMzAwMCIgeD0iMCIvPgogICAgPHJlY3QgZmlsbD0iIzIyOGJlNiIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwMCIgeT0iNDAwMCIgeD0iMCIvPgogICAgPHJlY3QgZmlsbD0iI2NjNWRlOCIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwMCIgeT0iNTAwMCIgeD0iMCIvPgogICAgPHJlY3QgZmlsbD0iI2Y3ODNhYyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwMCIgeT0iNjAwMCIgeD0iMCIvPgogICAgPHJlY3QgZmlsbD0iIzg2OGU5NiIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwMCIgeT0iNzAwMCIgeD0iMCIvPgo8L3N2Zz4K") 57 | } 58 | -------------------------------------------------------------------------------- /script.js: -------------------------------------------------------------------------------- 1 | const grid = 10; 2 | let body = document.querySelector("body"); 3 | 4 | let hue; 5 | 6 | let colours = ["#f03e3e", "#fd7e14", "#ffe066", "#51cf66", "#228be6", "#cc5de8", "#f783ac", "#868e96", "rainbow"]; 7 | let hues = ["red", "orange", "yellow", "green", "blue", "purple", "pink", "monochrome", ""]; 8 | 9 | function init() { 10 | for (let j in colours) { 11 | let el = document.createElement("div"); 12 | 13 | if (colours[j].indexOf("#") == 0) { 14 | el.style.backgroundColor = colours[j]; 15 | el.className = "colour-picker"; 16 | } else { 17 | el.className = "colour-picker rainbow"; 18 | } 19 | 20 | el.setAttribute("hue", hues[j]); 21 | el.style.bottom = j * 50 + 20 + "px"; 22 | 23 | el.onclick = (e) => { 24 | hue = e.target.getAttribute("hue"); 25 | e.preventDefault(); 26 | }; 27 | 28 | body.appendChild(el); 29 | } 30 | 31 | let el = document.createElement("div"); 32 | el.className = "trash"; 33 | el.innerText = "♻"; 34 | el.onclick = (e) => { 35 | body.innerHTML = ""; 36 | init(); 37 | }; 38 | body.appendChild(el); 39 | hue = null; 40 | } 41 | 42 | function drawAtTouch(t) { 43 | var el = document.createElement("div"); 44 | el.style.top = Math.floor(t.pageY / grid) * grid + "px"; 45 | el.style.left = Math.floor(t.pageX / grid) * grid + "px"; 46 | el.style.width = grid + "px"; 47 | el.style.height = grid + "px"; 48 | el.className = "box"; 49 | 50 | if (hue) { 51 | el.style.backgroundColor = randomColor({ hue: hue }); 52 | } else { 53 | el.style.backgroundColor = randomColor(); 54 | } 55 | body.appendChild(el); 56 | } 57 | 58 | function handleTouch(e) { 59 | e.preventDefault(); 60 | 61 | let touches = e.changedTouches; 62 | let text = "touches"; 63 | 64 | if (e.buttons && e.buttons == 1 && touches == undefined) { 65 | touches = [e]; 66 | } 67 | 68 | if (touches) { 69 | for (let t of touches) { 70 | drawAtTouch(t); 71 | } 72 | } 73 | } 74 | 75 | body.ontouchmove = handleTouch; 76 | body.ontouchstart = handleTouch; 77 | body.ontouchend = (e) => { 78 | e.target == body && e.preventDefault(); 79 | }; 80 | body.ontouchcancel = (e) => { 81 | e.preventDefault(); 82 | }; 83 | 84 | body.onmousemove = handleTouch; 85 | init(); 86 | --------------------------------------------------------------------------------