160行代码实现代码雨效果

news2024/11/27 23:42:45

效果

7c882188-540f-4e9a-b797-69e734eed561.gif

序言

很喜欢黑客帝国里面那种代码雨的效果,为了锻炼自己的特效编写能力就尝试了一下,花了一下午写出来了。有需要的小伙伴拿去参考.

代码

package com.zgh.myapplication;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * <pre>
 * Created by zhuguohui
 * Date: 2024/7/4
 * Time: 16:38
 * Desc:代码雨
 * </pre>
 */
public class CodeRainView extends View {
    private Paint paint;

    private float fontSize = 30;
    private Random random;
    private Handler handler = new Handler();

    public CodeRainView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        fontSize = 15 * getResources().getDisplayMetrics().density + 0.5f;
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.FILL);
        paint.setTextSize(fontSize);
        random = new Random();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        int colum = (int) (getWidth() / fontSize);
        codeList.clear();
        for (int i = 0; i < colum; i++) {
            float offset = -random.nextInt(getHeight() / 2);
            Code code = new Code(offset, h, i * fontSize, fontSize);
            codeList.add(code);
        }
        startAnimation();
    }

    private Runnable updateRunnable = new Runnable() {
        @Override
        public void run() {
            invalidate();
            handler.postDelayed(updateRunnable, 16);
        }
    };

    private void startAnimation() {
        //要保证60fps 需要16毫秒执行一次
        handler.removeCallbacks(updateRunnable);
        handler.post(updateRunnable);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.BLACK);
        for (Code code : codeList) {
            code.draw(canvas, paint);
        }
    }

    List<Code> codeList = new ArrayList<>();

    private class Code {
        private final int[] colors;
        long startTime;
        long duration;
        float offset;
        float moveY;
        float x;
        private String[] toShowStrArray;

        public Code(float offset, int height, float x, float fontSize) {
            startTime = System.currentTimeMillis();
            this.duration = getRandomDuration();
            this.offset = offset;
            this.moveY = (height + str.length() * fontSize) - offset;
            colors = new int[str.length()];
            getRandomContent();
            getRandomColors();
            this.x = x;
        }

        private void getRandomColors() {
            for (int i = 0; i < str.length(); i++) {
                //255-0;
                int alpha = (int) (255 - ((i * 1.0) / (str.length() - 1)) * 255);
                colors[i] = getRandomColor(alpha);
            }
        }

        float lastRatio;

        void draw(Canvas canvas, Paint paint) {
            final long now = System.currentTimeMillis();//当前时间
            final float ratio = ((now - startTime) % duration) * 1.0f / duration; //计算动画比例
            for (int i = 0; i < str.length(); i++) {
                String toShowStr = toShowStrArray[i];
                float y = ratio * moveY + offset - (i * fontSize);
                paint.setColor(colors[i]);
                canvas.drawText(toShowStr, x, y, paint);
            }
            if (ratio - lastRatio > 0.1) {
                getRandomContent();
                lastRatio = ratio;
            }

            if (ratio >= 0.99) {
                //重新随机一个速度
                startTime = System.currentTimeMillis();
                getRandomColors();
                duration = getRandomDuration();
                getRandomContent();
                lastRatio = 0;
            }
        }

        private int getRandomColor(int alpha) {
            return Color.argb(alpha, random.nextInt(255), random.nextInt(255), random.nextInt(255));
        }

        private final String str = "0123456789abcdefghijklmnopqrstuvwxyz";

        private String getRandomText() {
            return str.charAt(random.nextInt(str.length())) + "";
        }

        private void getRandomContent() {
            toShowStrArray = new String[str.length()];
            for (int i = 0; i < str.length(); i++) {
                toShowStrArray[i] = getRandomText();
            }
        }
    }
    

    private int getRandomDuration() {
        return random.nextInt(3000) + 3000;
    }
}

总结

一切纷繁复杂的效果,都要学会拆解。要用面向对象思想的来开发特效,把功能拆解到各种类中,以小胜换大胜。而驱动一切的就是时间。

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

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

相关文章

PLM系统:PLM系统如何重塑产品生命周期管理

PLM系统&#xff1a;重塑产品生命周期管理的未来 在当今快速变化的商业环境中&#xff0c;产品生命周期管理&#xff08;PLM&#xff09;系统正逐渐成为企业提升竞争力、加速创新并优化运营流程的关键工具。随着技术的不断进步和市场需求的日益复杂化&#xff0c;传统的手动或…

视创云展线上虚拟展厅的优势与特点

一、线上虚拟展厅的无限魅力 1、沉浸式体验&#xff0c;跨越时空界限 视创云展线上虚拟展厅借助前沿的虚拟现实技术&#xff0c;为参观者打造了一场跨越物理界限的奇妙之旅。无论身处世界的哪个角落&#xff0c;只需轻点鼠标&#xff0c;即可瞬间“穿越”至展览现场&#xff…

“免费”的可视化大屏案例分享-智慧园区综合管理平台

一.智慧园区是什么&#xff1f; 智慧园区是一种融合了新一代信息与通信技术的先进园区发展理念。它通过迅捷信息采集、高速信息传输、高度集中计算、智能事务处理和无所不在的服务提供能力&#xff0c;实现了园区内及时、互动、整合的信息感知、传递和处理。这样的园区旨在提高…

Python爬虫康复训练——笔趣阁《神魂至尊》

还是话不多说&#xff0c;很久没写爬虫了&#xff0c;来个bs4康复训练爬虫&#xff0c;正好我最近在看《神魂至尊》&#xff0c;爬个txt文件下来看看 直接上代码 """ 神魂至尊网址-https://www.bqgui.cc/book/1519/ """ import requests from b…

Contact Form 7表单获取提交用户IP及URL等信息

有时候&#xff0c;您可能需要了解Contact Form 7表单提交后的更多的信息&#xff0c;而不仅仅是通过联系人表单字段获取用户的联系信息。例如&#xff0c;需要知道用户是哪个国家&#xff08;通过获取IP&#xff09;&#xff0c;了解用户使用的设备&#xff08;手机还是电脑&a…

什么是空气电容器?

空气电容器是使用空气作为电介质的电容器。简单的空气电容器由两个导电板组成&#xff0c;中间有一个气隙。空气电容器可以制成可变或固定电容形式。固定电容空气电容器很少使用&#xff0c;因为还有许多其他具有优异特性的类型。可变空气电容器由于其结构简单而更常用。它们通…

利用联合概率分布筛选2个维度、三个维度数据

目录 1. 整体分析步骤1:联合分布可视化步骤2:定义筛选条件步骤3:应用筛选条件实例演示第一步:联合分布可视化第二步:定义筛选条件第三步:应用筛选条件数据检查与清洗步骤数据清洗步骤下一步2. 定义筛选条件方法一:基于分位数的筛选方法二:基于高密度区域的筛选进一步分…

Leetcode.342 4的幂

给定一个整数&#xff0c;写一个函数来判断它是否是 4 的幂次方。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 整数 n 是 4 的幂次方需满足&#xff1a;存在整数 x 使得 n 4x 示例 1&#xff1a; 输入&#xff1a;n 16 输出&#xff1a;true示…

第20章 Mac+VSCode配置C++环境

1. 下载VSCode VSCode下载地址在mac终端里输入xcode- select --install命令,根据提示安装xcode工具。2. 安装插件(4个) 打开VScode,点击应用右侧菜单栏 C/C++(必装) Code Runner(必装) CodeLLDB(代码调试),不安装这个插件程序调试时,无法在vscode自带的终端里输入参…

智慧办公楼宇可视化:智能管理与优化

通过图扑可视化技术集成多种数据源&#xff0c;实时展示智慧办公楼宇的运行状态和管理信息&#xff0c;助力高效运营和工作环境优化。

荣耀电脑误删U盘文件?别慌,这里有找回方法

荣耀电脑误删U盘文件怎么找回&#xff1f;在日常工作和生活中&#xff0c;U盘是我们存储和传输数据的重要工具之一。然而&#xff0c;在使用荣耀电脑时&#xff0c;如果不小心误删了U盘中的文件&#xff0c;可能会给我们带来不小的困扰。但是&#xff0c;别慌&#xff01;本文将…

4面体空间5点结构种类与占比

在30个点的4面体中取5个点&#xff0c;有30*29*28*27*26/(5*4*3*2)142506种取法&#xff0c; 这里要求5个点必须是直链或支链。共有496个组合符合要求&#xff0c;按平移对称性可分成181个不同的结构 结构 数量 结构 数量 结构 数量 结构 数量 结构 数量 结构 数量 …

四川赤橙宏海商务信息咨询有限公司引领抖音电商浪潮

在数字时代的浪潮下&#xff0c;电商行业飞速发展&#xff0c;抖音电商作为新兴的电商模式&#xff0c;凭借其独特的社交属性和短视频形式&#xff0c;迅速吸引了众多消费者和商家的目光。四川赤橙宏海商务信息咨询有限公司&#xff0c;作为抖音电商服务的佼佼者&#xff0c;凭…

Go堆内存管理

内存管理单元 内存管理单元有如下 page: x64下大小为8k。go与OS内存申请与释放都是以page为单位 span: 多个连续page组成&#xff0c;是内存管理的基本单元 mcache: 每个P所有的cache&#xff0c;包含多个空闲内存块链表&#xff0c;不同的链表上的内存块大小可能是不相同的…

出海拓圈! 环保企业走出去之马来西亚水环境项目考察

中办、国办印发《关于构建现代环境治理体系的指导意见》&#xff0c;其中明确提出“鼓励企业参与绿色‘一带一路’建设&#xff0c;带动先进的环保技术、装备、产能走出去”。近年来中国积极参与全球生态环境治理&#xff0c;在环境资源综合管理、水旱灾害防御、固危废无害化处…

Resilience4j之RateLimiter和常见限流算法总结

官网地址&#xff1a;https://resilience4j.readme.io/docs/ratelimiter 中文文档&#xff1a;https://resilience4j.readme.io/docs/ratelimiter 【1】概述 Resilience4j提供了一个限流器&#xff0c;它将从epoch开始的所有纳秒划分为多个周期。每个周期的持续时间RateLimi…

1975react社区问答管理系统开发mysql数据库web结构node.js编程计算机网页源码

一、源码特点 react 社区问答管理系统是一套完善的完整信息管理类型系统&#xff0c;结合react.js框架和node.js后端完成本系统&#xff0c;对理解react node编程开发语言有帮助系统采用node框架&#xff08;前后端分离&#xff09;&#xff09;&#xff0c;系统具有完整的源…

如何有效管理你的Facebook时间线?

Facebook作为全球最大的社交平台之一&#xff0c;每天都有大量的信息和内容在用户的时间线上展示。有效管理你的Facebook时间线&#xff0c;不仅可以提升用户体验&#xff0c;还能够帮助你更好地控制信息流和社交互动。本文将探讨多种方法和技巧&#xff0c;帮助你有效管理个人…

【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【19】认证服务03—分布式下Session共享问题

持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【19】分布式下Session共享问题 session原理分布式下session共享问题Session共享问题解决—session复制Session共享问题解决—客户端存储Session共享问题解决—hash一致性Session共享问题…