mirror of
https://github.com/flame-engine/flame.git
synced 2025-11-03 04:18:25 +08:00
Add flame rive package to monorepo (#1048)
Add flame rive package to monorepo
This commit is contained in:
@ -9,6 +9,7 @@ environment:
|
||||
sdk: ">=2.14.0 <3.0.0"
|
||||
flutter: ">=2.5.0"
|
||||
|
||||
|
||||
dependencies:
|
||||
flame:
|
||||
path: ../packages/flame
|
||||
|
||||
80
packages/flame_rive/.gitignore
vendored
Normal file
80
packages/flame_rive/.gitignore
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
# Miscellaneous
|
||||
*.class
|
||||
*.log
|
||||
*.pyc
|
||||
*.swp
|
||||
.DS_Store
|
||||
.atom/
|
||||
.buildlog/
|
||||
.history
|
||||
.svn/
|
||||
|
||||
# IntelliJ related
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
|
||||
# The .vscode folder contains launch configuration and tasks you configure in
|
||||
# VS Code which you may wish to be included in version control, so this line
|
||||
# is commented out by default.
|
||||
#.vscode/
|
||||
|
||||
# Flutter/Dart/Pub related
|
||||
**/doc/api/
|
||||
.dart_tool/
|
||||
.flutter-plugins
|
||||
.flutter-plugins-dependencies
|
||||
.packages
|
||||
.pub-cache/
|
||||
.pub/
|
||||
build/
|
||||
|
||||
# Android related
|
||||
**/android/**/gradle-wrapper.jar
|
||||
**/android/.gradle
|
||||
**/android/captures/
|
||||
**/android/gradlew
|
||||
**/android/gradlew.bat
|
||||
**/android/local.properties
|
||||
**/android/**/GeneratedPluginRegistrant.java
|
||||
|
||||
# iOS/XCode related
|
||||
**/ios/**/*.mode1v3
|
||||
**/ios/**/*.mode2v3
|
||||
**/ios/**/*.moved-aside
|
||||
**/ios/**/*.pbxuser
|
||||
**/ios/**/*.perspectivev3
|
||||
**/ios/**/*sync/
|
||||
**/ios/**/.sconsign.dblite
|
||||
**/ios/**/.tags*
|
||||
**/ios/**/.vagrant/
|
||||
**/ios/**/DerivedData/
|
||||
**/ios/**/Icon?
|
||||
**/ios/**/Pods/
|
||||
**/ios/**/.symlinks/
|
||||
**/ios/**/profile
|
||||
**/ios/**/xcuserdata
|
||||
**/ios/.generated/
|
||||
**/ios/Flutter/App.framework
|
||||
**/ios/Flutter/Flutter.framework
|
||||
**/ios/Flutter/Flutter.podspec
|
||||
**/ios/Flutter/Generated.xcconfig
|
||||
**/ios/Flutter/app.flx
|
||||
**/ios/Flutter/app.zip
|
||||
**/ios/Flutter/flutter_assets/
|
||||
**/ios/Flutter/flutter_export_environment.sh
|
||||
**/ios/ServiceDefinitions.json
|
||||
**/ios/Runner/GeneratedPluginRegistrant.*
|
||||
|
||||
# Exceptions to above rules.
|
||||
!**/ios/**/default.mode1v3
|
||||
!**/ios/**/default.mode2v3
|
||||
!**/ios/**/default.pbxuser
|
||||
!**/ios/**/default.perspectivev3
|
||||
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
|
||||
|
||||
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
|
||||
/pubspec.lock
|
||||
|
||||
|
||||
10
packages/flame_rive/.metadata
Normal file
10
packages/flame_rive/.metadata
Normal file
@ -0,0 +1,10 @@
|
||||
# This file tracks properties of this Flutter project.
|
||||
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||
#
|
||||
# This file should be version controlled and should not be manually edited.
|
||||
|
||||
version:
|
||||
revision: 0272047e8727f6913804112c763ae1711d114afb
|
||||
channel: master
|
||||
|
||||
project_type: package
|
||||
11
packages/flame_rive/CHANGELOG.md
Normal file
11
packages/flame_rive/CHANGELOG.md
Normal file
@ -0,0 +1,11 @@
|
||||
# CHANGELOG
|
||||
|
||||
## [next]
|
||||
|
||||
## [1.0.0-releasecandidate.1]
|
||||
|
||||
* Add Basic rive support to component mode
|
||||
|
||||
## [0.0.1]
|
||||
|
||||
* Empty release; in the future all flame rive related code will live here.
|
||||
22
packages/flame_rive/LICENSE
Normal file
22
packages/flame_rive/LICENSE
Normal file
@ -0,0 +1,22 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Blue Fire
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
4
packages/flame_rive/README.md
Normal file
4
packages/flame_rive/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
# Flame Rive
|
||||
|
||||
Package to add Rive support for the Flame game engine.
|
||||
|
||||
1
packages/flame_rive/analysis_options.yaml
Normal file
1
packages/flame_rive/analysis_options.yaml
Normal file
@ -0,0 +1 @@
|
||||
include: package:flame_lint/analysis_options.yaml
|
||||
49
packages/flame_rive/example/.gitignore
vendored
Normal file
49
packages/flame_rive/example/.gitignore
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
# Miscellaneous
|
||||
*.class
|
||||
*.log
|
||||
*.pyc
|
||||
*.swp
|
||||
.DS_Store
|
||||
.atom/
|
||||
.buildlog/
|
||||
.history
|
||||
.svn/
|
||||
|
||||
# IntelliJ related
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
|
||||
# The .vscode folder contains launch configuration and tasks you configure in
|
||||
# VS Code which you may wish to be included in version control, so this line
|
||||
# is commented out by default.
|
||||
#.vscode/
|
||||
|
||||
# Flutter/Dart/Pub related
|
||||
**/doc/api/
|
||||
**/ios/Flutter/.last_build_id
|
||||
.dart_tool/
|
||||
.flutter-plugins
|
||||
.flutter-plugins-dependencies
|
||||
.packages
|
||||
.pub-cache/
|
||||
.pub/
|
||||
/build/
|
||||
|
||||
# Web related
|
||||
lib/generated_plugin_registrant.dart
|
||||
|
||||
# Symbolication related
|
||||
app.*.symbols
|
||||
|
||||
# Obfuscation related
|
||||
app.*.map.json
|
||||
|
||||
# Exceptions to above rules.
|
||||
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
|
||||
|
||||
android
|
||||
ios
|
||||
web
|
||||
macos
|
||||
10
packages/flame_rive/example/.metadata
Normal file
10
packages/flame_rive/example/.metadata
Normal file
@ -0,0 +1,10 @@
|
||||
# This file tracks properties of this Flutter project.
|
||||
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||
#
|
||||
# This file should be version controlled and should not be manually edited.
|
||||
|
||||
version:
|
||||
revision: 0272047e8727f6913804112c763ae1711d114afb
|
||||
channel: master
|
||||
|
||||
project_type: app
|
||||
3
packages/flame_rive/example/README.md
Normal file
3
packages/flame_rive/example/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# Flame Rive example
|
||||
|
||||
Project to showcase the usage of flame_rive
|
||||
1
packages/flame_rive/example/analysis_options.yaml
Normal file
1
packages/flame_rive/example/analysis_options.yaml
Normal file
@ -0,0 +1 @@
|
||||
include: package:flame_lint/analysis_options.yaml
|
||||
BIN
packages/flame_rive/example/assets/skills.riv
Normal file
BIN
packages/flame_rive/example/assets/skills.riv
Normal file
Binary file not shown.
107
packages/flame_rive/example/lib/main.dart
Normal file
107
packages/flame_rive/example/lib/main.dart
Normal file
@ -0,0 +1,107 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flame/components.dart';
|
||||
import 'package:flame/game.dart';
|
||||
import 'package:flame/input.dart';
|
||||
import 'package:flame/palette.dart';
|
||||
import 'package:flame_rive/flame_rive.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rive/rive.dart';
|
||||
|
||||
void main() {
|
||||
runApp(const MyApp());
|
||||
}
|
||||
|
||||
class MyApp extends StatefulWidget {
|
||||
const MyApp({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<MyApp> createState() => _MyAppState();
|
||||
}
|
||||
|
||||
class _MyAppState extends State<MyApp> {
|
||||
late final game = RiveExampleGame();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GameWidget(
|
||||
game: game,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class RiveExampleGame extends FlameGame with HasTappableComponents {
|
||||
@override
|
||||
Color backgroundColor() {
|
||||
return const Color(0xFFFFFFFF);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void>? onLoad() async {
|
||||
await super.onLoad();
|
||||
final skillsArtboard =
|
||||
await loadArtboard(RiveFile.asset('assets/skills.riv'));
|
||||
add(SkillsAnimationComponent(skillsArtboard));
|
||||
}
|
||||
}
|
||||
|
||||
class SkillsAnimationComponent extends RiveComponent with Tappable {
|
||||
SkillsAnimationComponent(Artboard artboard)
|
||||
: super(
|
||||
artboard: artboard,
|
||||
size: Vector2.all(550),
|
||||
);
|
||||
|
||||
SMIInput<double>? _levelInput;
|
||||
|
||||
@override
|
||||
Future<void>? onLoad() {
|
||||
final controller = StateMachineController.fromArtboard(
|
||||
artboard,
|
||||
"Designer's Test",
|
||||
);
|
||||
if (controller != null) {
|
||||
artboard.addController(controller);
|
||||
_levelInput = controller.findInput<double>('Level');
|
||||
_levelInput?.value = 0;
|
||||
}
|
||||
return super.onLoad();
|
||||
}
|
||||
|
||||
@override
|
||||
bool onTapDown(TapDownInfo info) {
|
||||
final levelInput = _levelInput;
|
||||
if (levelInput == null) {
|
||||
return false;
|
||||
}
|
||||
levelInput.value = (levelInput.value + 1) % 3;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class Square extends PositionComponent with HasGameRef<RiveExampleGame> {
|
||||
late final Paint paint;
|
||||
|
||||
Square(Vector2 position) {
|
||||
this.position.setFrom(position);
|
||||
size.setValues(100, 100);
|
||||
paint = _randomPaint();
|
||||
}
|
||||
|
||||
@override
|
||||
void render(Canvas canvas) {
|
||||
super.render(canvas);
|
||||
canvas.drawRect(size.toRect(), paint);
|
||||
}
|
||||
|
||||
static Paint _randomPaint() {
|
||||
final rng = Random();
|
||||
final color = Color.fromRGBO(
|
||||
rng.nextInt(256),
|
||||
rng.nextInt(256),
|
||||
rng.nextInt(256),
|
||||
0.9,
|
||||
);
|
||||
return PaletteEntry(color).paint();
|
||||
}
|
||||
}
|
||||
27
packages/flame_rive/example/pubspec.yaml
Normal file
27
packages/flame_rive/example/pubspec.yaml
Normal file
@ -0,0 +1,27 @@
|
||||
name: example
|
||||
description: A testbed for flame_rive
|
||||
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
version: 1.0.0+1
|
||||
|
||||
environment:
|
||||
sdk: ">=2.14.0 <3.0.0"
|
||||
|
||||
dependencies:
|
||||
rive: 0.7.30
|
||||
flame_rive:
|
||||
path: ../
|
||||
flame:
|
||||
path: ../../flame
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
flame_lint:
|
||||
path: ../../flame_lint
|
||||
|
||||
flutter:
|
||||
uses-material-design: true
|
||||
assets:
|
||||
- assets/
|
||||
1
packages/flame_rive/lib/flame_rive.dart
Normal file
1
packages/flame_rive/lib/flame_rive.dart
Normal file
@ -0,0 +1 @@
|
||||
export 'src/rive_component.dart';
|
||||
177
packages/flame_rive/lib/src/rive_component.dart
Normal file
177
packages/flame_rive/lib/src/rive_component.dart
Normal file
@ -0,0 +1,177 @@
|
||||
import 'dart:async';
|
||||
import 'dart:math';
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
import 'package:flame/components.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:rive/rive.dart';
|
||||
|
||||
// ignore_for_file: implementation_imports
|
||||
import 'package:rive/src/rive_core/math/aabb.dart';
|
||||
import 'package:rive/src/rive_core/math/mat2d.dart';
|
||||
import 'package:rive/src/rive_core/math/vec2d.dart';
|
||||
|
||||
class RiveComponent extends PositionComponent {
|
||||
final Artboard artboard;
|
||||
final RiveArtboardRenderer _renderer;
|
||||
|
||||
RiveComponent({
|
||||
required this.artboard,
|
||||
bool antialiasing = true,
|
||||
bool useArtboardSize = true,
|
||||
BoxFit fit = BoxFit.contain,
|
||||
Alignment alignment = Alignment.center,
|
||||
|
||||
// position component arguments
|
||||
Vector2? position,
|
||||
Vector2? size,
|
||||
Vector2? scale,
|
||||
double angle = 0.0,
|
||||
Anchor anchor = Anchor.topLeft,
|
||||
int? priority,
|
||||
}) : _renderer = RiveArtboardRenderer(
|
||||
antialiasing: antialiasing,
|
||||
useArtboardSize: useArtboardSize,
|
||||
fit: fit,
|
||||
alignment: alignment,
|
||||
artboard: artboard,
|
||||
),
|
||||
super(
|
||||
position: position,
|
||||
size: size,
|
||||
scale: scale,
|
||||
angle: angle,
|
||||
anchor: anchor,
|
||||
priority: priority,
|
||||
);
|
||||
|
||||
@override
|
||||
void render(ui.Canvas canvas) {
|
||||
super.render(canvas);
|
||||
_renderer.render(canvas, size.toSize());
|
||||
}
|
||||
|
||||
@override
|
||||
void update(double dt) {
|
||||
super.update(dt);
|
||||
_renderer.advance(dt);
|
||||
}
|
||||
}
|
||||
|
||||
class RiveArtboardRenderer {
|
||||
final Artboard artboard;
|
||||
final bool antialiasing;
|
||||
final bool useArtboardSize;
|
||||
final BoxFit fit;
|
||||
final Alignment alignment;
|
||||
|
||||
RiveArtboardRenderer({
|
||||
required this.antialiasing,
|
||||
required this.useArtboardSize,
|
||||
required this.fit,
|
||||
required this.alignment,
|
||||
required this.artboard,
|
||||
});
|
||||
|
||||
void advance(double dt) {
|
||||
artboard.advance(dt, nested: true);
|
||||
}
|
||||
|
||||
AABB get aabb {
|
||||
final width = artboard.width;
|
||||
final height = artboard.height;
|
||||
return AABB.fromValues(0, 0, width, height);
|
||||
}
|
||||
|
||||
void render(Canvas canvas, ui.Size size) {
|
||||
_paint(canvas, aabb, size);
|
||||
}
|
||||
|
||||
void _paint(Canvas canvas, AABB bounds, ui.Size size) {
|
||||
final position = Offset.zero;
|
||||
|
||||
final contentWidth = bounds[2] - bounds[0];
|
||||
final contentHeight = bounds[3] - bounds[1];
|
||||
|
||||
if (contentWidth == 0 || contentHeight == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
final x = -1 * bounds[0] -
|
||||
contentWidth / 2.0 -
|
||||
(alignment.x * contentWidth / 2.0);
|
||||
final y = -1 * bounds[1] -
|
||||
contentHeight / 2.0 -
|
||||
(alignment.y * contentHeight / 2.0);
|
||||
|
||||
var scaleX = 1.0, scaleY = 1.0;
|
||||
|
||||
canvas.save();
|
||||
canvas.clipRect(position & size);
|
||||
|
||||
// fit
|
||||
switch (fit) {
|
||||
case BoxFit.fill:
|
||||
scaleX = size.width / contentWidth;
|
||||
scaleY = size.height / contentHeight;
|
||||
break;
|
||||
case BoxFit.contain:
|
||||
final minScale =
|
||||
min(size.width / contentWidth, size.height / contentHeight);
|
||||
scaleX = scaleY = minScale;
|
||||
break;
|
||||
case BoxFit.cover:
|
||||
final maxScale =
|
||||
max(size.width / contentWidth, size.height / contentHeight);
|
||||
scaleX = scaleY = maxScale;
|
||||
break;
|
||||
case BoxFit.fitHeight:
|
||||
final minScale = size.height / contentHeight;
|
||||
scaleX = scaleY = minScale;
|
||||
break;
|
||||
case BoxFit.fitWidth:
|
||||
final minScale = size.width / contentWidth;
|
||||
scaleX = scaleY = minScale;
|
||||
break;
|
||||
case BoxFit.none:
|
||||
scaleX = scaleY = 1.0;
|
||||
break;
|
||||
case BoxFit.scaleDown:
|
||||
final minScale =
|
||||
min(size.width / contentWidth, size.height / contentHeight);
|
||||
scaleX = scaleY = minScale < 1.0 ? minScale : 1.0;
|
||||
break;
|
||||
}
|
||||
|
||||
final transform = Mat2D();
|
||||
transform[4] = size.width / 2.0 + (alignment.x * size.width / 2.0);
|
||||
transform[5] = size.height / 2.0 + (alignment.y * size.height / 2.0);
|
||||
Mat2D.scale(transform, transform, Vec2D.fromValues(scaleX, scaleY));
|
||||
final center = Mat2D();
|
||||
center[4] = x;
|
||||
center[5] = y;
|
||||
Mat2D.multiply(transform, transform, center);
|
||||
|
||||
// translation
|
||||
canvas.translate(
|
||||
size.width / 2.0 + (alignment.x * size.width / 2.0),
|
||||
size.height / 2.0 + (alignment.y * size.height / 2.0),
|
||||
);
|
||||
|
||||
canvas.scale(scaleX, scaleY);
|
||||
canvas.translate(x, y);
|
||||
|
||||
artboard.draw(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
|
||||
Future<Artboard> loadArtboard(
|
||||
FutureOr<RiveFile> file, {
|
||||
String? artboardName,
|
||||
}) async {
|
||||
final loaded = await file;
|
||||
return artboardName == null
|
||||
? loaded.mainArtboard
|
||||
: loaded.artboardByName(artboardName) ?? loaded.mainArtboard;
|
||||
}
|
||||
24
packages/flame_rive/pubspec.yaml
Normal file
24
packages/flame_rive/pubspec.yaml
Normal file
@ -0,0 +1,24 @@
|
||||
name: flame_rive
|
||||
description: Rive support for the Flame game engine. This uses the rive package and provides wrappers and components to be used inside Flame.
|
||||
homepage: https://github.com/flame-engine/flame
|
||||
version: 1.0.0-releasecandidate.1
|
||||
publish_to: 'none'
|
||||
|
||||
environment:
|
||||
sdk: ">=2.14.0 <3.0.0"
|
||||
flutter: ">=1.17.0"
|
||||
|
||||
dependencies:
|
||||
flame:
|
||||
path: ../flame
|
||||
rive: ^0.7.30
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
dev_dependencies:
|
||||
dartdoc: ^0.42.0
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
dart_code_metrics: ^3.2.2
|
||||
flame_lint:
|
||||
path: ../flame_lint
|
||||
Reference in New Issue
Block a user