以曲线形状剪切贝塞尔路径

Posted

技术标签:

【中文标题】以曲线形状剪切贝塞尔路径【英文标题】:Clipping the bezier path in curve shape 【发布时间】:2018-06-05 12:05:22 【问题描述】:

我使用 Swift 在手机 UI 中创建自定义按钮,需要将按钮的底部剪裁成凸形。

问题是它应该是完美的,底部曲线应该与更大的按钮匹配

我尝试了不同的方法,但都没有得到完美的结果。

    使用圆角

    if buttonDirection == 0 
        path = UIBezierPath(roundedRect: rect, byRoundingCorners:[UIRectCorner.topLeft, .topRight], cornerRadii: CGSize(width: self.bounds.width/2, height: 0))
        path.close()  
    
    

    使用QuardCurve创建没有圆角曲线的整个路径 //仍然底部不是反向曲线加角也不像1那样平滑

     if buttonDirection == 0 
           //path = UIBezierPath(roundedRect: rect, byRoundingCorners:[UIRectCorner.topLeft, .topRight], cornerRadii: CGSize(width: self.bounds.width/2, height: 0))
          //path.close()
            let curve = UIBezierPath()
            curve.move(to: CGPoint(x: 0, y: self.bounds.height))
            curve.addLine(to:CGPoint(x: 0, y: self.bounds.width/3))
            curve.addQuadCurve(to: CGPoint(x: self.bounds.width, y: self.bounds.width/3), controlPoint: CGPoint(x: self.bounds.width/2, y: -5))
            curve.addLine(to: CGPoint(x: self.bounds.width, y: self.bounds.height))
            curve.addQuadCurve(to: CGPoint(x: 0, y: self.bounds.height), controlPoint: CGPoint(x: self.bounds.width/2, y: self.bounds.width - 10))
            UIColor.black.setFill()
            curve.fill()
        
    

    从 1 创建路径,然后只是 Clip QuardCurve

    if buttonDirection == 0 
        path = UIBezierPath(roundedRect: rect, byRoundingCorners:[UIRectCorner.topLeft, .topRight], cornerRadii: CGSize(width: self.bounds.width/2, height: 0))
        path.close()
        path.move(to: CGPoint(x: 0, y: self.bounds.height))
        path.addQuadCurve(to: CGPoint(x: self.bounds.width, y: self.bounds.height), controlPoint: CGPoint(x: self.bounds.width/2, y: self.bounds.height/2))
        path.addClip()
        UIColor.black.setFill()
        path.fill()
     
    

我也尝试了很多其他的东西,但没有得到结果,我想要的只是从第一条路径剪下底部曲线,比如如何从另一条路径切割一条路径(阅读苹果文档后我知道我可以使用路径.reverse() 也 )

这是一张图片中的所有按钮,当您单击按钮时说 vol + 它会改变颜色

PS编辑了原始问题,因为图像令人困惑,我找到了一种解决方案,但仍然想知道是否有更好的解决方案,具有一条路径和平滑的边缘。

【问题讨论】:

我阅读了您的问题,但我不明白您所说的“剪裁反曲线”是什么意思。您的图像还显示了大量的图形,您是在专门讨论“如何创建一个圆形并从中切出另一个圆形”? 检查第四张图片中的 Vol+ 按钮,你看到底部的曲线在底部切割成圆形 如果唯一的遮罩是第四张图像中的 vol+ 按钮,则删除其他图像,并以清晰、对比鲜明的配色方案显示该特定的东西。现在你正在展示五张图片,它们的颜色都会让很多人觉得“我的眼睛远远不够好,无法看到这个人在展示什么”。在解释您尝试过的内容之前,展示您的目标也很不错。 实际上,它的所有按钮 vol+, vol-, ch +, ch - 但是谢谢,会更新问题:-) 不使用曲线,为什么不使用圆弧?你知道你的圆的半径,所以使用实际的圆弧会比手动逼近好的曲率容易得多吗?只需使用以主圆为中心、以适当半径为中心的单个 2pi 圆弧作为剪切路径,这就是您需要做的全部? 【参考方案1】:

以下方法有效,但如果有人有更好的解决方案,请发布。 基本上我在这里做的是首先将整个按钮裁剪为凸面,在底部使用 addLines 和 Quardcurve,然后使用右上角和左上角的 bezier roundedRect 初始化创建新路径。

if buttonDirection == 0 
     let curve = UIBezierPath()
     curve.move(to: CGPoint(x: 0, y: self.bounds.height))
     curve.addLine(to: CGPoint(x: 0, y: 0))
     curve.addLine(to: CGPoint(x: self.bounds.width, y: 0))
     curve.addLine(to: CGPoint(x: self.bounds.width, y: self.bounds.height))
     curve.addQuadCurve(to: CGPoint(x: 0, y: self.bounds.height), controlPoint: CGPoint(x: self.bounds.width/2, y: self.bounds.height - self.bounds.height/4))
     curve.close()
     curve.addClip()
     path = UIBezierPath(roundedRect: rect, byRoundingCorners:[UIRectCorner.topLeft, .topRight], cornerRadii: CGSize(width: self.bounds.width/2, height: 0))
     path.close()
 

【讨论】:

以上是关于以曲线形状剪切贝塞尔路径的主要内容,如果未能解决你的问题,请参考以下文章

coreldraw的所有工具的详细作用?

Flutter BottomAppBar 自定义路径 + 贝塞尔曲线实现闲鱼底部导航

贝塞尔曲线与CAShapeLayer的关系以及Stroke动画

d3画svg基本图形以及贝塞尔曲线

模拟贝塞尔曲线(isPointInPath)

如何比较贝塞尔曲线的形状