使用Html5 Canvas 画芝麻信用的截屏

最近经常有人在微信朋友圈晒芝麻信用的分数, 虽然我的分数没有达到欧洲某小国申根的要求, 不过也不低. 今天台风"灿鸿" 袭来, 外边大风又大雨, 又是周末, 于是就想用 html5 的canvas 做一个假的芝麻信用截图.
下面是一个效果图:
latest.png

如果你想查看源代码, 或者修改, 看jsfiddle上的share
https://jsfiddle.net/manecocomph/edkg8z5w/1/

源代码:
html 源代码:

<canvas id="fakeImg"></canvas>

Javascript 源代码:

function drawTextAlongArc(context, str, centerX, centerY, radius, angle) {
    var len = str.length, s;
    context.save();
    context.translate(centerX, centerY);
    context.rotate(-1 * angle / 2);
    context.rotate(-1 * (angle / len) / 2);
    for (var n = 0; n < len; n++) {
        context.rotate(angle / len);
        context.save();
        context.translate(0, -1 * radius);
        s = str[n];
        context.fillText(s, -14, 0);
        context.restore();
    }
    context.restore();
}

// init score
var score = 849;
var screenWidth = 640;
var screenHeight = 1080;
var generalWordColor = 'gray';

var halfScreenWidth = screenWidth / 2;

// calculate angle & desc
var scoreDesc = "信用极好";
var angle = 1.8;
if (score <= 350) {
    angle = 0.9;
    scoreDesc = "信用极差";
} else if (score > 350 && score <= 550) {
    angle = 0.9 + ((score - 350) / 200) * ((2.1 - 0.9) / 5);
    scoreDesc = "信用较差";
} else if (score > 550 && score <= 700) {
    angle = 0.9 + (2.1 - 0.9) / 5 + ((score - 550) / 150) * ((2.1 - 0.9) / 5 * 3);
    if (score > 550 && score <= 600) {
        scoreDesc = "信用中等";
    } else if (score > 600 && score <= 650) {
        scoreDesc = "信用良好";
    } else {
        scoreDesc = "信用优秀";
    }
} else if (score > 700 && score <= 950) {
    angle = 0.9 + (2.1 - 0.9) / 5 * 4 + ((score - 700) / 250) * ((2.1 - 0.9) / 5);
    scoreDesc = "信用极好";
} else {
    angle = 2.1;
    scoreDesc = "信用爆棚";
}

// get canvas and set width & height
var canvas = document.getElementById("fakeImg");
canvas.setAttribute("width", screenWidth);
canvas.setAttribute("height", screenHeight);
var ctx = canvas.getContext("2d");

///// 开始画顶端 ////////
//header
ctx.fillStyle = '#000000';
ctx.fillRect(0, 0, screenWidth, 90);
//手机顶端
ctx.fillStyle = '#FFFFFF';
ctx.font = '10px Arial';
ctx.fillText("中国移动  4G", 5, 12);
ctx.fillText("13:59", halfScreenWidth - 22, 12);
ctx.fillRect(screenWidth - 50, 3, 10, 9);
ctx.strokeStyle = '#FFFFFF';
ctx.strokeRect(screenWidth - 50, 3, 30, 9);
ctx.font = '4px Arial';
ctx.fillText("▍", screenWidth - 20, 9);
//标题顶端
ctx.font = '24px Arial';
ctx.fillText("ㄑ 财富", 15, 60);
ctx.font = '28px Arial';
ctx.fillText("芝麻信用", halfScreenWidth - 66, 60);
ctx.strokeStyle = '#FFFFFF';
ctx.beginPath();
ctx.arc(screenWidth - 50, 50, 13, Math.PI * 2, 0, true);
ctx.stroke();
ctx.font = '20px Arial';
ctx.fillText("?", screenWidth - 55, 57);

///// 搜索部分
ctx.fillStyle = '#E4EDEC';
ctx.fillRect(0, 90, screenWidth, 60);
ctx.fillStyle = '#FFFFFF';
ctx.fillRect(60, 95, screenWidth - 120, 50);
ctx.font = '20px Arial';
ctx.fillStyle = 'gray';
ctx.fillText("看看Ta的芝麻分", 228, 130);
//search
ctx.beginPath();
ctx.arc(100, 122, 11, Math.PI * 2, 0, true);
ctx.strokeStyle = 'gray';
ctx.moveTo(108, 130);
ctx.lineTo(116, 137);
ctx.stroke();
//情怀部分
ctx.font = '26px Arial';
ctx.fillStyle = 'gray';
ctx.fillText("一  滴滴珍贵 重在参与  一", halfScreenWidth - 157, 203);

//////// 开始画中间的数据 //////////////
// init liner gradient, prepare for rainbow diagram
var grd = ctx.createLinearGradient(screenWidth / 9, screenHeight / 2, screenWidth / 9 * 8, screenHeight / 2);
grd.addColorStop(0, 'red');
grd.addColorStop(0.25, '#F99501');
grd.addColorStop(0.35, '#C1D500');
grd.addColorStop(0.55, '#AAE400');
grd.addColorStop(1, '#06D780');

// set circle center x,y
var circleCenterX = halfScreenWidth;
var circleCenterY = screenHeight / 2;

ctx.lineWidth = 25;
ctx.strokeStyle = grd;
// circle center : halfScreenWidth, circleCenterY 扇形部分
for (var i = 0; i < 45; i++) {
    ctx.beginPath();
    if (8 == i % 9) {
        ctx.arc(halfScreenWidth, circleCenterY, screenWidth / 8 * 3, Math.PI * ((i + 1) * 0.02666 + 0.897), Math.PI * (0.9 + i * 0.02666), true);
    } else {
        ctx.arc(halfScreenWidth, circleCenterY, screenWidth / 8 * 3, Math.PI * ((i + 1) * 0.02666 + 0.899), Math.PI * (0.9 + i * 0.02666), true);
    }
    ctx.stroke();
}

// draw credit level
ctx.fillStyle = generalWordColor;
ctx.font = '16px Arial';
ctx.lineWidth = 1;
var str = ['350', '较差', '550', '中等', '600', '良好', '650', '优秀', '700', '较好', '950'];
drawTextAlongArc(ctx, str, halfScreenWidth, circleCenterY, screenWidth / 8 * 3 - 35, 3.95);

// 画内圈虚线
ctx.lineWidth = 1;
ctx.strokeStyle = 'gray';
for (var i = 0; i < 120; i = i + 2) {
    ctx.beginPath();
    ctx.arc(halfScreenWidth, circleCenterY, screenWidth / 4, Math.PI * (0.9 + (i + 1) * 0.01), Math.PI * (0.9 + i * 0.01), true);
    ctx.stroke();
}

// drow outer circle 
ctx.lineWidth = 3;
if (angle > 0.92) {
    ctx.beginPath();
    ctx.arc(halfScreenWidth, circleCenterY, screenWidth / 16 * 5, Math.PI * (angle - 0.02), Math.PI * 0.9, true);
    ctx.strokeStyle = '#06D780';
    ctx.stroke();
}

if (angle < 2.08) {
    ctx.beginPath();
    ctx.arc(halfScreenWidth, circleCenterY, screenWidth / 16 * 5, Math.PI * 2.1, Math.PI * (angle + 0.02), true);
    ctx.strokeStyle = 'gray';
    ctx.stroke();
}

// 开始画指针 第一步 指针三角 
var anchorX1 = halfScreenWidth + screenWidth / 16 * 5 * Math.cos((angle - 0.02) * Math.PI);
var anchorY1 = circleCenterY + screenWidth / 16 * 5 * Math.sin((angle - 0.02) * Math.PI);
var anchorX2 = halfScreenWidth + screenWidth / 16 * 5 * Math.cos((angle + 0.02) * Math.PI);
var anchorY2 = circleCenterY + screenWidth / 16 * 5 * Math.sin((angle + 0.02) * Math.PI);
var anchorX3 = halfScreenWidth + (screenWidth / 16 * 5 - 36) * Math.cos(angle * Math.PI);
var anchorY3 = circleCenterY + (screenWidth / 16 * 5 - 36) * Math.sin(angle * Math.PI);
ctx.fillStyle = '#06D780';
ctx.beginPath();
ctx.moveTo(anchorX1, anchorY1);
ctx.lineTo(anchorX3, anchorY3);
ctx.lineTo(anchorX2, anchorY2);
ctx.fill();
ctx.closePath();

// 指针后部的2个圆圈的中心
var anchorX = halfScreenWidth + screenWidth / 16 * 5 * Math.cos(angle * Math.PI);
var anchorY = circleCenterY + screenWidth / 16 * 5 * Math.sin(angle * Math.PI);
// 指针后部 外环圆
ctx.strokeStyle = '#06D780';
ctx.beginPath();
ctx.arc(anchorX, anchorY, 12, 0, 2 * Math.PI, false);
ctx.stroke();
// 指针后部 中间白色圆
ctx.strokeStyle = '#FFFFFF';
ctx.lineWidth = 10;
ctx.beginPath();
ctx.arc(anchorX, anchorY, 5, 0, 2 * Math.PI, false);
ctx.stroke();
// 指针后部 最内部绿色圆
ctx.fillStyle = '#06D780';
ctx.lineWidth = 3;
ctx.beginPath();
ctx.arc(anchorX, anchorY, 5, 0, 2 * Math.PI, false);
ctx.fill();

// 内部文字部分
ctx.fillStyle = generalWordColor;
ctx.fillText("BETA", halfScreenWidth - 24, (circleCenterY - screenWidth / 4 + 62));
ctx.font = '94px Arial';
ctx.fillStyle = '#08BC8C';
ctx.fillText(score, halfScreenWidth - 84, (circleCenterY - screenWidth / 4 + 162));
ctx.font = '44px Arial';
ctx.fillText(scoreDesc, halfScreenWidth - 89, (circleCenterY - screenWidth / 4 + 212));
ctx.fillStyle = 'gray';
ctx.font = '14px Arial';
ctx.fillText("评估时间: 2015.07.11", halfScreenWidth - 74, (circleCenterY - screenWidth / 4 + 238));
ctx.strokeStyle = '#08BC8C';
ctx.strokeRect(halfScreenWidth - 85, (circleCenterY - screenWidth / 4 + 342), 180, 60);
ctx.font = '30px Arial';
ctx.fillStyle = '#08BC8C';
ctx.fillText("嘚瑟一下", halfScreenWidth - 50, (circleCenterY - screenWidth / 4 + 386));
ctx.font = '16px Arial';
ctx.fillStyle = 'gray';
ctx.fillText("高粱信用是合法独立的信用评估机构及信用采集机构", halfScreenWidth - 161, (circleCenterY - screenWidth / 4 + 432));

/////////// 开始画底部
//footer 的 2个点
ctx.fillStyle = '#06D780';
ctx.beginPath();
ctx.arc(halfScreenWidth - 35, screenHeight - 100, 8, 0, 2 * Math.PI, false);
ctx.fill();
ctx.fillStyle = 'gray';
ctx.beginPath();
ctx.arc(halfScreenWidth + 35, screenHeight - 100, 8, 0, 2 * Math.PI, false);

// 低端标题
ctx.fill();
ctx.fillStyle = '#EFF6EF';
ctx.fillRect(0, screenHeight - 80, screenWidth, 80);
ctx.font = '34px Arial';
ctx.fillStyle = '#27876B';
ctx.fillText("信用猜猜", 80, screenHeight - 25);
ctx.fillText("信用生活", halfScreenWidth + 80, screenHeight - 25);
ctx.strokeStyle = '#DBE4DF';
ctx.beginPath();
ctx.moveTo(0, screenHeight - 80);
ctx.lineTo(screenWidth, screenHeight - 80);
ctx.moveTo(halfScreenWidth, screenHeight - 80);
ctx.lineTo(halfScreenWidth, screenHeight);
ctx.stroke();

Using Docker [读书笔记] 1

Using Docker [读书笔记]

Containers are a lightweight and portable store for an application and its dependencies. 序的开头这么一句话, lightweight应该是较VM而言, 这里的container确实包含了你的应用及其依赖;
containerization: 集装箱化;
Containers share resources with the host OS;

Container 里面ps 看进程
psInContainer.png
Host OS 查看 docker 进程
psOutContainer.png

如果选择让container知道外部的线程, 那么container 内部其实是可以看到的
inContainerWithPidOption.png

The purpose of a VM is to fully emulate a foreign environment, whilst the purpose of a container is to make applications portable and self-contained;

Containers are an old concept. For decades, UNIX systems have had the chroot command which provides a simple form of filesystem isolation. FreeBSD has had the jail utility since 1998, which extended chroot sandboxing to processes. Solaris Zones offered a comparatively complete containerization technology around 2001, but was limited to the Solaris OS. Also in 2001, Parrallels Inc (then SWsoft) released the commercial Virtuozzo container technology for Linux, and later open sourced the core technology as OpenVZ in 2005[1]. Following on from this, Google started the development of CGroups for the Linux kernel and began moving their infrastructure to containers. The LXC project started in 2008 and brought together CGroups, kernel namespaces and chroot technology (amongst others) to provide a complete containerization solution. Finally, in 2013, Docker brought the final pieces to the containerization puzzle and the technology began to enter the mainstream.

Docker took the existing Linux container technology then wrapped it and extended it in various ways — primarily portable images and a user-friendly interface — to create a complete solution for the creation and distribution of containers. The Docker platform has two distinct components; the Docker Engine, which is responsible for creating and running containers and the Docker Hub, a cloud service for distributing containers.

The Docker Engine provides a very fast and convenient interface for running containers. Before this, running a container using a technology such as LXC required significant specialist knowledge and manual work. The Docker Hub provides an enormous number of public container images for download, allowing users to quickly get started and avoid duplicating work already done by others.

Early versions of Docker were little more than a wrapper around LXC paired with a Union Filesystem when start open-source;

Docker uses a Union File System (UFS) for containers, which allows multiple file systems to be mounted in a hierarchy and appear as a single file system. The file system from the image has been mounted as a read-only layer and any changes to the running container are made to a read-write layer mounted on top of this.

删除退出的container
$ docker rm $(docker ps -aq -f status=exited)

linux 磁盘 文件夹 大小查看

在 windows 系统上很容易查看整个磁盘的已使用大小, 也很容易看到某个文件夹下面的文件总大小.
其实在linux 系统中更容易, 一个命令行解决

查看磁盘使用情况:
df

查看某个文件夹下面的文件夹里面的大小
sudo du -sh *

制作自己的docker tomcat image

制作自己的dockfile image

新建文本文件: Dockerfile (没有后缀), 里面内容如下:

FROM tomcat:7.0
RUN rm -rf /usr/local/tomcat/webapps/ROOT
ADD http://ci.qa.tianxiaohui.com/job/bnrdash-r2-2_job_Eric/197/artifact/bnrdash/target/ROOT.war /usr/local/tomcat/webapps/
CMD ["catalina.sh", "run"]

每一行解释:
1) 基于公共的tomcat:7.0 的image, 更多tomcat image 看这里 https://registry.hub.docker.com/_/tomcat/
2) 因为我自己的包是ROOT.war, 所以把tomcat 再带的删除, 也为了安全, 当然其它自带的最好也删除
3) 把CI做好的war 文件ccopy 进去
4) 默认启动tomcat

使用下面的命令打包(最后的点表示当前目录去找 Dockerfile):

docker build -t xiatian/tomcatBnrdash .

查看local的images, 已经包含最新的

docker images

那么就可以去run了, 下面分别开8081, 8082, 开了2个containers.

docker run -d -p 8081:8080 xiatian/tomcatBnrdash
docker run -d -p 8082:8080 xiatian/tomcatBnrdash

查看正在运行的container

docker ps

进入正在运行的container

docker exec -it  CONTAINER_ID bash


Java Collection Framework List, Set, Queue, Deque 关系图

使用 https://www.draw.io/ 在线画的, 只涉及到List, Set, Queue, Deque. 只包含util 包里面的类和接口.
接口以圆角长方形表示, 类以直角长方形表示.

在线浏览版本: https://drive.google.com/file/d/0B6ry0l2WQQIjclhSSGZyNGgxX1k/view?usp=sharing

离线下载版本, 下面 png 格式图片, 可以另存为, 放大. 也可以下载pdf 格式
pdf version: JavaCollection.pdf
JavaCollection.png