Coder Social home page Coder Social logo

arts's Introduction

GitHub WidgetBox

  • 🔭 I’m currently working on sina weibo

  • 🌱 一名前端开发工程师 📍 北京

  • 📫 How to reach me [email protected]

📫 个人小站

callmejesus

🚀 技能,及在学

My Skills

rainbow gif

Code Time

I'm a Night 🦉

🌞 Morning                289 commits         ██░░░░░░░░░░░░░░░░░░░░░░░   08.49 % 
🌆 Daytime                1149 commits        ████████░░░░░░░░░░░░░░░░░   33.73 % 
🌃 Evening                1680 commits        ████████████░░░░░░░░░░░░░   49.32 % 
🌙 Night                  288 commits         ██░░░░░░░░░░░░░░░░░░░░░░░   08.46 % 

I Mostly Code in JavaScript

JavaScript               18 repos            █████████░░░░░░░░░░░░░░░░   36.73 % 
Vue                      11 repos            ██████░░░░░░░░░░░░░░░░░░░   22.45 % 
TypeScript               6 repos             ███░░░░░░░░░░░░░░░░░░░░░░   12.24 % 
CSS                      5 repos             ███░░░░░░░░░░░░░░░░░░░░░░   10.20 % 
Shell                    2 repos             █░░░░░░░░░░░░░░░░░░░░░░░░   04.08 % 

Last Updated on 07/05/2024 06:14:00 UTC

⚡ 最近

  1. ⬆️ Pushed 1 commit(s) to unbrain/unbrain
  2. ⬆️ Pushed 1 commit(s) to unbrain/unbrain
  3. ⬆️ Pushed 1 commit(s) to unbrain/unbrain
  4. ⬆️ Pushed 1 commit(s) to unbrain/unbrain
  5. ⬆️ Pushed 1 commit(s) to unbrain/unbrain

Last Updated: Tuesday, May 7th, 2024, 6:24:42 AM

arts's People

Contributors

unbrain avatar

arts's Issues

# js 获取 md5

js 获取 md5

一般情况下前端是没有必要获取 md5 的。但是当需要上传文件的时候,此时 md5 的校验作用是不可或缺的了。所以在前端拿到 md5 以及文件分片的 md5 非常有必要。

我是根据库 js-spark-md5 来进行操作的。

基于 FileReader, 我们看下 can i use/FileReader, 其对于浏览器的兼容性还是很好的。

export function getChunksMd5(file, cs) {
  return new Promise((resolve, reject) => {
    if (!SparkMD5) {
      reject();
      return;
    }

    var mySingleFileMd5 = []; //用于储存所有切片的MD5
    function getChunkMd5(file, i) {
      var spark = new SparkMD5.ArrayBuffer();
      var fileReader = new FileReader();
      fileReader.onload = function(e) {
        spark.append(e.target.result);
        mySingleFileMd5[i] = spark.end(); // 将每个切片的MD5存起来
      };
      fileReader.onerror = function() {
        console.warn('oops, something went wrong');
      };
      function loadNext() {
        fileReader.readAsArrayBuffer(blobSlice.call(file, 0, file.size));
      }
      loadNext();
    }

    var singleFileData = []; //初始空数组,储存所有的切片数据
    var fileReader = new FileReader(),
      blobSlice = File.prototype.mozSlice || File.prototype.webkitSlice || File.prototype.slice,
      chunkSize = cs ? cs : 2097152, //单个切片的总字节数
      chunks = Math.ceil(file.size / chunkSize), //总片数
      currentChunk = 0;
    var spark = new SparkMD5.ArrayBuffer();
    fileReader.onload = function(e) {
      //*******获取分片文件,用于计算所有切片的MD5***
      for (var i = 0; i < chunks; i++) {
        var start = i * chunkSize,
          end = start + chunkSize >= file.size ? file.size : start + chunkSize;
        var sliceFile = blobSlice.call(file, start, end);
        // 调用此方法,计算每个切片的MD5
        getChunkMd5(sliceFile, i);
      }
      //*****************************
      spark.append(e.target.result);
      if (currentChunk < chunks) {
        currentChunk++;
        loadNext();
      } else {
        console.log(mySingleFileMd5);
        var allFileEnd = spark.end();
        resolve([allFileEnd, mySingleFileMd5]);
        //真实MD5值 :allFileEnd=a0ce27800ee7d948422f3fe16e898f22
        // ***调用接口(1),查询从第几个切片开始上传***
        // ***在此处写接口A的调用方法***
      }
    };
    function loadNext() {
      //计算切片的start,end,用于切割出切片的数据
      var start = currentChunk * chunkSize,
        end = start + chunkSize >= file.size ? file.size : start + chunkSize;
      fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
      //储存切片的数据
      //判断如果singleFileData小于总切片数,则继续往数组添加切片数据
      if (singleFileData.length != chunks) {
        singleFileData.push(blobSlice.call(file, start, end)); //将每个切片push到空数组里
      }
    }
    //调用此方法,循环获取切片数据
    loadNext();
  });
}

一个简易的 vue 进度条组件

<template>
  <div
    class="progress-wrap"
    ref="progressWrap"
    @mousedown="dragProcess($event)"
  >
    <div
      class="progress"
      :style="progressStyle"
    >
      <div
        class="current-progress"
        :style="progress"
      >
        <div
          :style="ballStyle"
          class="ball"
        ></div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    progressOptions: {
      type: Object,
      required: true,
      default: {
        height: 100, borderRadius: 2, vertical: true, width: 4
      }
    },
    percent: {
      type: [String, Number],
      required: false,
      default: 0,
    }
  },
  data() {
    return {
      clientReact: {},
      modifyNum: 0,
      isDragProcess: false,
    }
  },
  mounted() {
    this.handleEvent();
  },
  methods: {
    dragProcess(e) {
      let currentNum
      if (this.progressOptions.vertical) {
        currentNum = this.$refs.progressWrap.getClientRects()[0].bottom - e.clientY;
        currentNum = currentNum > 0
          ? currentNum > this.$refs.progressWrap.clientHeight
            ? this.$refs.progressWrap.clientHeight
            : currentNum
          : 0;
        this.modifyNum = currentNum / this.$refs.progressWrap.clientHeight;
      } else {
        currentNum = e.screenX - this.$refs.progressWrap.getClientRects()[0].x;
        currentNum = currentNum > 0
          ? currentNum > this.$refs.progressWrap.clientWidth
            ? this.$refs.progressWrap.clientWidth
            : currentNum
          : 0;
        this.modifyNum = currentNum / this.$refs.progressWrap.clientWidth;
      }
      this.isDragProcess = true;
      this.$emit('drag', this.modifyNum)
    },
    handleEvent() {
      document.addEventListener('mouseup', () => { this.isDragProcess = false });
    },
  },
  computed: {
    ballStyle() {
      let styleObj = {
        width: `${this.progressOptions.height * 2}px`,
        height: `${this.progressOptions.height * 2}px`,
        right: `-${this.progressOptions.height}px`,
        top: `-${this.progressOptions.height / 2}px`,
      };
      if (this.progressOptions.vertical) {
        console.log(this.progressOptions.width);
        styleObj = {
          width: `${this.progressOptions.width * 2}px`,
          height: `${this.progressOptions.width * 2}px`,
          right: `-${this.progressOptions.width / 2}px`,
          top: `-${this.progressOptions.width / 2}px`,
        };
      }
      return styleObj;
    },
    progress() {
      console.log(this.progressOptions, this.percent);
      if (this.percent && this.progressOptions.vertical) {
        return {
          width: `4px`,
          height: `${this.percent * 100}%`
        };
      } else if (this.percent) {
        return {
          width: `${Number(this.percent) * 100}%`
        };
      } else {
        return 0;
      }
    },
    progressStyle() {
      let styleObj = {
        width: `${this.progressOptions.width}px`,
        height: `${this.progressOptions.height}px`,
        borderRadius: `${this.progressOptions.borderRadius}px`
      }
      if (this.progressOptions.vertical) {
        styleObj['justify-content'] = `center`;
        styleObj['align-items'] = `flex-end`;
      }
      return styleObj;
    }
  },
  watch: {
    isDragProcess(v) {
      if (v === true) {
        document.addEventListener('mousemove', this.dragProcess)
      } else if (v === false) {
        document.removeEventListener('mousemove', this.dragProcess)
      }
    }
  }
}
</script>

<style lang="less">
  .progress-wrap {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    cursor: pointer;
    background-color: rgba(13, 44, 138, 0.4);
    .progress {
      display: flex;
      flex-grow: 1;
      background: rgba(200, 200, 200, 0.3);
      .current-progress{
        position: relative;
        background: #ff9900;
        border-radius: inherit;
        .ball {
          position: absolute;
          border-radius: 50%;
          background: #ff9900;
          opacity: 0;
        }
      }
      &:hover {
        .ball {
          opacity: 1;
          transition: 0.3s;
        }
      }
    }
  }
</style>

TODO: 将更多可定制的属性进行抽离

windows terminal 预览版 profiles

{
"globals" :
{
"alwaysShowTabs" : true,
"defaultProfile" : "{58ad8b0c-3ef8-5f4d-bc6f-13e4c00f2530}",
"initialCols" : 120,
"initialRows" : 30,
"keybindings" :
[
{
"command" : "closeTab",
"keys" :
[
"ctrl+w"
]
},
{
"command" : "newTab",
"keys" :
[
"ctrl+t"
]
},
{
"command" : "newTabProfile0",
"keys" :
[
"ctrl+shift+1"
]
},
{
"command" : "newTabProfile1",
"keys" :
[
"ctrl+shift+2"
]
},
{
"command" : "newTabProfile2",
"keys" :
[
"ctrl+shift+3"
]
},
{
"command" : "newTabProfile3",
"keys" :
[
"ctrl+shift+4"
]
},
{
"command" : "newTabProfile4",
"keys" :
[
"ctrl+shift+5"
]
},
{
"command" : "newTabProfile5",
"keys" :
[
"ctrl+shift+6"
]
},
{
"command" : "newTabProfile6",
"keys" :
[
"ctrl+shift+7"
]
},
{
"command" : "newTabProfile7",
"keys" :
[
"ctrl+shift+8"
]
},
{
"command" : "newTabProfile8",
"keys" :
[
"ctrl+shift+9"
]
},
{
"command" : "nextTab",
"keys" :
[
"ctrl+tab"
]
},
{
"command" : "openSettings",
"keys" :
[
"ctrl+,"
]
},
{
"command" : "prevTab",
"keys" :
[
"ctrl+shift+tab"
]
},
{
"command" : "scrollDown",
"keys" :
[
"ctrl+shift+down"
]
},
{
"command" : "scrollDownPage",
"keys" :
[
"ctrl+shift+pgdn"
]
},
{
"command" : "scrollUp",
"keys" :
[
"ctrl+shift+up"
]
},
{
"command" : "scrollUpPage",
"keys" :
[
"ctrl+shift+pgup"
]
},
{
"command" : "switchToTab0",
"keys" :
[
"alt+1"
]
},
{
"command" : "switchToTab1",
"keys" :
[
"alt+2"
]
},
{
"command" : "switchToTab2",
"keys" :
[
"alt+3"
]
},
{
"command" : "switchToTab3",
"keys" :
[
"alt+4"
]
},
{
"command" : "switchToTab4",
"keys" :
[
"alt+5"
]
},
{
"command" : "switchToTab5",
"keys" :
[
"alt+6"
]
},
{
"command" : "switchToTab6",
"keys" :
[
"alt+7"
]
},
{
"command" : "switchToTab7",
"keys" :
[
"alt+8"
]
},
{
"command" : "switchToTab8",
"keys" :
[
"alt+9"
]
}
],
"requestedTheme" : "dark",
"showTabsInTitlebar" : true,
"showTerminalTitleInTitlebar" : true
},
"profiles" :
[
{
"acrylicOpacity" : 0.5,
"closeOnExit" : true,
"colorScheme" : "Solarized Dark",
"commandline" : "wsl.exe -d Debian",
"cursorColor" : "#FF8889",
"cursorShape" : "filledBox",
"fontFace" : "Fira Code",
"fontSize" : 12,
"guid" : "{58ad8b0c-3ef8-5f4d-bc6f-13e4c00f2530}",
"historySize" : 9001,
"icon" : "ms-appx:///ProfileIcons/{9acb9455-ca41-5af7-950f-6bca1bc9722f}.png",
"name" : "Debian",
"padding" : "0, 0, 0, 0",
"snapOnInput" : true,
"useAcrylic" : false
},
{
"acrylicOpacity" : 0.5,
"background" : "#012456",
"closeOnExit" : true,
"colorScheme" : "Campbell",
"commandline" : "powershell.exe",
"cursorColor" : "#FFFFFF",
"cursorShape" : "bar",
"fontFace" : "Consolas",
"fontSize" : 10,
"guid" : "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"historySize" : 9001,
"icon" : "ms-appx:///ProfileIcons/{61c54bbd-c2c6-5271-96e7-009a87ff44bf}.png",
"name" : "Windows PowerShell",
"padding" : "0, 0, 0, 0",
"snapOnInput" : true,
"startingDirectory" : "%USERPROFILE%",
"useAcrylic" : false
},
{
"acrylicOpacity" : 0.75,
"closeOnExit" : true,
"colorScheme" : "Campbell",
"commandline" : "cmd.exe",
"cursorColor" : "#FFFFFF",
"cursorShape" : "bar",
"fontFace" : "Consolas",
"fontSize" : 10,
"guid" : "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
"historySize" : 9001,
"icon" : "ms-appx:///ProfileIcons/{0caa0dad-35be-5f56-a8ff-afceeeaa6101}.png",
"name" : "cmd",
"padding" : "0, 0, 0, 0",
"snapOnInput" : true,
"startingDirectory" : "%USERPROFILE%",
"useAcrylic" : true
}
],
"schemes" :
[
{
"background" : "#0C0C0C",
"black" : "#0C0C0C",
"blue" : "#0037DA",
"brightBlack" : "#767676",
"brightBlue" : "#3B78FF",
"brightCyan" : "#61D6D6",
"brightGreen" : "#16C60C",
"brightPurple" : "#B4009E",
"brightRed" : "#E74856",
"brightWhite" : "#F2F2F2",
"brightYellow" : "#F9F1A5",
"cyan" : "#3A96DD",
"foreground" : "#F2F2F2",
"green" : "#13A10E",
"name" : "Campbell",
"purple" : "#881798",
"red" : "#C50F1F",
"white" : "#CCCCCC",
"yellow" : "#C19C00"
},
{
"background" : "#282C34",
"black" : "#282C34",
"blue" : "#61AFEF",
"brightBlack" : "#5A6374",
"brightBlue" : "#61AFEF",
"brightCyan" : "#56B6C2",
"brightGreen" : "#98C379",
"brightPurple" : "#C678DD",
"brightRed" : "#E06C75",
"brightWhite" : "#DCDFE4",
"brightYellow" : "#E5C07B",
"cyan" : "#56B6C2",
"foreground" : "#DCDFE4",
"green" : "#98C379",
"name" : "One Half Dark",
"purple" : "#C678DD",
"red" : "#E06C75",
"white" : "#DCDFE4",
"yellow" : "#E5C07B"
},
{
"background" : "#FAFAFA",
"black" : "#383A42",
"blue" : "#0184BC",
"brightBlack" : "#4F525D",
"brightBlue" : "#61AFEF",
"brightCyan" : "#56B5C1",
"brightGreen" : "#98C379",
"brightPurple" : "#C577DD",
"brightRed" : "#DF6C75",
"brightWhite" : "#FFFFFF",
"brightYellow" : "#E4C07A",
"cyan" : "#0997B3",
"foreground" : "#383A42",
"green" : "#50A14F",
"name" : "One Half Light",
"purple" : "#A626A4",
"red" : "#E45649",
"white" : "#FAFAFA",
"yellow" : "#C18301"
},
{
"background" : "#073642",
"black" : "#073642",
"blue" : "#268BD2",
"brightBlack" : "#002B36",
"brightBlue" : "#839496",
"brightCyan" : "#93A1A1",
"brightGreen" : "#586E75",
"brightPurple" : "#6C71C4",
"brightRed" : "#CB4B16",
"brightWhite" : "#FDF6E3",
"brightYellow" : "#657B83",
"cyan" : "#2AA198",
"foreground" : "#FDF6E3",
"green" : "#859900",
"name" : "Solarized Dark",
"purple" : "#D33682",
"red" : "#D30102",
"white" : "#EEE8D5",
"yellow" : "#B58900"
},
{
"background" : "#FDF6E3",
"black" : "#073642",
"blue" : "#268BD2",
"brightBlack" : "#002B36",
"brightBlue" : "#839496",
"brightCyan" : "#93A1A1",
"brightGreen" : "#586E75",
"brightPurple" : "#6C71C4",
"brightRed" : "#CB4B16",
"brightWhite" : "#FDF6E3",
"brightYellow" : "#657B83",
"cyan" : "#2AA198",
"foreground" : "#073642",
"green" : "#859900",
"name" : "Solarized Light",
"purple" : "#D33682",
"red" : "#D30102",
"white" : "#EEE8D5",
"yellow" : "#B58900"
}
]
}

mac 一些软件安装

homebrew

强大的安装神器

iterm2

oh-my-zsh

Mac 首先需要将 bash 换成 zsh

可以先看看有啥 shell

cat /etc/shells

换成 zsh

chsh -s /bin/zsh

spaceship

charles3

clipy

Shadowsocks

Popclip

Magnet

Vscode 由于之前使用了 setting sync 插件直接使用 gists 把之前的配置拿了过来

Fira code

同时装上一些会常用的命令行工具 打造高效的工作环境 – SHELL 篇

例如 bat, fd, prettyping, z, fzf, tldr 等等

安转 nvm

brew install nvm

记得按提示操作在看下是否加进去了

bat ~/.zshrc | grep nvm

《Don't make me think》读书笔记

第一章 别让我思考

摘抄

  • 你的目标应该是让每一个页面或屏幕都不言而喻,这样的话,普通用户只要看它一眼就知道是什么内容,知道怎么用它。换句话说,他们不需要思考就能明白。
  • 这里又一条原则:如果你不能做到让一个页面不言而喻,那么至少应该让它自我解释。
  • 大多数人会花上比我们想象中少得多的时间来浏览我们设计的网页

canvas判断一个图是不是比较黑的图

      let a = document.createElement("canvas");
      a.id = "canvas"
      document.body.appendChild(a);
      const canvas = document.getElementById("canvas");
      canvas.width = 100;
      canvas.height = 100;
      const ctx = canvas.getContext("2d");
      const img = new Image();
      img.src = "./heitu.png";
      img.onload = () => {
        ctx.drawImage(img, 0, 0, 100, 100);
        let x = ctx.getImageData(0, 0, 100, 100).data;
        let k = 0
        for (let i = 0; i < 10000; i += 4) {
          if (x[i] < 50) {
            k++
          }
        }
        if(k>1000){
          alert('heitu');
        }
        document.body.removeChild(a)
      };

Add Two Numbers

Add Two Numbers
两数相加
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

JavaScript:

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
var addTwoNumbers = function(l1, l2) {
    
};

解法是先参照 leetcode 的给出解法,再自己敲的

var addTwoNumbers = function(l1, l2) {
    let l3 = new ListNode(0);
    let current = l3;
    let count = 0;
    
    while(l1 || l2 || count > 0){
    	let num1 = l1 ? l1.val : 0;
        let num2 = l2 ? l2.val : 0;
        let num = num1 + num2 + count;
        
        if(num >= 10){
            current.val = num % 10;
            current.next = new ListNode(0);
            count = 1;
        } else {
            current.val += num;
            current.next = l1 && l1.next || l2 && l2.next ? new ListNode(0) : null;
            count = 0;
        }
        
        l1 = l1 ? l1.next : null;
        l2 = l2 ? l2.next : null;
        current = current.next;
    }
    
	return l3;
};

匹配字符串(kvm 算法)

/**
 * @param {string} haystack
 * @param {string} needle
 * @return {number}
 */
var strStr = function (haystack, needle) {
    const needleLength = needle.length;
    if (needleLength === 0) return 0;
    const haystackLength = haystack.length;
    // 状态机数组
    const pi = new Array(needleLength).fill(0);
    // needle 与自己比较构建状态机数组
    for (let i = 1, j = 0; i < needleLength; i++) {
        while (j > 0 && needle[i] !== needle[j]) {
            j = pi[j - 1];
        }
        if (needle[i] === needle[j]) {
            j++;
        }
        pi[i] = j;
    }

    // haystack 与 needle 比较
    for (let i = 0, j = 0; i < haystackLength; i++) {
        while (j > 0 && haystack[i] !== needle[j]) {
            j = pi[j - 1];
        }

        if (haystack[i] === needle[j]) {
            j++;
        }

        if (j === needleLength) {
            return i - needleLength + 1;
        }
    }

    return -1;
};

leetcode

参考资料:

花花酱 KMP Algorithm - 刷题找工作 SP19

Knuth–Morris–Pratt (KMP) Pattern Matching Substring Search - First Occurrence Of Substring

《算法4》(496页)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.