• three.js 制作属于自己的动态二维码


    今天郭先生说一下用canvas解析图片流,然后制作一个动态二维码的小案例,话不多说先上图,在线案例点击博客原文。这是郭先生的微信二维码哦!

    1. 解析图片流

    canvas = document.createElement('canvas');//创建canvas画布
    content = canvas.getContext('2d');//获取画布的上下文
    canvas.width = 310;//设置尺寸
    canvas.height = 310;
    img = new Image();//创建一张图片
    img.src = require("../assets/images/base/wechat.png");//设置图片地址
    img.onload = () => {
            //在图片加载后
        content.drawImage(img, 0, 0, canvas.width, canvas.height);//将图片添加到画布,并设置宽高
        imgData = content.getImageData(0, 0, canvas.width, canvas.height).data;//获取画布数据
    };

    imgData是什么样的呢?如下图

    这是一个Uint8ClampedArray的类型化数组,这个数组出现最多的也是在imgData上。它会将负数归入0,大于255的数归入255,所以取模就不用了。我们再来看这个数组的长度是384400是怎么来的呢?因为我们设置了画布长宽为310,而imgData四位代表一个rgba像素点,也就是imgData[0]是红色通道,imgData[1]是绿色通道,imgData[2]是蓝色通道,imgData[3]是透明通道…依次循环,所以310 * 310 * 4 = 384400。

    2. 处理像素点,画出二维码

    for (var i = 0; i < 31 * 31; i++) {
            //random_position为各个小平面块打乱时的位置信息,我设置小平面一共有31 * 31个
        random_position.push([Math.floor(Math.random() * 300 - 150), Math.floor(Math.random() * 300 - 150), Math.floor(Math.random() * 300 - 150)])
    }
    var color = new Array(310).fill('').map(d => []);//color设置成310个数组
    for (var i = 0; i < 310; i++) {
        for (var j = 0; j < 310; j++) {
            let clr = imgData[(i * 310 + j) * 4] + imgData[(i * 310 + j) * 4 + 1] + imgData[(i * 310 + j) * 4 + 2];
            clr = clr > 382 ? 'light' : 'black'; //因为颜色是有深色块和浅色块组成,他们的分界就是rgb通道颜色值之和小于等于127+127+127之和。
            color[i].push(clr)//每个数组有310项,每项的值为'light'或者'black'
        }
    }
    var color1 = [];//设置color1为小平面颜色数组31 * 31。
    color.filter((d, i) => (i + 6) % 10 == 0).forEach((dd, ii) => color1[ii] = dd.filter((d, i) => (i + 6) % 10 == 0));//每10个像素,筛选出1个像素作为小平面的颜色,选取的位置尽量在10个的中间选择,毕竟有的图片比较模糊。
    for (var i = 0; i < color1.length; i++) {//31 * 31的循环
        for (var j = 0; j < color1[i].length; j++) {
            var geometry = new THREE.PlaneGeometry(10, 10);
            var material = new THREE.MeshBasicMaterial({
                color: 0xffffff,
                side: THREE.DoubleSide,
                transparent: true,
                opacity: color1[i][j] == 'black' ? 0 : 1,
            });
            var mesh = new THREE.Mesh(geometry, material);//小方块网格
            origin_position.push([j * 10 - 15 * 10, 15 * 10 - i * 10, 0]);//保存序列换后小方块的位置
            mesh.position.set(random_position[j + i * j][0], random_position[j + i * j][1], random_position[j + i * j][2]);//先将小方块的位置设置成打乱的位置,便于动画播放。
            mesh.name = 'plane';
            group.add(mesh);//将所有小平面放到数组,便于操作。
        }
    }
    scene.add(group);

    这部分代码主要是计算部分,没什么技术含量。

    3. 实现tween动画

    var pos = { time: 0 };
    tween1 = new TWEEN.Tween(pos).to({ time: 1 }, 3000);
    tween2 = new TWEEN.Tween(pos).to({ time: 0 }, 3000);
    tween1.easing(TWEEN.Easing.Quadratic.In);
    tween2.easing(TWEEN.Easing.Quadratic.Out);
    tween1.onUpdate(onUpdate);
    tween2.onUpdate(onUpdate);
    tween1.start();
    
    function onUpdate() {
        let time = this._object.time;
        group.children.forEach((d, i) => {
            d.position.set(time * origin_position[i][0] + (1 - time) * random_position[i][0], time * origin_position[i][1] + (1 - time) * random_position[i][1], (1 - time) * random_position[i][2]);
        })
    }

    这部分只是用了tween的基础功能,请自行查看tween文档。

    转载请注明地址:郭先生的博客

  • 相关阅读:
    Spring spEL
    Spring 使用外部部署文件
    Spring 自动装配
    spring 属性配置细节
    hdu 1054 Strategic Game
    fzu 2037 Maximum Value Problem
    将博客搬至CSDN
    HDU 4714 Tree2Cycle
    HDU 1009 The Shortest Path in Nya Graph
    POJ 1942 Paths on a Grid 组合数的优化
  • 原文地址:https://www.cnblogs.com/vadim-web/p/13335081.html
Copyright © 2020-2023  润新知