You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter代码中实现文本的旋转、缩放、移动与删除功能

Flutter 实现文本的创建、旋转、缩放、移动及删除

下面是一套完整的实现方案,包含核心逻辑和可运行代码:

1. 定义文本数据模型

先创建一个类来存储每个可操作文本的核心属性:

class TextElement {
  final String id;
  String text;
  Offset position;
  double scale;
  double rotation;

  TextElement({
    required this.id,
    required this.text,
    this.position = Offset.zero,
    this.scale = 1.0,
    this.rotation = 0.0,
  });
}

2. 完整实现代码

将所有功能整合到一个StatefulWidget中:

import 'package:flutter/material.dart';

void main() => runApp(const MaterialApp(home: TextEditor()));

class TextEditor extends StatefulWidget {
  const TextEditor({super.key});

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

class _TextEditorState extends State<TextEditor> {
  final List<TextElement> _textElements = [];
  String _currentText = '';

  // 生成唯一ID用于删除文本
  String _generateId() => DateTime.now().millisecondsSinceEpoch.toString();

  // 构建文本输入区域
  Widget _buildTextInput() {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Row(
        children: [
          Expanded(
            child: TextField(
              decoration: const InputDecoration(hintText: '输入文本内容'),
              onChanged: (value) => setState(() => _currentText = value),
            ),
          ),
          const SizedBox(width: 8),
          ElevatedButton(
            onPressed: _currentText.isNotEmpty
                ? () {
                    setState(() {
                      _textElements.add(TextElement(
                        id: _generateId(),
                        text: _currentText,
                        // 默认将新文本放在屏幕中心
                        position: Offset(
                          MediaQuery.of(context).size.width / 2 - 50,
                          MediaQuery.of(context).size.height / 2 - 20,
                        ),
                      ));
                      _currentText = '';
                    });
                  }
                : null,
            child: const Text('添加文本'),
          ),
        ],
      ),
    );
  }

  // 构建单个可操作文本元素
  Widget _buildTextElement(TextElement element) {
    return Positioned(
      left: element.position.dx,
      top: element.position.dy,
      child: GestureDetector(
        // 处理移动手势
        onPanUpdate: (details) {
          setState(() {
            element.position += details.delta;
          });
        },
        // 处理缩放和旋转手势
        onScaleUpdate: (details) {
          setState(() {
            // 限制缩放范围,避免文本过小或过大
            element.scale *= details.scale;
            element.scale = element.scale.clamp(0.5, 3.0);
            // 累加旋转弧度
            element.rotation += details.rotation;
          });
        },
        child: Stack(
          children: [
            Transform(
              // 应用缩放和旋转变换
              transform: Matrix4.identity()
                ..scale(element.scale)
                ..rotateZ(element.rotation),
              // 设置变换原点为文本中心,操作更符合直觉
              origin: Offset(
                (element.text.length * 8).toDouble(),
                12.0,
              ),
              child: Text(
                element.text,
                style: const TextStyle(fontSize: 24, color: Colors.black),
              ),
            ),
            // 删除按钮
            Positioned(
              right: -15,
              top: -15,
              child: IconButton(
                icon: const Icon(Icons.close, color: Colors.red, size: 20),
                onPressed: () {
                  setState(() {
                    _textElements.removeWhere((e) => e.id == element.id);
                  });
                },
              ),
            ),
          ],
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('文本编辑器')),
      body: Column(
        children: [
          _buildTextInput(),
          Expanded(
            // 用Stack层叠所有可操作文本
            child: Stack(
              children: _textElements.map(_buildTextElement).toList(),
            ),
          ),
        ],
      ),
    );
  }
}

核心功能说明

  • 创建文本:通过输入框输入内容,点击按钮生成新的文本元素,默认放置在屏幕中心。
  • 移动文本:长按文本后拖动,通过onPanUpdate手势获取偏移量更新文本位置。
  • 缩放文本:双指捏合手势,通过onScaleUpdate的缩放倍数调整文本大小,并限制缩放范围避免异常。
  • 旋转文本:双指旋转手势,累加旋转弧度实现文本旋转效果。
  • 删除文本:每个文本右上角的红色关闭按钮,点击后通过唯一ID从列表中移除对应文本。

内容的提问来源于stack exchange,提问作者kk web

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 15:54:22