DRAW A CAT
-
-
-
That is what a four-dimensional cat must look like.
-
-
Check out my 1337 drawing skillz!
Okay, I might have cheated a bit
// [X] Add text input for setting image url // [X] Connect opacity to range input // [~] Connect backgroundPosition to range input (not quite there yet) // [ ] Connect backgroundSize to select or radio input // [ ] Add file input for setting image url from local file // [X] Implement image resizing // [X] Implement accepting image drops on canvas // [X] Implement paste // [ ] Implement image resizing and zoom via right-crag and mousewheel on canvas // [ ] Style the UI a little better // [X] Test on latest Firefox (53.0.3) // [X] Test on Chrome 58.0.numbers // [ ] Test on latest Opera (whatever it is) // [ ] Test on Edge // [ ] Test on Firefox 22 // [ ] Test on Internet Explorer(s) // [ ] Implement edge detection, vectorization and drawing over their canvas // [ ] Implement worldwide peace (function setupOverlay(){ let container = document.querySelector('#edges2cats'); let canvas = container.querySelector('canvas'); let overlay = container.querySelector('.overlay'); if( overlay ){ // There can be only one. overlay.parentNode.removeChild(overlay); } overlay = document.createElement('div'); overlay.className = 'overlay'; container.appendChild(overlay); setupDragAndDrop(overlay); let s = overlay.style; // typing is tiresome container.style.position = 'relative'; s.position = 'absolute'; s.width = '256px'; s.height = '256px'; s.left = '141px'; s.top = '50px'; // WOMM s.opacity = 0.5; s.backgroundSize = 'contain'; // or 'cover', depends s.backgroundPosition = 'center'; s.backgroundRepeat = 'no-repeat'; let controls = container.querySelector('.controls'); if( controls ){ // There can be only one. controls.parentNode.removeChild(controls); } controls = document.createElement('div'); container.appendChild(controls); controls.className = 'controls'; controls.innerHTML = [ '<style>', '.image-source-input { width: 51em; }', '</style>', '<div class="controls">', '<label>Image source: ', '<input class="image-source-input" placeholder="Paste anywhere or drag image on canvas, or write URL here">', '</label> ', '<label>Opacity: ', '<input class="opacity-input" min="0" max="1" step="0.05" type="range" value="' + s.opacity + '"></input> ', '<span class="current-opacity"> 0.50 </span>', '</label> ', '<fieldset>', '<legend>Size</legend>', '<label>Zoom: <input class="zoom-level" type="range" min="-13" max="10" step="0.01" class="image-x" value="0"></label> ', '<button class="size-100"> 100 % </button> ', '<button class="size-cover"> Cover </button> ', '<button class="size-contain"> Contain </button> ', '<span class="current-zoom">100 %</span>', '</fieldset> ', '<fieldset>', '<legend>Position</legend>', '<label>X: <input type="range" min="-100" max="200" class="position-x" value="50">%</label> ', '<label>Y: <input type="range" min="-100" max="200" class="position-y" value="50">%</label> ', '<button class="center-image">Center</button>', '</fieldset>', '</div>', ].join('\n'); let currentOpacitySpan = controls.querySelector('.current-opacity'); connectInput(controls, '.opacity-input', (val) => { s.opacity = val; currentOpacitySpan.textContent = Number(val).toFixed(2); }); connectInput(controls, '.zoom-level', (val) => { let level = 100 * (2 ** val); s.backgroundSize = level + '%'; currentZoomSpan.textContent = Number(level).toFixed(3) + '%'; }); let currentZoomSpan = controls.querySelector('.current-zoom'); connectInput(controls, '.size-100', () => { s.backgroundSize = '100%'; currentZoomSpan.textContent = '100 %'; }); connectInput(controls, '.size-cover', ()=>{ s.backgroundSize = 'cover'; currentZoomSpan.textContent = 'Cover: minimum that fills canvas'; }); connectInput(controls, '.size-contain', ()=>{ s.backgroundSize = 'contain'; currentZoomSpan.textContent = 'Contain: maximum that fits canvas'; }); connectInput(controls, '.position-x', ()=>{ updateBackgroundPosition(container); }); connectInput(controls, '.position-y', ()=>{ updateBackgroundPosition(container); }); connectInput(controls, '.center-image', () => { let xInput = container.querySelector('.position-x'); let yInput = container.querySelector('.position-y'); xInput.value = yInput.value = 50; s.backgroundPosition = 'center'; }); setupDragAndDrop( controls.querySelector('.image-source-input') ); document.addEventListener('paste', onPaste); setupDragAndDrop( document.body ); // Screw it, let's do this //s.pointerEvents = 'none'; return; // Done. Rest is helper functions function onPaste(evt){ evt.stopPropagation(); evt.preventDefault(); let data = processDataTransfer(evt.clipboardData); if( !data ){ return; } setImageSource(data); } function processDataTransfer(dataTransfer){ let text = dataTransfer.getData("text"); if( text ){ return text; } let uriList = dataTransfer.getData("text/uri-list"); if( uriList && uriList.length > 0 ){ return uriList[0]; } let plainText = dataTransfer.getData("text/plain"); if( plainText ){ return plainText; } let url = dataTransfer.getData("URL"); if( url ){ return url; } let files = dataTransfer.files; if( files && files.length == 1 ){ return files[0]; } return false; } function setupDragAndDrop(target){ target.addEventListener('dragover', (evt) => { // evt.dataTransfer has no .hasData() method, // .getData() returns nothing except on drops, // and I don't feel like iterating over .types. //if( processDataTransfer(evt.dataTransfer) ){ evt.preventDefault(); //} }); target.addEventListener('dragenter', (evt) => { //if( processDataTransfer(evt.dataTransfer) ){ evt.dataTransfer.dropEffect = "link"; //} }); target.addEventListener('drop', (evt) => { evt.preventDefault(); let data = processDataTransfer(evt.dataTransfer); if( !data ) return; setImageSource(data); }); } function setImageUrl(url){ s.backgroundImage = "url('"+url+"')"; container.querySelector('.image-source-input').value = url; } function setImageSource(urlOrFile){ if( typeof urlOrFile === 'string' ){ return setImageUrl(urlOrFile); } if( urlOrFile instanceof File ){ let objUrl = URL.createObjectURL(urlOrFile); return setImageUrl(objUrl); } // Shrug. Don't know what to do with anything else. } function updateBackgroundPosition(container){ let xInput = container.querySelector('.position-x'); let yInput = container.querySelector('.position-y'); s.backgroundPosition = xInput.value + '% ' + yInput.value + '%'; } function connectInput(controls, selector, onInput){ let input = controls.querySelector(selector); let handler = (evt) => { onInput(input.value); } if( input instanceof HTMLInputElement ){ input.addEventListener('input', handler, false); input.addEventListener('change', handler, false); } else if( input instanceof HTMLButtonElement ){ input.addEventListener('click', handler, false); } return input; } })();
-
Cheshire cat: doesn't understand the concept well but with a bit of trial and error... kinda:
-
-
-
@Fox Touched up the lineart a bit. Not sure if it improved the output.
Then I thought "Hey, I'm gonna make Mewtwo because he's technically a cat"
Then I thought "I should probably look up a reference image; I don't think that's what Mewtwo looks like."
And that's how I managed to perform a worse experiment on Mewtwo than Giovanni ever could.
-
@Fox I think the first one has avatar potential. I already thought this about your previous post.
-
-
@Fox I did a more zoomed-out version of Mewtwo to try to make him less mangled.
...I failed him again.
-
@Zecc said in DRAW A CAT:
@Fox I think the first one has avatar potential. I already thought this about your previous post.
It came out surprisingly adorable.
-
I decided to try a different feline pokemon. I'm so, so sorry, Incineroar.
ETA: The coloration actually came out pretty accurate though, so that's something.
-
@Fox said in DRAW A CAT:
Hey, I'm gonna make Mewtwo because he's technically a cat
Mewtwo's a cat?!?
...OK, I guess it makes sense
https://www.youtube.com/watch?v=Z6sfIBoPL_Y
Aw man, now I want a cat with superpowers. But the nice kind, not the murdering kind.
-
@Fox said in DRAW A CAT:
I decided to try a different feline pokemon. I'm so, so sorry, Incineroar.
Litten fared little better.
-
@Fox Poor Pyroar.
-
@Fox And my personal favorite feline, Lion
Actually came out pretty well once I added some texture and defined the lineart better (it started horrible with just the lineart)
-
cat volcano
-
@Fox Another attempt with a different reference image. The mane came out pretty nice. That's about it, unfortunately.
-
@anonymous234 said in DRAW A CAT:
Aw man, now I want a cat with superpowers. But the nice kind, not the murdering kind.
Like...a dog?
-
@Fox Take three. I think it came out pretty well.
-
Tried to catify a certain wild fox
-
@Fox said in DRAW A CAT:
Tried to catify a certain wild fox
Looks like someone's been hitting the hops pretty hard.
-
This looks like some creepypasta fan art.
-
@ben_lubar tagged this thread:
-
@anonymous234 said in DRAW A CAT:
the murdering kind.
-
-
@Fox said in DRAW A CAT:
the
murderburninating kind.
-
@Fox I said consummate v's, consummate!!
-
:@anonymous234:: Posts a link to the neural network cats thread that's been dormant for years
: Makes a necropost with the memeEveryone: