Skip to content

Instantly share code, notes, and snippets.

@yuriyskulskiy
Created August 11, 2020 15:20
Show Gist options
  • Save yuriyskulskiy/2972cf61351360ad7e91fac6554676b1 to your computer and use it in GitHub Desktop.
Save yuriyskulskiy/2972cf61351360ad7e91fac6554676b1 to your computer and use it in GitHub Desktop.
Distort edge effect: implement distorting
public class DistortEdgeEffect {
...
private static final float RADIUS_FACTOR = 1f; //not nessesary but I have changed it from 0.6 to 1
private final int HORIZONTAL_STEPS_COUNT = 40; // as more steps as more smoother it looks
private float[] mDistrotedVertices;
private float mStepWidth;
...
public void setSize(int width, int height) {
...
mDistrotedVertices = new float[(HORIZONTAL_STEPS_COUNT + 1) * 4];
mStepWidth = width / (float) HORIZONTAL_STEPS_COUNT;
}
public boolean drawWithDistortion(Canvas canvas, Bitmap bitmap,
float offsetY, Bitmap mHelperBitmap,
Canvas mHelperCanvas) {
update();
float currentRadiusMultiplier = Math.min(mGlowScaleY, 1.f) * mBaseGlowScale;
float currentDistortionHeight = currentRadiusMultiplier * maxDistortionHeight;
final float centerX = mDisplacement * mFullWidth;
final float centerY = computeCenterY(currentDistortionHeight);
float rLength = (currentDistortionHeight + Math.abs(centerY));
computeDistoredVetices(centerX, centerY, rLength);
mHelperBitmap.eraseColor(Color.TRANSPARENT);
mHelperCanvas
.drawBitmapMesh(bitmap, HORIZONTAL_STEPS_COUNT,
1, mDistrotedVertices, 0, null, 0, null);
canvas.drawBitmap(mHelperBitmap, 0, offsetY, null);
boolean oneLastFrame = false;
if (mState == STATE_RECEDE && mGlowScaleY == 0) {
mState = STATE_IDLE;
oneLastFrame = true;
}
return mState != STATE_IDLE || oneLastFrame;
}
private void computeDistoredVetices(float ceterX, float xenterY, float radius) {
for (int i = 0; i < mDistrotedVertices.length; i += 2) {
if (i < mDistrotedVertices.length / 2) {
mDistrotedVertices[i] = i / 2f * mStepWidth;
int pointY = computePointY(ceterX, xenterY, radius, mDistrotedVertices[i]);
mDistrotedVertices[i + 1] = 0 + pointY;
} else {
mDistrotedVertices[i] = (i - mDistrotedVertices.length / 2f) / 2 * mStepWidth;
mDistrotedVertices[i + 1] = mFulHeight;
}
}
}
private int computePointY(float centerX, float centerY, float radius, float pointX) {
if (centerY == Float.POSITIVE_INFINITY || radius == Float.POSITIVE_INFINITY) {
return 0;
}
return (int) (Math.sqrt(Math.pow(radius, 2)
- Math.pow(centerX - pointX, 2)) + centerY);
}
}
public class NestedScrollView extends FrameLayout
implements NestedScrollingParent3,
NestedScrollingChild3, ScrollingView {
...
private Bitmap mDistortBitmap;
private Canvas mDistortCanvas;
private Bitmap mHelperBitmap;
private Canvas mHelperCanvas;
...
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mDistortBitmap = Bitmap
.createBitmap(w,
h,
Bitmap.Config.ARGB_8888);
mDistortCanvas = new Canvas(mDistortBitmap);
mDistortCanvas.save();
//workaround
mHelperBitmap = Bitmap
.createBitmap(w,
h,
Bitmap.Config.ARGB_8888);
mHelperCanvas = new Canvas(mHelperBitmap);
...
}
@Override
public void draw(Canvas canvas) {
boolean hasEdgeDistortion = false;
if (mEdgeGlowTop != null && !mEdgeGlowTop.isFinished()) {
hasEdgeDistortion = true;
final int restoreCount = mDistortCanvas.save();
mDistortCanvas.translate(0, -getScrollY());
super.draw(mDistortCanvas);
int width = getWidth();
int height = getHeight();
mEdgeGlowTop.setSize(width, height);
if (mEdgeGlowTop.drawWithDistortion(canvas, mDistortBitmap,
getScrollY(), mHelperBitmap, mHelperCanvas)) {
ViewCompat.postInvalidateOnAnimation(this);
}
mDistortCanvas.restoreToCount(restoreCount);
}
if (mEdgeGlowBottom != null && !mEdgeGlowBottom.isFinished()) {
hasEdgeDistortion = true;
int width = getWidth();
int height = getHeight();
int saveDistortCanvas = mDistortCanvas.save();
mDistortCanvas.translate(width, getHeight() + getScrollY());
mDistortCanvas.rotate(180, 0, 0);
int saveHelperCanvas = mHelperCanvas.save();
mHelperCanvas.translate(getWidth(), getHeight());
mHelperCanvas.rotate(180, 0, 0);
super.draw(mDistortCanvas);
mEdgeGlowBottom.setSize(width, height);
if (mEdgeGlowBottom.drawWithDistortion(canvas,
mDistortBitmap, getScrollY(), mHelperBitmap, mHelperCanvas)) {
ViewCompat.postInvalidateOnAnimation(this);
}
mHelperCanvas.restoreToCount(saveHelperCanvas);
mDistortCanvas.restoreToCount(saveDistortCanvas);
}
if (!hasEdgeDistortion) {
super.draw(canvas);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment