blender的洋面烘焙贴图怎么都一样呢?

问题发现

今天使用blender洋面修改器制作海洋。制作完毕后,准备使用修改器自带的烘焙功能进行贴图烘焙,以节省后续的渲染性能。

但是却发现,渲染出来的帧数,结果都一样。

并且进一步发现,当前的时间线停留在第几帧,那么渲染出来的所有帧数就都是该帧。

这也太离谱了,总不能上百帧,然后一帧一帧的去电竞渲染吧?

Read more
Canvas学习之变换
  • 旋转问题:计算相对变化量并改变每一个图形坐标。注意旋转绝对值大于 360° 的问题
  • 放缩问题:计算相对变化量并改变每一个图形坐标
  • 多条贝塞尔曲线填充不满的问题:开始画第一条曲线的时候用 moveTo 就行了,之后的每一条贝塞尔曲线之间不用 moveTo 了,否则使用 fill 会填不满,会出现几个 moveTo 点形成一个封闭的空白区域。不用担心第二条、第三条等等曲线的起始点问题,因为程序会自动将上一条贝塞尔曲线的终点作为下一条贝塞尔曲线的起点。

Transform 变换

1 旋转

  • rotate(rangle * Math.PI/180)
  • 仅一个参数,弧度计
  • 默认以画布原点也就是 (0, 0) 作为旋转原点

1.1 自定义旋转点

默认的旋转方式都是以画布为原点,这其实满足不了多样的旋转,比如自旋或者以某个点旋转。

无论是哪种情况,我们都希望可以让图形围绕自定义的旋转点旋转,因此可以使用 ctx.translate(x, y) 移动至定义的点作为旋转点。

  • 但是这样就有一个问题:自定义一个点后,画布的最左上角的点会移动到该点作为原点(0, 0),那么如果按照此时的坐标系,图形的每个点也会增加相应的水平和垂直位移,就导致图形脱离了屏幕中的相对位置(我们希望的就是图形能以屏幕的任何一个点旋转,但前提条件)

  • 所以应该将图形的每个点减去相对变化位置

1.2 重新计算坐标点

  • o(x1, y1) 为原始画布原点,一般是 (0, 0)
  • o1(x2, y2) 为移动后的画布原点,也就是旋转点
  • dx = x1 - x2
  • dy = y1 - y2
  • 对于每一个图形的点:(X + dx, Y + dy)
  • 这样就可以保证图形在整个屏幕中的相对位置了

2 缩放

  • scale(x, y)

2.1 自定义缩放

默认的缩放是将画布扩大或者缩小响应的倍数,这会导致图形的坐标改变,从而脱离屏幕中的原始位置

大部分时候我们希望图形原地缩放,或者说缩放后在指定的位置,而不是随着画布缩放而移动到其他地方

2.2 重新计算坐标点

  • scale(sx, sy) sx 为水平轴的缩放倍数,sy 为垂直轴的缩放倍数
  • O(x1, y1) 为缩放前图形位置,一般是取图形中心位置的点
  • O1(x2, y2) 为缩放后随画布移动到的点 [ 对于 O1 点: x2 = x1 * sx, y2 = y1 * sy ]
  • 我们希望缩放前后都是在 O(x1, y1) 点
  • dx = (x1 - x2) * (1 / sx)
  • dy = (y1 - y2) * (1 / sy)
  • 对于图形上的每一点: (X + dx, Y + dy)
  • 这样可以保证缩放后的图形依然以 O(x1, y1) 为中心点

webpack学习01

前言

为什么突然想认真学一下webpack?

1 理解框架的需要

目前主流框架 Vue、React等都基于此,因此学一下基本使用时必要的

2 新框架开发需要

最近打算开发一个基于 html5、canvas 的小框架,涉及到页面频繁调试、浏览器兼容等;另外,开发过程中经常使用 import、ES6。如果直接基于 html + js + css来开发,那么效率很低还要处理很多兼容问题。

我们可以看到 webpack 的优势

  • 随意使用 import、ES6: 通过打包注入 html 即可, 使用 Babel 转译为 ES5 来兼容旧的浏览器
  • 使用 sass、less 等,使用 loader 进行处理生成 css 即可。另外,使用一些 plugins 给 css 加入不同浏览器前缀,以此来兼容
  • 使用热重载,这是最重要的,特别对于重复调整页面的前端来说!只需 ctrl+s 就可以自动刷新页面。

前言小结

基于以上几点,webpack 的使用时必需的,它会极大的加快开发效率,减少一些不必要的开发成本,从而将开发重心集中于框架本身的开发测试上。

webpack 基础

1 安装和配置文件

1.1 安装

1
npm install webpack webpack-dev-server -S
  • webpack: 核心文件
  • webpack-dev-server: 服务器板块,用于开发模式 development

1.2 配置文件

  • 新建文件 webpack.config.js
    1
    2
    3
    module.exports = {
    //....
    }

2 入口 entry

entry 指定入口文件,也就是告诉 webpack 应该从哪个文件开始读取

1
2
3
4
5
const path = require("path");

module.exports = {
entry: "index.js"
}

3 出口 output

output 指定输出文件的位置,名称

  • filename: 指定输出的文件名;可以使用 [name].js 来保留文件原有名,当然也可以定义新的名字
1
2
3
4
5
6
7
8
9
const path = require("path");

module.exports = {
entry: "index.js",
output: {
filename: "[name].js",
path: path.resolve(__dirname, "dist"),
},
}

4 loader

4.1 作用

webpack 只能处理 javascript 和 json,所以需要依靠外部模块来处理其他文件。通常是放在 module 的 rules 属性中,以数组形式排列。

每一组 loader 有以下常见属性

  • test: 使用正则表达式匹配要处理的文件类型
  • use: 所使用的的 loader,可以是单个,也可以是数组形式的多个 loader
  • exclude: 排除指定文件,不处理

4.2 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
const HtmlWepackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const path = require("path");

module.exports = {
//...出口, 入口配置
// loader
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: "babel-loader",
},
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
],
},
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
"sass-loader" ,
],
},
],
},
}

4.3 常见 loader

  • css-loader: 处理 js 文件中引用的 css 文件
  • style-loader: 将 js 文件中引用的 css 文件变为 style 标签 (注意: 该 loader 与 mini-css-extract-plugin 冲突,只能使用其中一个)
  • sass-loader: 将 scss 文件编译为 css 文件
  • babel-loader: 将 ES6 转译为 ES5
  • mini-css-extract-plugin: 将处理之后的 css/scss/less 打包成单独文件,并注入到 html 中,与 style-loader 冲突,因此使用 mini 时删除 style-loader

5 plugins

5.1 作用

插件,可以对文件作进一步处理,整合、注入等等

5.2 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const HtmlWepackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const path = require("path");

module.exports = {
//...出口、入口、loader配置
plugins: [
new MiniCssExtractPlugin({
filename: "css/[name].css"
}),
new HtmlWepackPlugin({
filename: "index.html",
template: "./src/index.html",
}),
],
}

6 devServer

6.1 作用

来源于 webpack-dev-server,是 webpack 提供的服务器模块,可以将打包生成后的文件放置与临时创建的 http 服务上,采可直接通过 ip:port 访问

6.2 常见属性

  • static: 指定服务来源的静态资源文件
  • port: 服务开启端口
  • hot: true/false,是否开启热重载

6.3 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const HtmlWepackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const path = require("path");

module.exports = {
//...出口、入口、loader、plugins配置
devServer: {
static: {
directory: path.join(__dirname, 'public'),
},
compress: true,
port: 9000,
hot: true,
},
}

7 完整示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
const HtmlWepackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const path = require("path");

module.exports = {
mode: "development",
entry: "./src/index.js",
output: {
filename: "[name].js",
path: path.resolve(__dirname, "dist"),
},
devServer: {
static: {
directory: path.join(__dirname, 'public'),
},
compress: true,
port: 9000,
hot: true,
},
plugins: [
new MiniCssExtractPlugin({
filename: "css/[name].css"
}),
new HtmlWepackPlugin({
filename: "index.html",
template: "./src/index.html",
}),
],
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: "babel-loader",
},
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
],
},
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
"sass-loader" ,
],
},
],
},
};

总结

  • 本次学习了入口、出口、loader、plugins、devServer 的基本使用。当然还有进阶的用法,这个之后学习了在进行总结。
  • 上述示例以及可以在热重载下进行简单的网页开发了,并且可以不用担心 javascript 语法 的兼容问题

Canvas学习之颜色渐变

线性渐变

(1) 基本方法

createLinearGradient(x1, y1, x2, y2)

  • 渐变开始坐标 (x1, y1) 到 结束坐标 (x2, y2)
  • 该坐标依然以整个页面为坐标系,而不是以填充渐变颜色的容器为基准

addColorStop(number, colorString)

  • 规定颜色渐变-中间-结束的颜色变化
  • number 的值为 0 ~ 1 之间
  • colorString 为颜色值

(2) 渐变范围

  • (x1, y1)(x2, y2) 创建一条线段 AB
  • 分别过线段两端点画 垂直于AB 的直线 LA、LB
  • LA 与 LB 两条平行直线构成的无限二维平面 ∞LALB
  • ∞LALB 与颜色容器的平面交集即为渐变的范围

(3) Exemple

1 矩形渐变

1
2
3
4
5
6
7
8
9
let doc = document.getElemntById("myapp");
let ctx = doc.getContext("2d");

let my_gradinet = ctx.createLinearGradient(0, 0, 100, 0);
my_gradinet.addColorStop(0, 'yellow');
my_gradinet.addColorStop(1, 'blue');

ctx.fillStyle = my_gradinet;
ctx.fillRect(0, 0, 300, 200);

2 线条渐变

1
2
3
4
5
6
7
8
9
10
11
12
13
let doc = document.getElemntById("myapp");
let ctx = doc.getContext("2d");

let my_gradinet = ctx.createLinearGradient(0, 0, 100, 0);
my_gradinet.addColorStop(0, 'yellow');
my_gradinet.addColorStop(1, 'blue');

ctx.beginPath();
ctx.lineWidth = 5;
ctx.strokeStyle = my_gradient;
ctx.moveTo(0, 400);
ctx.lineTo(500, 400);
ctx.stroke();

圆形渐变

(1) 基本方法

createRadialGradient(x1, y1, r1, x2, y2, r2)

  • 从开始圆 (x1, y1), r1 到 结束圆 (x2, y2), r1
  • 该坐标依然以整个页面为坐标系,而不是以填充渐变颜色的容器为基准

addColorStop(number, colorString)

  • 规定颜色渐变-中间-结束的颜色变化
  • number 的值为 0 ~ 1 之间
  • colorString 为颜色值

(2) 渐变范围

1 两圆为包含关系

  • 当一个圆完全在另一个圆里时,渐变范围为两圆相交部分以外的圆环部分

2 两圆为部分相交或相离

  • 过两圆的两侧做相切线,要求每边的直线都要同时与两圆相切
  • 两条相切直线:
    • 当两圆半径r相同时,构成一个无限长的平行二维面。其中从一个圆到另一个圆的部分为渐变范围
    • 当两圆半径r不同时,两切线交于某一点。从该点起与两直线框定成无限长三角面。其中从一个圆到另一个圆的部分为渐变范围

(3) Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//圆形渐变
let circle_1 = {
x: 800,
y: 200,
r: 50,
};
let circle_2 = {
x: 1000,
y: 200,
r: 80,
}
let my_gradients = draw2d.createRadialGradient(circle_1.x, circle_1.y, circle_1.r, circle_2.x, circle_2.y, circle_2.r);
my_gradients.addColorStop(0, 'blue');
my_gradients.addColorStop(1, 'green');

draw2d.beginPath();
draw2d.fillStyle = my_gradients;
draw2d.fillRect(600, 0, 600, 400);
draw2d.strokeRect(600, 0, 600, 400);
draw2d.stroke();
draw2d.save();

//draw2d.arc(800, 100, )
drawHelp.beginPath();
drawHelp.strokeStyle = "black";
drawHelp.arc(circle_1.x, circle_1.y, circle_1.r, 0 * Math.PI, 2 * Math.PI);
drawHelp.stroke();
drawHelp.beginPath();
drawHelp.arc(circle_2.x, circle_2.y, circle_2.r, 0 * Math.PI, 2 * Math.PI);
drawHelp.stroke();

感情中单方付出的人为何会觉得很累?

单方的付出让人怀疑

  • 通过努力换回的爱,往往使人生疑
  • 这种爱会让人痛苦的感到:
Read more
大厂前端面经

欢迎阅读

前言

目前已经毕业,在去年2020秋招的摸爬滚打中,侥幸收获了几个小offer。最后也很幸运去腾讯实习了一段时间。所以想着把自己经历的大厂前端面试题整理出来,留给需要找实习工作的童鞋们一个参考。

大厂前端秋招面经

包括腾讯区域研发、字节跳动、腾讯日常实习、小米的前端面经

Read more
httpBasic

HTTP

请求报文的构成

1
2
3
4
5
6
7
(GET/POST..) (/index) HTTP/1.1  
协议 资源地址 http版本
(HOST: tzwlink.xyz)
域名

(userName=gre&age=21)
请求内容
Read more
cssMustKnow

必会的几个css基础知识

CSS-选择器

这一块可以说是很基础了,只有用选择器选中元素,才能使样式生效

元素选择器

直接选中原生 html 标签名,该选择器可以说是优先级最低的了,在没有其它类型选择器时才会考虑它

Read more
es6basic

ES6 新增声明方式与各种扩展

为了提高开发效率,语言设计者从原生上支持了许多快捷高效的新操作。故推出称为新一代标准 ES6

Read more
eventloop

前言

在初次入门学习和使用 JavaScript 的过程中,相信遇到过许多程序执行顺序及结果与预期不一致的问题,在查阅资料的过程中了解到原来是程序的执行有同步与异步之分;与此同时也会看到许多有关概念,例如回调函数、执行栈、任务队列、事件循环机制(Event Loop)、宏任务、微任务、Promise(ES6)等等。此时对于一个刚入门不久的小白来说,要理解消化这些概念真的不容易。对于入门不久的我来说也一样,所以写一篇博客记录一下,有关 JavaScript 的运行机制,以及上述的这些概念为什么会出现,又解决了什么问题。

Read more