前端如何动态计算输入框内文本的起始位置?

业务场景

在用户输入了描述词语的基础上,用 gpt 进行续写或扩写。然后将其应用到给定时间长度的视频中,作为解说字幕。每个视频可以解说的字幕数量有限,如果到视频结尾还未读完字幕,便不再继续。本文生成案例的提示词以"猫咪"二字为主,视频渲染素材也均为猫咪

概念

  • 建议字数:视频在渲染后能阅读的字幕量(估值),输入框左下角展示的字数
  • 当前字数:输入框右下角展示的字数
  • 截断:如果一个视频是 15-20 秒的,那估计只能阅读 75 字左右(10%+-),超出超出后文本会被截断。也就是说如果建议字数有 75 字,但是生成、输入后一共有 100 字,可能最后 25 个字都会被截断

问题

由于视频的时长是有限的 ,可能只有 15 秒、20 秒,所以可以解说字数也是有限的,语速快一点,可能也就 100 字左右。在第一版的设计中,如果生成字数超出了建议字数限制,我们会直接将后续的内容截断 。但是从实际情况看来,生成的文本中,最后一段话往往是关键句,运营希望能在视频中进行保留,因此我们需要想个方法将最后一段文本的内容记录下来。同时,如果用户在关键句的位置进行了修改,需要保留修改后的关键句。最终,在提交渲染的时候,最后一段话会被保留,文本的截断将从关键句之前开始截断,直到满足建议字数

需求分析

将一段文本分为普通文本与关键句,关键句的位置往往在最后一段/句。如果用户修改后,保留用户修改后的关键句

解决方案

  • \n分隔其他文本与关键句,维护分隔线

接口给过来的文本,是通过 sse 连接的,以前后端每次请求 ai 扩写,只会调用 gpt 一次,现在会调用 gpt生成两次文本,以\n分隔。前端在 sse 中一次性获取,获取的文本以\n分隔,维护一个分隔线

  • 当用户更改文案的时候,动态的计算分割线 的位置,也就是关键句的起始位置。我们需要区分是在其他文本处更改,还是在关键句处更改。因为如果是在其他文本处进行了增删的操作,需要对分隔线进行前移或后移。如果在关键句处更改,不需要动分割线的位置。

比如,一段文本是这样的,"Hi,今天的天气真不错,风和日丽,阳光普照,气温舒适。\n真是个出去玩的好日子!",共 39 个字符,假设说超过 30 个字符就会被截断,但是最后一句话很关键,我们可能希望最终文本哪怕被截断,也能保留最后一句。生成后可能是这样的,"Hi,今天的天气真不错,风和日丽,真是个出去玩的好日子!"。

实现

首先,我们用全文文本搜索\n的位置,获取分割线,获取后一项。当用户在输入框内进行鼠标点击的时候,记录下光标的位置,如果是鼠标框选的,就记录选框后的起始位置

注意,window.getSelection().toString()这个 api,在火狐上似乎不支持,得用 element.selectionStart和 element.selectionEnd,但后者在 chrome 上又不支持。所以文本相关的 api 真的很多坑。

当用户更改的时候,我们去对比当前的字符串和上一次结果。如果光标的起始位置小于分隔线的位置,并且当前文本中还包含完整的关键句,就直接给分割线增减变动响应字数的数字。

效果

我们可以看到,渲染出来的视频,最后一段话是输入框内的最后一句,即关键句。在保留这句话作为关键句的基础上,从后往中间截断,虽然还是会需要截断,但是我们保留了关键句,提升了视频解说字幕的完整性。

未更改

更改过

后记

实现的时候就感觉,这个方式是不是可以应用在一些富文本的产品中,做一些标记处理?本人从来没开发过富文本,但这次稍微体会了一下富文本相关的 api 有多坑,也挺有意思。也许以后可以研究研究。

如果这篇文章对你有帮助,请点赞收藏支持一下,谢谢!!!

相关推荐
文心快码BaiduComate1 分钟前
冰城码力全开,共赴AI Coding英雄之旅!CEDxCNCC百度文心快码Meetup圆满落幕!
前端·后端·程序员
inx1772 分钟前
HTML 敲击乐 PART--2
javascript·css
社恐的下水道蟑螂6 分钟前
用CSS3拍一部《星球大战》片头?前端导演的"原力"修炼指南
前端·javascript
子非鱼37310 分钟前
git 常用命令行
前端
晨曦(zxr_0102)11 分钟前
CSP-X 2024 复赛编程题全解(B4104+B4105+B4106+B4107)
数据结构·c++·算法
ai安歌12 分钟前
【Rust编程:从新手到大师】 Rust 控制流深度详解
开发语言·算法·rust
Tzarevich12 分钟前
CSS3星球大战:前端代码界的视觉导演艺术
前端·css
BBB努力学习程序设计13 分钟前
CSS复合选择器
前端·html
Shinom1ya_14 分钟前
算法 day 36
算法
·白小白15 分钟前
力扣(LeetCode) ——15.三数之和(C++)
c++·算法·leetcode