ZWidget 是一個 Flutter 套件,可將任何 widget 轉換為偽 3D 版本,實現流暢且直覺的 3D 模擬動畫。透過應用深度與透視效果,它在不需要複雜 3D 渲染的情況下提升視覺吸引力。非常適合用來創造沉浸式 UI 元素,例如具有動態深度反應的卡片、按鈕或容器。此套件支援所有主要平台,包括行動裝置、網頁與桌面端,確保跨裝置行為一致。
適用情境
創建動畫3D卡片
增強按鈕互動
建構沉浸式 UI 組件
為靜態小部件增加深度
設計互動式產品預覽
動畫佈局過渡
主要特色
偽3D變換
基於深度的平滑動畫
跨平台相容性
與現有小部件的輕鬆整合
可自訂的視角和傾斜
支援觸控和手勢輸入
適合對象
尋求視覺深度的UI設計師
開發互動式原型的開發者
需要引人入勝的微互動的應用程式
針對多個平台的專案
創意數位體驗
使用建議
對低階設備的效能影響
有限的真實3D幾何
需要仔細調整動畫參數
不適合複雜的3D場景
可能稍微增加建構大小
原始 README
以下為關聯原始碼儲存庫的 README 原文快照,最新內容請造訪原始碼儲存庫。
ZWidget creates a 3D-like visual by stacking widgets one above the other and transforming them adequately.
Tilt your widgets and simulate 3D easily.
Here are a few examples with Text, FlutterLogo, Ìmage, Icon and CustomPaint:
You can also animate them:
The example project includes these demos and a few more.
Usage
ZWidget includes several constructors depending on the direction where you want your perspective effect to be.
ZWidget.backwards(), ZWidget.forwards() and ZWidget.bothDirections()
You must define at least the midChild, which is the base Widget that will be displayed.
Depending on the direction you want the perspective to take place, you may also define the extremities and the widget to display between them and the middle child.
Here is a full example for ZWidget.bothDirections():
ZWidget.bothDirections(
// middle layer
midChild: Container(
width: 60,
height: 60,
color: Colors.blue,
),
midToBotChild: Container(
width: 60,
height: 60,
color: Colors.blueGrey,
),
// layers between mid and top child
midToTopChild: Container(
width: 60,
height: 60,
color: Colors.lightBlue,
),
// layer at the bottom of the Stack
botChild: Container(
width: 60,
height: 60,
color: Colors.grey,
),
// layer at the top of the Stack
topChild: Container(
width: 60,
height: 60,
color: Colors.lightBlueAccent,
),
// rotation around X axis
rotationX: pi / 3,
// rotation around Y axis
rotationY: -pi / 4,
// Number of layers. Always odd (increased if even)
layers: 5,
// Space between layers
depth: 32,
)
ZWidget.backwards() and ZWidget.forwards() are similar but they provide only the children parameters adequate to their direction.
The layers of a ZWidget are visibles in the picture below:
There is always an odd number of layers. If you define an even number, it will be increased to be an odd number. Increase depth to increase their spacing.
ZDirection can be forward, backward or both.
Mid layer is the midChild. Depending on the ZDirection, other layers are displayed above or below the midChild.
You can define the botChild for the child at the bottom of the Stack and topChild for the one at the top.
You can also define Widgets between these extremities and midChild with midToTopChild and midToBotChild.
Use the alignment property to set the Transform origin.
To effectively see the 3D effect, you must define a rotation to the ZWidget using rotationX and rotationY.
ZWidget.builder()
In case you would like to control which Widget is displayed at each layer, you may use Widget.builder().
It can be used to make a gradient effect for instance.
Here are a few examples:
ZWidget()
While the base ZWidget constructor works, it may lead newcomers to define parameters that are not needed.
Therefore, it is now deprecated and you should use the other constructors instead.
Performance considerations
If ZWidget has 11 layers, it means that 11 Widgets will be drawn. Try to limit the complexity of widgets used at each layer.
For instance, an opaque Image could use simple Containers to simulate a 3D effect:
// The builder function used to build each layerfinalWidgetFunction(int) builder;
// Space between layersfinaldouble depth;
// Perspective directionfinalZDirection direction;
// Rotation around X axisfinaldouble rotationX;
// Rotation around Y axisfinaldouble rotationY;
// Number of layers. Always odd (increased if set even)finalint layers;
// Experimental, used to reverse the X and Y rotationsfinalbool reverse;
// Shows a pink border representing the size taken by this `ZWidget`.// Painting may go beyond that border.finalbool debug;
// The bigger the perspective, the more part of the widget will seem to be far away.finaldouble perspective;
// Transform originfinalAlignment? alignment;
// A fade effect (experimental)finalbool fade;
ZWidget size
Depending on the transformations and the 3D effect your want to achieve, your widget might be drawn beyond its limits.
The debug parameter shows a pink border around your ZWidget which indicates its layout size in the widget tree but the painting may go beyond that border.
That's because the Transform that we use doesn't change the base size of the widget, it just changes how it is rendered. The layout remains the same, but the painting can change a lot. See the Transformdocumentation for more infos.
You might want to cut it to fit in the border with a ClipRect for instance.
How does it work?
ZWidget fills a Stack with layers Widgets returned by a builder function.
These are then transformed to make the 3D effect.
This transformations is done using a Transform widget and a Matrix4. If you'd like to do something similar but not with Widget, you can use the top-level function zMatrix4().
zMatrix4
This method returns a Matrix4 used to perform 3D transformations.
You can use it on anything accepting a Matrix4 (Widget, Canvas, Path, ...).