mirror of
https://github.com/penpot/penpot.git
synced 2026-07-22 14:08:03 +00:00
🐛 Add :stroke-image support to plugins API (#10683)
This commit is contained in:
parent
a006a12ab6
commit
c11d3aaaa7
@ -206,11 +206,13 @@
|
||||
;; strokeCapStart?: StrokeCap;
|
||||
;; strokeCapEnd?: StrokeCap;
|
||||
;; strokeColorGradient?: Gradient;
|
||||
;; strokeImage?: ImageData;
|
||||
;; }
|
||||
(defn format-stroke
|
||||
[{:keys [stroke-color stroke-color-ref-file stroke-color-ref-id
|
||||
stroke-opacity stroke-style stroke-width stroke-alignment
|
||||
stroke-cap-start stroke-cap-end stroke-color-gradient] :as stroke}]
|
||||
stroke-cap-start stroke-cap-end stroke-color-gradient
|
||||
stroke-image] :as stroke}]
|
||||
|
||||
(when (some? stroke)
|
||||
(obj/without-empty
|
||||
@ -223,7 +225,8 @@
|
||||
:strokeAlignment (format-key stroke-alignment)
|
||||
:strokeCapStart (format-key stroke-cap-start)
|
||||
:strokeCapEnd (format-key stroke-cap-end)
|
||||
:strokeColorGradient (format-gradient stroke-color-gradient)})))
|
||||
:strokeColorGradient (format-gradient stroke-color-gradient)
|
||||
:strokeImage (format-image stroke-image)})))
|
||||
|
||||
|
||||
;; export interface Blur {
|
||||
|
||||
@ -214,6 +214,7 @@
|
||||
;; strokeCapStart?: StrokeCap;
|
||||
;; strokeCapEnd?: StrokeCap;
|
||||
;; strokeColorGradient?: Gradient;
|
||||
;; strokeImage?: ImageData;
|
||||
;; }
|
||||
(defn parse-stroke
|
||||
[^js stroke]
|
||||
@ -228,7 +229,8 @@
|
||||
:stroke-alignment (-> (obj/get stroke "strokeAlignment") parse-keyword)
|
||||
:stroke-cap-start (-> (obj/get stroke "strokeCapStart") parse-keyword)
|
||||
:stroke-cap-end (-> (obj/get stroke "strokeCapEnd") parse-keyword)
|
||||
:stroke-color-gradient (-> (obj/get stroke "strokeColorGradient") parse-gradient)})))
|
||||
:stroke-color-gradient (-> (obj/get stroke "strokeColorGradient") parse-gradient)
|
||||
:stroke-image (-> (obj/get stroke "strokeImage") parse-image-data)})))
|
||||
|
||||
(defn parse-strokes
|
||||
[^js strokes]
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
:strokeColor
|
||||
{:get (fn [] (:stroke-color @state))
|
||||
:set (fn [v]
|
||||
(swap! state #(-> % (assoc :stroke-color v) (dissoc :stroke-color-gradient)))
|
||||
(swap! state #(-> % (assoc :stroke-color v) (dissoc :stroke-color-gradient :stroke-image)))
|
||||
(on-change!))}
|
||||
|
||||
:strokeColorRefFile
|
||||
@ -62,7 +62,13 @@
|
||||
(on-change!))]
|
||||
(gradients/gradient-proxy gradient-state gradient-change!))))
|
||||
:set (fn [v]
|
||||
(swap! state #(-> % (assoc :stroke-color-gradient (parser/parse-gradient v)) (dissoc :stroke-color)))
|
||||
(swap! state #(-> % (assoc :stroke-color-gradient (parser/parse-gradient v)) (dissoc :stroke-color :stroke-image)))
|
||||
(on-change!))}
|
||||
|
||||
:strokeImage
|
||||
{:get (fn [] (format/format-image (:stroke-image @state)))
|
||||
:set (fn [v]
|
||||
(swap! state #(-> % (assoc :stroke-image (parser/parse-image-data v)) (dissoc :stroke-color :stroke-color-gradient)))
|
||||
(on-change!))})))
|
||||
|
||||
(defn format-strokes
|
||||
|
||||
@ -467,6 +467,7 @@
|
||||
"strokeColorGradient",
|
||||
"strokeColorRefFile",
|
||||
"strokeColorRefId",
|
||||
"strokeImage",
|
||||
"strokeOpacity",
|
||||
"strokeStyle",
|
||||
"strokeWidth"
|
||||
@ -7791,6 +7792,12 @@
|
||||
"kind": "getset",
|
||||
"type": "Gradient",
|
||||
"array": false
|
||||
},
|
||||
"strokeImage": {
|
||||
"decl": "Stroke",
|
||||
"kind": "getset",
|
||||
"type": "ImageData",
|
||||
"array": false
|
||||
}
|
||||
},
|
||||
"SvgRaw": {
|
||||
|
||||
@ -61,6 +61,39 @@ describe.skipIfMocked('Media', () => {
|
||||
expect(fill.fillImage).toBeDefined();
|
||||
});
|
||||
|
||||
test('an uploaded image can be used as a stroke', async (ctx) => {
|
||||
const image = await ctx.penpot.uploadMediaData(
|
||||
'plugin-stroke',
|
||||
PNG_1X1,
|
||||
'image/png',
|
||||
);
|
||||
const rect = ctx.penpot.createRectangle();
|
||||
ctx.board.appendChild(rect);
|
||||
rect.strokes = [{ strokeWidth: 2, strokeImage: image }];
|
||||
|
||||
const strokes = rect.strokes;
|
||||
expect(strokes).toHaveLength(1);
|
||||
expect(strokes[0].strokeImage).toBeDefined();
|
||||
});
|
||||
|
||||
test('Stroke.strokeImage can be set on a stroke and clears the solid color', async (ctx) => {
|
||||
const image = await ctx.penpot.uploadMediaData(
|
||||
'plugin-stroke-set',
|
||||
PNG_1X1,
|
||||
'image/png',
|
||||
);
|
||||
const rect = ctx.penpot.createRectangle();
|
||||
ctx.board.appendChild(rect);
|
||||
rect.strokes = [{ strokeColor: '#ff0000', strokeWidth: 2 }];
|
||||
|
||||
// Set strokeImage directly on the stroke (covers Stroke.strokeImage (set)).
|
||||
const stroke = rect.strokes[0];
|
||||
stroke.strokeImage = image;
|
||||
expect(stroke.strokeImage).toBeDefined();
|
||||
// An image stroke replaces the solid color.
|
||||
expect(stroke.strokeColor).toBeFalsy();
|
||||
});
|
||||
|
||||
test('uploadMediaUrl resolves to image data', async (ctx) => {
|
||||
// Needs the backend to fetch an external URL, which may be unavailable in
|
||||
// the headless runner; treat a rejection as an environment limitation.
|
||||
|
||||
4
plugins/libs/plugin-types/index.d.ts
vendored
4
plugins/libs/plugin-types/index.d.ts
vendored
@ -4180,6 +4180,10 @@ export interface Stroke {
|
||||
* The optional gradient stroke defined by a Gradient object.
|
||||
*/
|
||||
strokeColorGradient?: Gradient;
|
||||
/**
|
||||
* The optional image stroke defined by an ImageData object.
|
||||
*/
|
||||
strokeImage?: ImageData;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user