自定义弧形滑块加渐变色填充

首先用到的是:- (void)drawRect:(CGRect)rect此方法与视图绘画有关

方法使用:

  • 在视图第一次出现时,UIView设置frame才会调用drawRect;
  • 或者布局改变时、视图的内容改变时,调用sizeThatFits或setNeedsDisplay后drawRect方法才会被调用;
  • sizeThatFits后会调用drawRect:

下面在画布上画一个弧形,弧形涉及到的参数:圆的半径、开始/结束弧度、绘制方向(顺时针/逆时针)

 

 

然后绘制拖动按钮:

#pragma mark 画按钮

-(void)drawHandle:(CGContextRef)ctx{

    CGContextSaveGState(ctx);

    CGPoint handleCenter =  [self pointFromAngle: _angle +3.5];

    [UIColor.whiteColor set];

    CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter.x-4, handleCenter.y-4, _lineWidth+8, _lineWidth+8));

    CGContextRestoreGState(ctx);

}

渐变填充色CGContextDrawLinearGradient参数:根据需求传入一个颜色数组

-(void)drawBigHandle:(CGContextRef)ctx

{

    CGContextSaveGState(ctx);

    CGPoint handleCenter =  [self pointFromAngle: _angle +3.5];

    [KDSRGBColor(229, 229, 229) set];

    CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter.x-5, handleCenter.y-5, _lineWidth+10, _lineWidth+10));

    CGContextRestoreGState(ctx);

}

 

-(CGPoint)pointFromAngle:(int)angleInt{

    

    //Define the Circle center

    CGPoint centerPoint = CGPointMake(self.frame.size.width/2 - _lineWidth/2, self.frame.size.height/2 - _lineWidth/2);

    //Define The point position on the circumference

    CGPoint result;

    result.y = round(centerPoint.y + radius * sin(ToRad(angleInt)));

    result.x = round(centerPoint.x + radius * cos(ToRad(angleInt)));

    

    return result;

}

 

-(BOOL) beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {

    [super beginTrackingWithTouch:touch withEvent:event];

    

    return YES;

}

 

-(BOOL) continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {

    [super continueTrackingWithTouch:touch withEvent:event];

    

    CGPoint lastPoint = [touch locationInView:self];

    

    //用于排除点在圆外面点与圆心半径80以内的点

    if ((lastPoint.x>=0&&lastPoint.x<=275)&&(lastPoint.y>=0 && lastPoint.y<=275)) {

        

        if ((lastPoint.x<=57.5 ||lastPoint.x>=217.5)||(lastPoint.y<=57.5 ||lastPoint.y>=217.5)) {

//            [self moveHandle:lastPoint];

        }

    }

    [self sendActionsForControlEvents:UIControlEventValueChanged];

    return YES;

}

 

-(void)moveHandle:(CGPoint)point {

    CGPoint centerPoint = CGPointMake(self.frame.size.width/2, self.frame.size.height/2);

    int currentAngle = floor(AngleFromNorth(centerPoint, point, NO));

    if (currentAngle>40 && currentAngle <140) {

    }else{

        if (currentAngle<=40) {

            _angle = currentAngle+360;

        }else{

            _angle = currentAngle;

        }

        

    }

    _currentValue =[self valueFromAngle];

    [self setNeedsDisplay];

}

 

static inline float AngleFromNorth(CGPoint p1, CGPoint p2, BOOL flipped) {

    CGPoint v = CGPointMake(p2.x-p1.x,p2.y-p1.y);

    float vmag = sqrt(SQR(v.x) + SQR(v.y)), result = 0;

    v.x /= vmag;

    v.y /= vmag;

    double radians = atan2(v.y,v.x);

    result = ToDeg(radians);

    return (result >=0  ? result : result + 360.0);

}

 

效果图:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现一个canvas弧形滑块,可以按照以下步骤进行: 1. 引入vue和canvas,在vue组件中创建一个canvas元素。 2. 通过canvas API绘制一个弧形,可以使用arc方法绘制圆弧。 3. 绘制滑块,可以使用fillRect方法绘制一个矩形。 4. 监听鼠标事件(mousedown、mousemove、mouseup),根据鼠标位置计算滑块的位置,并重新绘制canvas。 下面是一个简单的实现代码: ```html <template> <canvas ref="canvas"></canvas> </template> <script> export default { mounted() { const canvas = this.$refs.canvas const ctx = canvas.getContext('2d') const width = canvas.width const height = canvas.height const centerX = width / 2 const centerY = height / 2 const radius = 100 const startAngle = Math.PI * 1.5 const endAngle = Math.PI * 2.5 let position = 0 let dragging = false function draw() { // 绘制弧形 ctx.beginPath() ctx.arc(centerX, centerY, radius, startAngle, endAngle) ctx.lineWidth = 10 ctx.strokeStyle = '#ddd' ctx.stroke() // 绘制滑块 const sliderWidth = 20 const sliderHeight = 40 const x = centerX + Math.cos(position) * radius - sliderWidth / 2 const y = centerY + Math.sin(position) * radius - sliderHeight / 2 ctx.fillStyle = '#aaa' ctx.fillRect(x, y, sliderWidth, sliderHeight) } function getPosition(x, y) { const dx = x - centerX const dy = y - centerY return Math.atan2(dy, dx) } function handleMouseDown(e) { const x = e.clientX - canvas.offsetLeft const y = e.clientY - canvas.offsetTop const distance = Math.sqrt(Math.pow(centerX - x, 2) + Math.pow(centerY - y, 2)) if (distance > radius - 10 && distance < radius + 10) { dragging = true } } function handleMouseMove(e) { if (dragging) { const x = e.clientX - canvas.offsetLeft const y = e.clientY - canvas.offsetTop position = getPosition(x, y) draw() } } function handleMouseUp() { dragging = false } draw() canvas.addEventListener('mousedown', handleMouseDown) canvas.addEventListener('mousemove', handleMouseMove) canvas.addEventListener('mouseup', handleMouseUp) } } </script> ``` 以上代码创建了一个canvas元素,并在mounted钩子函数中绘制了一个弧形和一个滑块。同时,监听了鼠标事件,在鼠标拖动时计算滑块的位置并重新绘制canvas。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值