package com.xixun.xixunplayer; import android.annotation.SuppressLint; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Rect; import android.view.Choreographer; import android.view.View; import androidx.annotation.NonNull; import java.util.ArrayList; import gnph.util.JSMap; @SuppressLint("ViewConstructor") public class SrcScroll extends View implements Choreographer.FrameCallback { ArrayList imgs = new ArrayList<>(); Rect rect = new Rect(); int interval, cur, end, step; char effect; public SrcScroll(Prog prog, JSMap json, Bitmap img) { super(prog.getContext()); if(img==null) img = BitmapFactory.decodeFile(Util.programDir+"/"+json.stnn("id")); var 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); } 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); 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; else effect = 0; } if(effect!=0) prog.calls.add(this); } @Override protected void onDraw(@NonNull Canvas canvas) { super.onDraw(canvas); if(imgs.isEmpty()) return; try { drawOther(canvas); } catch (Throwable e) { setVisibility(GONE); imgs.clear(); Util.printStackTrace(e); } } public void drawOther(Canvas canvas) { if(! canvas.getClipBounds(rect)) { rect.left = rect.top = 0; rect.right = getWidth(); rect.bottom = getHeight(); } if(effect=='l') { int ii = 0, x = cur; do { 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); } else if(effect=='r') { int ii = imgs.size()-1, x = cur + getWidth(); boolean con1; do { 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); } else if(effect=='t') { 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); } else if(effect=='b') { 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); } int freshCnt; @Override public void doFrame(long ms) { 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(); } } }