diff --git a/doric-android/doric/src/main/java/pub/doric/DoricRegistry.java b/doric-android/doric/src/main/java/pub/doric/DoricRegistry.java index a2ffa802..4fea8402 100644 --- a/doric-android/doric/src/main/java/pub/doric/DoricRegistry.java +++ b/doric-android/doric/src/main/java/pub/doric/DoricRegistry.java @@ -47,6 +47,7 @@ import pub.doric.resource.DoricBase64Loader; import pub.doric.resource.DoricLocalLoader; import pub.doric.resource.DoricRemoteLoader; import pub.doric.resource.DoricResourceManager; +import pub.doric.shader.AeroEffectViewNode; import pub.doric.shader.BlurEffectViewNode; import pub.doric.shader.DraggableNode; import pub.doric.shader.GestureContainerNode; @@ -132,6 +133,7 @@ public class DoricRegistry { this.registerViewNode(FlexNode.class); this.registerViewNode(GestureContainerNode.class); this.registerViewNode(BlurEffectViewNode.class); + this.registerViewNode(AeroEffectViewNode.class); this.getResourceManager().registerLoader(new DoricAndroidLoader("drawable")); this.getResourceManager().registerLoader(new DoricAndroidLoader("raw")); this.getResourceManager().registerLoader(new DoricAssetsLoader()); diff --git a/doric-android/doric/src/main/java/pub/doric/shader/AeroEffectView.java b/doric-android/doric/src/main/java/pub/doric/shader/AeroEffectView.java new file mode 100644 index 00000000..d7eb3213 --- /dev/null +++ b/doric-android/doric/src/main/java/pub/doric/shader/AeroEffectView.java @@ -0,0 +1,106 @@ +/* + * Copyright [2021] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package pub.doric.shader; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.PorterDuff; +import android.graphics.Rect; +import android.os.Build; + +import androidx.annotation.NonNull; +import jp.wasabeef.glide.transformations.internal.FastBlur; +import jp.wasabeef.glide.transformations.internal.RSBlur; +import jp.wasabeef.glide.transformations.internal.SupportRSBlur; + +/** + * @Description: This could blur what's contained. + * @Author: pengfei.zhou + * @CreateDate: 2021/11/24 + */ +public class AeroEffectView extends DoricLayer { + private Rect mEffectiveRect = null; + + private Bitmap mFullBitmap = null; + private Canvas mFullCanvas = null; + private Bitmap mRectBitmap = null; + private Canvas mRectCanvas = null; + private Rect mDstRect = null; + + public AeroEffectView(@NonNull Context context) { + super(context); + } + + public void setEffectiveRect(Rect rect) { + this.mEffectiveRect = rect; + this.mDstRect = new Rect(0, 0, rect.width(), rect.height()); + invalidate(); + } + + @Override + protected void dispatchDraw(Canvas canvas) { + if (mFullBitmap == null + || mFullBitmap.getWidth() != canvas.getWidth() + || mFullBitmap.getHeight() != canvas.getHeight()) { + mFullBitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888); + mFullCanvas = new Canvas(mFullBitmap); + } + mFullCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); + super.dispatchDraw(mFullCanvas); + Bitmap blurringBitmap; + if (mEffectiveRect != null) { + if (mRectBitmap == null + || mRectBitmap.getWidth() != mEffectiveRect.width() + || mRectBitmap.getHeight() != mEffectiveRect.height()) { + mRectBitmap = Bitmap.createBitmap(mEffectiveRect.width(), mEffectiveRect.height(), Bitmap.Config.ARGB_8888); + mRectCanvas = new Canvas(mRectBitmap); + } + blurringBitmap = mRectBitmap; + mRectCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); + mRectCanvas.drawBitmap(mFullBitmap, mEffectiveRect, mDstRect, null); + } else { + blurringBitmap = mFullBitmap; + } + Bitmap blurredBitmap; + int radius = 15; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + try { + blurredBitmap = SupportRSBlur.blur(getContext(), blurringBitmap, radius); + } catch (NoClassDefFoundError e) { + try { + blurredBitmap = RSBlur.blur(getContext(), blurringBitmap, radius); + } catch (Exception ee) { + blurredBitmap = FastBlur.blur(blurringBitmap, radius, true); + } + } catch (Exception e) { + blurredBitmap = FastBlur.blur(blurringBitmap, radius, true); + } + } else { + blurredBitmap = FastBlur.blur(blurringBitmap, radius, true); + } + Bitmap retBitmap; + if (mEffectiveRect != null) { + mFullCanvas.drawBitmap(blurredBitmap, mDstRect, mEffectiveRect, null); + retBitmap = mFullBitmap; + } else { + retBitmap = blurredBitmap; + } + + canvas.drawBitmap(retBitmap, 0, 0, null); + } +} diff --git a/doric-android/doric/src/main/java/pub/doric/shader/AeroEffectViewNode.java b/doric-android/doric/src/main/java/pub/doric/shader/AeroEffectViewNode.java index d3ff09bf..b351bcdb 100644 --- a/doric-android/doric/src/main/java/pub/doric/shader/AeroEffectViewNode.java +++ b/doric-android/doric/src/main/java/pub/doric/shader/AeroEffectViewNode.java @@ -38,22 +38,18 @@ public class AeroEffectViewNode extends StackNode { @Override protected FrameLayout build() { - return new BlurEffectView(getContext()); + return new AeroEffectView(getContext()); } @Override protected void blend(FrameLayout view, String name, JSValue prop) { - if ("radius".equals(name)) { - if (prop.isNumber()) { - ((BlurEffectView) view).setRadius(prop.asNumber().toInt()); - } - } else if ("effectiveRect".equals(name)) { + if ("effectiveRect".equals(name)) { if (prop.isObject()) { int x = DoricUtils.dp2px(prop.asObject().getProperty("x").asNumber().toFloat()); int y = DoricUtils.dp2px(prop.asObject().getProperty("x").asNumber().toFloat()); int width = DoricUtils.dp2px(prop.asObject().getProperty("width").asNumber().toFloat()); int height = DoricUtils.dp2px(prop.asObject().getProperty("height").asNumber().toFloat()); - ((BlurEffectView) view).setEffectiveRect(new Rect(x, y, x + width, y + height)); + ((AeroEffectView) view).setEffectiveRect(new Rect(x, y, x + width, y + height)); } } else { super.blend(view, name, prop);