写点什么

【圣诞节】会呼吸的玫瑰爱心代码 - 李峋爱心续 动画演示思路 代码开源

作者:非喵鱼
  • 2022-12-12
    重庆
  • 本文字数:2055 字

    阅读完需:约 7 分钟

【圣诞节】会呼吸的玫瑰爱心代码 -李峋爱心续 动画演示思路 代码开源

前言

之前有部电视剧《点燃我温暖你》没火,但是其中李峋的爱心代码却在程序圈超级火,这圣诞节快到了了,给大家来一波爱心代码的教学。希望大家能在圣诞节该浪漫的浪漫、该脱单的脱单,加油兄弟!同时我也把实现思路通过动画给大家说清楚,期望各个语言的大佬都能一起开发出来,浪漫 2022!(开发了可以在评论区留个言哦~)


特别说明:勇哥的粉丝,可以评论区或私信留言给我,我直接把你想写的话和名字,直接给你打包好!


解释一下,创作思路:


  • 程序以信封的方式,可以增加浪漫与惊喜的仪式感!

  • 心的形状+玫瑰花的形状,双重美丽,不怕你的她不喜欢!

  • 心跳+呼吸灯的效果,含义:你的心围她而动的深刻含义!

  • 内部心不停转动的效果,含义:你的心围她而动的深刻含义!(双重强调更具浪漫)



重点学习或必要技术

  • 对于不规则图形的绘制示例:从本文中将学习到 java 中 GeneralPath 绘制不规则图形的高级应用。

  • 对于不规则图形的填充示例:从本文中将学习到不规则图形的,特别是射线渐变填充等高级应用。

  • 对于不规则图形的动画示例:从本文中将学习到图形平移、旋转、以及多层次的平移等高级应用。

心的轮廓思路及实现

绘制好基本轮廓之后,填充的颜色、特效等才不会溢出轮廓,因此我们第一步需要画好重要的轮廓线,实现思路如下:

通过二次曲线(Java 中是 QuadCurve2D)来画出轮廓线,轮廓线分为以下九段:

  • 第一段为心的最上左边

  • 第二段为心的最上右边

  • 第三段心的最下,有点幅度让心看起来中心点平滑一些;注意上面线段比下面线段长,有主次感;

  • 第四段为右上角

  • 第五段为右边

  • 第六段为右下角

  • 第七段为左下角,与第六段对称

  • 第八段为左边,与第五段对称

  • 第九段为左上角,与第四段对称

PS:有人可能不明白,为什么要画这么复杂?勇哥给解释一下,这样画,有 9 个点和 9 个线段,蕴含长长久久的意思!懂了吧~

来看一下动画演示的效果吧:



参考代码:


GeneralPath generalPath = new GeneralPath();// 左边g2d.setColor(bgColor);generalPath.moveTo(getWidth()/2-6,getHeight()*3/10);generalPath.quadTo(getWidth()/2,getHeight()*3/10+5,getWidth()/2+6,getHeight()*3/10);// 上中generalPath.quadTo(getWidth()*5/8,getHeight()*2/10,getWidth()*3/4,getHeight()*2/10);// 右上generalPath.quadTo(getWidth(),getHeight()*2/10+10,getWidth()-5,getHeight()*2/5);generalPath.quadTo(getWidth(),getHeight()*3/5,getWidth()/2+5,getHeight()*4/5);generalPath.quadTo(getWidth()/2,getHeight()*4/5+3,getWidth()/2-5,getHeight()*4/5);generalPath.quadTo(10,getHeight()*3/5,5,getHeight()*2/5);generalPath.quadTo(0,getHeight()*2/10,getWidth()*1/4,getHeight()*2/10);generalPath.quadTo(getWidth()*3/8,getHeight()*2/10,getWidth()/2-6,getHeight()*3/10);
复制代码

玫瑰心思路及实现

有了轮廓就可以实现玫瑰花的效果了,思路就两步如下:

  • 纯色填充不好看,使用射线填充,纯色(#ffffff)到红色(#ff0000)的射线渐变

  • 复制 9 个渐变好的心,按照中心点重叠起来玫瑰花的效果

PS:这个地方又是 9,看得出勇哥的用心设计了吧~

动画演示一番,希望得的点赞:



参考实现代码:


for (int i = 0; i < 9; i++) {    AffineTransform transform = g2d.getTransform();    transform.scale(0.6d, 0.6d);    transform.translate(getWidth() *0.34, getHeight()*0.34);    if(i>3) {        transform.rotate(theta % 360, getWidth() / 2, getHeight() / 2);    }    g2d.setTransform(transform);    g2d.draw(generalPath);    g2d.setColor(Color.RED);    Color[] colors = { Color.RED, Color.WHITE, Color.RED };    float[] dist = {0.13f, 0.55f, 1.0f };    Point2D center = new Point2D.Float(0.5f * getWidth(), 0.5f * getHeight()-10);
RadialGradientPaint p = new RadialGradientPaint(center, 0.5f * getWidth()*per, dist, colors); g2d.setPaint(p); g2d.fill(generalPath);}
复制代码

呼吸效果 &内部心旋转思路及实现

呼吸效果,可以通过控制射线的大小比例来控制:

  • 定义 per 变量,等于 1 时,表示上一步的渐变效果,1.4 时表示白色圆圈扩大 1.4 倍,反正缩小

  • 通过线程每 100ms 修改一下缩放比例,步长为 0.1

内部心旋转思路:

  • 定义 theta 变量,表示内部心旋转的角度

  • 通过线程每 100ms 修改一下角度值,步长为 2 度


double theta = 0;// 选择的角度float per = 1;// 镜像的大小比例boolean isAdd = true;// 镜像大小是+计算还是-计算
@Overridepublic void run() { while (true){ try { theta += 2; if (isAdd) { per += 0.1; if (per > 1.3) { isAdd = false; } } else { per -= 0.1; if (per < 0.6) { isAdd = true; } } repaint(); Thread.sleep(100); } catch (InterruptedException e) { } }}
复制代码


发布于: 2022-12-12阅读数: 20
用户头像

非喵鱼

关注

技术专业一点,才能多一点时间陪家人! 2018-11-28 加入

Java生态开发高效工具 Tinkle、Boom的作者,欢迎大家持续关注!

评论

发布
暂无评论
【圣诞节】会呼吸的玫瑰爱心代码 -李峋爱心续 动画演示思路 代码开源_Java_非喵鱼_InfoQ写作社区