Compare commits

..

No commits in common. "master" and "0.1.0" have entirely different histories.

24 changed files with 148 additions and 377 deletions

View file

@ -1,10 +0,0 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "pub"
directory: "/"
schedule:
interval: "daily"

View file

@ -1,14 +0,0 @@
name: Iconica Standard Component CI Workflow
# Workflow Caller version: 2.0.0
on:
pull_request:
workflow_dispatch:
jobs:
call-global-iconica-workflow:
uses: Iconica-Development/.github/.github/workflows/component-ci.yml@master
secrets: inherit
permissions: write-all
with:
subfolder: "." # add optional subfolder to run workflow in

View file

@ -1,14 +0,0 @@
name: Iconica Standard Component Documentation Workflow
# Workflow Caller version: 1.0.0
on:
release:
types: [published]
workflow_dispatch:
jobs:
call-iconica-component-documentation-workflow:
uses: Iconica-Development/.github/.github/workflows/component-documentation.yml@master
secrets: inherit
permissions: write-all

4
.gitignore vendored
View file

@ -21,7 +21,3 @@ doc/api/
*.js.map *.js.map
.idea .idea
# FVM Version Cache
.fvm/
.fvmrc

View file

@ -1,10 +1,3 @@
## 0.3.1
* Added Iconica CI and Iconica Linter
## 0.3.0
* Added option for backwards infinite scrolling and intial page
## 0.1.0 ## 0.1.0
* add opacity as an option to the card transform * add opacity as an option to the card transform

View file

@ -1,7 +0,0 @@
* Every sort of widget can be animated as a card.
* For the animation the following properties can be set between animation frames:
this.x = 0,
this.y = 0,
this.angle = 0,
this.scale = 1,
this.opacity = 1.0,

10
LICENSE
View file

@ -1,9 +1 @@
Copyright (c) 2022 Iconica, All rights reserved. TODO: Add your license here.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -1,21 +1,18 @@
[![pub package](https://img.shields.io/pub/v/flutter_carousel.svg)](https://github.com/Iconica-Development) [![Build status](https://img.shields.io/github/workflow/status/Iconica-Development/flutter_carousel/CI)](https://github.com/Iconica-Development/flutter_carousel/actions/new) [![style: effective dart](https://img.shields.io/badge/style-effective_dart-40c4ff.svg)](https://github.com/tenhobi/effective_dart)
# Carousel # Carousel
Carousel widget. Makes it easier to create card carousels using a list of transforms. Carousel widget. Makes it easier to create card carousels using a list of transforms.
Each card can change its rotation, position and scale when swiping the cards. Each card can change its rotation, position and scale when swiping the cards.
![Carousel GIF](carousel.gif) Supports all platforms.
Figma Design that defines this component (only accessible for Iconica developers): https://www.figma.com/file/4WkjwynOz5wFeFBRqTHPeP/Iconica-Design-System?type=design&node-id=357%3A3335&mode=design&t=XulkAJNPQ32ARxWh-1
![Demo video](demo.gif)
## Usage ## Usage
To use this package, add `carousel` as a dependency in your pubspec.yaml file. To use this package, add `carousel` as a [dependency in your pubspec.yaml file](https://flutter.dev/docs/development/platform-integration/platform-channels).
## How to use ### Example
See the [Example Code](example/lib/main.dart) for an example on how to use this package. See [Example Code](example/lib/main.dart) for more info.
## Issues ## Issues
@ -27,4 +24,4 @@ If you would like to contribute to the plugin (e.g. by improving the documentati
## Author ## Author
This `carousel` for Flutter is developed by [Iconica](https://iconica.nl). You can contact us at <support@iconica.nl> This carousel for Flutter is developed by [Iconica](https://iconica.nl). You can contact us at <support@iconica.nl>

View file

@ -1,9 +1 @@
include: package:flutter_iconica_analysis/analysis_options.yaml include: package:flutter_lints/flutter.yaml
# Possible to overwrite the rules from the package
analyzer:
exclude:
linter:
rules:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 MiB

BIN
demo.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 MiB

View file

@ -21,6 +21,6 @@
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.0</string> <string>1.0</string>
<key>MinimumOSVersion</key> <key>MinimumOSVersion</key>
<string>11.0</string> <string>9.0</string>
</dict> </dict>
</plist> </plist>

View file

@ -272,7 +272,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;
@ -350,7 +350,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos; SDKROOT = iphoneos;
@ -399,7 +399,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;

View file

@ -1,4 +0,0 @@
extension CapitalizeExtension on String {
String capitalize() =>
isNotEmpty ? "${this[0].toUpperCase()}${substring(1)}" : this;
}

View file

@ -1,12 +1,7 @@
// SPDX-FileCopyrightText: 2022 Iconica
//
// SPDX-License-Identifier: BSD-3-Clause
import 'package:carousel/carousel.dart'; import 'package:carousel/carousel.dart';
import 'package:carousel_example/pokemon.dart'; import 'package:carousel_example/pokemon.dart';
import 'package:carousel_example/pokemon_card.dart'; import 'package:carousel_example/pokemon_card.dart';
import 'package:carousel_example/pokemon_types.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'dart:math' as math; import 'dart:math' as math;
@ -26,65 +21,14 @@ class _CarouselExampleAppState extends State<CarouselExampleApp> {
Pokemon? selected; Pokemon? selected;
final List<Pokemon> pokemons = [ final List<Pokemon> pokemons = [
Pokemon( Pokemon(name: 'Bulbasaur', nr: 1, types: ['grass', 'poison']),
name: 'Bulbasaur', Pokemon(name: 'Charmander', nr: 4, types: ['fire']),
nr: 1, Pokemon(name: 'Squirtle', nr: 7, types: ['water']),
types: [ Pokemon(name: 'Caterpie', nr: 10, types: ['bug']),
PokemonType.grass, Pokemon(name: 'Pidgey', nr: 16, types: ['normal', 'flying']),
PokemonType.poison, Pokemon(name: 'Pikachu', nr: 25, types: ['electric']),
], Pokemon(name: 'Machop', nr: 66, types: ['fighting']),
), Pokemon(name: 'Geodude', nr: 74, types: ['rock', 'ground']),
Pokemon(
name: 'Charmander',
nr: 4,
types: [
PokemonType.fire,
],
),
Pokemon(
name: 'Squirtle',
nr: 7,
types: [
PokemonType.water,
],
),
Pokemon(
name: 'Caterpie',
nr: 10,
types: [
PokemonType.bug,
],
),
Pokemon(
name: 'Pidgey',
nr: 16,
types: [
PokemonType.normal,
PokemonType.flying,
],
),
Pokemon(
name: 'Pikachu',
nr: 25,
types: [
PokemonType.electric,
],
),
Pokemon(
name: 'Machop',
nr: 66,
types: [
PokemonType.fighting,
],
),
Pokemon(
name: 'Geodude',
nr: 74,
types: [
PokemonType.rock,
PokemonType.ground,
],
),
]; ];
Widget _buildCard(BuildContext context, int index) { Widget _buildCard(BuildContext context, int index) {
@ -106,8 +50,7 @@ class _CarouselExampleAppState extends State<CarouselExampleApp> {
body: Stack( body: Stack(
alignment: Alignment.bottomCenter, alignment: Alignment.bottomCenter,
children: [ children: [
Padding( SafeArea(
padding: const EdgeInsets.all(16.0),
child: ListView( child: ListView(
children: [ children: [
const SizedBox(height: 50), const SizedBox(height: 50),
@ -178,7 +121,7 @@ class _CarouselExampleAppState extends State<CarouselExampleApp> {
), ),
if (selected != null) if (selected != null)
Padding( Padding(
padding: const EdgeInsets.only(bottom: 20), padding: const EdgeInsets.only(bottom: 10),
child: Text('Clicked: ${selected!.name}'), child: Text('Clicked: ${selected!.name}'),
), ),
], ],

View file

@ -1,9 +1,3 @@
// SPDX-FileCopyrightText: 2022 Iconica
//
// SPDX-License-Identifier: BSD-3-Clause
import 'package:carousel_example/pokemon_types.dart';
class Pokemon { class Pokemon {
Pokemon({ Pokemon({
required this.name, required this.name,
@ -12,5 +6,5 @@ class Pokemon {
}); });
String name; String name;
int nr; int nr;
List<PokemonType> types = const []; List<String> types = const [];
} }

View file

@ -1,10 +1,4 @@
// SPDX-FileCopyrightText: 2022 Iconica
//
// SPDX-License-Identifier: BSD-3-Clause
import 'package:carousel_example/extensions/string.dart';
import 'package:carousel_example/pokemon.dart'; import 'package:carousel_example/pokemon.dart';
import 'package:carousel_example/pokemon_types.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class PokemonCard extends StatelessWidget { class PokemonCard extends StatelessWidget {
@ -22,11 +16,9 @@ class PokemonCard extends StatelessWidget {
width: MediaQuery.of(context).size.width / 2.2, width: MediaQuery.of(context).size.width / 2.2,
height: 220, height: 220,
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: Colors.blue.shade700,
boxShadow: const [ boxShadow: const [
BoxShadow( BoxShadow(blurRadius: 4),
blurRadius: 8,
),
], ],
borderRadius: BorderRadius.circular(15), borderRadius: BorderRadius.circular(15),
), ),
@ -44,92 +36,35 @@ class PokemonCard extends StatelessWidget {
), ),
Padding( Padding(
padding: const EdgeInsets.only(top: 20, bottom: 8), padding: const EdgeInsets.only(top: 20, bottom: 8),
child: Text('Type', style: textStyle), child: Text('Types', style: textStyle),
), ),
Row( Row(
children: [ children: [
for (var type in pokemon.types) ...[ for (var type in pokemon.types) ...[
TypeBadge(type: type), Container(
],
],
),
],
),
),
);
}
}
class TypeBadge extends StatelessWidget {
const TypeBadge({
super.key,
required this.type,
});
final PokemonType type;
@override
Widget build(BuildContext context) {
return Container(
height: 25, height: 25,
width: 60, width: 60,
margin: const EdgeInsets.only(right: 10), margin: const EdgeInsets.only(right: 10),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5), borderRadius: BorderRadius.circular(5),
color: getTypeColor(type), color: Color(type.hashCode).withAlpha(255),
), ),
child: Center( child: Center(
child: Text( child: Text(
type.name.capitalize(), type,
style: const TextStyle( style: const TextStyle(
color: Colors.white, color: Colors.white,
), ),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
), ),
)
],
],
),
],
),
),
); );
} }
Color getTypeColor(PokemonType type) {
switch (type) {
case PokemonType.fire:
return const Color(0xFFF08030);
case PokemonType.water:
return const Color(0xFF6890F0);
case PokemonType.grass:
return const Color(0xFF78C850);
case PokemonType.normal:
return const Color(0xFFA8A878);
case PokemonType.electric:
return const Color(0xFFF8D030);
case PokemonType.ice:
return const Color(0xFF98D8D8);
case PokemonType.fighting:
return const Color(0xFFC03028);
case PokemonType.poison:
return const Color(0xFFA040A0);
case PokemonType.ground:
return const Color(0xFFE0C068);
case PokemonType.flying:
return const Color(0xFFA890F0);
case PokemonType.psychic:
return const Color(0xFFF85888);
case PokemonType.bug:
return const Color(0xFFA8B820);
case PokemonType.rock:
return const Color(0xFFB8A038);
case PokemonType.ghost:
return const Color(0xFF705898);
case PokemonType.dark:
return const Color(0xFF705848);
case PokemonType.dragon:
return const Color(0xFF7038F8);
case PokemonType.steel:
return const Color(0xFFB8B8D0);
case PokemonType.fairy:
return const Color(0xFFEE99AC);
default:
return const Color(0xFF68A090);
}
}
} }

View file

@ -1,20 +0,0 @@
enum PokemonType {
fire,
water,
grass,
normal,
electric,
ice,
fighting,
poison,
ground,
flying,
psychic,
bug,
rock,
ghost,
dark,
dragon,
steel,
fairy,
}

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: 2022 Iconica
//
// SPDX-License-Identifier: BSD-3-Clause
/// A Flutter package for creating a carousel widget.
library carousel; library carousel;
export 'package:carousel/src/carousel.dart'; export 'package:carousel/src/carousel.dart';

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: 2022 Iconica
//
// SPDX-License-Identifier: BSD-3-Clause
import 'package:carousel/src/models/card_transform.dart'; import 'package:carousel/src/models/card_transform.dart';
import 'package:carousel/src/widgets/carousel_card.dart'; import 'package:carousel/src/widgets/carousel_card.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
@ -11,8 +7,7 @@ typedef CarouselCardBuilder = Widget Function(BuildContext context, int index);
class Carousel extends StatefulWidget { class Carousel extends StatefulWidget {
/// Animated cards by swiping. /// Animated cards by swiping.
/// Each card can change its rotation, position /// Each card can change its rotation, position and scale when swiping the cards.
/// and scale when swiping the cards.
/// Transform path can be privided using [transforms] /// Transform path can be privided using [transforms]
const Carousel({ const Carousel({
required this.transforms, required this.transforms,
@ -22,10 +17,8 @@ class Carousel extends StatefulWidget {
this.onPageChanged, this.onPageChanged,
this.alignment = AlignmentDirectional.topStart, this.alignment = AlignmentDirectional.topStart,
this.onCardClick, this.onCardClick,
this.initialPage = 0, Key? key,
this.allowInfiniteScrollingBackwards = false, }) : super(key: key);
super.key,
});
/// A list of transforms to calculate the position of the card when swiping. /// A list of transforms to calculate the position of the card when swiping.
/// Every item in the list is one of the possible card positions. /// Every item in the list is one of the possible card positions.
@ -34,8 +27,7 @@ class Carousel extends StatefulWidget {
/// The index of the transform card which acts as the selected card. /// The index of the transform card which acts as the selected card.
final int selectableCardId; final int selectableCardId;
/// Builder for the card given a [context] and a [index] to /// Builder for the card given a [context] and a [index] to identify the right card.
/// identify the right card.
final CarouselCardBuilder builder; final CarouselCardBuilder builder;
/// Called when selected card is changed to the next one. /// Called when selected card is changed to the next one.
@ -50,31 +42,16 @@ class Carousel extends StatefulWidget {
/// Size of the pageview used to capture swipe gestures. /// Size of the pageview used to capture swipe gestures.
final double pageViewHeight; final double pageViewHeight;
/// The page to show when first creating the [Carousel].
final int initialPage;
/// Whether to allow infinite scrolling backwards. Defaults to false. If true,
/// this works by using a very large number of pages (10000).
/// Works in conjunction with [initialPage].
final bool allowInfiniteScrollingBackwards;
@override @override
State<Carousel> createState() => _CarouselState(); State<Carousel> createState() => _CarouselState();
} }
class _CarouselState extends State<Carousel> { class _CarouselState extends State<Carousel> {
late PageController _pageController; final PageController _pageController = PageController(initialPage: 0);
double _currentPage = 0; double _currentPage = 0;
@override @override
void initState() { void initState() {
_pageController = PageController(
initialPage: widget.allowInfiniteScrollingBackwards
? 10000 + widget.initialPage
: widget.initialPage,
);
_currentPage = _pageController.initialPage.toDouble();
_pageController.addListener(() { _pageController.addListener(() {
_currentPage = _pageController.page!; _currentPage = _pageController.page!;
}); });
@ -88,15 +65,16 @@ class _CarouselState extends State<Carousel> {
} }
@override @override
Widget build(BuildContext context) => Stack( Widget build(BuildContext context) {
return Stack(
alignment: widget.alignment, alignment: widget.alignment,
children: [ children: [
AnimatedBuilder( AnimatedBuilder(
animation: _pageController, animation: _pageController,
builder: (context, _) { builder: (context, _) {
var transitionPos = _currentPage % 1; final transitionPos = _currentPage % 1;
var index = _currentPage.floor(); final index = _currentPage.floor();
var length = widget.transforms.length - 1; final length = widget.transforms.length - 1;
return Stack( return Stack(
children: [ children: [
@ -117,7 +95,8 @@ class _CarouselState extends State<Carousel> {
scrollBehavior: _MouseSwipeOnWeb(), scrollBehavior: _MouseSwipeOnWeb(),
onPageChanged: widget.onPageChanged, onPageChanged: widget.onPageChanged,
controller: _pageController, controller: _pageController,
itemBuilder: (context, index) => Visibility( itemBuilder: (context, index) {
return Visibility(
visible: false, visible: false,
maintainState: true, maintainState: true,
maintainAnimation: true, maintainAnimation: true,
@ -137,12 +116,14 @@ class _CarouselState extends State<Carousel> {
), ),
], ],
), ),
), );
},
), ),
), ),
], ],
); );
} }
}
class _MouseSwipeOnWeb extends MaterialScrollBehavior { class _MouseSwipeOnWeb extends MaterialScrollBehavior {
@override @override

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: 2022 Iconica
//
// SPDX-License-Identifier: BSD-3-Clause
class CardTransform { class CardTransform {
/// Used by [Carousel] to build cards on the correct position. /// Used by [Carousel] to build cards on the correct position.
CardTransform({ CardTransform({
@ -28,14 +24,15 @@ class CardTransform {
/// [transitionPos] is a position value of a swipe for example. /// [transitionPos] is a position value of a swipe for example.
/// [other] is the position, scale, rotation /// [other] is the position, scale, rotation
/// which the current [CardTransform] need to be transformed to. /// which the current [CardTransform] need to be transformed to.
CardTransform transform(CardTransform other, double transitionPos) => CardTransform transform(CardTransform other, double transitionPos) {
CardTransform( return CardTransform(
x: _transformValue(x, other.x, transitionPos), x: _transformValue(x, other.x, transitionPos),
y: _transformValue(y, other.y, transitionPos), y: _transformValue(y, other.y, transitionPos),
angle: _transformValue(angle, other.angle, transitionPos), angle: _transformValue(angle, other.angle, transitionPos),
scale: _transformValue(scale, other.scale, transitionPos), scale: _transformValue(scale, other.scale, transitionPos),
opacity: _transformValue(opacity, other.opacity, transitionPos), opacity: _transformValue(opacity, other.opacity, transitionPos),
); );
}
double _transformValue(double valueA, double valueB, double transformPos) => double _transformValue(double valueA, double valueB, double transformPos) =>
valueA - ((valueA - valueB) * transformPos); valueA - ((valueA - valueB) * transformPos);

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: 2022 Iconica
//
// SPDX-License-Identifier: BSD-3-Clause
import 'package:carousel/src/models/card_transform.dart'; import 'package:carousel/src/models/card_transform.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -10,14 +6,15 @@ class CarouselCard extends StatelessWidget {
const CarouselCard({ const CarouselCard({
required this.cardTransform, required this.cardTransform,
required this.child, required this.child,
super.key, Key? key,
}); }) : super(key: key);
final CardTransform cardTransform; final CardTransform cardTransform;
final Widget child; final Widget child;
@override @override
Widget build(BuildContext context) => Transform.translate( Widget build(BuildContext context) {
return Transform.translate(
offset: Offset(cardTransform.x, cardTransform.y), offset: Offset(cardTransform.x, cardTransform.y),
child: Transform.rotate( child: Transform.rotate(
angle: cardTransform.angle, angle: cardTransform.angle,
@ -31,3 +28,4 @@ class CarouselCard extends StatelessWidget {
), ),
); );
} }
}

View file

@ -1,11 +1,9 @@
name: carousel name: carousel
description: card carousel description: card carousel
version: 0.3.1 version: 0.1.0
publish_to: https://forgejo.internal.iconica.nl/api/packages/internal/pub
environment: environment:
sdk: ">=3.0.0 <4.0.0" sdk: ">=2.17.6 <3.0.0"
flutter: ">=1.17.0" flutter: ">=1.17.0"
dependencies: dependencies:
@ -15,9 +13,41 @@ dependencies:
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
flutter_iconica_analysis: flutter_lints: ^2.0.0
git:
url: https://github.com/Iconica-Development/flutter_iconica_analysis
ref: 6.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter: flutter:
# To add assets to your package, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
#
# For details regarding assets in packages, see
# https://flutter.dev/assets-and-images/#from-packages
#
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
# To add custom fonts to your package, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts in packages, see
# https://flutter.dev/custom-fonts/#from-packages

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: 2022 Iconica
//
// SPDX-License-Identifier: BSD-3-Clause
import 'dart:math'; import 'dart:math';
import 'package:carousel/src/models/card_transform.dart'; import 'package:carousel/src/models/card_transform.dart';