앱을 구현하다가 이미지의 하단부분이 자연스럽게 투명해지면서 배경과 어우러지게 만들 필요가 있어졌다.
원래 이미지는 아래와 같다.
좀 어색하다. 배경색깔과 어우러지질 않는다.
최종 결과는 이러하다.
이를 구현하기 위해 ShaderMask라는 위젯을 사용했는데 이는 쉽게 말하면
자식 위젯에 페인트칠을 할 수 있게 해주는 위젯이다. 즉, 색을 덧댄다고 생각하면 된다. 나는 아래 문서를 참고했다. 위 비유도 아래 문서에서 나온 표현이다
일단 ShaderMask의 required 파라미터는 shaderCallback이다.
여기에는 Shader Function(Rect) 가 들어가면 된다.
Rect 타입을 받아 Shader라는 타입의 객체를 리턴해주는 함수를 넣어주면 된다.
나는 아래와 같이 구현했다.
ShaderMask(
shaderCallback: (Rect bound){
return LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Colors.white,Colors.transparent],
stops: [0.5,0.75]
).createShader(bound);
},
blendMode: BlendMode.dstIn,
child: Image.asset('assets/tree_main.png',width: 500,fit: BoxFit.fitWidth,)
),
return 에 일단 LinearGradient 객체를 써주고 그 안에서 구체적인 구현 값들을 넣어주고, 마지막에 createShader(Rect)를 사용해줌으로써 Shader객체로 변환해주는 것이다.
그러고 child 값에는 shaderCallback에서 열심히 설정한 것들로 색칠해줄 위젯을 넣어주면 된다.
나 같은 경우에는 Image 위젯인 것이고, 문서 설명에는 다른 위젯들도 다 색칠이 가능하다고 한다.
실례로 Text를 이쁘게 칠하는 code Sample들이 많더라.
위 영상에도 Text를 불타게 만드는 법이 설명되어 있음.
그럼이제 구체적으로 LindearGradient 안의 설정 값들을 살펴보자.
내가 0.5에서 0.75로 설정한 것은 무슨 의미냐? 0,5까지는 위의 colors[0]인 Colors.white를 그냥 단색으로 칠해주고 0.75까지 colors[1]인 Colors.transparent로 그라데이션 표현, 0.75부터는 그냥 transparent라는 소리다.
stops를 따로 설정하지 않으면 이렇게 이미지 전체어 걸쳐 뿌옇다. stops를 구체적으로 정해줘야 어디부터 어디까지 얼마나 빠르게 투명해질지 정할 수 잇다.
여기까지가 LinearGradient의 설정 끝! 이제 제일 중요한 것 중 하나가 남았다.
바로..! ShaderMask에서 설정해야 하는 blendMode다. 이는 그라데이션의 색 설정 값들을 어떻게 버무릴 것인가를 정하는 방식이다. 사실 위 설정까지 마치고 blendMode를 따로 지정해주지 않으면 이상한 값이 나온다.
사실 나도 정확한 원리는 모르겠다. 쉬운 이해를 위해서 Color 설정 값을 아래와 같이 바꾼 뒤 보여주겠따. 그리고 stops도 따로 설정하지 않겠다.
blendMode를 따로 설정해주지 않으면 아래와 같이 변한다.
전형적인 그라데이션이다. 흰색부터 빨간색까지 차근차근, 이미지에 덧씌어진다.
근데 여기에 blendMode를 추가로 설정해주면 뭐 요상한게 막 된다.
나도 자세히는 모르니까 값만 바꿔서 나열해주겠다.
https://medium.com/flutter-community/an-overview-on-shadermask-89201539ba8d
자세한건 여기 참고하시오.. 중반 부분부터 설명 나옴.
내가 사용한 건, BlendMode.dstIn임.
얘를 설정해주면 특이하게 Colors.transparent를 제외한 모든 색깔이 적용이 안된다. 그러니 내 상황에 제격이다. 불필요하게 색을 덧쒸울 필요가 없으니 말이다.
그래서 위 코드의 colors 목록에 Colors.white를 쓰든, Colors.red를 쓰든 아무런 상관이 없다.