下面是他的網址
http://www.curious-creature.org/2012/12/13/android-recipe-2-fun-with-shaders/
他的做法其實是利用 canvas draw bitmap 以及 paint來完成,
首先他將背景設置到 paint,
接著將mask 轉成 alpha 接著在canvas上繪製就完成了。
知道大概要怎麼做之後,我們來看code
- 將背景設置到 paint
private void createShader() {
View target = getRootView().findViewById(mTargetId);
mTargetBitmap = createBitmap(target);
Shader targetShader = createShader(mTargetBitmap);
mPaint.setShader(targetShader);
}
private static Shader createShader(Bitmap b) {
return new BitmapShader(b, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
}
private static Bitmap createBitmap(View target) {
Bitmap b = Bitmap.createBitmap(target.getWidth(), target.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
target.draw(c);
return b;
}
- 接著將mask圖轉成alpha
mMask = convertToAlphaMask(BitmapFactory.decodeResource(getResources(), maskId));
private static Bitmap convertToAlphaMask(Bitmap b) {
Bitmap a = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ALPHA_8);
Canvas c = new Canvas(a);
c.drawBitmap(b, 0.0f, 0.0f, null);
return a;
}
- 接著在canvas上繪製
canvas.drawBitmap(mMask, 0.0f, 0.0f, mPaint);
基本的功能這樣就完成了,如下圖
接著該如何讓spotlight移動以及放大是另一個問題,
假設我們希望將剛剛的spotlight放大3倍,並且移至較中間的位置 100,100 我們應該怎麼做呢?
mShaderMatrix.setScale(1.0f / 3, 1.0f / 3); mShaderMatrix.preTranslate(-100, -100); mPaint.getShader().setLocalMatrix(mShaderMatrix); canvas.translate(100, 100); canvas.scale(3, 3); canvas.drawBitmap(mMask, 0.0f, 0.0f, mPaint);
可以發現,作者的做法是
- 先將背景先縮小並反向位移
- 接著再將整個畫布放大並位移
也就是原先看到的mask 被放大的並位移到較中間的位置,而背景的縮放以及位移被抵銷掉
結果的圖如下
由於作者的範例包含太多動畫,所以我寫了一個更簡單的sample,由兩個按鈕來控制
postion以及 scale ,讓大家比較容易trace,附上 sample code


沒有留言:
張貼留言