Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Jetpack Compose Canvas入門

Jetpack Compose Canvas入門

rmakiyama

June 23, 2021
Tweet

More Decks by rmakiyama

Other Decks in Technology

Transcript

  1. +FUQBDL$PNQPTF

    $BOWBTೖ໳
    potatotips #74

    2021/06/23 Ryo Makiyama

    View Slide

  2. w ຀ࢁྎ
    w 3BEJPUBMLגࣜձࣾ
    w "OESPJEΤϯδχΞ
    [email protected]
    wSNBLJZBNB
    ࣗݾ঺հ

    View Slide

  3. ΞδΣϯμ
    w ͜Ε·Ͱͷ$BOWBT"1*
    w $BOWBTίϯϙʔβϒϧ
    w ͭͬͯ͋ͦ͘΅͏

    View Slide

  4. $BOWBTͬͯͳʹʁ
    w ੲ͔Β͋Δ௿Ϩϕϧͳ"1*
    w ਤܗ΍จࣈΛඳըͰ͖Δ
    w ΧελϜϏϡʔʹΑ͘࢖ΘΕΔ

    View Slide

  5. ͜Ε·Ͱͷॻ͖ํ
    w 7JFXͷPO%SBX
    ΛΦʔόʔϥΠυ
    w ύϥϝʔλʹ$BOWBTΛड͚औΔ
    w 1BJOUΠϯελϯεΛ࡞੒
    w $BOWBTͷϝιουΛݺͿ

    View Slide

  6. ԁΛඳ͍ͯΈΔ🙆
    class DrawCircleView @JvmOverloads constructor(

    context: Context,

    attrs: AttributeSet? = null,

    defStyleAttr: Int = 0

    ) : View(context, attrs, defStyleAttr) {

    private val paint = Paint().apply {
    //
    ͲͷΑ͏ʹඳը͢Δ͔

    color = Color.BLUE

    }

    override fun onDraw(canvas: Canvas) {

    val radius = width.toFloat() / 2

    //
    ԿΛඳը͢Δ͔

    canvas.drawCircle(

    (width / 2).toFloat(),
    //
    center x

    (height / 2).toFloat(),
    //
    center y

    radius,
    //
    radius

    paint
    //
    paint

    )

    }

    }

    View Slide

  7. ԁΛඳ͍ͯΈΔ🙆
    class DrawCircleView @JvmOverloads constructor(

    context: Context,

    attrs: AttributeSet? = null,

    defStyleAttr: Int = 0

    ) : View(context, attrs, defStyleAttr) {

    private val paint = Paint().apply {
    //
    ͲͷΑ͏ʹඳը͢Δ͔

    color = Color.BLUE

    }

    override fun onDraw(canvas: Canvas) {

    val radius = width.toFloat() / 2

    //
    ԿΛඳը͢Δ͔

    canvas.drawCircle(

    (width / 2).toFloat(),
    //
    center x

    (height / 2).toFloat(),
    //
    center y

    radius,
    //
    radius

    paint
    //
    paint

    )

    }

    }

    View Slide

  8. ԁΛඳ͍ͯΈΔ🙆
    class DrawCircleView @JvmOverloads constructor(

    context: Context,

    attrs: AttributeSet? = null,

    defStyleAttr: Int = 0

    ) : View(context, attrs, defStyleAttr) {

    private val paint = Paint().apply {
    //
    ͲͷΑ͏ʹඳը͢Δ͔

    color = Color.BLUE

    }

    override fun onDraw(canvas: Canvas) {

    val radius = width.toFloat() / 2

    //
    ԿΛඳը͢Δ͔

    canvas.drawCircle(

    (width / 2).toFloat(),
    //
    center x

    (height / 2).toFloat(),
    //
    center y

    radius,
    //
    radius

    paint
    //
    paint

    )

    }

    }

    View Slide

  9. ԁΛඳ͍ͯΈΔ🙆
    class DrawCircleView @JvmOverloads constructor(

    context: Context,

    attrs: AttributeSet? = null,

    defStyleAttr: Int = 0

    ) : View(context, attrs, defStyleAttr) {

    private val paint = Paint().apply {
    //
    ͲͷΑ͏ʹඳը͢Δ͔

    color = Color.BLUE

    }

    override fun onDraw(canvas: Canvas) {

    val radius = width.toFloat() / 2

    //
    ԿΛඳը͢Δ͔

    canvas.drawCircle(

    (width / 2).toFloat(),
    //
    center x

    (height / 2).toFloat(),
    //
    center y

    radius,
    //
    radius

    paint
    //
    paint

    )

    }

    }

    View Slide

  10. $BOWBTίϯϙʔβϒϧ
    w PO%SBXϥϜμؔ਺Λ࢖ͬͯඳը
    w Ϩγʔό͕%SBX4DPQFʹͳ͍ͬͯΔ
    w %SBX4DPQFͷϝιουΛݺͿ
    w ैདྷͷ$BOWBTΑΓγϯϓϧʹѻ͑Δ

    View Slide

  11. ԁΛඳ͍ͯΈΔ🙆
    @Composable

    fun CircleView() {

    Canvas(modifier = Modifier.fillMaxSize()) {

    / /
    this: DrawScope

    drawCircle(Color.Blue)

    }

    }

    View Slide

  12. ԁΛඳ͍ͯΈΔ🙆
    @Composable

    fun CircleView() {

    Canvas(modifier = Modifier.fillMaxSize()) {

    / /
    this: DrawScope

    drawCircle(Color.Blue)

    }

    }
    ͨͬͨ͜Ε͚ͩ👏

    View Slide

  13. $BOWBTίϯϙʔβϒϧ
    @Composable

    fun Canvas(modifier: Modifier, onDraw: DrawScope.()
    ->
    Unit) =

    Spacer(modifier.drawBehind(onDraw))

    View Slide

  14. %SBX4DPQF
    w 4J[FͳͲͷศརͳϑΟʔϧυ
    w ͞·͟·ͳඳըؔ਺
    w ESBX$JSDMFESBX-JOFESBX"SDESBX1BUIFUDʜ
    w σϑΥϧτͷύϥϝʔλ஋Λ׆༻
    w ඳըͷ୯७ͳม׵ؔ਺΋׬උ
    w SPUBUFTDBMFUSBOTMBUFFUDʜ

    View Slide

  15. ͨͱ͑͹ESBX$JSDMFϝιου
    fun drawCircle(

    color: Color,

    radius: Float = size.minDimension / 2.0f,

    center: Offset = this.center,

    /*
    @FloatRange(from = 0.0, to = 1.0)
    */


    alpha: Float = 1.0f,

    style: DrawStyle = Fill,

    colorFilter: ColorFilter? = null,

    blendMode: BlendMode = DefaultBlendMode

    )

    View Slide

  16. ͭͬͯ͋ͦ͘Ϳ
    w ؆୯ͳϩʔσΟϯάϏϡʔ
    w ԁΛ̐ͭඳը
    w ͦΕͬΆ͘Ξχϝʔγϣϯ

    View Slide

  17. ·ͣ͸ͭԁΛඳ͘
    @Composable

    fun DotLoading(

    modifier: Modifier = Modifier,

    dotSize: Dp = 24.dp,

    dotColor: Color = MaterialTheme.colors.primary,

    ) {

    val dotSpace: Dp = dotSize * 0.5f

    val canvasSize = dotSize * 2 + dotSpace

    Canvas(modifier = modifier.size(canvasSize)) {

    val radius = dotSize.toPx() / 2

    repeat(4) { index
    ->


    rotate(90f * (index - 1)) {

    drawCircle(

    color = dotColor,

    radius = radius,

    center = Offset(radius, radius)

    )

    }

    }

    }

    }

    View Slide

  18. Ξχϝʔγϣϯͷ࣮૷
    @Composable

    fun DotLoading(…) {

    val dotSpace: Dp = dotSize * 0.5f

    val offset = with(LocalDensity.current) {

    (dotSize + dotSpace).toPx()

    }

    val infiniteTransition = rememberInfiniteTransition()

    val xOffset by infiniteTransition.animateFloat(

    0f,

    offset,

    infiniteRepeatable(

    animation = tween(durationMillis = 500)

    )

    )

    val canvasSize = dotSize * 2 + dotSpace

    Canvas(modifier = modifier.size(canvasSize)) {

    val radius = dotSize.toPx() / 2

    repeat(4) { index
    ->


    rotate(90f * (index - 1)) {

    drawCircle(

    color = dotColor,

    radius = radius,

    center = Offset(radius + xOffset, radius)

    )

    }

    }

    }

    }

    View Slide

  19. Ξχϝʔγϣϯͷ࣮૷
    @Composable

    fun DotLoading(…) {

    val dotSpace: Dp = dotSize * 0.5f

    val offset = with(LocalDensity.current) {

    (dotSize + dotSpace).toPx()

    }

    val infiniteTransition = rememberInfiniteTransition()

    val xOffset by infiniteTransition.animateFloat(

    0f,

    offset,

    infiniteRepeatable(

    animation = tween(durationMillis = 500)

    )

    )

    val canvasSize = dotSize * 2 + dotSpace

    Canvas(modifier = modifier.size(canvasSize)) {

    val radius = dotSize.toPx() / 2

    repeat(4) { index
    ->


    rotate(90f * (index - 1)) {

    drawCircle(

    color = dotColor,

    radius = radius,

    center = Offset(radius + xOffset, radius)

    )

    }

    }

    }

    }

    View Slide

  20. ·ͱΊ
    w $BOWBT͕ͱͬͯ΋͔͍ͭ΍͘͢ͳͬͨʂ
    w දݱͷ෯͸͋ͳͨ࣍ୈ😎
    w &OKPZ$BOWBT-JGF🚀

    View Slide

  21. "QQFOEJY
    w IUUQTEFWFMPQFSBOESPJEDPNKFUQBDLDPNQPTFHSBQIJDT
    w IUUQTEFWFMPQFSBOESPJEDPNUSBJOJOHDVTUPNWJFXTDVTUPNESBXJOH
    w IUUQTEFWFMPQFSBOESPJEDPNKFUQBDLDPNQPTFBOJNBUJPO IMKBSFNFNCFSJO
    fi
    OJUFUSBOTJUJPO

    View Slide