Skip to content
This repository was archived by the owner on Feb 6, 2023. It is now read-only.

Commit 07e7d11

Browse files
committed
feat: Update matte draw logic.
1 parent 8070ec6 commit 07e7d11

File tree

3 files changed

+112
-42
lines changed

3 files changed

+112
-42
lines changed

app/src/main/assets/Rocket.svga

31.6 KB
Binary file not shown.

app/src/main/java/com/example/ponycui_home/svgaplayer/AnimationFromAssetsActivity.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,12 @@
66
import android.support.annotation.Nullable;
77
import android.view.View;
88

9-
import com.opensource.svgaplayer.SVGADrawable;
109
import com.opensource.svgaplayer.SVGAImageView;
1110
import com.opensource.svgaplayer.SVGAParser;
1211
import com.opensource.svgaplayer.SVGAVideoEntity;
1312

1413
import org.jetbrains.annotations.NotNull;
1514

16-
import java.net.URL;
1715
import java.util.ArrayList;
1816

1917
public class AnimationFromAssetsActivity extends Activity {
@@ -55,6 +53,8 @@ public void onError() {
5553

5654
private String randomSample() {
5755
if (samples.size() == 0) {
56+
samples.add("Goddess.svga");
57+
samples.add("Rocket.svga");
5858
samples.add("angel.svga");
5959
samples.add("alarm.svga");
6060
samples.add("EmptyState.svga");

library/src/main/java/com/opensource/svgaplayer/drawer/SVGACanvasDrawer.kt

Lines changed: 110 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package com.opensource.svgaplayer.drawer
22

3+
import android.annotation.TargetApi
34
import android.graphics.*
5+
import android.os.Build
46
import android.text.BoringLayout
57
import android.text.StaticLayout
8+
import android.widget.FrameLayout
69
import android.widget.ImageView
710
import com.opensource.svgaplayer.SVGADynamicEntity
811
import com.opensource.svgaplayer.SVGAVideoEntity
@@ -18,68 +21,134 @@ internal class SVGACanvasDrawer(videoItem: SVGAVideoEntity, val dynamicItem: SVG
1821
private val drawTextCache: HashMap<String, Bitmap> = hashMapOf()
1922
private val pathCache = PathCache()
2023

24+
private var beginIndexList: Array<Boolean>? = null
25+
private var endIndexList: Array<Boolean>? = null
26+
27+
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
2128
override fun drawFrame(canvas: Canvas, frameIndex: Int, scaleType: ImageView.ScaleType) {
2229
super.drawFrame(canvas,frameIndex, scaleType)
2330
this.pathCache.onSizeChanged(canvas)
2431
val sprites = requestFrameSprites(frameIndex)
2532
val matteSprites = mutableMapOf<String, SVGADrawerSprite>()
26-
27-
var isMatteing = false
28-
33+
var saveID = 0
34+
beginIndexList = null
35+
endIndexList = null
36+
37+
// Filte no matte layer
38+
var hasMatteLayer = false
39+
sprites.get(0).imageKey?.let {
40+
if (it.endsWith(".matte")) {
41+
hasMatteLayer = true
42+
}
43+
}
2944
sprites.forEachIndexed { index, svgaDrawerSprite ->
3045

46+
val iimageKey = svgaDrawerSprite.imageKey
47+
val mmatteKey = svgaDrawerSprite.matteKey
48+
3149
// save matte sprite
3250
svgaDrawerSprite.imageKey?.let {
33-
34-
// no matte
35-
sprites.get(0).imageKey?.let {
36-
if (!it.endsWith(".matte")) {
37-
drawSprite(svgaDrawerSprite, canvas, frameIndex)
38-
// continue
39-
return@forEachIndexed
40-
}
51+
/// No matte layer included
52+
if (!hasMatteLayer) {
53+
// Normal sprite
54+
drawSprite(svgaDrawerSprite, canvas, frameIndex)
55+
// Continue
56+
return@forEachIndexed
4157
}
42-
58+
/// Cache matte sprite
4359
if (it.endsWith(".matte")) {
4460
matteSprites.put(it, svgaDrawerSprite)
45-
// continue
61+
// Continue
4662
return@forEachIndexed
4763
}
4864
}
49-
50-
sprites.get(index - 1)?.let { lastSprite ->
51-
if (isMatteing && (svgaDrawerSprite.matteKey == null || svgaDrawerSprite.matteKey != lastSprite.matteKey)) {
52-
isMatteing = false
53-
54-
matteSprites.get(svgaDrawerSprite.matteKey)?.let {
55-
drawSprite(it, this.sharedValues.shareMatteCanvas(canvas.width, canvas.height), frameIndex)
56-
57-
canvas.drawBitmap(this.sharedValues.sharedMatteBitmap(), 0f, 0f, this.sharedValues.shareMattePaint())
58-
canvas.restore()
59-
}
60-
}
61-
if (svgaDrawerSprite.matteKey != null && (lastSprite.matteKey == null || lastSprite.matteKey != svgaDrawerSprite.matteKey)) {
62-
isMatteing = true
63-
canvas.save()
64-
}
65+
/// Is matte begin
66+
if (isMatteBegin(index, sprites)) {
67+
saveID = canvas.saveLayer(0f, 0f, canvas.width.toFloat(), canvas.height.toFloat(), null)
6568
}
6669

70+
/// Normal matte
6771
drawSprite(svgaDrawerSprite, canvas, frameIndex)
6872

69-
// if current sprite is the last one and isMatteing
70-
if (isMatteing && index == sprites.count() - 1) {
73+
/// Is matte end
74+
if (isMatteEnd(index, sprites)) {
7175
matteSprites.get(svgaDrawerSprite.matteKey)?.let {
7276
drawSprite(it, this.sharedValues.shareMatteCanvas(canvas.width, canvas.height), frameIndex)
73-
7477
canvas.drawBitmap(this.sharedValues.sharedMatteBitmap(), 0f, 0f, this.sharedValues.shareMattePaint())
75-
canvas.restore()
78+
canvas.restoreToCount(saveID)
79+
// Continue
80+
return@forEachIndexed
7681
}
7782
}
78-
7983
}
8084
playAudio(frameIndex)
8185
}
8286

87+
private fun isMatteBegin(spriteIndex: Int, sprites: List<SVGADrawerSprite>): Boolean {
88+
if (beginIndexList == null) {
89+
val boolArray = Array(sprites.count()){false}
90+
sprites.forEachIndexed { index, svgaDrawerSprite ->
91+
svgaDrawerSprite.imageKey?.let {
92+
/// Filter matte sprite
93+
if (it.endsWith(".matte")) {
94+
// Continue
95+
return@forEachIndexed
96+
}
97+
}
98+
svgaDrawerSprite.matteKey?.let {
99+
if (it.length > 0) {
100+
sprites.get(index - 1)?.let { lastSprite ->
101+
if (lastSprite.matteKey == null || lastSprite.matteKey.length == 0) {
102+
boolArray[index] = true
103+
} else {
104+
if (lastSprite.matteKey != svgaDrawerSprite.matteKey) {
105+
boolArray[index] = true
106+
}
107+
}
108+
}
109+
}
110+
}
111+
}
112+
beginIndexList = boolArray
113+
}
114+
return beginIndexList?.get(spriteIndex) ?: false
115+
}
116+
117+
private fun isMatteEnd(spriteIndex: Int, sprites: List<SVGADrawerSprite>): Boolean {
118+
if (endIndexList == null) {
119+
val boolArray = Array(sprites.count()){false}
120+
sprites.forEachIndexed { index, svgaDrawerSprite ->
121+
svgaDrawerSprite.imageKey?.let {
122+
/// Filter matte sprite
123+
if (it.endsWith(".matte")) {
124+
// Continue
125+
return@forEachIndexed
126+
}
127+
}
128+
svgaDrawerSprite.matteKey?.let {
129+
if (it.length > 0) {
130+
// Last one
131+
if (index == sprites.count() - 1) {
132+
boolArray[index] = true
133+
} else {
134+
sprites.get(index + 1)?.let { nextSprite ->
135+
if (nextSprite.matteKey == null || nextSprite.matteKey.length == 0) {
136+
boolArray[index] = true
137+
} else {
138+
if (nextSprite.matteKey != svgaDrawerSprite.matteKey) {
139+
boolArray[index] = true
140+
}
141+
}
142+
}
143+
}
144+
}
145+
}
146+
}
147+
endIndexList = boolArray
148+
}
149+
return endIndexList?.get(spriteIndex) ?: false
150+
}
151+
83152
private fun playAudio(frameIndex: Int) {
84153
this.videoItem.audios.forEach { audio ->
85154
if (audio.startFrame == frameIndex) {
@@ -371,7 +440,7 @@ internal class SVGACanvasDrawer(videoItem: SVGAVideoEntity, val dynamicItem: SVG
371440

372441
private val shareMattePaint = Paint()
373442
private var shareMatteCanvas: Canvas? = null
374-
private var sharedMatteBitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8)
443+
private var sharedMatteBitmap: Bitmap? = null
375444

376445
fun sharedPaint(): Paint {
377446
sharedPaint.reset()
@@ -404,17 +473,18 @@ internal class SVGACanvasDrawer(videoItem: SVGAVideoEntity, val dynamicItem: SVG
404473
}
405474

406475
fun sharedMatteBitmap(): Bitmap {
407-
return sharedMatteBitmap
476+
return sharedMatteBitmap as Bitmap
408477
}
409478

410479
fun shareMatteCanvas(width: Int, height: Int): Canvas {
411480
if (shareMatteCanvas == null) {
412481
sharedMatteBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ALPHA_8)
413-
shareMatteCanvas = Canvas(sharedMatteBitmap)
482+
// shareMatteCanvas = Canvas(sharedMatteBitmap)
414483
}
415-
val matteCanvas = shareMatteCanvas as Canvas
416-
matteCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
417-
return matteCanvas
484+
// val matteCanvas = shareMatteCanvas as Canvas
485+
// matteCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
486+
// return matteCanvas
487+
return Canvas(sharedMatteBitmap)
418488
}
419489
}
420490

0 commit comments

Comments
 (0)