Compose挑灯夜看 - 照亮手机屏幕里面的书本内容

news2024/12/23 22:49:32

一、前言

上一篇文章 Compose回忆童年 - 手拉灯绳-开灯/关灯里面82年钨丝灯,让我又有了新的想法,我们怎么照亮手机里面的文本内容呢?

我们会在上一篇文章的基础上来实现“挑灯夜看”的功能,怎么下手呢?往下看👇

二、文本着色器

我们想要实现照亮功能,那肯定需要有不亮的文本内容。

通过透明度来可以吗?肯定不行,文本内容是可以上下滑动的,是一个整体,我们不能通过透明度来做。

在看到小米手机的文本着色效果之后:

小米万象息屏.png

我知道如何下手了,我先来看看ComposeText如何做渐变着色?

1. 有些同学可能喜欢用Canvas去绘制:

Canvas(...) {
   drawIntoCanvas { canvas ->
       canvas.nativeCanvas.drawText(text, x, y, paint)
   }
}

2. 我们可以使用Modifeir的drawWithCache修饰符,官方文档的链接里面也给我们了不少示例。

Text(
    text = "永远相信美好的事情即将发生❤️",
    modifier = Modifier
        .graphicsLayer(alpha = 0.99f)
        .drawWithCache {
            val brush = Brush.horizontalGradient(
                listOf(
                     Color(0xFFE24CE2),
                     Color(0xFF73BB70),
                     Color(0xFFE24CE2)
                )
             )
             onDrawWithContent {
                 drawContent()
                 drawRect(brush, blendMode = BlendMode.SrcAtop)
             }
         }
)

上面代码,我们使用到了BlendMode,我们这里用的是BlendMode#SrcAtop
将源图像合成到目标图像上,仅限于与目标重叠的位置,确保只有文本可见并且矩形的其余部分被剪切。

3. Google在Compose1.2.0-beta01的API变更里面,向TextStyleSpanStyle添加了 Brush API,以提供使用渐变颜色绘制文本的方法。

兄弟们支持了吗.png

private val GradientColors = listOf(
        Color(0xFF00FFFF), Color(0xFF97E063),
        Color(0xFFE24CE2), Color(0xFF97E063)
)
Text(
    modifier = Modifier.align(Alignment.Center).requiredWidthIn(max = 250.dp),
    text = "永远相信美好的事情即将发生❤️,我们不会期待米粉的期待!\n\n兄弟们支持了吗?",
    style = TextStyle(
        brush = Brush.linearGradient(
           colors = GradientColors
       )
    )
)

我们可以看到Emoji表情没有被着色,非常Nice。

我们看一下linearGradient/verticalGradient/radialGradient/sweepGradient效果对比:

左边的是linearGradient右边的是verticalGradient

左边的是radialGradient右边的是sweepGradient

还有一种内置的BrushSolidColor,填充指定颜色。

查看Brush#LinearGradient源码发现它继承自ShaderBrush

// androidx.compose.ui.graphics.Brush
class LinearGradient internal constructor(
    private val colors: List<Color>,
    private val stops: List<Float>? = null,
    private val start: Offset,
    private val end: Offset,
    private val tileMode: TileMode = TileMode.Clamp
) : ShaderBrush()

自定义ShaderBrush,可以修改画笔大小,那么我们也来整一个,用于下面的钨丝灯的照亮效果,刚刚上面还介绍了到一个gradient符合我们的要求,radialGradient,更多的源码细节,这里就不做深入介绍,夜深了哈哈哈。

我们接下来需要初始化一个ShaderBrush

object : ShaderBrush() {
    override fun createShader(size: Size): Shader {
        return RadialGradientShader(
            center = ...,
            radius = ...,
            colors = ...
        )
    }
    ...
}

三、实现照亮文本

刚刚上面初始化了一个ShaderBrush,我们照亮文本内容,文本内容不可能只有一屏对吧,肯定需要支持滑动文本,那要怎么做呢?

我想肯定有掘友知道了,我们可以用ModifierverticalScroll修饰符,记录滚动状态ScrollState,然后设置到RadialGradientShadercenter里面。

我们这里的文本内容引用了:三国演义的第一章内容,我们同样需要上一篇文章RopHandleState

private fun ComposeText(state: RopeHandleState) {
    Text(
        text = sanguoString,
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp)
            .verticalScroll(state.scrollState),
        style = LocalTextStyle.current.merge(
            TextStyle(
                fontSize = 18.sp,
                brush = state.lightContentBrush
            )
        )
    )
}

这里我们用到了TextStyle#Brush的API,同时也添加了滚动修饰符,因为我们需要上下滑动文本,保证“钨丝灯”能照亮我们的文本内容。

我们在RopHandleState里面初始化ScrollState

val scrollState = ScrollState(0)

private val scrollOffset by derivedStateOf {
   // 这里增加Y轴的距离
   Offset(size.width / 2F, scrollState.value.toFloat() + size.width * 0.2F)
}

可以滚动,我们需要把滚动的距离同步给我们的ShaderBrush

// isOpen == true,钨丝灯亮了需要初始化ShaderBrush
object : ShaderBrush() {
     override fun createShader(size: Size): Shader {
     lastScrollOffset = Offset(size.width/2F, scrollOffset.y)
     return RadialGradientShader(
            center = lastScrollOffset!!,
            radius = size.minDimension,
            colors = listOf(Color.Yellow, Color(0xff85733a), Color.DarkGray)
           )
     }
     override fun equals(other: Any?): Boolean {
          return lastScrollOffset?.y == scrollOffset.y
     }
}

// isOpen == false,钨丝灯灭了
SolidColor(Color.DarkGray)

根据“钨丝灯”的状态,返回不同的Brush:

val lightContentBrush by derivedStateOf {
    if(isOpen) {
        object : ShaderBrush() { ... }
    } else {
        SolidColor(Color.DarkGray)
    }
}

这里需要注意一下,我们在打开和关闭钨丝灯的时候,需要把lastScrollOffset设置为初始状态值

fun toggle() {
    isOpen = !isOpen
    lastScrollOffset = Offset.Zero
}

其他相关的代码,请参考上一篇文章 Compose回忆童年 - 手拉灯绳-开灯/关灯

我们来看看最终效果吧

延伸:这里其实还可通过手指触摸指定范围区域内高亮哦,有兴趣的可以去试试!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/99820.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

小程序01/小程序 全局配置 tabBar 介绍、小程序模板语法数据绑定 wxml渲染

一.全局配置 tabBar 介绍 tabBar说明: tabBar是配置全局 页面底部导航 tabBar内包含 页面底部导航 背景 按钮 文字 文字颜色 注意: tabBar内list 最多是 5 项 &#xff0c;最少是 2 项 二.小程序模板语法数据绑定 说明: index.js文件data内定义属性 在index.wxml内渲染 in…

靠steam搬砖项目,傻瓜式操作单日500+,可放大操作

在分享干货之前&#xff0c;作为一个从15年开始创业的过来人&#xff0c;先教大家怎么分辨网络上的项目靠不靠谱&#xff0c;以后擦亮眼睛再做&#xff0c;切记&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 1、回本周期性我这个人比较俗&#xff0c;创业就是…

我的世界(MC) forge 1.19.3 开服教程

Debian系统使用MCSManager9面板搭建Minecraft Java版MOD服务器的教程&#xff0c;本教程用的forge1.19.3服务端&#xff0c;用其他服务端的也可以参考一下。 其他版本我的世界服务器搭建教程&#xff1a;https://blog.zeruns.tech/tag/mc/各种Minecraft服务端介绍和下载&#…

双线性变换法MATLAB实现巴特沃斯低通滤波器

实验名称 数字信号处理实验4 实验&#xff08;实习&#xff09;日期 12.13 得分 指导老师 学院 电信院 专业 电子信息工程 年级 2020 班次 姓名 学号 20208327 1.实验目的 掌握利用MATLAB求滤波器阶数和自然截至频率&#…

手把手带你理解TPS趋势分析

在性能分析中,前端的性能工具,我们只需要关注几条曲线就够了:TPS、响应时间和错误率。这是我经常强调的。 但是关注 TPS 到底应该关注什么内容,如何判断趋势,判断了趋势之后,又该如何做出调整,调整之后如何定位原因,这才是我们关注 TPS 的一系列动作。 今天,我们就通…

SSM闲置物品

14-13开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a;基于s5m闲置物品交易系统 网站前台&#xff1a;关于我们、联系我们、公告信息、闲置物品、求购信息 管理员功能&…

SQL语句练习06

目录 一、建表 二、SQL语句练习 一、建表 一、建立如下学生表(命名格式“姓名拼音_三位学号_week8student”&#xff0c;如LBJ_023_week8student&#xff09; create table LYL_116_week8student(SNO int primary key, SNAME char(8) not null unique,SEX char(2), DEPTNO i…

初学Nodejs(7):mysql模块的简单使用

文章目录Nodejsmysql模块1、在项目中操作数据库的步骤1.1 安装操作mysql数据库的第三方模块&#xff08;mysql&#xff09;1.2 通过mysql模块连接到mysql数据库&#xff0c;并进行必要配置1.3 通过mysql模块执行sql语句1.3.1 查询数据1.3.2 插入数据插入数据的快捷方式1.3.3 更…

43_读写内部Flash实验

目录 STM32的内部FLASH简介 内部FLASH的构成 主存储器 系统存储区 对内部FLASH的写入过程 解锁 擦除扇区 写入数据 操作内部FLASH的库函数 FLASH解锁、上锁函数 设置操作位数及擦除扇区 写入数据 实验源码 STM32的内部FLASH简介 在STM32芯片内部有一个FLASH(nor …

vTESTstudio入门到精通 - vTESTstudio工具栏介绍_ Traceability Documentation Environment

由于Traceability & Documentation和Environment的两块内容较少&#xff0c;所以就合并起来介绍&#xff0c;单独的功能介绍略少&#xff0c;就不分开了&#xff0c;vTESTstudio工具栏介绍这块内容主要也是给大家做个普及&#xff0c;大家也是主要做个了解&#xff0c;方便…

可信启动、安全启动:SGX、TrustZone、SecureEnclave

最近在公众号上看到了一篇文章&#xff0c;算是又丰富了自己的安全方面的眼界。 最近看公众号取代了小视频、知乎这些东西。以前是真的不喜欢碎片化的东西&#xff0c;看什么学什么总是要找到书籍。但是这样的做法太过的极端&#xff0c;因为有时候有些事是两面性的。比如像安全…

SD nand与SD卡 SPI模式驱动

SD nand 与 SD卡的SPI模式驱动 文章目录SD nand 与 SD卡的SPI模式驱动1. 概述2. SPI接口模式与SD接口模式区别2.1 接口模式区别2.2 硬件引脚2.3 注意事项3. SD接口协议3.1 命令3.1.1 命令格式3.1.2 命令类型3.2 响应3.2.1 响应格式4. SD nand&#xff08;SD卡&#xff09;结构描…

小程序01/ 小程序 模板语法—条件渲染方式、小程序 模板语法-列表循环渲染方式

模板语法—条件渲染方式 1.wx:if 语法: 单分支: wx:if" 条件 " 双分支: wx:else 多分支: wx:elif" 条件 " 作用: 根据条件渲染 如果条件不满足 则该元素不会添加到DOM数 注意: wx:else前面必须要有 wx:if 或 wx:elif 2.hidden 语法: hidden&qu…

Vue Router安装与基本使用

Vue Router安装与基本使用(入门使用) 一、安装 npm install vue-router4在package.json 会配置一行 “vue-router”: “^4.1.6” 二、基本使用 2.1、新建路由器 新建 router文件夹 1个index.js文件 //1.定义路由组件 import Home from ../views/Home.vue import About from ..…

[附源码]Python计算机毕业设计Django学生社团信息管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

QtCreator同时运行多个程序

更多精彩内容&#x1f449;个人内容分类汇总 &#x1f448;&#x1f449;Qt开发经验 &#x1f448; QtCreator同时运行多个程序 在Windows下QtCreator默认只能运行一个程序&#xff0c;再次编译运行就会自动关闭之前运行的程序&#xff1b; 有时候我们想运行多个程序时&#x…

【电力系统】考虑储能优化的微网能量管理双层模型附matlab代码

​✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法…

一篇文章带你了解HBase、Zookeeper的安装部署

第 2 章 HBase 快速入门2.1 HBase 安装部署2.1.1 Zookeeper 正常部署2.1.2 Hadoop 正常部署2.1.3 HBase 的解压2.1.4 HBase 的配置文件2.1.5 HBase 远程发送到其他集群2.1.6 HBase 服务的启动2.1.7 查看 HBase 页面2.1.8 高可用&#xff08;可选&#xff09;2.2 HBase Shell 操…

「地表最强」C++核心编程(四)类和对象—对象初始化和清理

环境&#xff1a; 编译器&#xff1a;CLion2021.3&#xff1b;操作系统&#xff1a;macOS Ventura 13.0.1 文章目录一、构造函数和析构函数1.1 构造函数1.2 析构函数1.3 示例二、构造函数的分类及调用1.1 构造函数的分类1.2 构造函数的调用三、拷贝构造函数调用时机3.1 调用时机…

黑*头条_第1章_环境搭建、SpringCloud微服务(注册发现、服务调用、网关)(新版)

黑*头条_第1章_环境搭建、SpringCloud微服务(注册发现、服务调用、网关)&#xff08;新版&#xff09; 文章目录黑*头条_第1章_环境搭建、SpringCloud微服务(注册发现、服务调用、网关)&#xff08;新版&#xff09;1)课程对比2)项目概述2.1)能让你收获什么2.2)项目课程大纲2.3…