3

I know that Flutter's Canvas.drawShadow translates to Skia's SkShadowUtils::DrawUtils, where the elevation on the Flutter side affects the zPlaneParams on the Skia side (see the flutter::PhysicalShapeLayer::DrawShadow engine implementation, which is called with dpr from Canvas::drawShadow which is directly called from Dart), however, I cannot at all figure out how elevation behaves when drawing a shadow in native (forget Flutter web because that is completely different again):

void drawShadow(Path path, Color color, double elevation, bool transparentOccluder) { // ...
  _drawShadow(path, color.value, elevation, transparentOccluder);
}
void _drawShadow(Path path, int color, double elevation, bool transparentOccluder)
                 native 'Canvas_drawShadow';
void Canvas::drawShadow(const CanvasPath* path, SkColor color, double elevation, bool transparentOccluder)
{ // ..
  SkScalar dpr = UIDartState::Current()->window()->viewport_metrics().device_pixel_ratio;
  flutter::PhysicalShapeLayer::DrawShadow(canvas_, path->path(), color,
                                          elevation, transparentOccluder, dpr);
}
void flutter::PhysicalShapeLayer::DrawShadow(...) {
   // ...
   SkShadowUtils::DrawShadow(canvas, path, SkPoint3::Make(0, 0, dpr * elevation),
       SkPoint3::Make(shadow_x, shadow_y, dpr * kLightHeight),
       dpr * kLightRadius, ambientColor, spotColor, flags);
 }

And so on - see the Skia source code link if you wish to dive deeper.

Precisely, I do not understand what range of numbers elevation accepts, i.e. what numbers I can put it - I would have assumed 0 to 600 looking at kLightHeight, but that does not map completely to what I experienced. Even then, I still do not know what values for elevation mean.
Additionally, I would love to understand how the size of the path and the canvas scale generally affects the shadow and potentially where the light source is located.
I need this information to ensure consistent behavior across different screen sizes.

So if anyone knows or can figure it out from the links I provided, I would gladly accept any input.

creativecreatorormaybenot
  • 114,516
  • 58
  • 291
  • 402

1 Answers1

0

After looking at SkPoint3::Make(0, 0, dpr * elevation) line of code.

I am sure that the value of elevation is used for determining how long/broad the shadow below the widget is going to be.

I don't think there's anything more to the elevation value.

If you find anything more than this, I am all ears. This is a really good question by the way.

Harshvardhan Joshi
  • 2,855
  • 2
  • 18
  • 31
  • 1
    Thanks for your answer! This is basically what I know already because that is how *elevation* usually works (the docs mention [Material elevation](https://material.io/develop/web/components/elevation/)). I was wondering more about what range of numbers is accepted, how this elevation value is affected by the size of the path, and potentially where the light source is located because that is what I need to know if I want to ensure consistend behavior. – creativecreatorormaybenot Jan 01 '20 at 14:16
  • 1
    In case of light source you can always assume that the light source is on the top left end of the device screen. Because that is where the origin(0,0) is and also on the opposite of that direction the shadow is cast. – Harshvardhan Joshi Jan 01 '20 at 14:18
  • 1
    but yeah, your question about size of path is one of core questios that I am wondering about my self – Harshvardhan Joshi Jan 01 '20 at 14:19