twicpics_components 0.3.0 copy "twicpics_components: ^0.3.0" to clipboard
twicpics_components: ^0.3.0 copied to clipboard

A library that brings the power of TwicPics to your flutter applications.

example/example.md

TwicPics Flutter Widget Samples #

How to install #

Add the twicpics_components package to your Flutter project by running:

$ flutter pub add twicpics_components

How to setup #

// main.dart

import 'package:twicpics_components/twicpics_components.dart';

void main() {
  install(
    domain: "https://<your-domain>.twic.pics/",
  );
  runApp(...);
}

If you don't already have a TwicPics domain, you can easily create your own TwicPics account for free.

How to use #

TwicImg and TwicVideo come as Flutter Widgets and are used as such.

Basic usage #

Remember, the widgets do not expose height nor width properties.

The image or video occupies the whole width of its container.

Its height is determined according to the desired ratio.

The default ratio is 1 (which generates a square variant of your master asset).

This will display a smart cropped image with an aspect-ratio of 1:

// my_widget.dart

import 'package:twicpics_components/twicpics_components.dart';

class MyWidget extends StatelessWidget {
  const MyWidget({super.key});
  @override
  Widget build(BuildContext context) {
    return TwicImg(
      src: 'path/to/my/image',
    );
  }
}

This will display a smart cropped video with an aspect-ratio of 1:

// my_widget.dart

import 'package:twicpics_components/twicpics_components.dart';

class MyWidget extends StatelessWidget {
  const MyWidget({super.key});
  @override
  Widget build(BuildContext context) {
    return TwicVideo(
      src: 'path/to/my/video',
    );
  }
}

Bulk loading #

When embedding TwicImg or TwicVideo in a lazily loading-compatible tree, it is recommended to disable lazy-loading feature:

// my_widget.dart

class GridSample extends StatelessWidget {
  const GridSample({super.key});
  @override
  Widget build(BuildContext context) {
    return GridView.count(
      primary: false,
      crossAxisCount: 3,
      children: [
        TwicImg(
          src: 'path/to/my/image',
          eager: true,
        ),
        TwicVideo(
          src: 'path/to/my/video',
          eager: true,
        ),
        // ...
      ]
    );
  }
}

Choose your focus #

You can control the crop function by using the focus property.

Read more about focus.

Set the focus point to coordinates

// my_widget.dart

class MyWidget extends StatelessWidget {
  const MyWidget({super.key});
  @override
  Widget build(BuildContext context) {
    return TwicImg(
      src: 'path/to/my/image',
      focus: '30px40p', // this will set the focus point coordinates using relative lengths
    );
  }
}
// my_widget.dart

class MyWidget extends StatelessWidget {
  const MyWidget({super.key});
  @override
  Widget build(BuildContext context) {
    return TwicImg(
      src: 'path/to/my/image',
      focus: '345x678', // this will set the focus point coordinates using absolute lengths
    );
  }
}

Set the focus automagically

This is only available for TwicImg.

// my_widget.dart

class MyWidget extends StatelessWidget {
  const MyWidget({super.key});
  @override
  Widget build(BuildContext context) {
    return TwicImg(
      src: 'path/to/my/image',
      focus: 'auto', // the focus point will be chosen automagically for you
    );
  }
}

Display a landscape asset #

Setting a value to ratio property changes the aspect-ratio of the generated and displayed asset.

This will display a smart cropped variant of your master image with an aspect-ratio of 4/3.

// my_widget.dart

class MyWidget extends StatelessWidget {
  const MyWidget({super.key});
  @override
  Widget build(BuildContext context) {
    return TwicImg(
      src: 'path/to/my/image', // your master image file
      ratio: '4/3',
    );
  }
}

This will display a smart cropped variant of your master video with an aspect-ratio of 4/3.

// my_widget.dart

class MyWidget extends StatelessWidget {
  const MyWidget({super.key});
  @override
  Widget build(BuildContext context) {
    return TwicVideo(
      src: 'path/to/my/video', // your master video file
      ratio: '4/3',
    );
  }
}

Display a portrait asset #

This will display a smart cropped variant of your master image with an aspect-ratio of 3/4.

// my_widget.dart

class MyWidget extends StatelessWidget {
  const MyWidget({super.key});
  @override
  Widget build(BuildContext context) {
    return TwicImg(
      src: 'path/to/my/image', // your master image file
      ratio: '3/4',
    );
  }
}

This will display a smart cropped variant of your master video with an aspect-ratio of 3/4.

// my_widget.dart

class MyWidget extends StatelessWidget {
  const MyWidget({super.key});
  @override
  Widget build(BuildContext context) {
    return TwicVideo(
      src: 'path/to/my/video', // your master video file
      ratio: '3/4',
    );
  }
}

Working with ratio="none" #

Allows to display both image or video with a free height while respecting its natural aspect-ratio.

Hero image

An image that occupies all available space:

// my_widget.dart

import 'package:flutter/material.dart';
import 'package:twicpics_components/twicpics_components.dart';

class HeroSample extends StatelessWidget {
  const HeroSample({super.key});
  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: double.infinity,
      child: TwicImg(
        src: 'path/to/my/image.jpg',
          ratio: 'none',
        ),
    );
  }
}

Hero video

An video that occupies all available space:

// my_widget.dart

import 'package:flutter/material.dart';
import 'package:twicpics_components/twicpics_components.dart';

class HeroSample extends StatelessWidget {
  const HeroSample({super.key});
  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: double.infinity,
      child: TwicVideo(
        src: 'path/to/my/video.jpg',
          ratio: 'none',
        ),
    );
  }
}

Hero banner

You can specify the height of your image (or video) while respecting its natural aspect-ratio and optimizing your Cumulative Layout Shift (CLS) metric.

// my_widget.dart

import 'package:flutter/material.dart';
import 'package:twicpics_components/twicpics_components.dart';

class HeroBanner extends StatelessWidget {
  const HeroBanner({super.key});
  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: double.infinity,
      height: 200,
      child: TwicImg(
        src: 'path/to/my/image.jpg',
        ratio: 'none',
      ),
    );
  }
}

Reframe your image #

The TwicImg widget allows to reframe your image on the main subject(s) it contains.

In cover mode, the resulting image will respect ratio while maximizing the area occupied by the main subject(s).

In contain mode, the image will be cropped as close as possible to the main subject(s).

To activate automatic cropping, simply add the refit property to your widget call.

Read more about refit.

// my_widget.dart

class MyWidget extends StatelessWidget {
  const MyWidget({super.key});
  @override
  Widget build(BuildContext context) {
    return TwicImg(
      anchor: TwicPosition.right, // will align main subject(s) with the right border
      src: 'path/to/my/image',
      mode: TwicMode.cover, // will maximize the area occupied by the main subject(s) in a squared area
      refit: '10p', // will add a 10% padding around the main subject(s)
    );
  }
}
// my_widget.dart

class MyWidget extends StatelessWidget {
  const MyWidget({super.key});
  @override
  Widget build(BuildContext context) {
    return TwicImg(
      src: 'path/to/my/image',
      mode: TwicMode.contain, // will crop the image as close as possible to main subject(s)
      refit: true, // default refit without any padding
    );
  }
}

refit is available only for TwicImg widget.

Working with Row Widget #

When using Row Widget you have to constrain available width for TwicImg or TwicVideo as in:

import 'package:flutter/material.dart';
import 'package:twicpics_components/twicpics_components.dart';

class RowSample extends StatelessWidget {
  const RowSample({super.key});
  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        SizedBox(
          width: 100, //fixed width
          child: TwicImg(
            src:'path/to/my/image',
          ),
        ),
        Expanded( // makes child fills the available space
          child: TwicVideo(
            src:'path/to/my/video',
          ),
        ),
      ],
    );
  }
}

Using TwicPics transformations #

You can access TwicPics Transformation through preTransform property.

This will display a variant of your master image for which background has been removed using artificial intelligence:

// grid_sample.dart

class MyWidget extends StatelessWidget {
  const MyWidget({super.key});
  @override
  Widget build(BuildContext context) {
    return TwicImg(
      src: 'path/to/my/image',
      preTransform: 'background=remove',
    );
  }
}

Displaying Optimal Segment from your Videos #

The TwicVideo widget allows you to select the displayed part of your master video file.

The properties of the TwicVideo that allow such selection are :

  • from: moves the starting point of the video
  • to: moves the end point of the video
  • duration: limits the duration of the video

Expected values for these props are expressed in seconds and must be positive.

// grid_sample.dart

class MyWidget extends StatelessWidget {
  const MyWidget({super.key});
  @override
  Widget build(BuildContext context) {
    return TwicVideo(
      src: 'path/to/my/video',
      from: '3' /* start playing the video at the 3rd second */
      to:'10.5' /* end at 10.5 seconds */
    );
  }
}

Read more about video slicing.

Questions and feedback #

Fell free to submit an issue or to ask us anything by dropping an email at support@twic.pics.