How to make lv_arc elliptical shape?

What do you want to achieve?

Hi everyone, I am trying to implement lv_arc with following design, but I am struggling with getting the required shape of Arc. I see that arc uses min(w, h) to draw rounded shape, while I need it to be a little elliptical.
Screenshot from 2025-11-13 11-04-50

Is there a way to do that with Arc or do I have to draw it manually?

Code to reproduce

    lv_obj_t *arc = lv_arc_create(lv_screen_active());
    lv_obj_remove_style_all(arc);
    lv_arc_set_range(arc, 0, 100);
    lv_obj_set_style_arc_rounded(arc, true, LV_PART_MAIN);
    lv_obj_set_style_arc_width(arc, 16, LV_PART_MAIN);
    lv_obj_set_style_arc_color(arc, lv_color_hex(0x1A1A1A), LV_PART_MAIN);

    lv_obj_set_style_arc_rounded(arc, true, LV_PART_INDICATOR);
    lv_obj_set_style_arc_width(arc, 8, LV_PART_INDICATOR);
    lv_obj_set_style_arc_color(arc, lv_color_hex(0x979797), LV_PART_INDICATOR);
    lv_obj_set_style_pad_all(arc, 4, LV_PART_INDICATOR);

    lv_obj_set_style_radius(arc, LV_RADIUS_CIRCLE, LV_PART_KNOB);
    lv_obj_set_style_bg_color(arc, lv_color_hex(0xEBEBEB), LV_PART_KNOB);
    lv_obj_set_style_bg_opa(arc, LV_OPA_COVER, LV_PART_KNOB);
    lv_obj_set_style_pad_all(arc, 2, LV_PART_KNOB);

    lv_obj_set_size(arc, 132, 103);

Screenshot from 2025-11-13 11-34-07

Environment

  • MCU/MPU/Board: N/A
  • LVGL version: v9.4.0-dev

Hi!

Let me try to understand more what kind of visual you want to achieve with the arc.

Do you want the whole arc to be more flat or smashed? Something like this?
image

If so then I’m not sure if that is possible.

But if you want something similar to the following, then you can adjust the properties start/end angles of the arc and start/end angles of its background. Also set a bigger size.
slim_arc

This is the code I used:

  lv_obj_t *arc = lv_arc_create(lv_screen_active());
  lv_obj_remove_style_all(arc);
  lv_obj_set_width(arc, 180);
  lv_obj_set_height(arc, 180);
  lv_arc_set_range(arc, 0, 100);
  lv_obj_set_style_arc_rounded(arc, true, LV_PART_MAIN);
  lv_obj_set_style_arc_width(arc, 16, LV_PART_MAIN);
  lv_obj_set_style_arc_color(arc, lv_color_hex(0x1A1A1A), LV_PART_MAIN);
  lv_arc_set_bg_start_angle(arc, 230);
  lv_arc_set_bg_end_angle(arc, 310);
  lv_arc_set_start_angle(arc, 230);
  lv_arc_set_end_angle(arc, 310);

  lv_obj_set_style_arc_rounded(arc, true, LV_PART_INDICATOR);
  lv_obj_set_style_arc_width(arc, 8, LV_PART_INDICATOR);
  lv_obj_set_style_arc_color(arc, lv_color_hex(0x979797), LV_PART_INDICATOR);
  lv_obj_set_style_pad_all(arc, 4, LV_PART_INDICATOR);

  lv_obj_set_style_radius(arc, LV_RADIUS_CIRCLE, LV_PART_KNOB);
  lv_obj_set_style_bg_color(arc, lv_color_hex(0xEBEBEB), LV_PART_KNOB);
  lv_obj_set_style_bg_opa(arc, LV_OPA_COVER, LV_PART_KNOB);
  lv_obj_set_style_pad_all(arc, 2, LV_PART_KNOB);

The arc widget doesn’t use any elliptical math. It uses only circle math so it will always use the smallest side of the size that is set to determine what the radius of the “arc” should be…

With that knowledge you can “stitch” together multiple arc widgets in order to get the effect you are looking for. It is a rather complicated process because it will involve hiding and showing the handle/thumb when you cross from one arc to the next. It will also involve altering how LVGL handles click and drag events so when you cross one of those thresholds you can transfer the input into the next widget. It’s not going to be something that would be easy to do that’s for sure.