gpt4 book ai didi

flutter - 在 flutter 中用 2 张图片设计背景

转载 作者:IT王子 更新时间:2023-10-29 06:52:28 35 4
gpt4 key购买 nike

我想创建一个新的无状态小部件类,它由 2 个图像(顶部、底部)和一条线(由函数定义,例如 (x){x+500} ,一个宽度(如果不应该被绘制,可以是 0)和一个颜色)分隔两个图像。

对于每个像素:

  • 如果像素的 y 位置大于 f(x) + width/2 的结果,则绘制底部的像素
  • 如果小于f(x) - width/2,则绘制顶部的像素
  • 否则应绘制给定线条颜色的像素

下面是一个示例,mywidget({'top': A, 'bottom': B, 'f': (x){return sin(x)+500;}, 'width': 1 , 'color': Color(0xFFFFFFFF)}); 看起来像:

(0,0)
+------+
| |
| A |
| __ |
|/ \__|
| |
| B |
+------+(e.g. 1920,1080)

是否有一个线条小部件,其形状由(数学)函数定义?

this唯一的方法吗?或者是否有一个容器小部件已经允许这样做?我看过 Stack widget但这并不能完全解决问题,因为我需要一个结构来决定渲染哪个像素,如上所述。决定应该发生什么的功能应该由用户提供。

最佳答案

ClipPathCustomClipper<Path>可以帮助你。
您可以获得什么:
Result screenshot
示例源代码:

import 'dart:math';

import 'package:flutter/material.dart';

void main() {
runApp(
MaterialApp(
home: Scaffold(
body: ClippedPartsWidget(
top: Container(
color: Colors.red,
),
bottom: Container(
color: Colors.blue,
),
splitFunction: (Size size, double x) {
// normalizing x to make it exactly one wave
final normalizedX = x / size.width * 2 * pi;
final waveHeight = size.height / 15;
final y = size.height / 2 - sin(normalizedX) * waveHeight;

return y;
},
),
),
),
);
}

class ClippedPartsWidget extends StatelessWidget {
final Widget top;
final Widget bottom;
final double Function(Size, double) splitFunction;

ClippedPartsWidget({
@required this.top,
@required this.bottom,
@required this.splitFunction,
});

@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
// I'm putting unmodified top widget to back. I wont cut it.
// Instead I'll overlay it with clipped bottom widget.
top,
Align(
alignment: Alignment.bottomCenter,
child: ClipPath(
clipper: FunctionClipper(splitFunction: splitFunction),
child: bottom,
),
),
],
);
}
}

class FunctionClipper extends CustomClipper<Path> {
final double Function(Size, double) splitFunction;

FunctionClipper({@required this.splitFunction}) : super();

Path getClip(Size size) {
final path = Path();

// move to split line starting point
path.moveTo(0, splitFunction(size, 0));

// draw split line
for (double x = 1; x <= size.width; x++) {
path.lineTo(x, splitFunction(size, x));
}

// close bottom part of screen
path.lineTo(size.width, size.height);
path.lineTo(0, size.height);

return path;
}

@override
bool shouldReclip(CustomClipper<Path> oldClipper) {
// I'm returning fixed 'true' value here for simplicity, it's not the part of actual question
// basically that means that clipping will be redrawn on any changes
return true;
}
}

关于flutter - 在 flutter 中用 2 张图片设计背景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57362018/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com