Android/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/SrcScroll.java

140 lines
4.8 KiB
Java
Raw Normal View History

2023-11-09 08:37:59 +08:00
package com.xixun.xixunplayer;
2024-01-24 20:17:59 +08:00
import android.annotation.SuppressLint;
2023-11-09 08:37:59 +08:00
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
2024-01-24 20:17:59 +08:00
import android.graphics.Rect;
2023-11-09 08:37:59 +08:00
import android.view.Choreographer;
import android.view.View;
2024-01-24 20:17:59 +08:00
import androidx.annotation.NonNull;
2023-11-10 20:44:11 +08:00
import java.util.ArrayList;
2024-01-24 20:17:59 +08:00
import java.util.List;
2023-11-10 20:44:11 +08:00
2023-11-09 08:37:59 +08:00
import gnph.util.JSMap;
2024-01-24 20:17:59 +08:00
@SuppressLint("ViewConstructor")
2024-02-02 19:34:33 +08:00
public class SrcScroll extends View implements Choreographer.FrameCallback {
2023-11-09 08:37:59 +08:00
2024-01-24 20:17:59 +08:00
ArrayList<Bitmap> imgs = new ArrayList<>();
Rect rect = new Rect();
int imgsWidth;
2023-11-09 08:37:59 +08:00
int interval, cur, end, step;
char effect;
2024-02-02 19:34:33 +08:00
public SrcScroll(Context context, JSMap json) {
2023-11-09 08:37:59 +08:00
super(context);
2024-01-24 20:17:59 +08:00
var img = BitmapFactory.decodeFile(Util.programDir+"/"+json.stnn("id"));
imgsWidth = img.getWidth();
if(imgsWidth <= 8192) imgs.add(img);
else {
var rem = img.getWidth();
do {
imgs.add(Bitmap.createBitmap(img, img.getWidth()-rem, 0, Math.min(8192, rem), img.getHeight()));
rem -= 8192;
} while (rem>0);
}
2023-11-09 08:37:59 +08:00
var effStr = json.str("effect");
if(effStr==null || effStr.equals("no")) return;
var scrollSpeed = json.dbl("scrollSpeed");
if(scrollSpeed==0) {
var scrollDur = json.dbl("effectSpeed");
if(scrollDur==0) return;
scrollSpeed = 1000 / scrollDur;
}
interval = step = 1;
if(scrollSpeed > 60) step = (int) Math.round(scrollSpeed/60);
else if(scrollSpeed < 60) interval = (int) Math.round(60/scrollSpeed);
int idx = effStr.lastIndexOf(' ');
if(idx > -1) {
effect = effStr.charAt(idx+1);
2024-01-24 20:17:59 +08:00
if(effect=='l') end = -(imgsWidth-step);
else if(effect=='r') end = imgsWidth-step;
else if(effect=='t') end = -(imgs.get(0).getHeight()-step);
else if(effect=='b') end = imgs.get(0).getHeight()-step;
2023-11-09 08:37:59 +08:00
}
}
@Override
2024-01-24 20:17:59 +08:00
protected void onDraw(@NonNull Canvas canvas) {
2023-11-09 08:37:59 +08:00
super.onDraw(canvas);
2024-01-24 20:17:59 +08:00
if(imgs.isEmpty()) return;
2023-11-09 08:37:59 +08:00
try {
2023-11-10 20:44:11 +08:00
drawOther(canvas);
2024-01-24 20:17:59 +08:00
if(freshCnt==0 && effect!=0 && interval!=0) {
choreographer.postFrameCallback(this);
freshCnt = 1;
}
2023-11-10 09:47:38 +08:00
} catch (Throwable e) {
setVisibility(GONE);
2024-01-24 20:17:59 +08:00
imgs.clear();
Util.printStackTrace(e);
2023-11-09 08:37:59 +08:00
}
}
2023-11-10 20:44:11 +08:00
public void drawOther(Canvas canvas) {
2024-01-24 20:17:59 +08:00
if(! canvas.getClipBounds(rect)) {
rect.left = rect.top = 0;
rect.right = getWidth();
rect.bottom = getHeight();
}
2023-11-10 20:44:11 +08:00
if(effect=='l') {
2024-01-24 20:17:59 +08:00
int ii = 0, x = cur;
2023-12-11 16:18:42 +08:00
do {
2024-01-24 20:17:59 +08:00
if(x > rect.left-imgs.get(ii).getWidth() && x < rect.right) canvas.drawBitmap(imgs.get(ii), x, 0, null);
x += imgs.get(ii).getWidth();
if(++ii >= imgs.size()) ii = 0;
} while(x < rect.right);
2023-11-10 20:44:11 +08:00
} else if(effect=='r') {
2024-01-24 20:17:59 +08:00
int ii = imgs.size()-1, x = cur + getWidth();
boolean con1;
2023-12-11 16:18:42 +08:00
do {
2024-01-24 20:17:59 +08:00
x -= imgs.get(ii).getWidth();
con1 = x > rect.left-imgs.get(ii).getWidth();
if(con1 && x < rect.right) canvas.drawBitmap(imgs.get(ii), x, 0, null);
if(--ii < 0) ii = imgs.size()-1;
} while(con1);
2023-11-10 20:44:11 +08:00
} else if(effect=='t') {
2024-01-24 20:17:59 +08:00
int ii = 0, y = cur;
do {
if(y > rect.top-imgs.get(ii).getHeight() && y < rect.bottom) canvas.drawBitmap(imgs.get(ii), 0, y, null);
y += imgs.get(ii).getHeight();
if(++ii >= imgs.size()) ii = 0;
} while(y < rect.bottom);
2023-11-10 20:44:11 +08:00
} else if(effect=='b') {
2024-01-24 20:17:59 +08:00
int ii = imgs.size()-1, y = cur + getHeight();
boolean con1;
do {
y -= imgs.get(ii).getHeight();
con1 = y > rect.top-imgs.get(ii).getHeight();
if(con1 && y < rect.bottom) canvas.drawBitmap(imgs.get(ii), 0, y, null);
if(--ii < 0) ii = imgs.size()-1;
} while(con1);
} else canvas.drawBitmap(imgs.get(0), 0, 0, null);
2023-11-10 20:44:11 +08:00
}
2023-11-09 08:37:59 +08:00
Choreographer choreographer = Choreographer.getInstance();
int freshCnt;
@Override
public void doFrame(long frameTimeNanos) {
if(! isShown()) {
freshCnt = cur = 0;
return;
}
if(freshCnt < interval) freshCnt++;
else {
freshCnt = 1;
if(effect=='t' || effect=='l') {
if(cur <= end) cur -= end;
else cur -= step;
} else if(effect=='b' || effect=='r') {
if(cur >= end) cur -= end;
else cur += step;
}
invalidate();
}
choreographer.postFrameCallback(this);
}
}