<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> heart </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
<style>
html, body {
height: 100%;
padding: 0;
margin: 0;
background: white;
}
canvas {
position: absolute;
width: 100%;
height: 100%;
}
</style>
</HEAD>
<BODY>
<canvas id="pinkboard"></canvas>
<script>
/*
* Settings
*/
var settings = {
particles: {
length: 500, // maximum amount of particles
duration: 2, // particle duration in sec
velocity: 100, // particle velocity in pixels/sec
effect: -0.75, // play with this for a nice effect
size: 30, // particle size in pixels
},
};
/*
* RequestAnimationFrame polyfill by Erik Möller
*/
(function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;a<c.length&&!window.requestAnimationFrame;++a){window.requestAnimationFrame=window[c[a]+"RequestAnimationFrame"];window.cancelAnimationFrame=window[c[a]+"CancelAnimationFrame"]||window[c[a]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(h,e){var d=new Date().getTime();var f=Math.max(0,16-(d-b));var g=window.setTimeout(function(){h(d+f)},f);b=d+f;return g}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(d){clearTimeout(d)}}}());
/*
* Point class
*/
var Point = (function() {
function Point(x, y) {
this.x = (typeof x !== 'undefined') ? x : 0;
this.y = (typeof y !== 'undefined') ? y : 0;
}
Point.prototype.clone = function() {
return new Point(this.x, this.y);
};
Point.prototype.length = function(length) {
if (typeof length == 'undefined')
return Math.sqrt(this.x * this.x + this.y * this.y);
this.normalize();
this.x *= length;
this.y *= length;
return this;
};
Point.prototype.normalize = function() {
var length = this.length();
this.x /= length;
this.y /= length;
return this;
};
return Point;
})();
/*
* Particle class
*/
var Particle = (function() {
function Particle() {
this.position = new Point();
this.velocity = new Point();
this.acceleration = new Point();
this.age = 0;
}
Particle.prototype.initialize = function(x, y, dx, dy) {
this.position.x = x;
this.position.y = y;
this.velocity.x = dx;
this.velocity.y = dy;
this.acceleration.x = dx * settings.particles.effect;
this.acceleration.y = dy * settings.particles.effect;
this.age = 0;
};
Particle.prototype.update = function(deltaTime) {
this.position.x += this.velocity.x * deltaTime;
this.position.y += this.velocity.y * deltaTime;
this.velocity.x += this.acceleration.x * deltaTime;
this.velocity.y += this.acceleration.y * deltaTime;
this.age += deltaTime;
};
Particle.prototype.draw = function(context, image) {
function ease(t) {
return (--t) * t * t + 1;
}
var size = image.width * ease(this.age / settings.particles.duration);
context.globalAlpha = 1 - this.age / settings.particles.duration;
context.drawImage(image, this.position.x - size / 2, this.position.y - size / 2, size, size);
};
return Particle;
})();
/*
* ParticlePool class
*/
var ParticlePool = (function() {
var particles,
firstActive = 0,
firstFree = 0,
duration = settings.particles.duration;
function ParticlePool(length) {
// create and populate particle pool
particles = new Array(length);
for (var i = 0; i < particles.length; i++)
particles[i] = new Particle();
}
ParticlePool.prototype.add = function(x, y, dx, dy) {
particles[firstFree].initialize(x, y, dx, dy);
// handle circular queue
firstFree++;
if (firstFree == particles.length) firstFree = 0;
if (firstActive == firstFree ) firstActive++;
if (firstActive == particles.length) firstActive = 0;
};
ParticlePool.prototype.update = function(deltaTime) {
var i;
// update active particles
if (firstActive < firstFree) {
for (i = firstActive; i < firstFree; i++)
particles[i].update(deltaTime);
}
if (firstFree < firstActive) {
for (i = firstActive; i < particles.length; i++)
particles[i].update(deltaTime);
for (i = 0; i < firstFree; i++)
particles[i].update(deltaTime);
}
// remove inactive particles
while (particles[firstActive].age >= duration && firstActive != firstFree) {
firstActive++;
if (firstActive == particles.length) firstActive = 0;
}
};
ParticlePool.prototype.draw = function(context, image) {
// draw active particles
if (firstActive < firstFree) {
for (i = firstActive; i < firstFree; i++)
particles[i].draw(context, image);
}
if (firstFree < firstActive) {
for (i = firstActive; i < particles.length; i++)
particles[i].draw(context, image);
for (i = 0; i < firstFree; i++)
particles[i].draw(context, image);
}
};
return ParticlePool;
})();
/*
* Putting it all together
*/
(function(canvas) {
var context = canvas.getContext('2d'),
particles = new ParticlePool(settings.particles.length),
particleRate = settings.particles.length / settings.particles.duration, // particles/sec
time;
// get point on heart with -PI <= t <= PI
function pointOnHeart(t) {
return new Point(
160 * Math.pow(Math.sin(t), 3),
130 * Math.cos(t) - 50 * Math.cos(2 * t) - 20 * Math.cos(3 * t) - 10 * Math.cos(4 * t) + 25
);
}
// creating the particle image using a dummy canvas
var image = (function() {
var canvas = document.createElement('canvas'),
context = canvas.getContext('2d');
canvas.width = settings.particles.size;
canvas.height = settings.particles.size;
// helper function to create the path
function to(t) {
var point = pointOnHeart(t);
point.x = settings.particles.size / 2 + point.x * settings.particles.size / 350;
point.y = settings.particles.size / 2 - point.y * settings.particles.size / 350;
return point;
}
// create the path
context.beginPath();
var t = -Math.PI;
var point = to(t);
context.moveTo(point.x, point.y);
while (t < Math.PI) {
t += 0.01; // baby steps!
point = to(t);
context.lineTo(point.x, point.y);
}
context.closePath();
// create the fill
context.fillStyle = 'red';
context.fill();
// create the image
var image = new Image();
image.src = canvas.toDataURL();
return image;
})();
// render that thing!
function render() {
// next animation frame
requestAnimationFrame(render);
// update time
var newTime = new Date().getTime() / 1000,
deltaTime = newTime - (time || newTime);
time = newTime;
// clear canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// create new particles
var amount = particleRate * deltaTime;
for (var i = 0; i < amount; i++) {
var pos = pointOnHeart(Math.PI - 2 * Math.PI * Math.random());
var dir = pos.clone().length(settings.particles.velocity);
particles.add(canvas.width / 2 + pos.x, canvas.height / 2 - pos.y, dir.x, -dir.y);
}
// update and draw particles
particles.update(deltaTime);
particles.draw(context, image);
}
// handle (re-)sizing of the canvas
function onResize() {
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
}
window.onresize = onResize;
// delay rendering bootstrap
setTimeout(function() {
onResize();
render();
}, 10);
})(document.getElementById('pinkboard'));
</script>
</BODY>
</HTML>
7 posts tagged with "docusaurus"
View All Tagspython版爱心代码
import random
from math import sin, cos, pi, log
from tkinter import *
import ctypes
user32 = ctypes.windll.user32
CANVAS_WIDTH = user32.GetSystemMetrics(0) # 画布的宽
CANVAS_HEIGHT = user32.GetSystemMetrics(1) # 画布的高
CANVAS_CENTER_X = CANVAS_WIDTH / 2 # 画布中心的X轴坐标
CANVAS_CENTER_Y = CANVAS_HEIGHT / 2 # 画布中心的Y轴坐标
IMAGE_ENLARGE = 11 # 放大比例
HEART_COLOR = "#ff2121" # 心的颜色,这个是中国红
def heart_function(t, shrink_ratio: float = IMAGE_ENLARGE):
"""
“爱心函数生成器”
:param shrink_ratio: 放大比例
:param t: 参数
:return: 坐标
"""
# 基础函数
x = 16 * (sin(t) ** 3)
y = -(13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t))
# 放大
x *= shrink_ratio
y *= shrink_ratio
# 移到画布中央
x += CANVAS_CENTER_X
y += CANVAS_CENTER_Y
return int(x), int(y)
def scatter_inside(x, y, beta=0.15):
"""
随机内部扩散
:param x: 原x
:param y: 原y
:param beta: 强度
:return: 新坐标
"""
ratio_x = - beta * log(random.random())
ratio_y = - beta * log(random.random())
dx = ratio_x * (x - CANVAS_CENTER_X)
dy = ratio_y * (y - CANVAS_CENTER_Y)
return x - dx, y - dy
def shrink(x, y, ratio):
"""
抖动
:param x: 原x
:param y: 原y
:param ratio: 比例
:return: 新坐标
"""
force = -1 / (((x - CANVAS_CENTER_X) ** 2 + (y - CANVAS_CENTER_Y) ** 2) ** 0.6) # 这个参数...
dx = ratio * force * (x - CANVAS_CENTER_X)
dy = ratio * force * (y - CANVAS_CENTER_Y)
return x - dx, y - dy
def curve(p):
"""
自定义曲线函数,调整跳动周期
:param p: 参数
:return: 正弦
"""
# 可以尝试换其他的动态函数,达到更有力量的效果(贝塞尔?)
return 2 * (2 * sin(4 * p)) / (2 * pi)
class Heart:
"""
爱心类
"""
def __init__(self, generate_frame=20):
self._points = set() # 原始爱心坐标集合
self._edge_diffusion_points = set() # 边缘扩散效果点坐标集合
self._center_diffusion_points = set() # 中心扩散效果点坐标集合
self.all_points = {} # 每帧动态点坐标
self.build(2000)
self.random_halo = 1000
self.generate_frame = generate_frame
for frame in range(generate_frame):
self.calc(frame)
def build(self, number):
# 爱心
for _ in range(number):
t = random.uniform(0, 2 * pi) # 随机不到的地方造成爱心有缺口
x, y = heart_function(t)
self._points.add((x, y))
# 爱心内扩散
for _x, _y in list(self._points):
for _ in range(3):
x, y = scatter_inside(_x, _y, 0.05)
self._edge_diffusion_points.add((x, y))
# 爱心内再次扩散
point_list = list(self._points)
for _ in range(4000):
x, y = random.choice(point_list)
x, y = scatter_inside(x, y, 0.17)
self._center_diffusion_points.add((x, y))
@staticmethod
def calc_position(x, y, ratio):
# 调整缩放比例
force = 1 / (((x - CANVAS_CENTER_X) ** 2 + (y - CANVAS_CENTER_Y) ** 2) ** 0.520) # 魔法参数
dx = ratio * force * (x - CANVAS_CENTER_X) + random.randint(-1, 1)
dy = ratio * force * (y - CANVAS_CENTER_Y) + random.randint(-1, 1)
return x - dx, y - dy
def calc(self, generate_frame):
ratio = 10 * curve(generate_frame / 10 * pi) # 圆滑的周期的缩放比例
halo_radius = int(4 + 6 * (1 + curve(generate_frame / 10 * pi)))
halo_number = int(3000 + 4000 * abs(curve(generate_frame / 10 * pi) ** 2))
all_points = []
# 光环
heart_halo_point = set() # 光环的点坐标集合
for _ in range(halo_number):
t = random.uniform(0, 2 * pi) # 随机不到的地方造成爱心有缺口
x, y = heart_function(t, shrink_ratio=11.6) # 魔法参数
x, y = shrink(x, y, halo_radius)
if (x, y) not in heart_halo_point:
# 处理新的点
heart_halo_point.add((x, y))
x += random.randint(-14, 14)
y += random.randint(-14, 14)
size = random.choice((1, 2, 2))
all_points.append((x, y, size))
# 轮廓
for x, y in self._points:
x, y = self.calc_position(x, y, ratio)
size = random.randint(1, 3)
all_points.append((x, y, size))
# 内容
for x, y in self._edge_diffusion_points:
x, y = self.calc_position(x, y, ratio)
size = random.randint(1, 2)
all_points.append((x, y, size))
for x, y in self._center_diffusion_points:
x, y = self.calc_position(x, y, ratio)
size = random.randint(1, 2)
all_points.append((x, y, size))
self.all_points[generate_frame] = all_points
def render(self, render_canvas, render_frame):
for x, y, size in self.all_points[render_frame % self.generate_frame]:
render_canvas.create_rectangle(x, y, x + size, y + size, width=0, fill=HEART_COLOR)
def draw(main: Tk, render_canvas: Canvas, render_heart: Heart, render_frame=0):
render_canvas.delete('all')
render_heart.render(render_canvas, render_frame)
main.after(160, draw, main, render_canvas, render_heart, render_frame + 1)
if __name__ == '__main__':
root = Tk() # 一个Tk
root.attributes('-fullscreen', True) # 全屏
root.attributes('-alpha', 0.9) # 透明度
canvas = Canvas(root, bg='black', height=CANVAS_HEIGHT, width=CANVAS_WIDTH)
canvas.pack()
heart = Heart() # 心
draw(root, canvas, heart) # 开始画画~
root.mainloop()
Git命令
Git
安装(略)
配置
配置name和email
git config --global user.name "xxxx"
git config --global user.email "xxx@xxx.xxx"
使用git:
查看当前仓库的状态
git status
初始化仓库
git init
文件状态:
- 未跟踪
- 已跟踪
- 暂存
- 未修改
- 已修改
未跟踪 → 暂存
git add <filename> 将文件切换到暂存的状态
git add * 将所有已修改(未跟踪)的文件暂存暂存 → 未修改
git commit -m "xxxx" 将暂存的文件存储到仓库中
git commit -a -m "xxxx" 提交所有已修改的文件(未跟踪的文件不会提交)未修改 → 修改
- 修改代码后,文件会变为修改状态
常用的命令
- 重置文件
git restore <filename> # 恢复文件
git restore --staged <filename> # 取消暂存状态- 删除文件
git rm <filename> # 删除文件
git rm <filename> -f # 强制删除- 移动文件
git mv from to # 移动文件 重命名文件
分支
git在存储文件时,每一次代码代码的提交都会创建一个与之对应的节点,git就是通过一个一个的节点来记录代码的状态的。节点会构成一个树状结构,树状结构就意味着这个树会存在分支,默认情况下仓库只有一个分支,命名为master。在使用git时,可以创建多个分支,分支与分支之间相互独立,在一个分支上修改代码不会影响其他的分支。
git branch # 查看当前分支
git branch <branch name> # 创建新的分支
git branch -d <branch name> # 删除分支
git switch <branch name> # 切换分支
git switch -c <branch name> # 创建并切换分支
git merge <branch name> # 和并分支
在开发中,都是在自己的分支上编写代码,代码编写完成后,在将自己的分支合并到主分支中。
变基(rebase)
在开发中除了通过merge来合并分支外,还可以通过变基来完成分支的合并。
我们通过merge合并分支时,在提交记录中会将所有的分支创建和分支合并的过程全部都显示出来,这样当项目比较复杂,开发过程比较波折时,我必须要反复的创建、合并、删除分支。这样一来将会使得我们代码的提交记录变得极为混乱。
原理(变基时发生了什么):
当我们发起变基时,git会首先找到两条分支的最近的共同祖先
对比当前分支相对于祖先的历史提交,并且将它们提取出来存储到一个临时文件中
将当前部分指向目标的基底
以当前基底开始,重新执行历史操作
变基和merge对于合并分支来说最终的结果是一样的!但是变基会使得代码的提交记录更整洁更清晰!注意!大部分情况下合并和变基是可以互换的,但是如果分支已经提交给了远程仓库,那么这时尽量不要变基。
远程仓库(remote)
目前我对于git所有操作都是在本地进行的。在开发中显然不能这样的,这时我们就需要一个远程的git仓库。远程的git仓库和本地的本质没有什么区别,不同点在于远程的仓库可以被多人同时访问使用,方便我们协同开发。在实际工作中,git的服务器通常由公司搭建内部使用或是购买一些公共的私有git服务器。我们学习阶段,直接使用一些开放的公共git仓库。目前我们常用的库有两个:GitHub和Gitee(码云)
将本地库上传git:
git remote add origin https://github.com/lilichao/git-demo.git
# git remote add <remote name> <url>
git branch -M main
# 修改分支的名字的为main
git push -u origin main
# git push 将代码上传服务器上
将本地库上传gitee:
git remote add gitee https://gitee.com/ymhold/vue-course.git
git push -u gitee main
远程库的操作的命令
git remote # 列出当前的关联的远程库
git remote add <远程库名> <url> # 关联远程仓库
git remote remove <远程库名> # 删除远程库
git push -u <远程库名> <分支名> # 向远程库推送代码,并和当前分支关联
git push <远程库> <本地分支>:<远程分支>
git clone <url> # 从远程库下载代码
git push # 如果本地的版本低于远程库,push默认是推不上去
git fetch # 要想推送成功,必须先确保本地库和远程库的版本一致,fetch它会从远程仓库下载所有代码,但是它不会将代码和当前分支自动合并
# 使用fetch拉取代码后,必须要手动对代码进行合并
git pull # 从服务器上拉取代码并自动合并
注意:推送代码之前,一定要先从远程库中拉取最新的代码
tag 标签
当头指针没有指向某个分支的头部时,这种状态我们称为分离头指针(HEAD detached),分离头指针的状态下也可以操作操作代码,但是这些操作不会出现在任何的分支上,所以注意不要再分离头指针的状态下来操作仓库。
如果非得要回到后边的节点对代码进行操作,则可以选择创建分支后再操作
git switch -c <分支名> <提交id>
可以为提交记录设置标签,设置标签以后,可以通过标签快速的识别出不同的开发节点:
git tag
git tag 版本
git tag 版本 提交id
git push 远程仓库 标签名
git push 远程仓库 --tags
git tag -d 标签名 # 删除标签
git push 远程仓库 --delete 标签名 # 删除远程标签
gitignore
- 默认情况下,git会监视项目中所有内容,但是有些内容比如node_modules目录中的内容,我们不希望它被git所管理。我们可以在项目目录中添加一个
.gitignore
文件,来设置那些需要git忽略的文件。
github的静态页面
- 在github中,可以将自己的静态页面之间部署到github中,它会给我们提供一个地址使得我们的页面变成一个真正的网站,可以供用户访问。
- 要求:
- 静态页面的分支必须叫做:gh-pages
- 如果希望页面可以通过xxx.github.io访问,则需要将库的名字配置为xxx.github.io
docusaurus
facebook推出的开源的静态的内容管理系统,通过它可以快速的部署一个静态网站
使用:
网址:
安装
npx create-docusaurus@latest my-website classic
启动项目
npm start
或yarn start
构建项目
npm run build
或yarn build
配置项目:
- docusaurus.config.js 项目的配置文件
添加页面:
- 在docusaurus框架中,页面分成三种:1.page,2.blog,3.doc
案例地址:
Welcome
Docusaurus blogging features are powered by the blog plugin.
Simply add Markdown files (or folders) to the blog
directory.
Regular blog authors can be added to authors.yml
.
The blog post date can be extracted from filenames, such as:
2019-05-30-welcome.md
2019-05-30-welcome/index.md
A blog post folder can be convenient to co-locate blog post images:
The blog supports tags as well!
And if you don't want a blog: just delete this directory, and use blog: false
in your Docusaurus config.
MDX Blog Post
Blog posts support Docusaurus Markdown features, such as MDX.
Use the power of React to create interactive blog posts.
<button onClick={() => alert('button clicked!')}>Click me!</button>
Long Blog Post
This is the summary of a very long blog post,
Use a <!--
truncate
-->
comment to limit blog post size in the list view.
First Blog Post
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet