Right now juce colour gradients only allow you to specify two points, which will always create a circle with identical width and height. Is there a way to create elliptical gradients?
This would be especially great for converting figma designs into juce code.
Is there maybe a third party module Im not aware of?
Maybe you could create a circle in an offsecreen context, apply the gradient to that, then render it with different x and y mappings into the actual graphical context?
Try applying a transform to the fill type.
void paint(juce::Graphics& g) override
{
auto localBounds = getLocalBounds().toFloat();
juce::ColourGradient gradient{ juce::Colours::magenta,
localBounds.getCentre(),
juce::Colours::cyan,
localBounds.getTopLeft(), true };
auto transform = juce::AffineTransform::scale(0.5f, 1.5f).
translated(getWidth() * 0.25f, getHeight() * -0.25f);
auto fill = juce::FillType{ gradient }.transformed(transform);
g.setFillType(fill);
g.fillRect(localBounds);
}
Matt
Nice solution! Looks very Georgia O’Keefe
I would never have thought of that, nice!
Didn’t even know about juce::FillType::transformed
thanks.
Never even occurred to me that you could do this until I saw the original question and started thinking about what happens in the low-level graphics context.
You could do more; here’s a rotated, translated, and scaled gradient:
Gradient meshes would be even more fun.
Matt
I also found Graphics::addTransform
after seeing your solution, incase your method should be independent of the current fill
Sure; this way you can transform the gradient fill separately from the painted image.
juce::ColourGradient gradient{ juce::Colours::magenta,
localBounds.getCentre(),
juce::Colours::cyan,
localBounds.getTopLeft(), true };
auto transform = juce::AffineTransform{}.
scaled(0.5f, 1.5f).
translated(getWidth() * 0.25f, getHeight() * -0.25f).
rotated(juce::MathConstants<float>::pi * 0.25f, localBounds.getCentreX(), localBounds.getCentreY());
auto fill = juce::FillType{ gradient }.transformed(transform);
g.setFillType(fill);
g.addTransform(AffineTransform::shear(0.2f, 0.0f).translated(-getWidth() * 0.1f, 0.0f));
g.fillEllipse(localBounds.reduced(30.0f));