Very nice - yes that's quite quick and definitely uses less memory. When I tested it on an older iPad and on an Android device the difference in speed between the two approaches is a bit more obvious. Watching my kids bash away at this and expect it to keep up makes me more willing to use extra memory to do so. All that said though, I really like your implementation, it would likely be the right choice for a lot of use cases
Thanks! By the way, I realised just now I was leaving a bit of performance on the table: getImageData() is slow, but I don't need to do it on click, I can do it just once after loading the image. Changing that gets it to be consistently under 100ms for clicks after the first one.