贝塞尔曲线自定义视图的阴影效果
Shadow effect on Bezier curve custom view
如何在弯曲的自定义视图组底部添加阴影效果?我正在实施贝塞尔曲线路径以将底部曲线添加到矩形形状。我想添加一个平行于弯曲底部边缘的底部阴影,有人可以建议这样做的方法吗?
class CurveContainer : ConstraintLayout{
var mainPaint = Paint()
var mShadowPaint = Paint()
var mainPath = Path()
var xWidth = 0f
var xHeight = 0f
var biezerYValue = 50
constructor(context: Context?) : super(context){
init()
}
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
init()
}
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr){
init()
}
open fun setBiezerY(y : Int){
biezerYValue = y
invalidate()
}
private fun init() {
mainPaint.color = ContextCompat.getColor(context, R.color.showContainer)
mainPaint.style = Paint.Style.FILL
mainPaint.isAntiAlias = true
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
xWidth = measuredWidth.toFloat()
xHeight = measuredHeight.toFloat()
invalidate()
}
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
mainPath.reset()
canvas!!.drawColor(Color.TRANSPARENT)
mainPath.moveTo(0f, 0f)
mainPath.lineTo(xWidth, 0f)
mainPath.lineTo(xWidth, xHeight - biezerYValue)
mainPath.quadTo(xWidth/2, xHeight + biezerYValue - 10, 0f, xHeight - biezerYValue)
mainPath.lineTo(0f, 0f)
canvas!!.drawPath(mainPath, mainPaint)
}
}
这是目前的样子
你可以做的是在原始形状下方绘制相同的形状,但带有 BlurMaskFilter
,我对你的 class 进行了一些重构,但结果似乎很有希望
class CurveContainer @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0)
: ConstraintLayout(context, attrs, defStyleAttr) {
private val mainPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = 0xffff0000.toInt()
style = Paint.Style.FILL
}
private val shadowPaint = Paint(Paint.ANTI_ALIAS_FLAG.or(Paint.DITHER_FLAG)).apply {
color = 0xff000000.toInt()
style = Paint.Style.FILL
maskFilter = BlurMaskFilter(32f, BlurMaskFilter.Blur.OUTER)
}
private val mainPath = Path()
private val shadowPath = Path()
private var bezierEdgeY = 0f
private var bezierHandleY = 0f
private var edgePercentY = 0.25f
private var handlePercentY = 0.5f
init {
setWillNotDraw(false)
setLayerType(View.LAYER_TYPE_SOFTWARE, shadowPaint)
}
fun setBezierPositionPercent(edgePercentY: Float, handlePercentY: Float) {
this.edgePercentY = edgePercentY
this.handlePercentY = handlePercentY
computePath(width.toFloat(), height.toFloat())
}
private fun computePath(width: Float, height: Float) {
bezierEdgeY = height * 0.25f
bezierHandleY = height * 0.5f
val halfWidth = width / 2
shadowPath.reset()
shadowPath.moveTo(0f, 0f)
shadowPath.lineTo(width, 0f)
shadowPath.lineTo(width, bezierEdgeY)
shadowPath.quadTo(halfWidth, bezierHandleY, 0f, bezierEdgeY)
shadowPath.lineTo(0f, 0f)
mainPath.reset()
mainPath.moveTo(0f, 0f)
mainPath.lineTo(width, 0f)
mainPath.lineTo(width, bezierEdgeY)
mainPath.quadTo(halfWidth, bezierHandleY, 0f, bezierEdgeY)
mainPath.lineTo(0f, 0f)
invalidate()
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
computePath(w.toFloat(), h.toFloat())
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvas.drawPath(shadowPath, shadowPaint)
canvas.drawPath(mainPath, mainPaint)
}
}
如何在弯曲的自定义视图组底部添加阴影效果?我正在实施贝塞尔曲线路径以将底部曲线添加到矩形形状。我想添加一个平行于弯曲底部边缘的底部阴影,有人可以建议这样做的方法吗?
class CurveContainer : ConstraintLayout{
var mainPaint = Paint()
var mShadowPaint = Paint()
var mainPath = Path()
var xWidth = 0f
var xHeight = 0f
var biezerYValue = 50
constructor(context: Context?) : super(context){
init()
}
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
init()
}
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr){
init()
}
open fun setBiezerY(y : Int){
biezerYValue = y
invalidate()
}
private fun init() {
mainPaint.color = ContextCompat.getColor(context, R.color.showContainer)
mainPaint.style = Paint.Style.FILL
mainPaint.isAntiAlias = true
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
xWidth = measuredWidth.toFloat()
xHeight = measuredHeight.toFloat()
invalidate()
}
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
mainPath.reset()
canvas!!.drawColor(Color.TRANSPARENT)
mainPath.moveTo(0f, 0f)
mainPath.lineTo(xWidth, 0f)
mainPath.lineTo(xWidth, xHeight - biezerYValue)
mainPath.quadTo(xWidth/2, xHeight + biezerYValue - 10, 0f, xHeight - biezerYValue)
mainPath.lineTo(0f, 0f)
canvas!!.drawPath(mainPath, mainPaint)
}
}
这是目前的样子
你可以做的是在原始形状下方绘制相同的形状,但带有 BlurMaskFilter
,我对你的 class 进行了一些重构,但结果似乎很有希望
class CurveContainer @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0)
: ConstraintLayout(context, attrs, defStyleAttr) {
private val mainPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = 0xffff0000.toInt()
style = Paint.Style.FILL
}
private val shadowPaint = Paint(Paint.ANTI_ALIAS_FLAG.or(Paint.DITHER_FLAG)).apply {
color = 0xff000000.toInt()
style = Paint.Style.FILL
maskFilter = BlurMaskFilter(32f, BlurMaskFilter.Blur.OUTER)
}
private val mainPath = Path()
private val shadowPath = Path()
private var bezierEdgeY = 0f
private var bezierHandleY = 0f
private var edgePercentY = 0.25f
private var handlePercentY = 0.5f
init {
setWillNotDraw(false)
setLayerType(View.LAYER_TYPE_SOFTWARE, shadowPaint)
}
fun setBezierPositionPercent(edgePercentY: Float, handlePercentY: Float) {
this.edgePercentY = edgePercentY
this.handlePercentY = handlePercentY
computePath(width.toFloat(), height.toFloat())
}
private fun computePath(width: Float, height: Float) {
bezierEdgeY = height * 0.25f
bezierHandleY = height * 0.5f
val halfWidth = width / 2
shadowPath.reset()
shadowPath.moveTo(0f, 0f)
shadowPath.lineTo(width, 0f)
shadowPath.lineTo(width, bezierEdgeY)
shadowPath.quadTo(halfWidth, bezierHandleY, 0f, bezierEdgeY)
shadowPath.lineTo(0f, 0f)
mainPath.reset()
mainPath.moveTo(0f, 0f)
mainPath.lineTo(width, 0f)
mainPath.lineTo(width, bezierEdgeY)
mainPath.quadTo(halfWidth, bezierHandleY, 0f, bezierEdgeY)
mainPath.lineTo(0f, 0f)
invalidate()
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
computePath(w.toFloat(), h.toFloat())
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvas.drawPath(shadowPath, shadowPaint)
canvas.drawPath(mainPath, mainPaint)
}
}