Loading editor/widgets/container/container.cpp +18 −15 Original line number Diff line number Diff line Loading @@ -365,7 +365,7 @@ extern "C" { addField("shape_divider_position", "Shape Divider Position", "select", nullptr, "desktop", mkOpts({"bottom","top","both"}), "simple"); addField("shape_divider_color", "Shape Divider Color", "color_var", nullptr, "desktop", nullptr, "simple"); addField("shape_divider_height", "Shape Divider Height", "text", "80px", "desktop"); addField("shape_divider_flip", "Shape Divider Flip", "checkbox", nullptr, "desktop", nullptr, "simple"); addField("shape_divider_flip", "Shape Divider Invert", "checkbox", nullptr, "desktop", nullptr, "simple"); { json_object *sdf = json_object_array_get_idx(arr, json_object_array_length(arr) - 1); json_object_object_add(sdf, "default", json_object_new_boolean(false)); Loading Loading @@ -1254,22 +1254,11 @@ extern "C" { " line-height: 0; pointer-events: none;"; dividerStyle += (pos == "top") ? " top: 0;" : " bottom: 0;"; if (!shapeDividerHeight.empty()) dividerStyle += " height: " + shapeDividerHeight + ";"; // Position and flip must be independent axis mirrors, not // rotate(180deg) + scaleX(-1): since rotate(180deg) is itself // equivalent to scaleX(-1) scaleY(-1), combining it with an // extra scaleX(-1) for "flip" always cancels the horizontal // component back out (diagonal transforms commute), leaving // only a vertical flip regardless of transform order -- so the // "mirror" checkbox silently did nothing (or the wrong thing) // whenever position was "top". Using scaleY(-1) for the top // position instead of rotate(180deg) gives the same baseline // look (identical for left-right-symmetric shapes, and the // intended vertical flip for asymmetric ones) while composing // cleanly with scaleX(-1): top+flip now yields a true combined // 180-degree-equivalent flip instead of cancelling. // "top" is a pure vertical mirror of the "bottom" shape (not // rotate(180deg), which is equivalent to scaleX(-1) scaleY(-1) // and used to silently cancel with the invert logic below). std::string transform; if (pos == "top") transform += "scaleY(-1) "; if (shapeDividerFlip) transform += "scaleX(-1) "; if (!transform.empty()) dividerStyle += " transform: " + transform + ";"; libhtmlpp::HtmlElement dividerWrap("div"); Loading @@ -1282,7 +1271,21 @@ extern "C" { svg.setAttribute("style", "display: block; width: 100%; height: 100%;"); libhtmlpp::HtmlElement svgPath("path"); if (shapeDividerFlip) { // "Invert" swaps which side of the curve is filled // (convex bulge <-> concave notch) by adding a // full-viewBox rectangle as a second subpath and // letting the even-odd fill rule punch the original // shape out of it. A plain horizontal mirror // (scaleX(-1)) would be invisible on left-right // symmetric shapes like "oval", so this works // uniformly across every shape instead. std::string invertedPath = "M0,0H1200V120H0Z" + path; svgPath.setAttribute("d", invertedPath.c_str()); svgPath.setAttribute("fill-rule", "evenodd"); } else { svgPath.setAttribute("d", path.c_str()); } std::string fill = shapeDividerColor.empty() ? "var(--blogi-bg)" : shapeDividerColor; svgPath.setAttribute("fill", fill.c_str()); Loading editor/widgets/container/translations.h +1 −1 Original line number Diff line number Diff line Loading @@ -84,7 +84,7 @@ namespace blogi { namespace webedit { namespace container_i18n { {"Shape Divider Position", "Formteiler-Position"}, {"Shape Divider Color", "Formteiler-Farbe"}, {"Shape Divider Height", "Formteiler-Höhe"}, {"Shape Divider Flip", "Formteiler spiegeln"}, {"Shape Divider Invert", "Formteiler Wölbung umkehren"}, {"Vertical Align", "Vertikale Ausrichtung"}, {"Width", "Breite"}, }; Loading Loading
editor/widgets/container/container.cpp +18 −15 Original line number Diff line number Diff line Loading @@ -365,7 +365,7 @@ extern "C" { addField("shape_divider_position", "Shape Divider Position", "select", nullptr, "desktop", mkOpts({"bottom","top","both"}), "simple"); addField("shape_divider_color", "Shape Divider Color", "color_var", nullptr, "desktop", nullptr, "simple"); addField("shape_divider_height", "Shape Divider Height", "text", "80px", "desktop"); addField("shape_divider_flip", "Shape Divider Flip", "checkbox", nullptr, "desktop", nullptr, "simple"); addField("shape_divider_flip", "Shape Divider Invert", "checkbox", nullptr, "desktop", nullptr, "simple"); { json_object *sdf = json_object_array_get_idx(arr, json_object_array_length(arr) - 1); json_object_object_add(sdf, "default", json_object_new_boolean(false)); Loading Loading @@ -1254,22 +1254,11 @@ extern "C" { " line-height: 0; pointer-events: none;"; dividerStyle += (pos == "top") ? " top: 0;" : " bottom: 0;"; if (!shapeDividerHeight.empty()) dividerStyle += " height: " + shapeDividerHeight + ";"; // Position and flip must be independent axis mirrors, not // rotate(180deg) + scaleX(-1): since rotate(180deg) is itself // equivalent to scaleX(-1) scaleY(-1), combining it with an // extra scaleX(-1) for "flip" always cancels the horizontal // component back out (diagonal transforms commute), leaving // only a vertical flip regardless of transform order -- so the // "mirror" checkbox silently did nothing (or the wrong thing) // whenever position was "top". Using scaleY(-1) for the top // position instead of rotate(180deg) gives the same baseline // look (identical for left-right-symmetric shapes, and the // intended vertical flip for asymmetric ones) while composing // cleanly with scaleX(-1): top+flip now yields a true combined // 180-degree-equivalent flip instead of cancelling. // "top" is a pure vertical mirror of the "bottom" shape (not // rotate(180deg), which is equivalent to scaleX(-1) scaleY(-1) // and used to silently cancel with the invert logic below). std::string transform; if (pos == "top") transform += "scaleY(-1) "; if (shapeDividerFlip) transform += "scaleX(-1) "; if (!transform.empty()) dividerStyle += " transform: " + transform + ";"; libhtmlpp::HtmlElement dividerWrap("div"); Loading @@ -1282,7 +1271,21 @@ extern "C" { svg.setAttribute("style", "display: block; width: 100%; height: 100%;"); libhtmlpp::HtmlElement svgPath("path"); if (shapeDividerFlip) { // "Invert" swaps which side of the curve is filled // (convex bulge <-> concave notch) by adding a // full-viewBox rectangle as a second subpath and // letting the even-odd fill rule punch the original // shape out of it. A plain horizontal mirror // (scaleX(-1)) would be invisible on left-right // symmetric shapes like "oval", so this works // uniformly across every shape instead. std::string invertedPath = "M0,0H1200V120H0Z" + path; svgPath.setAttribute("d", invertedPath.c_str()); svgPath.setAttribute("fill-rule", "evenodd"); } else { svgPath.setAttribute("d", path.c_str()); } std::string fill = shapeDividerColor.empty() ? "var(--blogi-bg)" : shapeDividerColor; svgPath.setAttribute("fill", fill.c_str()); Loading
editor/widgets/container/translations.h +1 −1 Original line number Diff line number Diff line Loading @@ -84,7 +84,7 @@ namespace blogi { namespace webedit { namespace container_i18n { {"Shape Divider Position", "Formteiler-Position"}, {"Shape Divider Color", "Formteiler-Farbe"}, {"Shape Divider Height", "Formteiler-Höhe"}, {"Shape Divider Flip", "Formteiler spiegeln"}, {"Shape Divider Invert", "Formteiler Wölbung umkehren"}, {"Vertical Align", "Vertikale Ausrichtung"}, {"Width", "Breite"}, }; Loading