Прямой способ применения отсутствует и объединяет две краски на одном узле.Мы можем наложить много разных красок (например, сплошные, линейные градиенты или даже рисунки), используя цвет фона через css, но это не скомбинирует.
Итак, чтобы объединить две разные краскис одной стороны - линейный градиент, с другой - заливка шаблона, нам нужно применить их к двум узлам и использовать эффект смешивания между обеими красками.
Согласно опубликованному коду, это SVGPath слинейный градиент:
@Override
public void start(Stage primaryStage) {
Node base = getNodeWithGradient();
BorderPane root = new BorderPane();
Group group = new Group(base);
root.setCenter(group);
Scene scene = new Scene(root, 400, 200);
primaryStage.setScene(scene);
primaryStage.show();
}
private SVGPath getNodeWithGradient() {
List<Color> colors = Arrays.asList(Color.RED, Color.YELLOW, Color.GREEN);
ArrayList<Stop> stops = new ArrayList<>(colors.size() * 2);
for (int i = 0; i < colors.size(); i++) {
stops.add(new Stop(getOffset(i, colors.size()), colors.get(i)));
stops.add(new Stop(getOffset(i + 1, colors.size()), colors.get(i)));
}
LinearGradient lg = new LinearGradient(0, 0, 20, 20, false, CycleMethod.REPEAT, stops);
SVGPath svgPath = getSVGPath();
svgPath.setFill(lg);
svgPath.setStroke(lg);
return svgPath;
}
private SVGPath getSVGPath() {
SVGPath svgPath = new SVGPath();
svgPath.setContent("M-84.1487,-15.8513 a22.4171,22.4171 0 1 0 0,31.7026 h168.2974 a22.4171,22.4171 0 1 0 0,-31.7026 Z");
return svgPath;
}
private double getOffset(double i, int count) {
return (((double) 1) / (double) count * (double) i);
}
Пока это SVGPath с заливкой рисунка:
@Override
public void start(Stage primaryStage) {
Node overlay = getNodeWithPattern();
BorderPane root = new BorderPane();
Group group = new Group(overlay);
root.setCenter(group);
Scene scene = new Scene(root, 400, 200);
primaryStage.setScene(scene);
primaryStage.show();
}
private SVGPath getNodeWithPattern() {
Image hatch = createCrossHatch();
ImagePattern pattern = new ImagePattern(hatch, 0, 0, 10, 10, false);
SVGPath svgPath = getSVGPath();
svgPath.setFill(pattern);
return svgPath;
}
private SVGPath getSVGPath() {
SVGPath svgPath = new SVGPath();
svgPath.setContent("M-84.1487,-15.8513 a22.4171,22.4171 0 1 0 0,31.7026 h168.2974 a22.4171,22.4171 0 1 0 0,-31.7026 Z");
return svgPath;
}
private static Image createCrossHatch() {
Pane pane = new Pane();
pane.setPrefSize(20, 20);
Line fw = new Line(-5, -5, 25, 25);
Line bw = new Line(-5, 25, 25, -5);
fw.setStroke(Color.BLACK);
bw.setStroke(Color.BLACK);
fw.setStrokeWidth(3);
bw.setStrokeWidth(3);
pane.getChildren().addAll(fw, bw);
new Scene(pane);
SnapshotParameters sp = new SnapshotParameters();
return pane.snapshot(sp, null);
}
Теперь хитрость заключается в том, чтобы объединить оба узла SVGPath, добавив режим смешивания к верхнему.
Согласно JavaDoc для BlendMode.ADD
:
Компоненты цвета и альфа-канала из верхнего ввода добавляются к компонентам из нижнего ввода.
@Override
public void start(Stage primaryStage) {
Node base = getNodeWithGradient();
Node overlay = getNodeWithPattern();
overlay.setBlendMode(BlendMode.ADD);
BorderPane root = new BorderPane();
Group group = new Group(base, overlay);
root.setCenter(group);
Scene scene = new Scene(root, 400, 200);
primaryStage.setScene(scene);
primaryStage.show();
}
private SVGPath getNodeWithGradient() {
List<Color> colors = Arrays.asList(Color.RED, Color.YELLOW, Color.GREEN);
ArrayList<Stop> stops = new ArrayList<>(colors.size() * 2);
for (int i = 0; i < colors.size(); i++) {
stops.add(new Stop(getOffset(i, colors.size()), colors.get(i)));
stops.add(new Stop(getOffset(i + 1, colors.size()), colors.get(i)));
}
LinearGradient lg = new LinearGradient(0, 0, 20, 20, false, CycleMethod.REPEAT, stops);
SVGPath svgPath = getSVGPath();
svgPath.setFill(lg);
svgPath.setStroke(lg);
return svgPath;
}
private SVGPath getNodeWithPattern() {
Image hatch = createCrossHatch();
ImagePattern pattern = new ImagePattern(hatch, 0, 0, 10, 10, false);
SVGPath svgPath = getSVGPath();
svgPath.setFill(pattern);
return svgPath;
}
private SVGPath getSVGPath() {
SVGPath svgPath = new SVGPath();
svgPath.setContent("M-84.1487,-15.8513 a22.4171,22.4171 0 1 0 0,31.7026 h168.2974 a22.4171,22.4171 0 1 0 0,-31.7026 Z");
return svgPath;
}
private static Image createCrossHatch() {
Pane pane = new Pane();
pane.setPrefSize(20, 20);
Line fw = new Line(-5, -5, 25, 25);
Line bw = new Line(-5, 25, 25, -5);
fw.setStroke(Color.BLACK);
bw.setStroke(Color.BLACK);
fw.setStrokeWidth(3);
bw.setStrokeWidth(3);
pane.getChildren().addAll(fw, bw);
new Scene(pane);
SnapshotParameters sp = new SnapshotParameters();
return pane.snapshot(sp, null);
}
private double getOffset(double i, int count) {
return (((double) 1) / (double) count * (double) i);
}
И мы получаем желаемый результат: