Canvas 仿百度贴吧客户端 loading 小球
前言
几天前在简书上看到在一篇文章《Android仿百度贴吧客户端Loading小球》,看了一下作者,他写了两个好玩的 demo,效果图如下:
今天趁着周末有空,用 H5 的 Canvas 仿了一下。这篇文章只实现第一个效果图。
这是我实现的效果:
实现原理
实现原理是参考简书的那篇文章,这里不再复述。现在我们来一步一步实现这样的效果。
第零步:画一个圆
源码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>百度贴吧客户端Loading小球</title>
<style>
canvas {
border: 1px solid #ccc;
}
</style>
</head>
<body>
<canvas id="canvas" width="500" height="500"></canvas>
<script>
var canvas = document.getElementById('canvas')
var ctx = canvas.getContext('2d')
canvas.width = 500
canvas.height = 500
var grid = canvas.width / 4
var cx = canvas.width / 2 // 圆中心点 x 坐标
var cy = canvas.height / 2 // 圆中心点 y 坐标
function circle() {
ctx.beginPath()
ctx.arc(cx, cy, grid / 2, 0, 2 * Math.PI)
}
circle()
ctx.stroke()
</script>
</body>
</html>
运行效果如下:
这个 demo 只涉及 Canvas 最简单的用法。
第一步:绘制蓝色的“贴”字
使用 ctx.fillText
,在圆的中心绘制一个蓝色的“帖”字。文字粗体、水平居中。
代码如下:
function text(fillStyle) {
var fontSize = size / 250 * 120
ctx.font = 'bold ' + fontSize + 'px Arial'
ctx.textAlign = 'center'
ctx.fillStyle = fillStyle
ctx.fillText('贴', cx, cy + fontSize * 0.3)
}
text('#29a3fe')
效果如下:
第二步:绘制蓝色的波浪
var waveSize = size / 6 // 波浪大小
var x = 0 // 波浪位置偏移大小
function curve() {
ctx.beginPath()
ctx.moveTo(cx - size + x + size / 2, cy)
ctx.quadraticCurveTo(cx - size + size / 4 + x + size / 2, cy - waveSize, cx - size + size / 2 + x + size / 2, cy)
ctx.quadraticCurveTo(cx - size + size * 3 / 4 + x + size / 2, cy + waveSize, cx - size + size + x + size / 2, cy)
ctx.quadraticCurveTo(cx + size / 4 + x + size / 2, cy - waveSize, cx + size / 2 + x + size / 2, cy)
ctx.quadraticCurveTo(cx + size * 3 / 4 + x + size / 2, cy + waveSize, cx + size + x + size / 2, cy)
ctx.lineTo(cx + size + x + size / 2, canvas.height)
ctx.lineTo(cx - size + x + size / 2, canvas.height)
ctx.lineTo(cx - size + x + size / 2, cy)
ctx.closePath()
}
ctx.fillStyle = '#29a3fe'
curve()
ctx.fill()
效果如下:
第三步:绘制白色的“贴”字
curve()
ctx.clip()
text('#f00')
第一句代码 curve()
创建了一个波浪形状的路径,和第三步不同的是,这里并没有使用 ctx.fill()
填充路径,而是使用了 ctx.clip()
裁剪路径,这样的话,后面绘制的路径(包括文字)只有在剪裁区域内才能显示。
为了和背景色区分开来,我把“贴”字改成红色。
效果如下:
第四步:绘制运动的波浪
function loop(){
ctx.clearRect(0, 0, canvas.width, canvas.height)
x -= 1.5
x = x % size
ctx.save()
circle()
ctx.stroke()
ctx.fillStyle = '#29a3fe'
curve()
ctx.fill()
ctx.restore()
requestAnimationFrame(loop)
}
loop()
效果如下:
第五步:整合前面的内容
效果如下:
第六步:剪裁圆形
把第零步的:
circle()
ctx.stroke()
改成:
circle()
ctx.clip()
这样就能把圆形外面的形状剪裁掉,然后就大功告成了。
最后,附上完整源码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
html,
body {
height: 100%;
}
canvas {
border: 1px solid #ccc;
}
</style>
</head>
<body>
<canvas id="canvas" width="500" height="500"></canvas>
<script>
var canvas = document.getElementById('canvas')
var ctx = canvas.getContext('2d')
canvas.width = 500
canvas.height = 500
var size = canvas.width / 4 // 圆的大小
var cx = canvas.width / 2 // 圆中心点 x 坐标
var cy = canvas.height / 2 // 圆中心点 y 坐标
var waveSize = size / 6 // 波浪大小
var x = 0 // 波浪位置偏移大小
function circle() {
ctx.beginPath()
ctx.arc(cx, cy, size / 2, 0, 2 * Math.PI)
}
function curve() {
ctx.beginPath()
ctx.moveTo(cx - size + x + size / 2, cy)
ctx.quadraticCurveTo(cx - size + size / 4 + x + size / 2, cy - waveSize, cx - size + size / 2 + x + size / 2, cy)
ctx.quadraticCurveTo(cx - size + size * 3 / 4 + x + size / 2, cy + waveSize, cx - size + size + x + size / 2, cy)
ctx.quadraticCurveTo(cx + size / 4 + x + size / 2, cy - waveSize, cx + size / 2 + x + size / 2, cy)
ctx.quadraticCurveTo(cx + size * 3 / 4 + x + size / 2, cy + waveSize, cx + size + x + size / 2, cy)
ctx.lineTo(cx + size + x + size / 2, canvas.height)
ctx.lineTo(cx - size + x + size / 2, canvas.height)
ctx.lineTo(cx - size + x + size / 2, cy)
ctx.closePath()
}
function text(fillStyle) {
var fontSize = size / 250 * 120
ctx.font = 'bold ' + fontSize + 'px Arial'
ctx.textAlign = 'center'
ctx.fillStyle = fillStyle
ctx.fillText('贴', cx, cy + fontSize * 0.3)
}
function loop(){
ctx.clearRect(0, 0, canvas.width, canvas.height)
x -= 1.5
x = x % size
ctx.save()
circle()
ctx.clip()
text('#29a3fe')
ctx.fillStyle = '#29a3fe'
curve()
ctx.fill()
curve()
ctx.clip()
text('#fff')
ctx.restore()
requestAnimationFrame(loop)
}
loop()
</script>
</body>
</html>
总结
略
Canvas 仿百度贴吧客户端 loading 小球的更多相关文章
- 在Android上仿百度贴吧客户端Loading图标小球
封面 前言 使用百度贴吧客户端的时候发发现加载的小动画挺有意思的,于是自己动手写写看.想学习自定义View以及自定义动画的小伙伴一定不要错过哦. 读者朋友需要有最基本的canvas绘图功底,比如画笔P ...
- 仿百度壁纸客户端(六)——完结篇之Gallery画廊实现壁纸预览已经项目细节优化
仿百度壁纸客户端(六)--完结篇之Gallery画廊实现壁纸预览已经项目细节优化 百度壁纸系列 仿百度壁纸客户端(一)--主框架搭建,自定义Tab + ViewPager + Fragment 仿百度 ...
- 仿百度壁纸客户端(五)——实现搜索动画GestureDetector手势识别,动态更新搜索关键字
仿百度壁纸客户端(五)--实现搜索动画GestureDetector手势识别,动态更新搜索关键字 百度壁纸系列 仿百度壁纸客户端(一)--主框架搭建,自定义Tab + ViewPager + Frag ...
- 仿百度壁纸客户端(二)——主页自定义ViewPager广告定时轮播图
仿百度壁纸客户端(二)--主页自定义ViewPager广告定时轮播图 百度壁纸系列 仿百度壁纸客户端(一)--主框架搭建,自定义Tab + ViewPager + Fragment 仿百度壁纸客户端( ...
- 仿百度壁纸客户端(一)——主框架搭建,自定义Tab+ViewPager+Fragment
仿百度壁纸客户端(一)--主框架搭建,自定义Tab+ViewPager+Fragment 百度壁纸系列 仿百度壁纸客户端(一)--主框架搭建,自定义Tab + ViewPager + Fragment ...
- 高仿百度传课应用客户端源码iOS版
高仿百度传课iOS版,版本号:2.4.1.2 运行环境:xcode6.3 ios8.3 (再往上系统没有测试) 转载请注明出处,不可用于商业用途及不合法用途. 如果你觉得不错,欢迎 star 哦 ...
- WPF仿百度Echarts人口迁移图
GitHub地址:https://github.com/ptddqr/wpf-echarts-map/tree/master 关于大名鼎鼎的百度Echarts我就不多说了 不了解的朋友直接看官方的例子 ...
- 仿优酷Android客户端图片左右滑动(自动滑动)
最终效果: 页面布局main.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayou ...
- 【原创】jQuery 仿百度输入标签插件
1.先上效果图 2.调用方式 <link href="/Styles/tagsinput.css" rel="stylesheet" type=" ...
随机推荐
- python list有关remove的问题
在python 中进行一次简单的列表循环,当用到remove时出现了一个很有趣的现象, 代码如下: a=range(30) for i in a : if i%4!=0: a.remove(i) 这段 ...
- Linux: Bash基本命令
切换目录 cd 查看当前目录 pwd 生成目录 mkdir 搜索文件 查看当前的文件 ls 删除文件但保留特定类型 rm !(**) 例如: rm !(.tex|*.eps)其中,.tex, .eps ...
- java中volatile不能保证线程安全
今天打了打代码研究了一下java的volatile关键字到底能不能保证线程安全,经过实践,volatile是不能保证线程安全的,它只是保证了数据的可见性,不会再缓存,每个线程都是从主存中读到的数据,而 ...
- Java软件系统功能设计实战训练视频教程
Java软件系统功能设计实战训练视频教程 第01节课:整体课程介绍和杂项介绍第02节课:软件功能设计常见理念和方法第03节课:关于软件设计的一些思考第04节课:第一周作业的业务和相应模式:综合应用简单 ...
- el 表达式遍历Map
el 表达式遍历Map<c:forEach var="item" items="${payMentMap}"> <option value=& ...
- Install Composer on CentOS
First you have to go to the /tmp directory cd /tmp Download the composer.phar file curl -sS https:// ...
- [leetcode-438-Find All Anagrams in a String]
Given a string s and a non-empty string p, find all the start indices of p's anagrams in s.Strings c ...
- 跨进程通信之Messenger
1.简介 Messenger,顾名思义即为信使,通过它可以在不同进程中传递Message对象,通过在Message中放入我们需要的入局,就可以轻松实现数据的跨进程传递了.Messenger是一种轻量级 ...
- canvas学习总结五:线段的端点与连接点
我们在第三节中描述了线段的绘制,其中线段的属性lineWidth是用来改变线段的宽度.让我们来回忆下线宽的用法 function drawLine(){ cxt.lineWidth = 3; cxt. ...
- python迭代器生成器(二)
其他内置类型迭代器 除了文件以及列表这样的实际的序列外,其他类型也有适合的迭代器. 遍历字典的经典方法是明确的获取其键的列表. 在最近的python版本中,字典有一个迭代器,在迭代环境中,会自动一次返 ...