基于JavaScript实现年份数字拼图效果

 更新时间:2022年12月30日 09:57:56   作者:青天诀  
时光荏苒,2022年又要收尾了,公司的年会是不是都安排上了?前几天看到一个年会抽奖系统,功能十分的强大,其中有一个年份数字的拼图效果深深的吸引了哥,决定用JS实现一下该效果,需要的可以参考一下

背景

时光荏苒,2022年又要收尾了,公司的年会是不是都安排上了?(顺便问一嘴,您阳了吗?)

前几天看到一个年会抽奖系统,功能十分的强大,其中有一个年份数字的拼图效果深深的吸引了哥,决定深入探索一番。先看下具体的效果,图中有个2022的年份数字。

实现原理

从效果能看出,实际就是将相应卡片设置为高亮颜色拼成数字,实现原理大致是:

  • 设计好数字(0-9)在横向和纵向占据的卡片列数和行数,比如上图中的横向为3列,纵向为5行;
  • 针对每个数字(0-9)的形状,获取亮色卡片位置的坐标,从而得到每个数字的形状坐标数组;
  • 根据每个数字的形状坐标、要展示数字的顺序计算出具体的位置,将对应坐标卡片设置为亮色就可以了;

具体实现

1. 创建背景卡片

拼图展示的数字是当前的年份(2022),也就是4位数字。根据数字在横行占3列,纵向占5行,数字前后间隔1列,为了美观数字区域上下左右边界要空出一行或者一列。所以整个背景卡片的列数和行数就有了:

行数 = 5 + 1 + 1 = 7;

列数 = 3 * 4 + 3(间隔) + 1 + 1 = 17;

const rowCount = 7;
const colCount = 17;
// 创建卡片
const createCard = () => {
  const frag = document.createDocumentFragment();
  for (let i = 0; i < rowCount; i++) {
    for (let j = 0; j < colCount; j++) {
      const item = document.createElement('div');
      item.className = "item";
      frag.appendChild(item);
    }

  }
  document.querySelector('.container').appendChild(frag);
}

2. 设置数字形状坐标

这个其实就是根据每个数字的形状,记录下形状路径上的每个点的坐标。规则是从上到下,从左到右,找到所有路径上的点。0-9的形状坐标数组如代码所示,可以比照着上文中的图片,确认下数字的形状坐标。

注意:如果想设计其他的数字字体展示形式,可以根据具体形状收集路径点坐标。

// 0-9数字的坐标形状
const NUMBER_MATRIX = [
  [
    // 0
    [0, 0],
    [1, 0],
    [2, 0],
    [0, 1],
    [2, 1],
    [0, 2],
    [2, 2],
    [0, 3],
    [2, 3],
    [0, 4],
    [1, 4],
    [2, 4]
  ],
  [
    // 1
    [1, 0],
    [0, 1],
    [1, 1],
    [1, 2],
    [1, 3],
    [0, 4],
    [1, 4],
    [2, 4]
  ],
  [
    // 2
    [0, 0],
    [1, 0],
    [2, 0],
    [2, 1],
    [0, 2],
    [1, 2],
    [2, 2],
    [0, 3],
    [0, 4],
    [1, 4],
    [2, 4]
  ],
  [
    // 3
    [0, 0],
    [1, 0],
    [2, 0],
    [2, 1],
    [0, 2],
    [1, 2],
    [2, 2],
    [2, 3],
    [0, 4],
    [1, 4],
    [2, 4]
  ],
  [
    // 4
    [0, 0],
    [2, 0],
    [0, 1],
    [2, 1],
    [0, 2],
    [1, 2],
    [2, 2],
    [2, 3],
    [2, 4]
  ],
  [
    // 5
    [0, 0],
    [1, 0],
    [2, 0],
    [0, 1],
    [0, 2],
    [1, 2],
    [2, 2],
    [2, 3],
    [0, 4],
    [1, 4],
    [2, 4]
  ],
  [
    // 6
    [0, 0],
    [1, 0],
    [2, 0],
    [0, 1],
    [0, 2],
    [1, 2],
    [2, 2],
    [0, 3],
    [2, 3],
    [0, 4],
    [1, 4],
    [2, 4]
  ],
  [
    // 7
    [0, 0],
    [1, 0],
    [2, 0],
    [2, 1],
    [2, 2],
    [2, 3],
    [2, 4]
  ],
  [
    // 8
    [0, 0],
    [1, 0],
    [2, 0],
    [0, 1],
    [2, 1],
    [0, 2],
    [1, 2],
    [2, 2],
    [0, 3],
    [2, 3],
    [0, 4],
    [1, 4],
    [2, 4]
  ],
  [
    // 9
    [0, 0],
    [1, 0],
    [2, 0],
    [0, 1],
    [2, 1],
    [0, 2],
    [1, 2],
    [2, 2],
    [2, 3],
    [0, 4],
    [1, 4],
    [2, 4]
  ]
];

3. 数字拼图

第二步中,给出的数字形状坐标实际是单个数字展示时的坐标,如果多个数字并排展示,需要对每个数字的坐标进行换算,换算规则主要有2条

  • 因为数字是横向排列的,所以每增加一个数字,x坐标都要增加4列(包含一列数字间隔)
  • 由于数字展示区域周边上下左右都空了一行或者一列,所以x坐标和y坐标的开始位置,都是从(1,1)开始的。
// 根据数字形状、当前年份等信息,筛选出需要设置为亮色的卡片位置
const getHighlight = () => {
  // 获取当前年份
  let year = new Date().getFullYear() + "";
  let step = 4,
    xoffset = 1,
    yoffset = 1,
    highlight = [];

  year.split('').forEach(n => {
    highlight = highlight.concat(
      NUMBER_MATRIX[n].map(item => {
        return `${item[0] + xoffset}-${item[1] + yoffset}`;
      })
    );
    xoffset += step;
  });

  return highlight;
}

最后highlight返回的其实就是点坐标字符串的数组,类似['1-1', '2-1']这种。

然后就可以根据返回的点坐标数组进行绘制拼图,其实就是将对应坐标的卡片添加高亮的样式类名

const createHighLight = async (cards, hightLight) => {
  for (let i = 0; i < hightLight.length; i++) {
    const [col, row] = hightLight[i].split('-');
    const index = Math.floor(row) * colCount + Math.floor(col);
    cards[index].className = 'item highlight'
  }
}

最终实现效果如下图所示:

延伸

上文中只是实现了静态数字的拼图展示效果,如果能够让数字动起来呢?比如实现一个写字效果、或者倒计时变动数字效果,这些会让拼图更加的酷炫。我们下面实现一个写字效果

其实,原理很简单,只需要在绘制数字拼图卡片时,将每个坐标点的绘制,改成异步串行绘制就行了

const createHighLight = async (cards, hightLight) => {
  for (let i = 0; i < hightLight.length; i++) {
    await new Promise((resolve, reject) => setTimeout(resolve, 100));
    const [col, row] = hightLight[i].split('-');
    const index = Math.floor(row) * colCount + Math.floor(col);
    cards[index].className = 'item highlight'
  }
  // 绘制结束后,循环绘制
  await new Promise((resolve, reject) => setTimeout(resolve, 100));
  drawData(); 
}

具体实现效果如下所示:

注意:数字的绘制效果可能和我们正常的书写笔画顺序不一致,这是因为坐标点是按照从上到下,从左到右的顺序收集的,其实可以调整坐标点顺序,让它符合书写笔画的顺序,就可以看到正常的书写效果了,自己尝试吧哈

总结

本文主要分析了数字拼图效果的实现原理,实现核心就是要先确定每个数字的形状坐标,然后根据形状坐标去绘制高亮卡片。最后在静态数字拼图效果的基础之上,借助异步串行,实现了手写字的效果,其他效果可以自己在此基础上自己尝试。

以上就是基于JavaScript实现年份数字拼图效果的详细内容,更多关于JavaScript年份数字拼图的资料请关注脚本之家其它相关文章!

相关文章

  • 简单实现js进度条加载效果

    简单实现js进度条加载效果

    这篇文章主要为大家详细介绍了如何简单实现js进度条加载效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • js内置对象处理_打印学生成绩单的简单实现

    js内置对象处理_打印学生成绩单的简单实现

    下面小编就为大家带来一篇js内置对象处理_打印学生成绩单的简单实现。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • javascript实现仿银行密码输入框效果的代码

    javascript实现仿银行密码输入框效果的代码

    这篇文章通过实例代码给大家介绍了javascript实现仿银行密码输入框效果,代码简单易懂,非常不错,具有一定的参考借鉴价值,需要的朋友参考下吧
    2007-12-12
  • JavaScript实现翻页功能(附效果图)

    JavaScript实现翻页功能(附效果图)

    这篇文章主要介绍了JavaScript实现翻页功能(附效果图),在项目需求中经常遇到,今天小编抽时间给大家分享JavaScript实现翻页功能实例代码,需要的朋友参考下吧
    2017-02-02
  • PixiJS学习之如何实现文字的绘制

    PixiJS学习之如何实现文字的绘制

    PixiJS是一个开源的基于web的渲染系统,为游戏、数据可视化和其他图形密集型项目提供了极快的性能。这篇文章主要带大家学习一下PixiJS是如何实现文字绘制的,希望对大家有所帮助
    2023-02-02
  • js Proxy的原理详解

    js Proxy的原理详解

    Proxy用于修改某些操作的默认行为,在目标对象前架设一个“拦截”层,外界对该对象的访问都必须先通过这一层拦截,因此提供了一种机制可以对外界的访问进行过滤和改写。本文就讲讲Proxy的使用
    2021-05-05
  • 详解JavaScript中Hash Map映射结构的实现

    详解JavaScript中Hash Map映射结构的实现

    Hash Map通常在JavaScript中作为一个简单的来存储键值对的地方,不过哈希对象Object并不是一个真正的哈希映射,没Java中的Hash Map来的那么强大,well,接下来带大家详解JavaScript中Hash Map映射结构的实现
    2016-05-05
  • TypeScript中的交叉类型和联合类型示例讲解

    TypeScript中的交叉类型和联合类型示例讲解

    交叉类型简单来说就是通过&符号将多个类型进行合并成一个类型,然后用type来声明新生成的类型,联合类型和交叉类型比较相似,联合类型通过|符号连接多个类型从而生成新的类型,本文就这两个类型结合示例代码详细讲解,感兴趣的朋友跟随小编一起学习吧
    2022-12-12
  • JS中append字符串包含onclick无效传递参数失败的解决方案

    JS中append字符串包含onclick无效传递参数失败的解决方案

    这篇文章主要介绍了JS中append字符串包含onclick无效传递参数失败的解决方案,需要的朋友可以参考下
    2016-12-12
  • js showModalDialog 弹出对话框的简单实例(子窗体)

    js showModalDialog 弹出对话框的简单实例(子窗体)

    本篇文章主要是对js_showModalDialog弹出对话框的简单实例(子窗体) 进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2014-01-01

最新评论