パッケージ、リポジトリ、アプリカテゴリを検索

image_compare_slider のカバー
パッケージ詳細v3.2.0

image_compare_slider

スライダーとドラッグ可能なライン/ハンドルを使用して、2つの画像を簡単に比較できます。完全にカスタマイズ可能です。

AndroidiOSWebmacOSWindowsLinux
30日間ダウンロード
1780
いいね数
116
Pub ポイント
160

パッケージをインストール

flutter pub add image_compare_slider

パッケージ概要

公開情報に基づく選定ガイドです。参考としてご利用ください。

image_compare_slider パッケージは、ドラッグ可能なスライダーハンドルを使用して、画像をシームレスに横並びで比較できるようにします。ユーザーがハンドルをスライドすると、1枚の画像が徐々に表示されるため、前後比較のビジュアライゼーションに最適です。ハンドルの外観、スライダーの位置、アニメーション速度など、カスタマイズ可能なオプションが豊富で、Android、iOS、Web、macOS、Windows、Linux などの主要プラットフォームをすべてサポートしています。軽量で、最小限のセットアップで Flutter アプリに簡単に統合できます。

用途

  • 前後比較写真
  • 製品機能のデモ
  • ビジュアルデザインレビュー
  • 教育画像分析
  • ユーザーインターフェーステスト

主な機能

  • ドラッグ可能なスライダーハンドル
  • カスタマイズ可能なハンドルとトラック
  • スムーズなトランジションアニメーション
  • クロスプラットフォーム対応
  • Flutterとの簡単な統合
  • 設定可能な初期位置

適している対象

  • 視覚的比較ツールを必要とするアプリ開発者
  • デザイナーが画像の変更を紹介しています
  • 教育アプリの作成者
  • eコマース製品プレビュー
  • インタラクティブUIコンポーネント

注意事項

  • 最高の結果を得るには、同じサイズの2枚の画像が必要です
  • 大きな画像ではパフォーマンスが異なる場合があります
  • 水平スライドレイアウトに制限
  • カスタムスタイルにはFlutterウィジェットの理解が必要です
  • 複雑なレイアウトでは、追加のパディングまたは制約が必要になる場合があります

元の README

関連するソースリポジトリの README 原文のスナップショットです。最新の内容はリポジトリをご覧ください。

Image Compare Slider

ci pub package Coverage badge style: very good analysis Powered by Mason License: MIT

Inspired by react-compare-slider, this package allows you to easily compare two images with a slider — with zoom & pan, rotation (with lock), custom handles and size matching.

PR's are welcome!

Installation 💻

❗ In order to start using Image Compare you must have the Dart SDK installed on your machine.

Add image_compare_slider to your pubspec.yaml:

dependencies:
  image_compare_slider:

Install it:

dart pub get

Import it:

import 'package:image_compare_slider/image_compare_slider.dart';

Use it:

//...
ImageCompareSlider(
  itemOne: const Image.asset('...'),
  itemTwo: const Image.network('...'),
)
//...

The widget its pretty simple and customizable, see:

Example

Customization 🎨

You can customize the widget with the following parameters:

Parameter Type Description
itemOne Image The first image to compare
itemTwo Image The second image to compare
changePositionOnHover bool If the slider should change position when the mouse is over it
handleSize Size The size of the handle
handleRadius BorderRadius The radius of the handle
fillHandle bool If the handle should be filled
hideHandle bool If the handle should be hidden
handlePosition double The position of the handle relative to the slider
handleFollowsPosition bool If the handle should follow the position of the slider
onPositionChange void Function(double position)? The callback to be called when the position changes
direction SliderDirection The direction of the slider will clip the image
dividerColor Color The color of the divider
handleColor Color The color of the handle
handleOutlineColor Color The color of the handle outline
dividerWidth double The width of the divider
dividerLineStyle DividerLineStyle The line style of the divider: solid, dashed, dotted or a custom dash pattern (default DividerLineStyle.solid())
itemOneBuilder Widget Function(Widget child, BuildContext context)? The wrapper for the first image
itemTwoBuilder Widget Function(Widget child, BuildContext context)? The wrapper for the second image
photoRadius BorderRadiusGeometry Radius of the photo
controller ImageCompareSliderController? Drives position, zoom, pan and rotation programmatically
handleBuilder HandleBuilder? Builds a fully custom, draggable handle widget
onlyHandleDraggable bool Restrict slider movement to dragging the handle
fit BoxFit How both images are inscribed into their box (default BoxFit.contain)
aspectRatio double? Force both images into the same box to match different sizes
zoomable bool Enable pinch / double-tap zoom on both images
pannable bool Enable drag-to-pan on both images
enableGestureRotation bool Enable two-finger rotation gestures
doubleTapToZoom bool Toggle zoom on double-tap (default true)
minScale / maxScale double Zoom bounds (default 1.0 / 5.0)
doubleTapScale double Zoom factor applied on double-tap (default 2.5)

If you want to add some effects you can use the itemOneBuilder and itemTwoBuilder parameters to wrap the images with a ColorFilter or ImageFilter, or any other widget you want.

For example, to add a ImageFilter with a blur effect:

// ...
ImageCompareSlider(
  itemOne: const Image.asset('...'),
  itemTwo: const Image.asset('...'),
  itemOneBuilder: (child, context) => ImageFiltered(
  imageFilter: ImageFilter.blur(sigmaX: 2, sigmaY: 5),
    child: child,
  ),
)
// ...

Will result in:

You can also pass any custom properties to the Image for itemOne and itemTwo, and most of the Image properties will be applied to the ImageCompareSlider widget.

For example, adding a colorBlendMode with a color to itemOne:

// ...
ImageCompareSlider(
  itemOne: const Image.asset('...', color: Colors.red, colorBlendMode: BlendMode.overlay),
  itemTwo: const Image.asset('...'),
)
// ...

Will result in:

Customizing the handle and divider is also possible:

// ...
ImageCompareSlider(
  itemOne: const Image.asset('...'),
  itemTwo: const Image.asset('...'),
  handleSize: Size(0.05, 0.05),
  handleRadius: const BorderRadius.all(Radius.circular(50)),
  fillHandle: true,
  dividerColor: Colors.black,
  dividerWidth: 10,
  handlePosition: 0.8,
  // ...
)
// ...

Will result in:

Line style 〰️

Control how the divider line is stroked with dividerLineStyle. Pick a preset or build a fully custom dash pattern. This only affects the painted line, not the handle.

// Solid (the default).
ImageCompareSlider(
  itemOne: const Image.asset('...'),
  itemTwo: const Image.asset('...'),
  dividerLineStyle: const DividerLineStyle.solid(),
);

// Dashed — dashes of `dashLength` separated by `gapLength` (logical pixels).
ImageCompareSlider(
  itemOne: const Image.asset('...'),
  itemTwo: const Image.asset('...'),
  dividerLineStyle: DividerLineStyle.dashed(dashLength: 10, gapLength: 6),
);

// Dotted — round dots whose diameter equals `dividerWidth`.
ImageCompareSlider(
  itemOne: const Image.asset('...'),
  itemTwo: const Image.asset('...'),
  dividerWidth: 4,
  dividerLineStyle: DividerLineStyle.dotted(gapLength: 8),
);

// Fully custom — a repeating list of alternating on/off lengths, starting
// with an "on" (drawn) segment. Here: long dash, gap, short dash, gap.
ImageCompareSlider(
  itemOne: const Image.asset('...'),
  itemTwo: const Image.asset('...'),
  dividerLineStyle: const DividerLineStyle(
    pattern: <double>[12, 4, 4, 4],
    strokeCap: StrokeCap.round,
  ),
);
Preset Description
DividerLineStyle.solid() An unbroken line (default).
DividerLineStyle.dashed({dashLength, gapLength, strokeCap}) Evenly spaced dashes separated by gaps.
DividerLineStyle.dotted({gapLength}) Round dots sized to dividerWidth.
DividerLineStyle({pattern, strokeCap}) Any custom repeating dash pattern.

Zoom & pan 🔍

Enable zoomable and/or pannable to pinch-zoom and drag both images at once while keeping them perfectly aligned. Double-tap toggles zoom. Dragging the handle still moves the slider, even while zoomed in.

ImageCompareSlider(
  itemOne: const Image.asset('...'),
  itemTwo: const Image.asset('...'),
  zoomable: true,
  pannable: true,
  maxScale: 6, // optional zoom bounds
)

Rotation with lock 🔄

Pass an ImageCompareSliderController to rotate either image in either direction. Turn on lockRotation to rotate both images together in the same cycle. The controller also exposes zoom, pan, position and a reset().

final controller = ImageCompareSliderController();

ImageCompareSlider(
  controller: controller,
  itemOne: const Image.asset('...'),
  itemTwo: const Image.asset('...'),
);

// Rotate the left image a quarter turn clockwise.
controller.rotateOne(ImageCompareSliderController.quarterTurn);
// Rotate the right image counter-clockwise.
controller.rotateTwo(-ImageCompareSliderController.quarterTurn);
// Lock so both rotate together.
controller.lockRotation = true;
// Snap the second image to the first's angle.
controller.matchRotation();
// Reset zoom/pan/rotation.
controller.reset();

Remember to dispose() controllers you create yourself.

Custom handle ✋

Replace the painted handle with any widget via handleBuilder. It is centered on the handle anchor and stays draggable. The divider line is still drawn.

ImageCompareSlider(
  itemOne: const Image.asset('...'),
  itemTwo: const Image.asset('...'),
  handleBuilder: (context, position, portrait) => Container(
    padding: const EdgeInsets.all(6),
    decoration: const BoxDecoration(
      color: Colors.white,
      shape: BoxShape.circle,
    ),
    child: const Icon(Icons.unfold_more, size: 18),
  ),
)

Matching image sizes 📐

If your images have different sizes or aspect ratios, set an aspectRatio and a fit (e.g. BoxFit.cover) so both are forced into the same box and line up.

ImageCompareSlider(
  itemOne: const Image.asset('...'), // 4000x3000
  itemTwo: const Image.asset('...'), // 1920x1080
  fit: BoxFit.cover,
  aspectRatio: 16 / 9,
)

Releasing 🚀

Releases are driven by the changelog using cider. During development, record changes under the ## Unreleased section of CHANGELOG.md (manually, or with dart run cider log added "...").

When ready, run the helper script. It bumps the version, promotes the Unreleased section to the new version, commits and creates the v<version> tag:

dart run tool/release.dart            # patch release (default)
dart run tool/release.dart minor      # or: major | patch | build | breaking | none
dart run tool/release.dart minor --push   # cut and push in one step

By default it does not push. Push the tag to publish:

git push --follow-tags

You can also run the Release: … entries in the VS Code Run & Debug panel. Pushing a version tag triggers .github/workflows/publish.yaml, which publishes to pub.dev (via GitHub OIDC, no secrets) and creates a GitHub release with notes from the matching CHANGELOG.md section.

One-time setup: on pub.dev go to the package admin page → Automated publishing → enable GitHub Actions publishing for cgutierr-zgz/image_compare_slider with the tag pattern v{{version}}.

カテゴリー

ソースリポジトリ

このパッケージを使用しているプロジェクト

データはまだありません。