Exactly, paint() is a snapshot in time. Don’t think about paint() in terms of an animation. In that case you need to create multiple paint() calls that result in a changing scene.
Just correcting this:
The Graphics context is not blank but contains garbage, probably from previous paints, but could be anything really. That’s why not implementing paint() in a component with
setOpaque (true) will assert. In opaque components you need to fill the background, either with a g.fillAll() call or if you know for a fact you will cover all pixels you can do that as well.
If you need the background from the previous call you can draw in an Image and use that in the next call. I didn’t understand your flow exactly, but something like that could work:
void paint (juce::Graphics& g) override
juce::Image canvas (juce::Image::ARGB, getWidth(), getHeight(), false);
juce::Graphics cg (canvas);
cg.drawImageAt (m_lastImage, 0, 0); // copy from last drawing
// draw your stuff on cg here
// draw the virtual image
g.drawImageAt (m_lastImage, 0, 0);
// save the canvas
m_lastImage = canvas;