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

业务场景

在用户输入了描述词语的基础上,用 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 有多坑,也挺有意思。也许以后可以研究研究。

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

相关推荐
2401_858286113 分钟前
101.【C语言】数据结构之二叉树的堆实现(顺序结构) 下
c语言·开发语言·数据结构·算法·
Beau_Will8 分钟前
数据结构-树状数组专题(1)
数据结构·c++·算法
迷迭所归处12 分钟前
动态规划 —— 子数组系列-单词拆分
算法·动态规划
爱吃烤鸡翅的酸菜鱼13 分钟前
Java算法OJ(8)随机选择算法
java·数据结构·算法·排序算法
gqkmiss16 分钟前
Chrome 浏览器 131 版本开发者工具(DevTools)更新内容
前端·chrome·浏览器·chrome devtools
Summer不秃22 分钟前
Flutter之使用mqtt进行连接和信息传输的使用案例
前端·flutter
旭日猎鹰26 分钟前
Flutter踩坑记录(二)-- GestureDetector+Expanded点击无效果
前端·javascript·flutter
Viktor_Ye32 分钟前
高效集成易快报与金蝶应付单的方案
java·前端·数据库
hummhumm35 分钟前
第 25 章 - Golang 项目结构
java·开发语言·前端·后端·python·elasticsearch·golang
寻找码源1 小时前
【头歌实训:利用kmp算法求子串在主串中不重叠出现的次数】
c语言·数据结构·算法·字符串·kmp