Flutter neumorphic designs
📕Overview
ニューモーフィズム(Neumorphism)とは、立体感と質感を備えた「スキューモーフィズム」と、シンプルでミニマムな「フラットデザイン」や「マテリアルデザイン」を組み合わせたデザイン手法です。
時々見かける立体的なUI/UXデザインをFlutterでやってみたいと思った。Dartのパッケージがあるようなので、使ってみようと思います。
とはいえこれはしばらくメンテナンスされていなかったようだ💦
🧷summary
main.dart
を修正してコンポーネントを別にファイル作成して読み込んでみよう。
import 'package:clay_containers_example/my_example.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter Demo'),
),
body: Center(
child: MyExampleScreen(),
),
);
}
}
🏺シンプルな粘土の容器
最良の結果を得るには、周囲のウィジェットの背景色を、粘土コンテナに設定する色と一致するように設定します。この基本色を複数回再利用する可能性が高いため (特に、何か派手なことをする場合には)、この色を 1 つの値に設定することをお勧めします。次の例では、baseColor に設定されています。
立体的な正方形
import 'package:clay_containers/clay_containers.dart';
import 'package:flutter/material.dart';
class MyExampleScreen extends StatelessWidget {
const MyExampleScreen({super.key});
Widget build(BuildContext context) {
Color baseColor = const Color(0xFFF2F2F2);
return Container(
color: baseColor,
child: Center(
child: ClayContainer(
color: baseColor,
height: 200,
width: 200,
),
),
);
}
}
ClayContainer with a ClayText Child.
前の例では、ClayContainer には子がないため、高さと幅が指定されています。 ClayContainer は通常の Container と同じように動作し、高さと幅を指定するか、子を表示する必要があります。次の例では、ClayContainer が子を受け取ります。
受け取る子は、何らかの Padding でラップされた ClayText です。
import 'package:clay_containers/clay_containers.dart';
import 'package:flutter/material.dart';
class MyExampleScreen extends StatelessWidget {
const MyExampleScreen({super.key});
Widget build(BuildContext context) {
Color baseColor = const Color(0xFFF2F2F2);
return Container(
color: baseColor,
child: Center(
child: ClayContainer(
color: baseColor,
child: Padding(
padding: EdgeInsets.all(20),
child: ClayText("Seize the Clay!", emboss: true, size: 40),
),
),
),
);
}
}
Rounded ClayContainers
四角くならないでください! borderRadius を使用してフレアを追加します。均一な borderRadius が必要な場合は、ClayContainer コンストラクターで直接設定するだけです。
公式のサンプルは、borderRadiusが50だったが、100にしないと丸にならなかった😅
import 'package:clay_containers/clay_containers.dart';
import 'package:flutter/material.dart';
class MyExampleScreen extends StatelessWidget {
const MyExampleScreen({super.key});
Widget build(BuildContext context) {
Color baseColor = const Color(0xFFF2F2F2);
return Container(
color: baseColor,
child: Center(
child: ClayContainer(
color: baseColor,
height: 150,
width: 150,
borderRadius: 100,
),
),);
}
}
emboss: trueのパラメーターを追加すると丸が凹んだデザインになります。
import 'package:clay_containers/clay_containers.dart';
import 'package:flutter/material.dart';
class MyExampleScreen extends StatelessWidget {
const MyExampleScreen({super.key});
Widget build(BuildContext context) {
Color baseColor = const Color(0xFFF2F2F2);
return Container(
color: baseColor,
child: Center(
child: ClayContainer(
emboss: true,// add
color: baseColor,
height: 150,
width: 150,
borderRadius: 100,
),
),);
}
}
🧑🎓thoughts
以前から時々見かける立体的なUI/UXデザインを作ってみたいと思いました。まさかパッケージを使えばできるとは。でも待って。これ長いことメンテナンスされてなかった。もしまたされなくなったらどうすればいいのか?
自作する方法はあるはず。
やり方
clay_containersパッケージを使わずに、BoxDecorationとBoxShadowを使って凹んだ丸を作ることができます。以下にそのコードを示します。
import 'package:flutter/material.dart';
class ShowContainer extends StatelessWidget {
const ShowContainer({super.key});
Widget build(BuildContext context) {
Color baseColor = const Color(0xFFF2F2F2);
return Container(
color: baseColor,
child: Center(
child: Container(
height: 150,
width: 150,
decoration: BoxDecoration(
color: baseColor,
borderRadius: BorderRadius.circular(100),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: const Offset(-3, -3), // changes position of shadow
),
const BoxShadow(
color: Colors.white,
spreadRadius: 5,
blurRadius: 7,
offset: Offset(3, 3), // changes position of shadow
),
],
),
),
),
);
}
}
このコードでは、BoxDecorationとBoxShadowを使って、ClayContainerのemboss効果を再現しています。BoxShadowは2つ定義されており、一つは灰色の影で、もう一つは白色の影です。これにより、凹んだ効果が生まれます。
立体的なフォームを作る
同じように立体的な入力フォームを作ることもできます。
import 'package:flutter/material.dart';
class BoxShowForm extends StatelessWidget {
const BoxShowForm({super.key});
Widget build(BuildContext context) {
Color baseColor = const Color(0xFFF2F2F2);
return Container(
color: baseColor,
child: Center(
child: Container(
height: 60,
width: 300,
decoration: BoxDecoration(
color: baseColor,
borderRadius: BorderRadius.circular(30),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: const Offset(-3, -3), // changes position of shadow
),
const BoxShadow(
color: Colors.white,
spreadRadius: 5,
blurRadius: 7,
offset: Offset(3, 3), // changes position of shadow
),
],
),
child: const TextField(
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.all(10),
),
),
),
),
);
}
}
このコードでは、TextFieldウィジェットをContainerウィジェットの中に配置し、Containerウィジェットに影をつけることで凹んだ効果を作り出しています。また、TextFieldのdecorationプロパティを使って、入力フォームの内側の余白を調整しています。
Discussion