Legge til SVG-ikonet i den tilpassede glidebryteren ved å bruke den egendefinerte maleren

stemmer
3

Jeg implementerer den tilpassede glidebryteren, der jeg har fullført bevegelsesdeteksjonen på glidebryteren, nå vil jeg legge til SVG-ikonet på knotten for å dra, kan ikke finne noen ressurs. Jeg vil bare legge SVG til en ide om hvordan jeg implementerer den. Jeg har satt koden min og fortalt meg om ethvert forslag hvis dere har det.

Hoved ui-fil

import 'package:animations_sample/custom_slider.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  MyApp({Key key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Container(
            width: 200,
            height: 200,
            child: LeftSlider(),
          ),
        ),
      ),
    );
  }
}

Tilpasset skyvefil

import 'dart:io';

import 'package:animations_sample/base_painter.dart';
import 'package:animations_sample/customleftPainter.dart';
import 'package:animations_sample/utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'dart:async';
import 'dart:typed_data';
import 'dart:ui' as UI;

import 'package:flutter/services.dart' show rootBundle;
import 'package:path_provider/path_provider.dart';

import 'package:flutter/services.dart';

class LeftSlider extends StatefulWidget {
  LeftSlider({Key key}) : super(key: key);

  @override
  _LeftSliderState createState() => _LeftSliderState();
}

class _LeftSliderState extends State<LeftSlider> {
  //intial Values coming
  int leftEnd = 12;
  String rawLeftSvg =
      '''<svg xmlns=http://www.w3.org/2000/svg height=512px viewBox=0 0 32 32 width=512px><g><path d=m8 0c-4.41113 0-8 3.58887-8 8s3.58887 8 8 8 8-3.58887 8-8-3.58887-8-8-8zm0 15c-3.85986 0-7-3.14014-7-7s3.14014-7 7-7 7 3.14014 7 7-3.14014 7-7 7z data-original=#000000 class=active-path data-old_color=#000000 fill=#2184C4/><path d=m9 3c-1.04364 0-1.9624.536926-2.5 1.34772v-3.84772c0-.276367-.223633-.5-.5-.5-1.6543 0-3 1.3457-3 3 0 1.04364.536926 1.9624 1.34772 2.5h-3.84772c-.276367 0-.5.223633-.5.5 0 1.6543 1.3457 3 3 3 1.04364 0 1.9624-.536926 2.5-1.34772v3.84772c0 .276367.223633.5.5.5 1.6543 0 3-1.3457 3-3 0-1.04364-.536926-1.9624-1.34772-2.5h3.84772c.276367 0 .5-.223633.5-.5 0-1.6543-1.3457-3-3-3zm-6 5c-.930176 0-1.71436-.638184-1.93652-1.5h3.87305c-.222168.861816-1.00635 1.5-1.93652 1.5zm1-5c0-.930176.638184-1.71436 1.5-1.93652v3.87305c-.861816-.222168-1.5-1.00635-1.5-1.93652zm2 3.5c-.276123 0-.5-.223877-.5-.5 0-.276184.223877-.5.5-.5s.5.223816.5.5c0 .276123-.223877.5-.5.5zm2 2.5c0 .930176-.638184 1.71436-1.5 1.93652v-3.87305c.861816.222168 1.5 1.00635 1.5 1.93652zm-.936523-3.5c.222168-.861816 1.00635-1.5 1.93652-1.5.930176 0 1.71436.638184 1.93652 1.5h-3.87305z transform=translate(2 2) data-original=#000000 class=active-path data-old_color=#000000 fill=#2184C4/></g> </svg>''';
  DrawableRoot svgRoot;
  UI.Image image;
  @override
  void initState() {
    super.initState();
    getLeftIcon();
  }
    // this is for the Ui.Image
  Future<UI.Image> loadUiImage(String imageAssetPath) async {
    final ByteData data = await rootBundle.load(imageAssetPath);

    final Completer<UI.Image> completer = Completer();
    UI.decodeImageFromList(Uint8List.view(data.buffer), (UI.Image img) {
      return completer.complete(img);
    });
    return completer.future;
  }
   //Please Ignore
  /* Future<File> getImageFileFromAssets(String path) async {
    final byteData = await rootBundle.load('assets/$path');

    final file = File('${(await getTemporaryDirectory()).path}/$path');
    await file.writeAsBytes(byteData.buffer
        .asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));

    return file;
  } */

  getLeftIcon() async {
    /*  svgRoot= await svg.fromSvgString(rawLeftSvg, rawLeftSvg); */
    //File file = await getImageFileFromAssets('icon.png');

    image = await loadUiImage('assets/snowflake.png');
    svgRoot = await svg.fromSvgString(rawLeftSvg, rawLeftSvg);
    print('sucess');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.transparent,
      body: SliderLeftPaint(
        leftsvgIcon: svgRoot,
        leftIcon: image,
        leftInitial: 0,
        leftEnd: leftEnd,
        onSelectionChange: (int left) {
          setState(() {
            leftEnd = left;
          });
        },
        child: Center(
            child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.only(right: 10),
              child: Text(
                '$leftEnd\u00B0',
              ),
            ),
          ],
        )),
      ),
    );
  }
}

class SliderLeftPaint extends StatefulWidget {
  final DrawableRoot leftsvgIcon;
  final UI.Image leftIcon;
  final int leftInitial;
  final int leftEnd;

  final Function onSelectionChange;
  final Widget child;

  const SliderLeftPaint(
      {Key key,
      this.leftsvgIcon,
      @required this.leftIcon,
      @required this.leftInitial,
      @required this.leftEnd,
      @required this.onSelectionChange,
      this.child})
      : super(key: key);

  @override
  _SliderLeftPaintState createState() => _SliderLeftPaintState();
}

class _SliderLeftPaintState extends State<SliderLeftPaint> {
  bool _isInitLeftHandlerSelected = false;

  CustomLeftPainter customLeftPainter;

  /// start angle in radians where we need to locate the initial left handler
  double _leftStartAngle;

  /// end angle in radians where we need to locate the end left  handler
  double _leftEndAngle;

  /// the absolute angle in radians representing the selection
  double _leftSweepAngle;

// we need to update this widget both with gesture detector but
  // also when the parent widget rebuilds itself
  @override
  void didUpdateWidget(SliderLeftPaint oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.leftInitial != widget.leftInitial ||
        oldWidget.leftEnd != widget.leftEnd) {
      _calculatePercentage();
    }
  }

  void _calculatePercentage() {
    if (_isInitLeftHandlerSelected) {
      // This is for left inti and end percentage and the sweep Angle
      // TODO That it should be in a limit of half circle

      double initLeftPercentage = valueToPercentage(widget.leftInitial, 100);
      print('This is initial Left Percentge $initLeftPercentage');
      double endLeftPercentage = valueToPercentage(widget.leftEnd, 100);
      print('This is  End  Left Percentage $endLeftPercentage');

      double sweepLeftAngle =
          getSweepAngle(initLeftPercentage, endLeftPercentage);
      print('This is the sweep angle for the left hand side $sweepLeftAngle');
      _leftStartAngle = percentageToRadians(initLeftPercentage);
      print('This is the Left Start Angle $_leftStartAngle');
      _leftEndAngle = percentageToRadians(endLeftPercentage);
      print('This is the Left End Angle $_leftEndAngle');

      _leftSweepAngle = percentageToRadians(sweepLeftAngle.abs());
      print('This is the Left Sweep Angle $_leftSweepAngle');
    }

    customLeftPainter = CustomLeftPainter(
      leftdrawablesvgIcon: widget.leftsvgIcon,
      leftSvgIcon: widget.leftIcon,
      startLeftAngle: _leftStartAngle,
      endLeftAngle: _leftEndAngle,
      leftSweepAngle: _leftSweepAngle,
      selectionLeftColor: Colors.blueAccent,
    );
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _calculatePaintData();
  }

  void _calculatePaintData() {
    // This is for the right init and end percentage and the sweepangle

    // This is for left inti and end percentage and the sweep Angle
    double initLeftPercentage = valueToPercentage(widget.leftInitial, 100);
    print('This is initial Left Percentge $initLeftPercentage');
    double endLeftPercentage = valueToPercentage(widget.leftEnd, 100);
    print('This is  End  Left Percentage $endLeftPercentage');

    double sweepLeftAngle =
        getSweepAngle(initLeftPercentage, endLeftPercentage);
    print('This is the sweep angle for the left hand side $sweepLeftAngle');
    _leftStartAngle = percentageToRadians(initLeftPercentage);
    print('This is the Left Start Angle $_leftStartAngle');
    _leftEndAngle = percentageToRadians(endLeftPercentage);
    print('This is the Left End Angle $_leftEndAngle');

    _leftSweepAngle = percentageToRadians(sweepLeftAngle.abs());
    print('This is the Left Sweep Angle $_leftSweepAngle');

    customLeftPainter = CustomLeftPainter(
      leftdrawablesvgIcon: widget.leftsvgIcon,
      leftSvgIcon: widget.leftIcon,
      startLeftAngle: _leftStartAngle,
      endLeftAngle: _leftEndAngle,
      leftSweepAngle: _leftSweepAngle,
      selectionLeftColor: Colors.blue,
    );
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onPanUpdate: _onPanUpdate,
      onPanEnd: _onPanEnd,
      onPanDown: _onPanDown,
      child: CustomPaint(
        painter: BasePainter(
          baseColor: Color(0XFF5E5C5D),
        ),
        foregroundPainter: customLeftPainter,
        child: Padding(
          padding: const EdgeInsets.all(12.0),
          child: widget.child,
        ),
      ),
    );
  }

  _onPanUpdate(DragUpdateDetails details) {
    if (!_isInitLeftHandlerSelected) {
      return;
    }
    if (customLeftPainter.leftcenter == null) {
      return;
    }

    RenderBox renderBox = context.findRenderObject();
    var position = renderBox.globalToLocal(details.globalPosition);
    var leftAngle;

    var leftPercent;

    var newLeftValue;

    if (_leftSweepAngle >= 0) {
      leftAngle = coordinatesToRadians(customLeftPainter.leftcenter, position);
      leftPercent = radianstoPercentageLeft(leftAngle);
      newLeftValue = percentageToValue(leftPercent, 100);
      if (_isInitLeftHandlerSelected) {
        widget.onSelectionChange(newLeftValue);
      }
    }
  }

  _onPanDown(DragDownDetails details) {
    if (customLeftPainter == null) {
      return;
    }
    RenderBox renderBox = context.findRenderObject();
    var position = renderBox.globalToLocal(details.globalPosition);
    if (position != null) {
      _isInitLeftHandlerSelected = isPointInsideCircle(
          position, customLeftPainter.leftInitHandler, 12.0);
    }
  }

  _onPanEnd(_) {
    _isInitLeftHandlerSelected = false;
  }
}

Venstre maler

import 'dart:math';
import 'dart:ui' as UI;

import 'package:animations_sample/utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';

class CustomLeftPainter extends CustomPainter {
  DrawableRoot leftdrawablesvgIcon;
  UI.Image leftSvgIcon;
  double startLeftAngle;
  double endLeftAngle;
  double leftSweepAngle;
  Color selectionLeftColor;
  Size actuallsize = Size(30, 30);

  Offset leftcenter;

  double leftradius;

  Offset leftInitHandler;

  CustomLeftPainter({
    @required this.leftdrawablesvgIcon,
    @required this.leftSvgIcon,
    @required this.startLeftAngle,
    @required this.endLeftAngle,
    @required this.leftSweepAngle,
    @required this.selectionLeftColor,
  });

  @override
  void paint(Canvas canvas, Size size) {
    //This was the problem when all the both left and right angles are 0 then it will return with no points
    /* if (startLeftAngle == 0.0 &&
        endLeftAngle == 0.0 &&
        startRightAngle == 0.0 &&
        endRightAngle == 0.0) return;
 */

    Paint leftprogress = _getPaint(color: selectionLeftColor, width: 20);

    leftcenter = Offset(size.width / 2, size.height / 2);

    leftradius = min(size.width / 2, size.height / 2);

    canvas.drawArc(Rect.fromCircle(center: leftcenter, radius: leftradius),
        pi / 2 + startLeftAngle, leftSweepAngle, false, leftprogress);

    Paint lefthandler =
        _getPaint(color: Colors.white, style: PaintingStyle.fill);
    Paint lefthandlerOutter = _getPaint(color: selectionLeftColor);

    leftInitHandler =
        radiansToCoordinates(leftcenter, pi / 2 + endLeftAngle, leftradius);
    canvas.drawCircle(leftInitHandler, 8.0, lefthandler);
    canvas.drawCircle(leftInitHandler, 12.0, lefthandlerOutter);



    // To draw image but problem is it has scalling problem

    /* canvas.drawImage(
        leftSvgIcon,
        Offset(leftInitHandler.dx - 12, leftInitHandler.dy - 12),
        lefthandlerOutter); */
    //


    leftdrawablesvgIcon.scaleCanvasToViewBox(canvas, size);

    leftdrawablesvgIcon.clipCanvasToViewBox(canvas);

       //This is the add part for the edit
    Rect myRect = Offset(leftInitHandler.dx,leftInitHandler.dy) & const Size(50.0, 50.0);

    leftdrawablesvgIcon.draw(
        canvas,myRect);
  }

  Paint _getPaint({@required Color color, double width, PaintingStyle style}) =>
      Paint()
        ..color = color
        ..strokeCap = StrokeCap.square
        ..style = style ?? PaintingStyle.stroke
        ..strokeWidth = width ?? 8.0;

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}


verktøyfil for konverteringer.

import 'dart:math';
import 'dart:ui';

double percentageToRadians(double percentage) => ((pi * percentage) / 100);

double radiansToPercentage(double radians) {
  var normalized = radians < 0 ? -radians : pi - radians;
  var percentage = ((100 * normalized) / (pi));
  // TODO we have an inconsistency of pi/2 in terms of percentage and radians
  return (percentage + 50) % 100;
}

double radianstoPercentageLeft(double radians) {
  var normalized = radians < 0 ? -radians : pi - radians;
  print('************This is left normalized $normalized');
  var percentage = ((100 * normalized) / (pi));
  return (percentage - 50) % 100;
}

double coordinatesToRadians(Offset center, Offset coords) {
  var a = coords.dx - center.dx;
  var b = center.dy - coords.dy;
  return atan2(b, a);
}

Offset radiansToCoordinates(Offset center, double radians, double radius) {
  var dx = center.dx + radius * cos(radians);
  var dy = center.dy + radius * sin(radians);
  return Offset(dx, dy);
}

double valueToPercentage(int time, int intervals) => (time / intervals) * 100;

int percentageToValue(double percentage, int intervals) =>
    ((percentage * intervals) / 100).round();

bool isPointInsideCircle(Offset point, Offset center, double rradius) {
  if(center ==Offset(0,0))
  {
    return false;
  }
  var radius = rradius * 1.2;
  return point.dx < (center.dx + radius) &&
      point.dx > (center.dx - radius) &&
      point.dy < (center.dy + radius) &&
      point.dy > (center.dy - radius);
}

bool isPointAlongCircle(Offset point, Offset center, double radius) {
  // distance is root(sqr(x2 - x1) + sqr(y2 - y1))
  // i.e., (7,8) and (3,2) -> 7.21
  var d1 = pow(point.dx - center.dx, 2);
  var d2 = pow(point.dy - center.dy, 2);
  var distance = sqrt(d1 + d2);
  return (distance - radius).abs() < 10;
}

double getSweepAngle(double init, double end) {
  if (end > init) {
    return end - init;
  }
  if(end == init)
  {
    return 0;
  }
  return (100 - init + end).abs();
}

List<Offset> getSectionsCoordinatesInCircle(
    Offset center, double radius, int sections) {
  var intervalAngle = (pi * 2) / sections;
  return List<int>.generate(sections, (int index) => index).map((i) {
    var radians = (pi / 2) + (intervalAngle * i);
    return radiansToCoordinates(center, radians, radius);
  }).toList();
}

bool isAngleInsideRadiansSelection(double angle, double start, double sweep) {
  var normalized = angle > pi / 2 ? 5 * pi / 2 - angle : pi / 2 - angle;
  var end = (start + sweep) % (2 * pi);
  return end > start
      ? normalized > start && normalized < end
      : normalized > start || normalized < end;
}

// this is not 100% accurate but it works
// we just want to see if a value changed drastically its value
bool radiansWasModuloed(double current, double previous) {
  return (previous - current).abs() > (3 * pi / 2);
}

legg

Vil gjerne legge til dette lille svg-ikonet på knotten

<?xml version=1.0?>
<svg xmlns=http://www.w3.org/2000/svg height=512px viewBox=0 0 16 16 width=512px><g><path d=m8 0c-4.41113 0-8 3.58887-8 8s3.58887 8 8 8 8-3.58887 8-8-3.58887-8-8-8zm0 15c-3.85986 0-7-3.14014-7-7s3.14014-7 7-7 7 3.14014 7 7-3.14014 7-7 7z data-original=#000000 class=active-path data-old_color=#000000 fill=#2184C4/><path d=m9 3c-1.04364 0-1.9624.536926-2.5 1.34772v-3.84772c0-.276367-.223633-.5-.5-.5-1.6543 0-3 1.3457-3 3 0 1.04364.536926 1.9624 1.34772 2.5h-3.84772c-.276367 0-.5.223633-.5.5 0 1.6543 1.3457 3 3 3 1.04364 0 1.9624-.536926 2.5-1.34772v3.84772c0 .276367.223633.5.5.5 1.6543 0 3-1.3457 3-3 0-1.04364-.536926-1.9624-1.34772-2.5h3.84772c.276367 0 .5-.223633.5-.5 0-1.6543-1.3457-3-3-3zm-6 5c-.930176 0-1.71436-.638184-1.93652-1.5h3.87305c-.222168.861816-1.00635 1.5-1.93652 1.5zm1-5c0-.930176.638184-1.71436 1.5-1.93652v3.87305c-.861816-.222168-1.5-1.00635-1.5-1.93652zm2 3.5c-.276123 0-.5-.223877-.5-.5 0-.276184.223877-.5.5-.5s.5.223816.5.5c0 .276123-.223877.5-.5.5zm2 2.5c0 .930176-.638184 1.71436-1.5 1.93652v-3.87305c.861816.222168 1.5 1.00635 1.5 1.93652zm-.936523-3.5c.222168-.861816 1.00635-1.5 1.93652-1.5.930176 0 1.71436.638184 1.93652 1.5h-3.87305z transform=translate(2 2) data-original=#000000 class=active-path data-old_color=#000000 fill=#2184C4/></g> </svg>

Publisert på 25/05/2020 klokken 13:31
kilden bruker
På andre språk...                            


1 svar

stemmer
0

Bruk flutter_svg- pakken, den har et eksempel på hvordan du tegner en SVG til et lerret, som i utgangspunktet er det du vil oppnå:

import 'package:flutter_svg/flutter_svg.dart';
final String rawSvg = '''<svg viewBox="...">...</svg>''';
final DrawableRoot svgRoot = await svg.fromSvgString(rawSvg, rawSvg);

// If you only want the final Picture output, just use
final Picture picture = svgRoot.toPicture();

// Otherwise, if you want to draw it to a canvas:
// Optional, but probably normally desirable: scale the canvas dimensions to
// the SVG's viewbox
svgRoot.scaleCanvasToViewBox(canvas);

// Optional, but probably normally desireable: ensure the SVG isn't rendered
// outside of the viewbox bounds
svgRoot.clipCanvasToViewBox(canvas);
svgRoot.draw(canvas, size); // <---------- I think this is the one that you actually want

Du kan også laste SVG som et aktivum fra filene dine. Husk at et enklere eksempel på spørsmålet ditt kan føre til bedre svar.

Svarte 31/05/2020 kl. 05:31
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more