Cary Clark | bef063a | 2017-10-31 15:44:45 -0400 | [diff] [blame] | 1 | |
| 2 | var canvas |
| 3 | var context |
| 4 | var getFromWeb = true |
| 5 | var mouseDown = false |
| 6 | var scale = .6 |
| 7 | var outset = 15 |
| 8 | var columnWidth = 256 |
| 9 | var maxHeight = 256 |
| 10 | var lastLink = null |
| 11 | var lastLinkStr = null |
| 12 | var labelback = {} |
| 13 | var loadedImages = 0 |
| 14 | var images = {} |
| 15 | var imagesLength = 0; |
| 16 | |
| 17 | function recContains(rec, value) { |
Cary Clark | d49980c | 2017-11-01 10:21:45 -0400 | [diff] [blame] | 18 | if (!value.length) |
| 19 | return 0 |
| 20 | var lc = value.toLowerCase() |
| 21 | if (rec.name.toLowerCase().indexOf(lc) >= 0) |
| 22 | return 1 |
| 23 | if (rec.code.toLowerCase().indexOf(lc) >= 0) |
| 24 | return 2 |
| 25 | return 3 |
Cary Clark | bef063a | 2017-10-31 15:44:45 -0400 | [diff] [blame] | 26 | } |
| 27 | |
| 28 | function setLink(recstr) { |
| 29 | var under |
| 30 | var link = recstr |
Cary Clark | d49980c | 2017-11-01 10:21:45 -0400 | [diff] [blame] | 31 | if (!link.startsWith("Sk")) { |
Cary Clark | bef063a | 2017-10-31 15:44:45 -0400 | [diff] [blame] | 32 | under = link.indexOf('_') |
Cary Clark | d49980c | 2017-11-01 10:21:45 -0400 | [diff] [blame] | 33 | link = link.substring(under + 1) |
Cary Clark | bef063a | 2017-10-31 15:44:45 -0400 | [diff] [blame] | 34 | } |
| 35 | under = link.lastIndexOf('_') |
| 36 | var len = link.length |
Cary Clark | d49980c | 2017-11-01 10:21:45 -0400 | [diff] [blame] | 37 | if (under == len - 2) { |
Cary Clark | bef063a | 2017-10-31 15:44:45 -0400 | [diff] [blame] | 38 | var letter = link[len - 1] |
Cary Clark | d49980c | 2017-11-01 10:21:45 -0400 | [diff] [blame] | 39 | if ('a' <= letter && letter <= 'z') { |
| 40 | link = link.substr(0, len - 2) |
| 41 | } else if ('0' <= letter && letter <= '9') { |
| 42 | link = link.substr(0, len - 2) |
| 43 | } |
Cary Clark | bef063a | 2017-10-31 15:44:45 -0400 | [diff] [blame] | 44 | } |
Cary Clark | d49980c | 2017-11-01 10:21:45 -0400 | [diff] [blame] | 45 | lastLinkStr = link |
Cary Clark | bef063a | 2017-10-31 15:44:45 -0400 | [diff] [blame] | 46 | } |
| 47 | |
Cary Clark | d49980c | 2017-11-01 10:21:45 -0400 | [diff] [blame] | 48 | function showLink() { |
| 49 | var link = lastLink.file + '#' + lastLinkStr |
| 50 | context.save() |
Cary Clark | bef063a | 2017-10-31 15:44:45 -0400 | [diff] [blame] | 51 | context.font = "normal 16px Arial"; |
Cary Clark | d49980c | 2017-11-01 10:21:45 -0400 | [diff] [blame] | 52 | labelback.w = Math.max(labelback.w, context.measureText(link).width + 8) |
| 53 | context.beginPath() |
| 54 | context.rect(labelback.x, labelback.y, labelback.w, labelback.h) |
| 55 | context.fillStyle = "rgba(232,180,220, 1)" |
| 56 | context.fill() |
| 57 | context.fillStyle = "rgba(64,32,48, 1)" |
| 58 | context.fillText(link, labelback.x + 4, labelback.y + 16) |
| 59 | context.restore() |
Cary Clark | bef063a | 2017-10-31 15:44:45 -0400 | [diff] [blame] | 60 | } |
| 61 | |
Cary Clark | d49980c | 2017-11-01 10:21:45 -0400 | [diff] [blame] | 62 | function imageIterator(callout, state) { |
Cary Clark | bef063a | 2017-10-31 15:44:45 -0400 | [diff] [blame] | 63 | var row = outset + 30 |
| 64 | var column = outset |
| 65 | for (var recstr in pngs) { |
| 66 | var rec = pngs[recstr] |
| 67 | var contains = recContains(rec, input.value) |
Cary Clark | d49980c | 2017-11-01 10:21:45 -0400 | [diff] [blame] | 68 | if (3 == contains) |
| 69 | continue; |
Cary Clark | bef063a | 2017-10-31 15:44:45 -0400 | [diff] [blame] | 70 | var height = rec.height < maxHeight ? rec.height : maxHeight |
| 71 | if (callout(state, column, row, height, contains, recstr)) |
| 72 | break; |
| 73 | row += height + outset |
| 74 | if (row >= canvas.height / scale) { |
| 75 | row = 0 |
| 76 | column += columnWidth + outset |
| 77 | if (column >= canvas.width / scale) { |
| 78 | break |
| 79 | } |
| 80 | } |
| 81 | } |
| 82 | } |
| 83 | |
| 84 | function handleMouseOver(event) { |
| 85 | var callout = function(state, column, row, height, contains, recstr) { |
| 86 | if (state.x >= column && state.x <= column + columnWidth && |
| 87 | state.y >= row && state.y <= row + height) { |
| 88 | document.body.style.cursor = "pointer" |
| 89 | lastLink = pngs[recstr] |
| 90 | setLink(recstr) |
| 91 | showLink() |
| 92 | return true |
| 93 | } |
| 94 | return false |
| 95 | } |
| 96 | var state = { |
| 97 | x: (event.clientX - 5) / scale, |
| 98 | y: (event.clientY - 7) / scale |
| 99 | } |
| 100 | document.body.style.cursor = "" |
| 101 | lastLink = null |
| 102 | imageIterator(callout, state) |
| 103 | } |
| 104 | |
| 105 | function handleMouseClick() { |
| 106 | if (null != lastLink) { |
| 107 | var link = 'https://skia.org/user/api/' + lastLink.file + '#' + lastLinkStr |
| 108 | window.location = link |
| 109 | } |
| 110 | } |
| 111 | |
Cary Clark | d49980c | 2017-11-01 10:21:45 -0400 | [diff] [blame] | 112 | function doKeyPress(evt) { |
Cary Clark | bef063a | 2017-10-31 15:44:45 -0400 | [diff] [blame] | 113 | idiv.style.height = 20 |
| 114 | input.focus() |
| 115 | } |
| 116 | |
Cary Clark | d49980c | 2017-11-01 10:21:45 -0400 | [diff] [blame] | 117 | function drawImage(hash, x, y, w, h, contains) { |
Cary Clark | bef063a | 2017-10-31 15:44:45 -0400 | [diff] [blame] | 118 | context.save() |
| 119 | context.transform(scale, 0, 0, scale, 0, 0) |
| 120 | context.save() |
| 121 | context.beginPath() |
| 122 | context.rect(x, y, w, h) |
| 123 | context.clip() |
| 124 | context.drawImage(images[hash], x, y) |
| 125 | context.restore() |
| 126 | context.beginPath() |
| 127 | context.rect(x, y, w, h) |
| 128 | context.strokeStyle = 1 == contains ? "red" : "black" |
| 129 | context.stroke() |
| 130 | context.restore() |
| 131 | } |
| 132 | |
| 133 | function draw() { |
| 134 | var callout = function(state, column, row, height, contains, recstr) { |
| 135 | drawImage(pngs[recstr].hash, column, row, columnWidth, height, contains) |
Cary Clark | d49980c | 2017-11-01 10:21:45 -0400 | [diff] [blame] | 136 | return false |
Cary Clark | bef063a | 2017-10-31 15:44:45 -0400 | [diff] [blame] | 137 | } |
| 138 | imageIterator(callout, null) |
| 139 | } |
| 140 | |
Cary Clark | d49980c | 2017-11-01 10:21:45 -0400 | [diff] [blame] | 141 | function sleep(ms) { |
| 142 | return new Promise(resolve => setTimeout(resolve, ms)); |
| 143 | } |
| 144 | |
| 145 | async function redraw() { |
| 146 | context.strokeStyle = "white" |
Cary Clark | bef063a | 2017-10-31 15:44:45 -0400 | [diff] [blame] | 147 | context.beginPath() |
| 148 | context.fillStyle = "white" |
| 149 | context.rect(0, 30, canvas.width, canvas.height) |
| 150 | context.fill() |
| 151 | context.rect((256 + outset) * scale, 0, canvas.width, 30) |
Cary Clark | d49980c | 2017-11-01 10:21:45 -0400 | [diff] [blame] | 152 | context.fill() |
| 153 | for (var image in images) { |
| 154 | image.drawn = false |
| 155 | } |
| 156 | do { |
| 157 | draw(); |
| 158 | if (loadedImages >= imagesLength) |
| 159 | break; |
| 160 | console.debug(" loadedImages:" + loadedImages + " imagesLength:" + imagesLength) |
| 161 | await sleep(1000); |
| 162 | } while (true) |
Cary Clark | bef063a | 2017-10-31 15:44:45 -0400 | [diff] [blame] | 163 | } |
| 164 | |
| 165 | function resize() { |
| 166 | setSize() |
| 167 | redraw() |
| 168 | } |
| 169 | |
| 170 | function setSize() { |
| 171 | canvas.width = window.innerWidth - 20 |
| 172 | canvas.height = window.innerHeight - 20 |
| 173 | labelback.x = 0 |
| 174 | labelback.y = canvas.height - 20 |
| 175 | labelback.w = 0 |
| 176 | labelback.h = 20 |
| 177 | } |
| 178 | |
Cary Clark | d49980c | 2017-11-01 10:21:45 -0400 | [diff] [blame] | 179 | function loadImages() { |
| 180 | for (var recstr in pngs) { |
Cary Clark | bef063a | 2017-10-31 15:44:45 -0400 | [diff] [blame] | 181 | var rec = pngs[recstr] |
| 182 | var image = new Image() |
Cary Clark | d49980c | 2017-11-01 10:21:45 -0400 | [diff] [blame] | 183 | images[rec.hash] = image |
Cary Clark | bef063a | 2017-10-31 15:44:45 -0400 | [diff] [blame] | 184 | if (getFromWeb) |
| 185 | image.src = 'https://fiddle.skia.org/i/' |
| 186 | image.src += rec.hash + '_raster.png' |
Cary Clark | d49980c | 2017-11-01 10:21:45 -0400 | [diff] [blame] | 187 | image.onload = function () { |
| 188 | loadedImages += 1 |
| 189 | } |
| 190 | imagesLength += 1; |
| 191 | } |
Cary Clark | bef063a | 2017-10-31 15:44:45 -0400 | [diff] [blame] | 192 | } |
| 193 | |
Cary Clark | d49980c | 2017-11-01 10:21:45 -0400 | [diff] [blame] | 194 | function start() { |
Cary Clark | bef063a | 2017-10-31 15:44:45 -0400 | [diff] [blame] | 195 | loadImages() |
| 196 | window.addEventListener('keypress', doKeyPress, true); |
| 197 | window.addEventListener('keydown', doKeyPress, true); |
| 198 | canvas = document.getElementById('canvas') |
| 199 | context = canvas.getContext('2d') |
| 200 | resize() |
| 201 | } |
| 202 | |
| 203 | </script> |
| 204 | </head> |
| 205 | |
| 206 | <body onLoad="start()" onresize="resize()"> |
Cary Clark | d49980c | 2017-11-01 10:21:45 -0400 | [diff] [blame] | 207 | <div style="height:0" id="idiv"> |
| 208 | <input type="text" id="input" onkeypress="redraw()" onkeydown="redraw()"/> |
Cary Clark | bef063a | 2017-10-31 15:44:45 -0400 | [diff] [blame] | 209 | </div> |
| 210 | <canvas id="canvas" width="750" height="500" |
| 211 | onmousedown="mouseDown = true" |
| 212 | onmouseup="mouseDown = false" |
| 213 | onmousemove="handleMouseOver(event)" |
| 214 | onclick="handleMouseClick()" |
| 215 | ></canvas > |
| 216 | </body> |
| 217 | </html> |