From 573252cc8fed19559b483aeb278f7ddccec16559 Mon Sep 17 00:00:00 2001 From: Isaiah Odhner Date: Mon, 11 May 2020 13:22:21 -0400 Subject: [PATCH] Handle no clipart results --- src/speech-recognition.js | 74 ++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 32 deletions(-) diff --git a/src/speech-recognition.js b/src/speech-recognition.js index 1dcd0e7..40d061c 100644 --- a/src/speech-recognition.js +++ b/src/speech-recognition.js @@ -255,39 +255,47 @@ window.interpret_command = (command, default_to_entering_text)=> { const draw_match = command.match(/(?:draw|sketch|doodle|render|(?:paint|draw|do|render|sketch) (?:a picture|an image|a drawing|a painting|a rendition|a sketch|a doodle) of) (?:an? )?(.+)/i); if (draw_match) { best_match_text = draw_match[0]; - best_match_fn = async ()=> { + best_match_fn = ()=> { const subject_matter = draw_match[1]; - const results = await find_clipart(subject_matter); - // @TODO: select less complex images (less file size to width, say?) maybe, and/or better semantic matches by looking for the search terms in the title? - // detect gradients / spread out histogram at least, and reject based on that - let image_url = results[~~(Math.random() * results.length)].image_url; - console.log("Using source image:", image_url); - if (!image_url.match(/^data:/)) { - image_url = `https://jspaint-cors-proxy.herokuapp.com/${image_url}`; - } - const img = new Image(); - img.crossOrigin = "Anonymous"; - img.onload = ()=> { - // @TODO: find an empty spot on the canvas for the sketch, smaller if need be - const max_sketch_width = 500; - const max_sketch_height = 500; - let aspect_ratio = img.width / img.height; - let width = Math.min(img.width, max_sketch_width); - let height = Math.min(img.height, max_sketch_height); - if (width / height < aspect_ratio) { - height = width / aspect_ratio; + find_clipart(subject_matter).then((results)=> { + + // @TODO: select less complex images (less file size to width, say?) maybe, and/or better semantic matches by looking for the search terms in the title? + // detect gradients / spread out histogram at least, and reject based on that + let image_url = results[~~(Math.random() * results.length)].image_url; + console.log("Using source image:", image_url); + if (!image_url.match(/^data:/)) { + image_url = `https://jspaint-cors-proxy.herokuapp.com/${image_url}`; } - if (width / height > aspect_ratio) { - width = height * aspect_ratio; + const img = new Image(); + img.crossOrigin = "Anonymous"; + img.onload = ()=> { + // @TODO: find an empty spot on the canvas for the sketch, smaller if need be + const max_sketch_width = 500; + const max_sketch_height = 500; + let aspect_ratio = img.width / img.height; + let width = Math.min(img.width, max_sketch_width); + let height = Math.min(img.height, max_sketch_height); + if (width / height < aspect_ratio) { + height = width / aspect_ratio; + } + if (width / height > aspect_ratio) { + width = height * aspect_ratio; + } + const img_canvas = make_canvas(width, height); + img_canvas.ctx.drawImage(img, 0, 0, width, height); + const image_data = img_canvas.ctx.getImageData(0, 0, img_canvas.width, img_canvas.height); + resize_canvas_without_saving_dimensions(Math.max(canvas.width, image_data.width), Math.max(canvas.height, image_data.height)); + trace_and_sketch(image_data); + // @TODO: visible cancel button, and Escape key handling, in addition to the "stop" voice command + }; + img.src = image_url; + }, (error)=> { + if (error.code === "no-results") { + $status_text.text(`No clipart found for '${subject_matter}'`); + } else { + show_error_message("Failed to find clipart.", error); } - const img_canvas = make_canvas(width, height); - img_canvas.ctx.drawImage(img, 0, 0, width, height); - const image_data = img_canvas.ctx.getImageData(0, 0, img_canvas.width, img_canvas.height); - resize_canvas_without_saving_dimensions(Math.max(canvas.width, image_data.width), Math.max(canvas.height, image_data.height)); - trace_and_sketch(image_data); - // @TODO: visible cancel button, and Escape key handling, in addition to the "stop" voice command - }; - img.src = image_url; + }); }; } } @@ -453,14 +461,16 @@ function find_clipart(query) { // fallback in case they also change the class for images (this may match totally irrelevant things) if (items.length === 0) { console.log("Fallback to most imgs"); - items = $html.find("img").toArray() + items = $html.find("img:not(.sw_spd):not(.rms_img):not(.flagIcon)").toArray() .filter((el)=> !el.closest("[role='navigation'], nav")) // ignore "Related searches", "Refine your search" etc. .map((el)=> ({image_url: el.src || el.dataset.src, title: ""})) .filter(validate_item); } console.log(`Search results for '${query}':`, items); if (items.length === 0) { - throw new Error(`failed to get clipart: no results returned for query '${query}'`); + const error = new Error(`failed to get clipart: no results returned for query '${query}'`); + error.code = "no-results"; + throw error; } return items; })