package com.rncamerakit.barcode import android.content.Context import android.graphics.* import android.util.Log import android.util.Size import android.view.View import androidx.annotation.ColorInt import com.rncamerakit.R import kotlin.math.max import kotlin.math.min class BarcodeFrame(context: Context) : View(context) { private var borderPaint: Paint = Paint() private var laserPaint: Paint = Paint() var frameRect: Rect = Rect() private var barcodeFrameSize = DEFAULT_SIZE private var frameWidth = 0 private var frameHeight = 0 private var borderMargin = 0 private var previousFrameTime = System.currentTimeMillis() private var laserY = 0 private fun init(context: Context) { borderPaint = Paint() borderPaint.style = Paint.Style.STROKE borderPaint.strokeWidth = STROKE_WIDTH.toFloat() laserPaint.style = Paint.Style.STROKE laserPaint.strokeWidth = STROKE_WIDTH.toFloat() borderMargin = context.resources.getDimensionPixelSize(R.dimen.border_length) } override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { super.onMeasure(widthMeasureSpec, heightMeasureSpec) calculateFrameRect() } private fun calculateFrameRect() { val marginHeight = 40 val marginWidth = 40 val frameMaxWidth = barcodeFrameSize.width * context.resources.displayMetrics.density val frameMaxHeight = barcodeFrameSize.height * context.resources.displayMetrics.density val frameMinWidth = 100 val frameMinHeight = 100 frameWidth = max(frameMinWidth, min(frameMaxWidth.toInt(), measuredWidth - (marginWidth * 2))) frameHeight = max(frameMinHeight, min(frameMaxHeight.toInt(), measuredHeight - (marginHeight * 2))) frameRect.left = (measuredWidth / 2) - (frameWidth / 2) frameRect.right = (measuredWidth / 2) + (frameWidth / 2) frameRect.top = (measuredHeight / 2) - (frameHeight / 2) frameRect.bottom = (measuredHeight / 2) + (frameHeight / 2) } override fun onDraw(canvas: Canvas) { val timeElapsed = System.currentTimeMillis() - previousFrameTime super.onDraw(canvas) drawBorder(canvas) drawLaser(canvas, timeElapsed) previousFrameTime = System.currentTimeMillis() this.invalidate(frameRect) } private fun drawBorder(canvas: Canvas) { canvas.drawLine(frameRect.left.toFloat(), frameRect.top.toFloat(), frameRect.left.toFloat(), (frameRect.top + borderMargin).toFloat(), borderPaint) canvas.drawLine(frameRect.left.toFloat(), frameRect.top.toFloat(), (frameRect.left + borderMargin).toFloat(), frameRect.top.toFloat(), borderPaint) canvas.drawLine(frameRect.left.toFloat(), frameRect.bottom.toFloat(), frameRect.left.toFloat(), (frameRect.bottom - borderMargin).toFloat(), borderPaint) canvas.drawLine(frameRect.left.toFloat(), frameRect.bottom.toFloat(), (frameRect.left + borderMargin).toFloat(), frameRect.bottom.toFloat(), borderPaint) canvas.drawLine(frameRect.right.toFloat(), frameRect.top.toFloat(), (frameRect.right - borderMargin).toFloat(), frameRect.top.toFloat(), borderPaint) canvas.drawLine(frameRect.right.toFloat(), frameRect.top.toFloat(), frameRect.right.toFloat(), (frameRect.top + borderMargin).toFloat(), borderPaint) canvas.drawLine(frameRect.right.toFloat(), frameRect.bottom.toFloat(), frameRect.right.toFloat(), (frameRect.bottom - borderMargin).toFloat(), borderPaint) canvas.drawLine(frameRect.right.toFloat(), frameRect.bottom.toFloat(), (frameRect.right - borderMargin).toFloat(), frameRect.bottom.toFloat(), borderPaint) } private fun drawLaser(canvas: Canvas, timeElapsed: Long) { if (laserY > frameRect.bottom || laserY < frameRect.top) laserY = frameRect.top canvas.drawLine((frameRect.left + STROKE_WIDTH).toFloat(), laserY.toFloat(), (frameRect.right - STROKE_WIDTH).toFloat(), laserY.toFloat(), laserPaint) laserY += (timeElapsed / ANIMATION_SPEED).toInt() } fun setFrameColor(@ColorInt borderColor: Int) { borderPaint.color = borderColor } fun setLaserColor(@ColorInt laserColor: Int) { laserPaint.color = laserColor } fun setFrameSize(size: Size?) { barcodeFrameSize = size ?: DEFAULT_SIZE calculateFrameRect() } companion object { private const val STROKE_WIDTH = 5 private const val ANIMATION_SPEED = 4 private val DEFAULT_SIZE = Size(300, 150) } init { init(context) } }