首页 文章 精选 留言 我的

精选列表

搜索[地图工具],共10000篇文章
优秀的个人博客,低调大师

仿百度地图小度语音助手的贝塞尔曲线动画

废话不多说,看下面的动图,和百度的还是有点点差别,我也不修改了,很简单,我实在是没有多余的时间,还要学习其他的东西,累啊,(复杂的动态View,可以使用SurfaceView,效率更高,我这里就简单使用View了) 效果图: 仔细观察一下百度那个动画,其实是由三层曲线组成的;每层曲线又是由三个贝塞尔曲线组成的。所以一层一层叠加,加上颜色的渐变,就可以绘制出来类似于山峰的曲线;最后,动态改变曲线的高度就可以达到那种效果(你也可以加上声音的波动值,那就看起来更加逼真了) 一个草图(见笑了): package com.example.helang.volumewave; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.LinearGradient; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Shader; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.animation.DecelerateInterpolator; import java.util.Random; /** * 仿百度的语音助手--波浪动画控件 */ public class VolumeWaveView extends View { private static final String TAG = "VolumeWaveView"; private static final int HEIGHT = 400;//整个控件的高度 private static final int HEIGHT1 = 60;//第一层曲线的高度 private static final int HEIGHT2 = 40;//第二层曲线的高度 private static final int HEIGHT3 = 50;//第三层曲线的高度 private int h1 = 0,h2 = 0, h3 = 0,h4 = 0,h5 = 0; private int range = 0;//波动的幅度,你可以动态改变这个值,比如麦克风录入的音量的高低 private Path path; private Paint paint1,paint2,paint3,paint4; private LinearGradient linearGradient1,linearGradient2,linearGradient3,linearGradient4;//四种渐变色 private ValueAnimator animator1,animator2,animator3,animator4,animator5;//五种动画 public VolumeWaveView(Context context) { this(context,null); } public VolumeWaveView(Context context, @Nullable AttributeSet attrs) { this(context,attrs,0); } public VolumeWaveView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs,defStyleAttr); initPaint(); } private void initPaint(){ path = new Path(); paint1 = new Paint(); paint1.setStyle(Paint.Style.FILL); paint1.setAntiAlias(true);//抗锯齿 //渐变色1 linearGradient1 = new LinearGradient(0, 0, 0, HEIGHT1, Color.parseColor("#e652a6d2"), Color.parseColor("#e652d5a1"), Shader.TileMode.MIRROR); paint1.setShader(linearGradient1); paint2 = new Paint(); paint2.setAntiAlias(true);//抗锯齿 paint2.setStyle(Paint.Style.FILL); //渐变色2 linearGradient2 = new LinearGradient(0, 0, 0, HEIGHT2, Color.parseColor("#e68952d5"), Color.parseColor("#e6525dd5"), Shader.TileMode.MIRROR); paint2.setShader(linearGradient2); paint3 = new Paint(); paint3.setAntiAlias(true);//抗锯齿 paint3.setStyle(Paint.Style.FILL); //渐变色3 linearGradient3 = new LinearGradient(0, 0, 0, HEIGHT3, Color.parseColor("#e66852d5"), Color.parseColor("#e651b9d2"), Shader.TileMode.MIRROR); paint3.setShader(linearGradient3); paint4 = new Paint(); paint4.setAntiAlias(true);//抗锯齿 paint4.setStyle(Paint.Style.FILL); //渐变色4 linearGradient4 = new LinearGradient(0, 0, 0, HEIGHT2, Color.parseColor("#e6d5527e"), Color.parseColor("#e6bf52d5"), Shader.TileMode.MIRROR); paint4.setShader(linearGradient4); } /** * draw方法中不要创建大量对象,尽量复用对象 * @param canvas */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawLayer3(canvas); drawLayer2(canvas); drawLayer1(canvas); } /** * 绘制第一层 * @param canvas */ private void drawLayer1(Canvas canvas){ drawCurve(path,canvas,paint1,getWidth()/5,getWidth()/3,h1); drawCurve(path,canvas,paint1,getWidth()/3+getWidth()/5,getWidth()/3,h2); } /** * 绘制第二层 * @param canvas */ private void drawLayer2(Canvas canvas){ drawCurve(path,canvas,paint2,0,getWidth()/2,h3); drawCurve(path,canvas,paint4,getWidth()/2-10,getWidth()/2,h4); } /** * 绘制第三层 * @param canvas */ private void drawLayer3(Canvas canvas){ drawCurve(path,canvas,paint3,getWidth()/4,getWidth()/2,h5); } /** * 画贝塞尔曲线 * @param path * @param canvas * @param x 横向起点的位置 * @param width 曲线的整个宽度 * @param height 曲线的高度 */ private void drawCurve(Path path,Canvas canvas,Paint paint,int x,int width,int height){ path.reset(); int divideWith = width/6;//因为一个弧形是由六部分组成的,所以这里就平均分一下 path.moveTo(x,HEIGHT); path.quadTo(x+divideWith,HEIGHT-height,x+divideWith*2,HEIGHT-height*2);//B - C path.lineTo(x+divideWith*2,HEIGHT-height*2); path.quadTo(x+divideWith*3,HEIGHT-height*3,x+divideWith*4,HEIGHT-height*2); path.lineTo(x+divideWith*4,HEIGHT-height*2); path.quadTo(x+divideWith*5,HEIGHT-height,x+divideWith*6,HEIGHT); canvas.drawPath(path,paint); } /** * 添加属性动画,每一个动画的变化范围和周期都不一样,这样错开的效果才好看点 */ public void startAnimation() { Random random = new Random(); range = random.nextInt(100)%(100-10+1) + 10;//波动的幅度,模拟动态音量输入,你可以自己设置 animator1 = ValueAnimator.ofInt(0,HEIGHT1,0); animator1.setDuration(1400); animator1.setInterpolator(new DecelerateInterpolator()); //无限循环 animator1.setRepeatCount(ValueAnimator.INFINITE); animator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { h1 = (int) animation.getAnimatedValue(); invalidate(); } }); animator1.start(); animator2 = ValueAnimator.ofInt(0,HEIGHT1,0); animator2.setDuration(1700); animator2.setInterpolator(new DecelerateInterpolator()); //无限循环 animator2.setRepeatCount(ValueAnimator.INFINITE); animator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { h2 = (int) animation.getAnimatedValue(); invalidate(); } }); animator2.start(); animator3 = ValueAnimator.ofInt(0,HEIGHT2,0); animator3.setDuration(1600); animator3.setInterpolator(new DecelerateInterpolator()); //无限循环 animator3.setRepeatCount(ValueAnimator.INFINITE); animator3.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { h3 = (int) animation.getAnimatedValue(); invalidate(); } }); animator3.start(); animator4 = ValueAnimator.ofInt(0,HEIGHT2,0); animator4.setDuration(1300); animator4.setInterpolator(new DecelerateInterpolator()); //无限循环 animator4.setRepeatCount(ValueAnimator.INFINITE); animator4.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { h4 = (int) animation.getAnimatedValue(); invalidate(); } }); animator4.start(); animator5 = ValueAnimator.ofInt(0,HEIGHT3,0); animator5.setDuration(2000); animator5.setInterpolator(new DecelerateInterpolator()); //无限循环 animator5.setRepeatCount(ValueAnimator.INFINITE); animator5.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { h5 = (int) animation.getAnimatedValue(); invalidate(); } }); animator5.start(); } /** * 关闭动画 */ public void removeAnimation(){ if (animator1 != null){ animator1.cancel(); animator1 = null; } if (animator2 != null){ animator2.cancel(); animator2 = null; } if (animator3 != null){ animator3.cancel(); animator3 = null; } if (animator4 != null){ animator4.cancel(); animator4 = null; } if (animator5 != null){ animator5.cancel(); animator5 = null; } } } 主要是利用Path中的贝塞尔曲线,然后加上属性动画,动态改变曲线的高度就可以了 喜欢的话,就去github给个star吧 https://github.com/helang1991/VolumeWave

优秀的个人博客,低调大师

基于Leaflet和天地图的南海部分岛礁标准名称可视化实践

最近的新闻比较多,我们的军事实力,装备大量服役。南北的新飞机发布,海上的076两栖攻击舰,我们的制空权和制海权得到了长足的保障。我们拥有很长的海岸线,有很多的岛屿和岛礁,都需要我们的实力去维护。南海不仅天然的风高浪急,这水下暗藏的又有多少波涛汹涌。随着我们综合国力的上升,对于规范的地名使用,官方发布了规范的岛礁标准名称。随着这些名称的公开,为我们在研究南海相关岛礁有了基础。

优秀的个人博客,低调大师

llms.txt 机制探究:为何 AI 爬虫需要一份纯文本内容地图

我在豆包搜了 4 个核心提问词,抓回 25 条引用源,我的博客一篇都没被引用,0%。这个 0 让我意识到,光有好内容不够,还得让 AI 知道怎么找到它。llms.txt 就是解决这个问题的方案——一个放在网站根目录的纯文本文件,用 Markdown 格式告诉 AI 爬虫你的网站结构、核心内容和权威信息源。配置它不需要写代码,10 分钟能搞定,但它能直接影响 AI 引擎怎么理解你的网站。

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册