zoukankan      html  css  js  c++  java
  • 女神节 | 程序员如何低调而又不失逼格

    今天。。。是一个非常重要的日子-女神节。作为一名程序员,如何向心仪的人低调而又不失逼格的表达祝福,关系到我们后半生的幸福,祝福的到位,普通朋友加个字变成女朋友,女朋友变成老婆,如果已经是老婆了,那么这个月的零花钱又能多好几百,想想都激动。

    回到现实,作为程序员,我们当然要独一无二,要与众不同,要突破天际,要能体现我们的身份,逼格满满,因此我们要给女神开发一个天上地下、唯吾独尊的App绝对是你不二的选择。

    废话不多说,No 图 No 说话:

    先来分析一波:

    首先上面的效果是一直在绘制路径,当绘制完花和叶子时在对其着色,因此这里比较难是如何获取路径的点坐标,只要有点的坐标了一个个的画出来也就实现了上面的效果。

    那么现在的重点就是如何获取点坐标,一种方法是人工一个一个的写,然后调整,这种方法工作量太大了,作为程序员怎么能用这种方法呢?怎么才可以让程序生成这些坐标呢?

    想想我们在监听手势(鼠标)时是不是可以获取到当前点的坐标,移动的时候也可以获取到一个移动的路径坐标,因此我们只需要在屏幕上先加载想要的图片,然后按照图片上的路径移动,是不是就可以获取到我们想要的路径了啊。

    对于任何语言来说都可以按照上面的思路来实现,下面以目前非常火热的Flutter来实现这个功能。

    好,首先来加载一张图片,然后监听其手势(鼠标)移动事件,代码如下:

    Container(
       400,
      height: 700,
      child: GestureDetector(
        onLongPressStart: (LongPressStartDetails details) {
          print('${details.localPosition},');
        },
        onLongPressMoveUpdate: (LongPressMoveUpdateDetails details) {
          print('${details.localPosition},');
        },
        onLongPressEnd: (LongPressEndDetails details) {
          print('${details.localPosition},');
        },
        child: Image.asset(
          'images/123.png',
          fit: BoxFit.fill,
        ),
      ),
    )
    

    这里要注意2点:

    • 图片显示的大小最好和最终的画布一样大小,这样得到的坐标不需要在转换。
    • 图片的宽高比和画布的宽高比要一样。

    我们把路径输出到控制台,后台只需将这些坐标拷贝到应用程序即可,将这些坐标定义为数组,如下:

    static final List<Offset> flowerPoints = [
      Offset(182.0, 136.3),
      Offset(182.7, 135.3),
      Offset(183.0, 135.3),
      Offset(183.3, 135.3),
      ...
    )
    

    点到路径获取到,下面就是绘制了,先绘制红色的花骨朵,在Flutter中绘制路径需要继承CustomPainter类,重写paint方法,绘制路径及填充颜色代码如下:

    @override
    void paint(Canvas canvas, Size size) {
      //将花变为红色
        if (flowerPaths.length >= RoseData.flowerPoints.length) {
          var path = Path();
          for (int i = 0; i < flowerPaths.length; i++) {
            if (i == 0) {
              path.moveTo(flowerPaths[i].dx, flowerPaths[i].dy);
            } else {
              path.lineTo(flowerPaths[i].dx, flowerPaths[i].dy);
            }
          }
          _paint.style = PaintingStyle.fill;
          _paint.color = _flowerColor;
          canvas.drawPath(path, _paint);
        }
        //绘制线
        _paint.style = PaintingStyle.stroke;
        _paint.color = _strokeColor;
    	 canvas.drawPoints(PointMode.polygon, flowerPaths, _paint);
    }
    

    这里要注意只有当当花骨朵所有的路径都绘制完之后才填充颜色,而且要先填充颜色,然后绘制路线,不然路线会被填充颜色覆盖。

    要想有绘制路径的效果,需要将点依次增加,增加动画控制器,控制绘制路径,代码如下:

    AnimationController _controller;
    Animation<num> _animation;
    
    @override
    void initState() {
      _controller = AnimationController(
          duration: Duration(seconds: 10), vsync: this)
        ..addListener(() {
          setState(() {
            _flowerPaths = RoseData.flowerPoints.sublist(0, _animation.value.floor());
          });
          });
    
        _animation = Tween(
                begin: 0.0,
                end: RoseData.flowerPoints.length)
            .animate(_controller);
    }
    

    构建UI代码如下:

    @override
      Widget build(BuildContext context) {
    		Container(
               400,
              height: 700,
              child: CustomPaint(
                painter: RosePaint(_flowerPaths),
              ),
            )
      }
    

    RosePaint是自定义的CustomPaint。效果如下:

    在最终的填充上发现有一部分没有填充上,图中蓝色点为最后一个点,所以需要在增加2个点,绿色和黄色位置的点,把未填充区域填充上。

    填充点代码如下:

    static final List<Offset> flowerPoints = [
        Offset(182.0, 136.3),
        Offset(182.7, 135.3),
        ...
    	Offset(179.3, 301.7),
      Offset(237.7, 144.7),
    ];
    

    在绘制线的时候需要将这2个点去掉:

    if (flowerPaths.length >= RoseData.flowerPoints.length) {
      var path = Path();
      for (int i = 0; i < flowerPaths.length; i++) {
        if (i == 0) {
          path.moveTo(flowerPaths[i].dx, flowerPaths[i].dy);
        } else {
          path.lineTo(flowerPaths[i].dx, flowerPaths[i].dy);
        }
      }
      _paint.style = PaintingStyle.fill;
      _paint.color = _flowerColor;
      canvas.drawPath(path, _paint);
    }
    //绘制线
    _paint.style = PaintingStyle.stroke;
    _paint.color = _strokeColor;
    //去掉最后2个点,最后2个点为了绘制红色
    var points = flowerPaths.sublist(0, max(0, flowerPaths.length - 2));
    canvas.drawPoints(PointMode.polygon, points, _paint);
    

    花骨朵就好了,其他的叶子和部位也是一样的画法,这里就不在介绍了,由于代码比较多,就不全贴在这里了,如果需要可以加我微信。

    今天的文章对大家是否有帮助?如果有,请在文章底部留言和点赞,以表示对我的支持,你们的留言、点赞和转发关注是我持续更新的动力!

    本人创建了一个关于Flutter的微信交流群和“技术人运营自己(吹NB)”交流群,欢迎您的加入,让我们一起学习,一起进步,开始我们的故事。

    添加微信请备注:Flutter(进Flutter交流群)、吹NB(进吹NB群)、2(都进)。我希望您备注“2”,生活不止眼前的苟且,还有诗和《远方》。

    微信:mqd_zzy

  • 相关阅读:
    数据库操作相关(sql语句-命令行)
    五月份和六月份的总结
    解决IE6下透明图片有背景的问题
    LceMeaning专用函数集《Lcemeaning》
    Delphi获得与设置系统时间格式《转》
    Delphi 调用Excel《转》
    调用外部程序并等待程序运行结束《Lcemeaning》
    如何获取Memo的行数与列数《转》
    delphi小写金额转大写的函数《转》
    delphi中的时间函数运算《转》
  • 原文地址:https://www.cnblogs.com/mengqd/p/12443270.html
Copyright © 2011-2022 走看看