年会签到小项目总结

关于技术选型

  • 首先是选择不够严谨,其次是对时间的把控不是很好,导致在接受项目以后出现了连续一周的加班现象。
  • 对个人能力有些高估。表现的形式为之前认为很熟悉的技术,在很久没有使用过的时间以后发现变得生疏。
  • 技术覆盖范围不够,钻研深度也不够,需要在下一步提升自己的技术水平和范围,更多的利用自己的琐碎时间,对各个方面的知识进行整理和完善。
  • 在开发后期和后台对接的时候出现了扯皮的现象。接下来的开发阶段都需要进行专业规范文档,如果没有,拒绝开发。杜绝扯皮的现象,从规范对接流程开始。

开发实现的时候,遇到的问题

  • 关于3d旋转,开始使用旋转的时候没有实现头像旋转的时候,用了好几中方案,感觉觉都有瑕疵,最后还是借鉴网上别人的做法得到了解决,具体思路如下
    • 首先使用一个包裹层,宽度和高度为0,绝对定位,top和left都为50%;然后直接确定了 中心点
    • 然后旋转使用一个包裹层,设置他的旋转中心点,rotateY实现立体视角,
    • 显示头像,同样是绝对定位,tranlate,超出他的包裹元素,便可以实现可见
    • 旋转,包裹曾进行逆时针旋转,照片进行顺时针旋转,解决头像显示角度的问题,transLate不会导致浏览器重绘,在我网页后台运行的时候始终在原地
    • 在进行与后台数据交互的时候为了实现网页实时刷新,get数据的时候使用了递归调用,反觉逻辑还不是很好,有很大的优化空间,签到完成显示大图的时候没有进行优化,导致浏览器过多次添加dom,这个是最差的方案,没有之一。以后一定要找一个可替代方法。
    • 动画用requestAnimationFrame

PC端签到页面

  • 思路和需
    • 以星空为背景,公司logo为中心的大转盘
    • 人员签到以后,出现在大屏幕,进入大转盘围绕着中心旋转
    • 人员签到为实时数据
    • 主要要素有3d视觉显示,签到人员大转盘,星空闪烁,星云,流星
  • 实现 动画完全用css动画animation
  • 效果代码
  • 利用canvas将图片缓存到本地demo
//1.得到一个img对象
a = document.querySelector('img')
localImg = {}; 
a.addEventListener("load", function () {
    //2.创建一个canvas对象 用来处理图片
     var imgCanvas = document.createElement("canvas");
     imgContext = imgCanvas.getContext("2d");
    //3. 确保canvas尺寸和图片一致
     imgCanvas.width = a.width;
     imgCanvas.height = a.height;
    //4. 在canvas中绘制图片
     imgContext.drawImage(a, 0, 0, a.width, a.height);

    //5. 将图片保存为Data URI
     localImg.url = imgCanvas.toDataURL("bj.png");

    localImg.date = new Date().getTime();

    //6.将JSON保存到本地存储中
  if(window.hasOwnProperty(localStorage)) {
    localStorage.setItem("gsFiles", JSON.stringify(gsFiles));
    return 
  }
  alert('骚年,你的浏览器是上个世纪的吧,不支持localStorage的,没得玩!!!')
}, false);
  • 动画定时器的思考
    • 通过setTimeout和setInterval方法来在脚本中实现动画,但是这样效果可能不够流畅,且会占用额外的资源。
    • 即使向其传递毫秒为单位的参数,它们也不能达到ms的准确性。这是因为javascript是单线程的,可能会发生阻塞。
    • 没有对调用动画的循环机制进行优化。
    • 没有考虑到绘制动画的最佳时机,只是一味地以某个大致的事件间隔来调用循环。
    • 使用setInterval或setTimeout来实现主循环,根本错误就在于它们抽象等级不符合要求。我们想让浏览器执行的是一套可以控制各种细节的api,实现如“最优帧速率”、“选择绘制下一帧的最佳时机”等功能。但是如果使用它们的话,这些具体的细节就必须由开发者自己来完成。
//requestAnimationFrame不需要使用者指定循环间隔时间,浏览器会基于当前页面是否可见、CPU的负荷情况等来自行决定最佳的帧速率,从而更合理地使用CPU。  (网上很多文献和大神都这么说,我没有具体考证,拿过来用了一下下 ,感觉还不错,五星好评啦,有心的可以自己去研究,然后告诉我结果,比当重谢)!
(function() {
        var lastTime = 0;
        var vendors = ['webkit', 'moz'];
        for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
            window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
            window.cancelAnimationFrame =
              window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
        }

        if (!window.requestAnimationFrame)
            window.requestAnimationFrame = function(callback) {
                var currTime = new Date().getTime();
                var timeToCall = Math.max(0, 16 - (currTime - lastTime));
                var id = window.setTimeout(function() { callback(currTime + timeToCall); },
                  timeToCall);
                lastTime = currTime + timeToCall;
                return id;
            };

        if (!window.cancelAnimationFrame)
            window.cancelAnimationFrame = function(id) {
                clearTimeout(id);
            };
    }());
//1.在做动画的时候替代setTimeout
//2.使用方法:  requestAnimationFrame(animate)
//3.关闭方法:  cancelAnimationFrame(animate)
function animate() {
  //do something...
}
  • 流星实现代码
//网上摘抄的代码 还没有明白原理,周六研究完再说思路:flag立于2018.01.16
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>流星</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        body{
            background: green;
        }
        .liuxing{

            position: fixed;
            top: 10%;
            left: 50%;
        }
        .stari {
            display: block;
            width: 5px;
            height: 5px;
            border-radius: 50%;
            background: #FFF;
            top: 100px;
            left: 500px;
            position: relative;
            transform-origin: 100% 0;
            animation: star-ani 4s linear infinite;
            -webkit-animation:star-ani 5s linear infinite;
            box-shadow: 0 0 5px 5px rgba(255, 255, 255, .3);
            opacity: 0;
            z-index: 2;
        }
        .stari:after {
            content: '';
            display: block;
            top: 0px;
            left: 4px;
            border: 0px solid #fff;
            border-width: 0px 90px 2px 90px;
            border-color: transparent transparent transparent rgba(255, 255, 255, .3);
            transform: rotate(-45deg) translate3d(1px, 3px, 0);
            box-shadow: 0 0 1px 0 rgba(255, 255, 255, .1);
            transform-origin: 0% 100%;
            animation: shooting-ani 3s infinite ease-out;
        }
        .liuxing .pink {
            top: 100px;
            left: 800px;
            background: #fff;
            animation-delay: 3s;
            -webkit-animation-delay: 3s;
            -moz-animation-delay: 3s;
        }
        .liuxing .pink:after {
            border-color: transparent transparent transparent #fff;
            animation-delay: 3s;
            -webkit-animation-delay: 3s;
            -moz-animation-delay: 3s;
        }
        .liuxing .blue {
            top: 120px;
            left: 1200px;
            background: fff;
            animation-delay: 7s;
            -webkit-animation-delay: 7s;
            -moz-animation-delay: 7s;
        }
        .liuxing .left{
          top: 100px;
          left: -300px;
        }
        .liuxing .blue:after {
             border-color: transparent transparent transparent fff;
            -webkit-animation-delay: 7s;
            -moz-animation-delay: 7s;
            animation-delay: 7s;
        }
        @keyframes star-ani {
            0% {
                opacity: 0;
                transform: scale(0) translate3d(0, 0, 0);
            }
            20%{
                opacity: 0.8;
                transform: scale(0.2) translate3d(-100px, 100px, 0);
            }
            40% {
                opacity: 0.8;
                transform: scale(0.4) translate3d(-200px, 200px, 0);
            }
            60% {
                opacity: 0.8;
                transform: scale(0.6) translate3d(-300px, 300px, 0);
            }
            80% {
                opacity: 1;
                transform: scale(1) translate3d(-350px, 350px, 0);
            }
            100% {
                opacity: 1;
                transform: scale(1.2) translate3d(-400px, 380px, 0);
            }
        }
    </style>
</head>
<body>
    <div class="liuxing">
        <div class="stari pink"></div>
        <div class="stari blue"></div>
        <div class="stari"></div>
        <div class="stari left"></div>
    </div>
</body>
</html>

移动端签到页面的问题和使用到的技术

  • 图片裁剪:copper.js进行首次裁剪,
  • 图片处理:自己定义图片大小,转码质量
  • 图片裁剪为圆形的问题
  • 图片上传 —–> <input type="file"> 读取文件的时候,在安卓手机无法读取到文件路径,监听不到监听不到input Value change 事件。
  • 找到了移动端显示控制台的插件,保存以后期调用
  • https://github.com/Tencent/vConsole/blob/dev/doc/tutorial_CN.md
1.预览图片
//fileInput  选择文件的input
 //预览图片
fileInput.addEventListener('change', function () {
                file = fileInput.files[0]; //拿到文件
                //使用FileReader对象读取
                 var reader = new FileReader();
                 //监听load时间 得到result
                 reader.addEventListener('load', function () {
                        // console.log('reader', reader.result)
                        //假设你选择的是图片的话这里解析出来的就是URL,
                        img1[0].src = reader.result; //这里完成预览
                        //这边是初始化corpperjs(图片裁剪插件)
                        img1.cropper('destroy');
                        img1.cropper({
                                aspectRatio: 1 / 1,//裁剪框比例 1:1  
                                viewMode : 1,//显示  
                                guides :false,//裁剪框虚线 默认true有  
                                dragMode : "move",  
                                build: function (e) { //加载开始  
                                    //可以放你的过渡 效果  
                                },  
                                built: function (e) { //加载完成  
                                    // $("#containerDiv").show();  
                                    // $("#imgEdit").show();  
                                },  
                                zoom: function (e) {  
                                  console.log(e.type, e.detail);  
                                },  
                                background : true,// 容器是否显示网格背景  
                                movable : true,//是否能移动图片  
                                // cropBoxMovable :false,//是否允许拖动裁剪框  
                                cropBoxResizable :false,//是否允许拖动 改变裁剪框大小
                                crop: function (e) {
                                    // console.log(e);
                                }
                            });
                        //不想存在多选,直接清空input的值
                        file = null;
                        fileInput.value = '';
                        img1.cropper('setCropBoxData',{width: imgW, height: imgW});
                    }, false)
                //使用这个方法读取文件
                reader.readAsDataURL(file)
             }, false)
2.图片裁剪和压缩
//新建图片对象 canvas对象用来渲染图片
var tempImg = new Image(),
tempimg2 = new Image(),
// canvas = document.querySelector('#canvas'),
canvas = document.createElement('canvas'),
context = canvas.getContext("2d"),
w = 356,
canvas2 = document.createElement('canvas'),
context2 = canvas2.getContext("2d");


//w代表需要处理的图片的width ,因为我处理的图片是正方形,所以没有height,
context.fillStyle="rgba(255, 255, 255, 0)";
canvas.width = w
canvas.height = w
canvas2.width = w
canvas2.height = w
tempImg.src = 'img-url';//这里是一个URL


tempimg2.onload = function () {
    //第一次渲染 这里处理图片的尺寸问题
    //context2.drawImage(img,x , y,img.width, img.height, img.offsetX, img.offsetY, targetWidth, targetHeight);
    var width = this.width;
    context2.drawImage(this,0 , 0,width, width, 0, 0, w, w);
    //将图片转为base64编码 ,传入两个参数,第一个是需要转换的格式(png | jpg),第二个是处理的质量0-1;
    //var base64url2 = canvas2.toDataURL('image/png', 0.7);
    var base64url2 = canvas2.toDataURL('image/png', 0.7);
    //拿到处理宽高的照片之后,进行圆角处理
    tempImg.src = base64url2;
    // console.log(base64url2)
    tempImg.onload = function () {
        // 创建图片纹理
        var pattern = context.createPattern(tempImg, "no-repeat");
        // 绘制一个圆
        context.arc(w/2, w/2, w/2, 0, 2 * Math.PI);
        // 填充绘制的圆
        context.fillStyle = pattern;
        context.fill(); 
        var tempBase64Url3 = canvas.toDataURL('image/png', 0.7);

    }
}

猜你喜欢

转载自blog.csdn.net/weixin_33768153/article/details/79071493
今日推荐