[flutter/플러터] 투명도 그라데이션 넣기(ShaderMask)

박민준·2022년 1월 21일
1

앱을 구현하다가 이미지의 하단부분이 자연스럽게 투명해지면서 배경과 어우러지게 만들 필요가 있어졌다.

원래 이미지는 아래와 같다.

좀 어색하다. 배경색깔과 어우러지질 않는다.

최종 결과는 이러하다.

이를 구현하기 위해 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 안의 설정 값들을 살펴보자.

  • begin -> 그라데이션의 시작 부분
  • end -> 끝 부분, 둘 다 Alignment객체를 요한다.
  • colors -> 그라데이션에 포함될 색을 리스트 형태로 구성한다. 일단 나는 마지막엔 투명해져야 하니깐 Colors.transparent는 당연히 넣어야 하고 그럼 나머지 색깔은..? 아무거나 써도 된다. 왜 그런진 아래 blendMode를 설명할 때 알려주겟다.
  • stops -> 그라데이션이 시작되고 끝날 부분을 0~1 사이의 double값으로 정해준다. 아무것도 설정하지 않으면 0,1이 기본값으로 설정될 것. 즉 child의 begin부터 end까지 다 그라데이션으로 칠해준다는 것.

    내가 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를 따로 지정해주지 않으면 이상한 값이 나온다.

blendMode

사실 나도 정확한 원리는 모르겠다. 쉬운 이해를 위해서 Color 설정 값을 아래와 같이 바꾼 뒤 보여주겠따. 그리고 stops도 따로 설정하지 않겠다.


blendMode를 따로 설정해주지 않으면 아래와 같이 변한다.
전형적인 그라데이션이다. 흰색부터 빨간색까지 차근차근, 이미지에 덧씌어진다.

근데 여기에 blendMode를 추가로 설정해주면 뭐 요상한게 막 된다.
나도 자세히는 모르니까 값만 바꿔서 나열해주겠다.



https://medium.com/flutter-community/an-overview-on-shadermask-89201539ba8d
자세한건 여기 참고하시오.. 중반 부분부터 설명 나옴.
내가 사용한 건, BlendMode.dstIn임.
얘를 설정해주면 특이하게 Colors.transparent를 제외한 모든 색깔이 적용이 안된다. 그러니 내 상황에 제격이다. 불필요하게 색을 덧쒸울 필요가 없으니 말이다.
그래서 위 코드의 colors 목록에 Colors.white를 쓰든, Colors.red를 쓰든 아무런 상관이 없다.

완성 화면!!

완성 코드!!

profile
코린이

0개의 댓글