程序猿的情人节是这样开启的

转眼间,情人节马上就要到了,作为程序猿的我们有属于自己的浪漫,跟随本文让我们一起看看程序猿的情人节是如何开启的,下面我们就开始程序猿的土味情人节吧。

情人节,属于彼此相爱的人的节日,爱是永恒的话题,所以得有爱心,对于程序而言,爱心对应的是一堆公式,比如:

r = a * (1-sinθ)

这个公式的函数图像是心形线,又被称为“笛卡尔的爱情坐标公式”,在这个公式的背后还有一个凄美的爱情故事:

笛卡尔成为了公主的数学老师。公主的数学在笛卡尔的悉心指导下突飞猛进,他们之间也开始变得亲密起来,每天的形影不离也使他们彼此产生了爱慕之心,一段纯粹、美好的爱情悄然萌发。然而,没过多久,他们的恋情传到了国王的耳朵里,国王大怒,下令马上将笛卡尔处死。在克里斯汀的苦苦哀求下,国王将他放逐回国,公主被软禁在宫中。

身体孱弱的笛卡尔回到法国后不久,便染上重病。在生命进入倒计时的那段日子,他日夜思念公主,每天坚持给她写信,盼望着她的回音。在笛卡尔给克里斯汀寄出第十三封信后,他永远地离开了这个世界,这最后的一封信上没有写一句话,只有一个方程式:r=a(1-sinθ),这条曲线就是著名的“心形线”。

但是这里我们准备选用另外一个爱心公式:

x = 16 * Math.pow(Math.sin(t), 3); y = 13 * Math.cos(t) - 5 * Math.cos(2 * t) - 2 * Math.cos(3 * t) - Math.cos(4 * t);

使用方式如下:

function getPoints(scale = 1) {
    const points = [];
    for (let t = 0; t < 2 * Math.PI; t += 0.01) {
        const x = scale * 16 * Math.pow(Math.sin(t), 3);
        const y = scale * 13 * (Math.cos(t) - 5 * Math.cos(2 * t) - 2 * Math.cos(3 * t) - Math.cos(4 * t));
        points.push({ x, y });
    }
    return points;
}

接下来,情人节得有花吧,虽然玫瑰更佳,这里我们准备了各种花,然后再辅以一定的动画,就得到了以下的效果:

在实际绘制的时候我们将爱心做了翻转和放大:

// 根据爱心公式获取点集合
const points = getPoints(20);

// 移动到中心点
ctx.translate(canvasWidth / 2, canvasHeight / 2);

// 动画绘制花朵
drawHeartWithFlower();

function getPoints(scale = 1) {
    const points = [];
    for (var i = 10; i < 30; i += 0.2) {
      const t = i / Math.PI;
        const x = scale * 16 * Math.pow(Math.sin(t), 3);
        const y = -scale * (13 * Math.cos(t) - 5 * Math.cos(2 * t) - 2 * Math.cos(3 * t) - Math.cos(4 * t));
        points.push({ x, y });
    }
    return points;
}

function loadImage(src) {
    return new Promise(function(resolve, reject) {
      var img = new Image();
      img.src = src;
      img.onload = function() {
        resolve(this);
      }
      img.onerror = function() {
        reject();
      }
    });
}

function drawPointImage(point, img, width) {
    var width = width || img.width;
    var height = img.height / (img.width / width);
    ctx.drawImage(img, point.x, point.y, width, height);
}

function getFlower() {
  return `img/${Math.floor(Math.random() * flowerPicLength)}.png`;
}

function drawHeartWithFlower(cb) {
  const point = points.shift();
  if (point) {
    const flower = getFlower();
    loadImage(flower)
      .then(img => {
        drawPointImage(point, img, 50);
        requestAnimationFrame(drawHeartWithFlower.bind(undefined, cb));
      });
  } else {
    if (typeof cb === 'function') {
      cb();
    }
  }
}

然后,情人节得一起回忆一些重要的纪念日吧,比如我们在一起多少天啦,我们结婚多少天啦之类的,让我们用程序来将这些日子展现出来吧。

这里涉及到了纪念日和纪念的事情,我们分别将其定义成两个变量:

const memoryTime = new Date('2016-08-09 14:56:00');
const memoryEvent = '结婚';

然后计算当前时间和纪念日之间的时间差, 代码如下:

function getTimeDiff(oldDate, newDate) {
  const subTime = (newDate.getTime() - oldDate.getTime()) / 1000;
  const days = parseInt(subTime / 86400);
  const hours = parseInt(subTime / 3600) - 24 * days;
  const mins = parseInt(subTime % 3600 / 60);
  const secs = parseInt(subTime % 60);
  return `<span>${days}</span>天<span>${hours}</span>小时<span>${mins}</span>分钟<span>${secs}</span>秒`;
}

function setDiffText() {
  const diffStr = getTimeDiff(memoryTime, new Date());
  $time.innerHTML = diffStr;
}

function realTimeDiff() {
  setDiffText();
  requestAnimationFrame(realTimeDiff);
}

最终的效果:

好了,本文到此就结束了,本文的案例肯定还是有很多不完善的地方,大家可以根据自己喜好去完善,然后送给你心目中的TA。

最后,提前预祝大家情人节快乐,Happy Valentine's Day!!!

后记:在大部分人的印象里,程序猿就是戴着眼镜儿,坐在电脑前,敲着代码,沉默寡言,不善交际,但是我们并不是不懂爱,不懂浪漫,我们有自己表达爱和浪漫的方式,我们值得被爱,请善待你身边做程序的TA。

在线demo:https://demo.deanhan.cn/valentine/

如需下载本文源码及素材包,请在关注本站公众号后发送:valentine

  • 支付宝二维码 支付宝
  • 微信二维码 微信

本文地址: /valentine.html

版权声明: 本文为原创文章,版权归 逐梦个人博客 所有,欢迎分享本文,转载请保留出处!

相关文章