首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于UIPanGestureRecognizer速度的UIBezierPath lineWidth

基于UIPanGestureRecognizer速度的UIBezierPath lineWidth
EN

Stack Overflow用户
提问于 2015-04-08 02:13:15
回答 1查看 401关注 0票数 0

我试图找出如何根据UIPanGestureRecognizer的速度构造一个有限范围的浮点值,我的最小值或起始值为1.0,最大值为3.0,为UIBezierPathlineWidth属性提供了一个有限的范围。

我试图找出如何根据UIPanGestureRecognizer的速度建立一个指数范围从1.0到3.0,但我很难开始映射这些值。合并的x和y速度越快,lineWidth就应该越小(下到1.0),如果组合速度较慢,lineWidth应该是相反的。我还试图通过存储lastWidth属性来缩减/平滑正在进行的线宽,这样子路径之间的转换就不会明显了。

如果能提供任何帮助,我将不胜感激。

基于答案的工作和最后守则:

代码语言:javascript
复制
@property (nonatomic, assign) CGFloat lastWidth;

if (recognizer.state == UIGestureRecognizerStateChanged)
{
    CGPoint velocity = [recognizer velocityInView:self.view];

    CGFloat absoluteVelocity = 1000.0 / sqrtf(pow(velocity.x, 2) + pow(velocity.y, 2));

    CGFloat clampedVel = MAX(MIN(absoluteVelocity, 3.0), 1.0);

    if (clampedVel > self.lastWidth)
    {
        clampedVel = self.lastWidth + 0.15;
    }
    else if (clampedVel < self.lastWidth)
    {
        clampedVel = self.lastWidth - 0.15;
    }

    self.lastWidth = clampedVel;

    UIBezierPath *path = [UIBezierPath bezierPath];
    path.lineCapStyle = kCGLineCapRound;
    path.lineWidth = self.lastWidth;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-10 17:48:19

所以我会用一个倒指数函数。

从你的速度,V(x,y)开始。你的绝对速度很明显是:

代码语言:javascript
复制
sqrt(pow(x, 2) + pow(y, 2));

我们称这个值为"v.“

接下来,我们需要一个介于1到3之间的值,其中1是"v“非常高的宽度,3是"v”非常低的宽度。

我们可以使用以下指数函数来计算:

代码语言:javascript
复制
- (CGFloat)getExponentialWidthForVeloctity(CGFloat)v {
    if (v <= 1 / 3.0)
        return 3;
    CGFloat inverse = 1 / v;
    return 1 + inverse;
}

或者这个功能可以使它平滑一点

代码语言:javascript
复制
- (CGFloat)getExponentialRootWidthForVeloctity(CGFloat)v {
    //play with this value to get the feel right
    //The higher it is, the faster you'll have to go to get a thinner line
    CGFloat rootConstantYouCanAdjust = 2;
    if (pow(v, rootConstantYouCanAdjust) <= 1 / 3.0)
        return 3;
    CGFloat inverse = 1 / pow(v, rootConstantYouCanAdjust);
    return 1 + inverse;
}

如果这感觉不对,尝试一个线性解决方案:

代码语言:javascript
复制
- (CGFloat)getLinearWidthForVelocity(CGFloat)v {
    //Find this value by swiping your finger really quickly and seeing what the fastest velocity you can get is
    CGFloat myExpectedMaximumVelocity = 1000; 
    if (v > myExpectedMaximumVelocity)
        v = myExpectedMaximumVelocity;
    return 3 - 2 * (v / myExpectedMaximumVelocity);
}

最后,作为一个奖励,尝试这个基于sqrt的函数,您可能会发现它工作得很好:

代码语言:javascript
复制
- (CGFloat)getSqrtWidthForVelocity(CGFloat)v {
    //find the same way as above
    CGFloat myExpectedMaximumVelocity = 1000;
    if (v > myExpectedMaximumVelocity)
        return 1;
    return 3 - 2 * sqrt(v) / sqrt(myExpectedMaximumVelocity);
}

我很想知道哪一种最有效!让我知道。我有更多的功能在我的袖子里,这些只是一些非常简单的,应该让你开始。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29504711

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档