给好朋友用代码画一个爱心吧
目录
html爱心
python爱心
编辑 代码
html
python
浅浅分析一下《燃烧我,照亮你》剧中的爱心代码
光棍节要到了,不给心意的人写个爱心代码?
话不多说,上才艺,这里有两种爱心,一种是html,一种是用python编写的,都是动态的先看一下两种效果截图。
这两个核心代码都不是自己所编写,都来至于网上,但经过个人修改的。
效果图
html爱心
一个自己的网站,大家可以直接通过这个网站来看(每次点开颜色不一样哦)
zhongyiz.space3v.work
python爱心
python代码参考b站up主码农高夫的视频所写下了的。
代码
html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
<meta charset="UTF-8">
<style>
html, body {
height: 100%;
padding: 0;
margin: 0;
background: #000;
}
canvas {
position: absolute;
width: 100%;
height: 100%;
}
</style>
</HEAD>
<BODY>
<canvas id="pinkboard"></canvas>
<script>
/*
* Settings
*/
arr=new Array(21);
arr[0]='Only for you';
arr[1]='You make my heart smile';
arr[2]='My heart is with you';
arr[3]='First impression of you is most lasting';
arr[4]='Love me little and love me long';
arr[5]='Brief is life, but love is long';
arr[6]='因为你,我的心脏总是忙个不停';
arr[7]='喜欢有很多种吧,无论是哪一种我都想给你';
arr[8]='你是我一生只会遇见一次的惊喜';
arr[9]='未曾相逢先一笑,初会便已许平生';
arr[10]='I think I like it';
arr[11]='愿言配德兮,携手相将';
arr[12]='你撇下半天风韵,我拾得万种思量';
arr[13]='相见情已深,未语可知心';
arr[14]='只愿君心似我心,定不负相思意';
arr[15]='有人可爱,有梦可待';
arr[16]='初见倾心,再见痴心';
arr[17]='How about being my girlfriend';
arr[18]='I love you';
arr[19]='我想和你走一段路';
arr[20]='时间得意 ,春风嘉许, 我遇上你';
index0 = Math.floor(Math.random() * arr.length);
window.document.title=arr[index0]
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
tips=new Array(42);
tips[0]='#FFE4E1';
tips[1]='#E6E6FA';
tips[2]='#F0FFF0';
tips[3]='#FFFFF0';
tips[4]='#FFFAFA';
tips[6]='#F8F8FF';
tips[7]='#BBFFFF';
tips[8]='#97FFFF';
tips[9]='#C1FFC1';
tips[10]='#87CEEB';
tips[11]='#C0FF3E';
tips[12]='#00FFFF';
tips[13]='#FFEC8B';
tips[14]='#FFFFE0';
tips[15]='#FFC1C1';
tips[16]='#FF6A6A';
tips[17]='#FA8072';
tips[18]='#FFB6C1';
tips[19]='#FF3030';
tips[20]='#D8BFD8';
tips[21]='#FFE4C4';
tips[22]='#FF4500';
tips[23]='#FFDEAD';
tips[24]='#FFB5C5';
tips[25]='#FFAEB9';
tips[26]='#F0FFF0';
tips[27]='#FFF0F5';
tips[28]='#FFE4E1';
tips[29]='#F0FFFF';
tips[30]='#EE00EE';
tips[31]='#00BFFF';
tips[32]='#D15FEE';
tips[33]='#B0E2FF';
tips[34]='#FFE1FF';
tips[35]='#BFEFFF';
tips[36]='#90EE90';
tips[37]='#9B30FF';
tips[38]='#FF0000';
tips[39]='#FF6347';
tips[40]='#F8F8FF';
tips[41]='#FFFACD';
index1 = Math.floor(Math.random() * tips.length);
context.fillStyle = tips[index1];
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>
python
import random
from math import sin, cos, pi, log
from tkinter import *
CANVAS_WIDTH = 880 # 画布的宽
CANVAS_HEIGHT = 680 # 画布的高
CANVAS_CENTER_X = CANVAS_WIDTH / 2 # 画布中心的X轴坐标
CANVAS_CENTER_Y = CANVAS_HEIGHT / 2 # 画布中心的Y轴坐标
IMAGE_ENLARGE = 8 # 放大比例
HEART_COLOR = "#FF3E96" # 心的颜色
def heart_function(t):
"""
“爱心函数生成器”
:param t: 参数
:return: 坐标
"""
# 基础函数
x = 16 * (sin(t) ** 3)
y = -(13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t))
# 放大
x *= IMAGE_ENLARGE
y *= IMAGE_ENLARGE
# 移到画布中央
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.7) # 这个参数...
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 4 * (4* 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(20000)
self.random_halo = 10000
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, 3 * 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(5000):
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, 3* pi) # 随机不到的地方造成爱心有缺口
x, y = heart_function(t)
x, y = shrink(x, y, halo_radius)
if (x, y) not in heart_halo_point:
# 处理新的点
heart_halo_point.add((x, y))
x += random.randint(-11, 11)
y += random.randint(-11, 11)
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._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()
canvas = Canvas(root, bg='black', height=CANVAS_HEIGHT, width=CANVAS_WIDTH)
canvas.pack()
heart = Heart()
draw(root, canvas, heart)
root.mainloop()
如果你想将html弄成大家可以浏览器打开的形式,大家就自行百度学习啦。
浅浅分析一下《燃烧我,照亮你》剧中的爱心代码
就是最近有部阿瑟很火的剧嘛,里面男主给女主画了一个爱心,我也想复刻一下(最终只能成效果二那样的爱心)。我最先通过观察视频里女主的代码是这样的
于是咱们去找找源码,发现源码来源于这个网址
C++17 - Draw a Valentine's Day heart shape | Solarian Programmer
其剧中的那段代码就应该是这一段了
可惜运行它你只能得到一个简单的爱心,我想一定是我水平问题,于是咱们去b站码农高夫的博主那里学习了一下,最终得到了这样的效果
但好像似乎与剧中的这个效果还是有点差别
这是什么问题呢,但又从剧这个图里面发现
好像女主前后播放的不是一个图,前者更像是用视频剪辑做成的,后者更像代码编写的。于是咱们得出结论,首先女主最先使用c语言编写的爱心,但如果真的用c来写,估计会麻烦死,其次爱心可以通过代码复刻出大致的效果,但要达到剧中的效果估计得有后期渲染。
沙糖桔45: 哥们解决了吗? 今天心血来潮用java爬也是,四个线程会有一个失败
你的名字(学习中): 博主,数据可以发一下吗
DRHN_white: 数据可以发我一下吗?1991190693@qq.com
茶馆大橘: An error occurred. Sorry, the page you are looking for is currently unavailable. Please try again later. If you are the system administrator of this resource then you should check the error log for details. Faithfully yours, nginx. 网页报错信息。 然后我试了一下线程池的极限,我发现我开到2的时候,都会偶尔造成上述报错的发生,不知道如何解决这种情况。如果想要完整的爬取数据,还是只能单线程。
茶馆大橘: 开太多进程服务器承受不了这么多请求,然后你会发现,虽然你爬取了两万多页数据,但是最后只拿到了2万条数据,原因就是 nginx服务器崩了