• 给好朋友用代码画一个爱心吧


    目录

    效果图

    html爱心

    python爱心

    ​编辑 代码

    html

    python

    浅浅分析一下《燃烧我,照亮你》剧中的爱心代码


    光棍节要到了,不给心意的人写个爱心代码?

    话不多说,上才艺,这里有两种爱心,一种是html,一种是用python编写的,都是动态的先看一下两种效果截图。

    这两个核心代码都不是自己所编写,都来至于网上,但经过个人修改的。

    效果图

    html爱心

    一个自己的网站,大家可以直接通过这个网站来看(每次点开颜色不一样哦)

    zhongyiz.space3v.work

    python爱心

    python代码参考b站up主码农高夫的视频所写下了的。

     代码

    html

    1. HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    2. <HTML>
    3. <HEAD>
    4. <TITLE> TITLE>
    5. <META NAME="Generator" CONTENT="EditPlus">
    6. <META NAME="Author" CONTENT="">
    7. <META NAME="Keywords" CONTENT="">
    8. <META NAME="Description" CONTENT="">
    9. <meta charset="UTF-8">
    10. <style>
    11. html, body {
    12. height: 100%;
    13. padding: 0;
    14. margin: 0;
    15. background: #000;
    16. }
    17. canvas {
    18. position: absolute;
    19. width: 100%;
    20. height: 100%;
    21. }
    22. style>
    23. HEAD>
    24. <BODY>
    25. <canvas id="pinkboard">canvas>
    26. <script>
    27. /*
    28. * Settings
    29. */
    30. arr=new Array(21);
    31. arr[0]='Only for you';
    32. arr[1]='You make my heart smile';
    33. arr[2]='My heart is with you';
    34. arr[3]='First impression of you is most lasting';
    35. arr[4]='Love me little and love me long';
    36. arr[5]='Brief is life, but love is long';
    37. arr[6]='因为你,我的心脏总是忙个不停';
    38. arr[7]='喜欢有很多种吧,无论是哪一种我都想给你';
    39. arr[8]='你是我一生只会遇见一次的惊喜';
    40. arr[9]='未曾相逢先一笑,初会便已许平生';
    41. arr[10]='I think I like it';
    42. arr[11]='愿言配德兮,携手相将';
    43. arr[12]='你撇下半天风韵,我拾得万种思量';
    44. arr[13]='相见情已深,未语可知心';
    45. arr[14]='只愿君心似我心,定不负相思意';
    46. arr[15]='有人可爱,有梦可待';
    47. arr[16]='初见倾心,再见痴心';
    48. arr[17]='How about being my girlfriend';
    49. arr[18]='I love you';
    50. arr[19]='我想和你走一段路';
    51. arr[20]='时间得意 ,春风嘉许, 我遇上你';
    52. index0 = Math.floor(Math.random() * arr.length);
    53. window.document.title=arr[index0]
    54. var settings = {
    55. particles: {
    56. length: 500, // maximum amount of particles
    57. duration: 2, // particle duration in sec
    58. velocity: 100, // particle velocity in pixels/sec
    59. effect: -0.75, // play with this for a nice effect
    60. size: 30, // particle size in pixels
    61. },
    62. };
    63. /*
    64. * RequestAnimationFrame polyfill by Erik Möller
    65. */
    66. (function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;alength&&!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)}}}());
    67. /*
    68. * Point class
    69. */
    70. var Point = (function() {
    71. function Point(x, y) {
    72. this.x = (typeof x !== 'undefined') ? x : 0;
    73. this.y = (typeof y !== 'undefined') ? y : 0;
    74. }
    75. Point.prototype.clone = function() {
    76. return new Point(this.x, this.y);
    77. };
    78. Point.prototype.length = function(length) {
    79. if (typeof length == 'undefined')
    80. return Math.sqrt(this.x * this.x + this.y * this.y);
    81. this.normalize();
    82. this.x *= length;
    83. this.y *= length;
    84. return this;
    85. };
    86. Point.prototype.normalize = function() {
    87. var length = this.length();
    88. this.x /= length;
    89. this.y /= length;
    90. return this;
    91. };
    92. return Point;
    93. })();
    94. /*
    95. * Particle class
    96. */
    97. var Particle = (function() {
    98. function Particle() {
    99. this.position = new Point();
    100. this.velocity = new Point();
    101. this.acceleration = new Point();
    102. this.age = 0;
    103. }
    104. Particle.prototype.initialize = function(x, y, dx, dy) {
    105. this.position.x = x;
    106. this.position.y = y;
    107. this.velocity.x = dx;
    108. this.velocity.y = dy;
    109. this.acceleration.x = dx * settings.particles.effect;
    110. this.acceleration.y = dy * settings.particles.effect;
    111. this.age = 0;
    112. };
    113. Particle.prototype.update = function(deltaTime) {
    114. this.position.x += this.velocity.x * deltaTime;
    115. this.position.y += this.velocity.y * deltaTime;
    116. this.velocity.x += this.acceleration.x * deltaTime;
    117. this.velocity.y += this.acceleration.y * deltaTime;
    118. this.age += deltaTime;
    119. };
    120. Particle.prototype.draw = function(context, image) {
    121. function ease(t) {
    122. return (--t) * t * t + 1;
    123. }
    124. var size = image.width * ease(this.age / settings.particles.duration);
    125. context.globalAlpha = 1 - this.age / settings.particles.duration;
    126. context.drawImage(image, this.position.x - size / 2, this.position.y - size / 2, size, size);
    127. };
    128. return Particle;
    129. })();
    130. /*
    131. * ParticlePool class
    132. */
    133. var ParticlePool = (function() {
    134. var particles,
    135. firstActive = 0,
    136. firstFree = 0,
    137. duration = settings.particles.duration;
    138. function ParticlePool(length) {
    139. // create and populate particle pool
    140. particles = new Array(length);
    141. for (var i = 0; i < particles.length; i++)
    142. particles[i] = new Particle();
    143. }
    144. ParticlePool.prototype.add = function(x, y, dx, dy) {
    145. particles[firstFree].initialize(x, y, dx, dy);
    146. // handle circular queue
    147. firstFree++;
    148. if (firstFree == particles.length) firstFree = 0;
    149. if (firstActive == firstFree ) firstActive++;
    150. if (firstActive == particles.length) firstActive = 0;
    151. };
    152. ParticlePool.prototype.update = function(deltaTime) {
    153. var i;
    154. // update active particles
    155. if (firstActive < firstFree) {
    156. for (i = firstActive; i < firstFree; i++)
    157. particles[i].update(deltaTime);
    158. }
    159. if (firstFree < firstActive) {
    160. for (i = firstActive; i < particles.length; i++)
    161. particles[i].update(deltaTime);
    162. for (i = 0; i < firstFree; i++)
    163. particles[i].update(deltaTime);
    164. }
    165. // remove inactive particles
    166. while (particles[firstActive].age >= duration && firstActive != firstFree) {
    167. firstActive++;
    168. if (firstActive == particles.length) firstActive = 0;
    169. }
    170. };
    171. ParticlePool.prototype.draw = function(context, image) {
    172. // draw active particles
    173. if (firstActive < firstFree) {
    174. for (i = firstActive; i < firstFree; i++)
    175. particles[i].draw(context, image);
    176. }
    177. if (firstFree < firstActive) {
    178. for (i = firstActive; i < particles.length; i++)
    179. particles[i].draw(context, image);
    180. for (i = 0; i < firstFree; i++)
    181. particles[i].draw(context, image);
    182. }
    183. };
    184. return ParticlePool;
    185. })();
    186. /*
    187. * Putting it all together
    188. */
    189. (function(canvas) {
    190. var context = canvas.getContext('2d'),
    191. particles = new ParticlePool(settings.particles.length),
    192. particleRate = settings.particles.length / settings.particles.duration, // particles/sec
    193. time;
    194. // get point on heart with -PI <= t <= PI
    195. function pointOnHeart(t) {
    196. return new Point(
    197. 160 * Math.pow(Math.sin(t), 3),
    198. 130 * Math.cos(t) - 50 * Math.cos(2 * t) - 20 * Math.cos(3 * t) - 10 * Math.cos(4 * t) + 25
    199. );
    200. }
    201. // creating the particle image using a dummy canvas
    202. var image = (function() {
    203. var canvas = document.createElement('canvas'),
    204. context = canvas.getContext('2d');
    205. canvas.width = settings.particles.size;
    206. canvas.height = settings.particles.size;
    207. // helper function to create the path
    208. function to(t) {
    209. var point = pointOnHeart(t);
    210. point.x = settings.particles.size / 2 + point.x * settings.particles.size / 350;
    211. point.y = settings.particles.size / 2 - point.y * settings.particles.size / 350;
    212. return point;
    213. }
    214. // create the path
    215. context.beginPath();
    216. var t = -Math.PI;
    217. var point = to(t);
    218. context.moveTo(point.x, point.y);
    219. while (t < Math.PI) {
    220. t += 0.01; // baby steps!
    221. point = to(t);
    222. context.lineTo(point.x, point.y);
    223. }
    224. context.closePath();
    225. // create the fill
    226. tips=new Array(42);
    227. tips[0]='#FFE4E1';
    228. tips[1]='#E6E6FA';
    229. tips[2]='#F0FFF0';
    230. tips[3]='#FFFFF0';
    231. tips[4]='#FFFAFA';
    232. tips[6]='#F8F8FF';
    233. tips[7]='#BBFFFF';
    234. tips[8]='#97FFFF';
    235. tips[9]='#C1FFC1';
    236. tips[10]='#87CEEB';
    237. tips[11]='#C0FF3E';
    238. tips[12]='#00FFFF';
    239. tips[13]='#FFEC8B';
    240. tips[14]='#FFFFE0';
    241. tips[15]='#FFC1C1';
    242. tips[16]='#FF6A6A';
    243. tips[17]='#FA8072';
    244. tips[18]='#FFB6C1';
    245. tips[19]='#FF3030';
    246. tips[20]='#D8BFD8';
    247. tips[21]='#FFE4C4';
    248. tips[22]='#FF4500';
    249. tips[23]='#FFDEAD';
    250. tips[24]='#FFB5C5';
    251. tips[25]='#FFAEB9';
    252. tips[26]='#F0FFF0';
    253. tips[27]='#FFF0F5';
    254. tips[28]='#FFE4E1';
    255. tips[29]='#F0FFFF';
    256. tips[30]='#EE00EE';
    257. tips[31]='#00BFFF';
    258. tips[32]='#D15FEE';
    259. tips[33]='#B0E2FF';
    260. tips[34]='#FFE1FF';
    261. tips[35]='#BFEFFF';
    262. tips[36]='#90EE90';
    263. tips[37]='#9B30FF';
    264. tips[38]='#FF0000';
    265. tips[39]='#FF6347';
    266. tips[40]='#F8F8FF';
    267. tips[41]='#FFFACD';
    268. index1 = Math.floor(Math.random() * tips.length);
    269. context.fillStyle = tips[index1];
    270. context.fill();
    271. // create the image
    272. var image = new Image();
    273. image.src = canvas.toDataURL();
    274. return image;
    275. })();
    276. // render that thing!
    277. function render() {
    278. // next animation frame
    279. requestAnimationFrame(render);
    280. // update time
    281. var newTime = new Date().getTime() / 1000,
    282. deltaTime = newTime - (time || newTime);
    283. time = newTime;
    284. // clear canvas
    285. context.clearRect(0, 0, canvas.width, canvas.height);
    286. // create new particles
    287. var amount = particleRate * deltaTime;
    288. for (var i = 0; i < amount; i++) {
    289. var pos = pointOnHeart(Math.PI - 2 * Math.PI * Math.random());
    290. var dir = pos.clone().length(settings.particles.velocity);
    291. particles.add(canvas.width / 2 + pos.x, canvas.height / 2 - pos.y, dir.x, -dir.y);
    292. }
    293. // update and draw particles
    294. particles.update(deltaTime);
    295. particles.draw(context, image);
    296. }
    297. // handle (re-)sizing of the canvas
    298. function onResize() {
    299. canvas.width = canvas.clientWidth;
    300. canvas.height = canvas.clientHeight;
    301. }
    302. window.onresize = onResize;
    303. // delay rendering bootstrap
    304. setTimeout(function() {
    305. onResize();
    306. render();
    307. }, 10);
    308. })(document.getElementById('pinkboard'));
    309. script>
    310. BODY>
    311. HTML>

    python

    1. import random
    2. from math import sin, cos, pi, log
    3. from tkinter import *
    4. CANVAS_WIDTH = 880 # 画布的宽
    5. CANVAS_HEIGHT = 680 # 画布的高
    6. CANVAS_CENTER_X = CANVAS_WIDTH / 2 # 画布中心的X轴坐标
    7. CANVAS_CENTER_Y = CANVAS_HEIGHT / 2 # 画布中心的Y轴坐标
    8. IMAGE_ENLARGE = 8 # 放大比例
    9. HEART_COLOR = "#FF3E96" # 心的颜色
    10. def heart_function(t):
    11. """
    12. “爱心函数生成器”
    13. :param t: 参数
    14. :return: 坐标
    15. """
    16. # 基础函数
    17. x = 16 * (sin(t) ** 3)
    18. y = -(13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t))
    19. # 放大
    20. x *= IMAGE_ENLARGE
    21. y *= IMAGE_ENLARGE
    22. # 移到画布中央
    23. x += CANVAS_CENTER_X
    24. y += CANVAS_CENTER_Y
    25. return int(x), int(y)
    26. def scatter_inside(x, y, beta=0.15):
    27. """
    28. 随机内部扩散
    29. :param x: 原x
    30. :param y: 原y
    31. :param beta: 强度
    32. :return: 新坐标
    33. """
    34. ratio_x = - beta * log(random.random())
    35. ratio_y = - beta * log(random.random())
    36. dx = ratio_x * (x - CANVAS_CENTER_X)
    37. dy = ratio_y * (y - CANVAS_CENTER_Y)
    38. return x - dx, y - dy
    39. def shrink(x, y, ratio):
    40. """
    41. 抖动
    42. :param x: 原x
    43. :param y: 原y
    44. :param ratio: 比例
    45. :return: 新坐标
    46. """
    47. force = -1 / (((x - CANVAS_CENTER_X) ** 2 + (y - CANVAS_CENTER_Y) ** 2) ** 0.7) # 这个参数...
    48. dx = ratio * force * (x - CANVAS_CENTER_X)
    49. dy = ratio * force * (y - CANVAS_CENTER_Y)
    50. return x - dx, y - dy
    51. def curve(p):
    52. """
    53. 自定义曲线函数,调整跳动周期
    54. :param p: 参数
    55. :return: 正弦
    56. """
    57. return 4 * (4* sin(4* p)) / (2 * pi)
    58. class Heart:
    59. """
    60. 爱心类
    61. """
    62. def __init__(self, generate_frame=20):
    63. self._points = set() # 原始爱心坐标集合
    64. self._edge_diffusion_points = set() # 边缘扩散效果点坐标集合
    65. self._center_diffusion_points = set() # 中心扩散效果点坐标集合
    66. self.all_points = {} # 每帧动态点坐标
    67. self.build(20000)
    68. self.random_halo = 10000
    69. self.generate_frame = generate_frame
    70. for frame in range(generate_frame):
    71. self.calc(frame)
    72. def build(self, number):
    73. # 爱心
    74. for _ in range(number):
    75. t = random.uniform(0, 3 * pi) # 随机不到的地方造成爱心有缺口
    76. x, y = heart_function(t)
    77. self._points.add((x, y))
    78. # 爱心内扩散
    79. for _x, _y in list(self._points):
    80. for _ in range(3):
    81. x, y = scatter_inside(_x, _y, 0.05)
    82. self._edge_diffusion_points.add((x, y))
    83. # 爱心内再次扩散
    84. point_list = list(self._points)
    85. for _ in range(5000):
    86. x, y = random.choice(point_list)
    87. x, y = scatter_inside(x, y, 0.17)
    88. self._center_diffusion_points.add((x, y))
    89. @staticmethod
    90. def calc_position(x, y, ratio):
    91. # 调整缩放比例
    92. force = 1 / (((x - CANVAS_CENTER_X) ** 2 + (y - CANVAS_CENTER_Y) ** 2) ** 0.520)
    93. dx = ratio * force * (x - CANVAS_CENTER_X) + random.randint(-1, 1)
    94. dy = ratio * force * (y - CANVAS_CENTER_Y) + random.randint(-1, 1)
    95. return x - dx, y - dy
    96. def calc(self, generate_frame):
    97. ratio = 10 * curve(generate_frame / 10 * pi) # 圆滑的周期的缩放比例
    98. halo_radius = int(4 + 6 * (1 + curve(generate_frame / 10 * pi)))
    99. halo_number = int(3000 + 4000 * abs(curve(generate_frame / 10 * pi) ** 2))
    100. all_points = []
    101. # 光环
    102. heart_halo_point = set() # 光环的点坐标集合
    103. for _ in range(halo_number):
    104. t = random.uniform(0, 3* pi) # 随机不到的地方造成爱心有缺口
    105. x, y = heart_function(t)
    106. x, y = shrink(x, y, halo_radius)
    107. if (x, y) not in heart_halo_point:
    108. # 处理新的点
    109. heart_halo_point.add((x, y))
    110. x += random.randint(-11, 11)
    111. y += random.randint(-11, 11)
    112. size = random.choice((1, 2, 2))#控制外围粒子的大小
    113. all_points.append((x, y, size))
    114. # 轮廓
    115. for x, y in self._points:
    116. x, y = self.calc_position(x, y, ratio)
    117. size = random.randint(1, 3)
    118. all_points.append((x, y, size))
    119. # 内容
    120. for x, y in self._center_diffusion_points:
    121. x, y = self.calc_position(x, y, ratio)
    122. size = random.randint(1, 2)
    123. all_points.append((x, y, size))
    124. self.all_points[generate_frame] = all_points
    125. def render(self, render_canvas, render_frame):
    126. for x, y, size in self.all_points[render_frame % self.generate_frame]:
    127. render_canvas.create_rectangle(x, y, x + size, y + size, width=0, fill=HEART_COLOR)
    128. def draw(main: Tk, render_canvas: Canvas, render_heart: Heart, render_frame=0):
    129. render_canvas.delete('all')
    130. render_heart.render(render_canvas, render_frame)
    131. main.after(160, draw, main, render_canvas, render_heart, render_frame + 1)
    132. if __name__ == '__main__':
    133. root = Tk()
    134. canvas = Canvas(root, bg='black', height=CANVAS_HEIGHT, width=CANVAS_WIDTH)
    135. canvas.pack()
    136. heart = Heart()
    137. draw(root, canvas, heart)
    138. root.mainloop()

    如果你想将html弄成大家可以浏览器打开的形式,大家就自行百度学习啦。

    浅浅分析一下《燃烧我,照亮你》剧中的爱心代码

    就是最近有部阿瑟很火的剧嘛,里面男主给女主画了一个爱心,我也想复刻一下(最终只能成效果二那样的爱心)。我最先通过观察视频里女主的代码是这样的

     于是咱们去找找源码,发现源码来源于这个网址

    C++17 - Draw a Valentine's Day heart shape | Solarian Programmer

    其剧中的那段代码就应该是这一段了

     可惜运行它你只能得到一个简单的爱心,我想一定是我水平问题,于是咱们去b站码农高夫的博主那里学习了一下,最终得到了这样的效果

    但好像似乎与剧中的这个效果还是有点差别

    这是什么问题呢,但又从剧这个图里面发现

     好像女主前后播放的不是一个图,前者更像是用视频剪辑做成的,后者更像代码编写的。于是咱们得出结论,首先女主最先使用c语言编写的爱心,但如果真的用c来写,估计会麻烦死,其次爱心可以通过代码复刻出大致的效果,但要达到剧中的效果估计得有后期渲染。

  • 相关阅读:
    Pandas | value_counts() 的详细用法
    评价指标篇——IOU(交并比)
    JAVA最佳学习方法
    C#的LINQ select查询、where过滤、group分组、join关联
    c#文件读写
    unity基础1-事件执行顺序、自定义事件
    得了肾囊肿该怎么办呢?
    [datawhale202208]计算之魂共读:怎样寻找最好的算法
    【虹科新品】 HK-MR430&330绝对式光纤编码器(上)
    Spring Boot 之Thymeleaf的爆红用注解【<!--/*@thymesVar id=“data“ type=“ch“*/-->】解决
  • 原文地址:https://blog.csdn.net/qq_55977554/article/details/127793709