Created
August 11, 2020 15:20
-
-
Save yuriyskulskiy/2972cf61351360ad7e91fac6554676b1 to your computer and use it in GitHub Desktop.
Distort edge effect: implement distorting
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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