画画
http://www.effectgames.com/demos/canvascycle/
https://www.w3schools.com/graphics/canvas_coordinates.asp
https://www.w3schools.com/graphics/game_sound.asp
刷上蓝色渐层背景增添质感
以下这段程序,若非不是一开始就画出,就必须设定
globalCompositeOperation,否则,预设会盖掉先前的内容
https://www.w3schools.com/tags/playcanvas.asp?filename=playcanvas_globalcompop&preval=source-over
ctx.globalCompositeOperation = "destination-over";
var grd = ctx.createLinearGradient(0, 0, 0, 50);
grd.addColorStop(0, "white");
grd.addColorStop(1, "#0000EE");
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 200, 50);
画线
var canvas = document.getElementById("myCanvas2");
var ctx = canvas.getContext("2d");
ctx.moveTo(0, 0);
ctx.lineTo(100, 50);
ctx.moveTo(100, 50);
ctx.lineTo(200, 0);
ctx.stroke(); //定案
涂满
var canvas = document.getElementById("myCanvas3");
var ctx = canvas.getContext("2d");
ctx.moveTo(0, 0);
ctx.lineTo(100, 50);
ctx.lineTo(200, 0);
ctx.fill();
划十字
// width="400px" height="300px"
ctx.moveTo(0, 150);
ctx.lineTo(400, 150);
ctx.stroke();
ctx.moveTo(200, 0);
ctx.lineTo(200, 300);
ctx.stroke();
用来对齐文字(自己的口绝:起始点在中间 => 相反)
ctx.font = "64px Arial";
ctx.textBaseline = "top"; //top ,middle ,botton
ctx.textAlign = "left"; //对齐起点 ; left, center, right
ctx.fillText("hello", 200, 150);
还原 让後面的设计不受此处影响
let bakFillStyle = ctx.fillStyle;
ctx.font = "8px Arial italic";
ctx.textBaseline = "top";
ctx.textAlign = "center";
ctx.fillStyle = "#FFFFFF";
ctx.fillText("Powered by HTML5", 100, 35);
ctx.fillStyle = bakFillStyle; //
arc画圆圈圈
arc(120, 100, 80, 0, 2 * Math.PI [0~2PI] ,true[是否逆时针:预设False])
ctx.arc(120, 100, 80, 0, 2 * Math.PI, true);
ctx.stroke(); //1.输出
// ctx.fill(); //2.填满
ctx.clip(); //3.裁切画布
ctx.drawImage(imgRabbit, 0, 0); //3.放图片
做一个重复的
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage
var ctxSmall = canvasSmall.getContext("2d");
// (canvasLab, 来源[0, 0, 240, 200], 目的[0, 0, 120, 100])
ctxSmall.drawImage(canvasLab, 0, 0, 240, 200, 0, 0, 120, 100);
图片灰阶
原理:红绿蓝相同,为灰色(数字大小只差在深浅)
把红绿蓝抓出来,取得平均数,作为灰阶的渐层
var imgData = ctxSmall.getImageData(0, 0, 120, 100);
console.log(imgData);
var data = imgData.data;
//data.length 48000 ; 一个画素4位元 ; 0, 4, ,8 ,12
for (var i = 0; i < data.length; i += 4) {
var avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
data[i] = avg; // red ; 4
data[i + 1] = avg; // green ; 5
data[i + 2] = avg; // blue ; 6
}
ctxSmall.putImageData(imgData, 0, 0);
画布转图片 toDataURL
如同 img src="data:image/png;base64,iVBORw0KGgoAAAANSUhE............."
imgView.src = canvasSmall.toDataURL("image/png");
撞球
var canvas = document.getElementById("surface");
var ctx = canvas.getContext("2d");
setInterval(function () {
//撞到墙壁反弹
//下
if (ball.y + ball.r >= surface.height) {
ball.vy = Math.abs(ball.vy) * -1;
}
//上
if (ball.y + ball.r <= 0) {
ball.vy = Math.abs(ball.vy);
}
//右
if (ball.x + ball.r >= surface.width) {
ball.vx = Math.abs(ball.vx) * -1;
}
//左
if (ball.x + ball.r <= 0) {
ball.vx = Math.abs(ball.vx);
}
//擦掉
ctx.fillStyle = "white";
ctx.fillRect(0, 0, surface.width, surface.height);
//球移动 20 22 24 26 28...
ball.x += ball.vx;
ball.y += ball.vy;
//不会重复画 (重新计算路径)
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.r, 0, Math.PI * 2); //画球
ctx.stroke();
}, 1000 / 70);
下堂课接续
(2)启用keyboard事件
var key_flag = "none";
document.onkeydown = function (e) {
console.log(e);
console.log(e.keyCode); //37左 38上 39右 40下
switch (e.keyCode) {
case 37:
// 按左 提早转向(*-1)
// abs回传一个数字的绝对值
// ball.vx = Math.abs(ball.vx) * -1;
// 虽然可以执行但是难维护
//维护用
key_flag = "left";
break;
case 38:
key_flag = "up";
break;
case 39:
key_flag = "right";
break;
case 40:
key_flag = "down";
break;
}
};
(3)撞到方向(上),按下按钮要反弹(相反:下)
if (ball.y + ball.r >= surface.height || key_flag == "up") {
ball.vy = Math.abs(ball.vy) * -1;
}
// 上
if (ball.y + ball.r <= 0 || key_flag == "down") {
ball.vy = Math.abs(ball.vy);
}
// 右
// if (ball.x + ball.r >= surface.width) {
// ball.vx = Math.abs(ball.vx) * -1;
// }
if (ball.x + ball.r >= surface.width || key_flag == "left") {
ball.vx = Math.abs(ball.vx) * -1;
}
// 左
if (ball.x + ball.r <= 0 || key_flag == "right") {
ball.vx = Math.abs(ball.vx);
}
(4)按完恢复原状
key_flag = "none";
4.canvas 对 focus 无效 所以 无反应
键盘按下时 事件
canvas 对 focus 无效 所以 无反应
<canvas id="surface" height="400" width="600" style="border: 1px solid gray">
</canvas>
surface.onkeydown = function (e) {
console.log(e);
};
修改为document
document.onkeydown = function (e) {
console.log(e);
};
5.不要用setinterval侦测是否按下按键,请使用事件onkeydown
不管设定多少时间侦测一次,都会有遗漏
setInterval(function () {
}, 1000); 1s
document.onkeydown = function (e) {
console.log(e);
console.log(e.keyCode); //37左 38上 39右 40下
switch (e.keyCode) {
case 37:
key_flag = "left";
break;
case 38:
key_flag = "up";
break;
case 39:
key_flag = "right";
break;
case 40:
key_flag = "down";
break;
}
};
6.关於圆周率、sin、cos...三角函数 详见JS_API影片03(死亡)
7.ChartJS - 直线图 (Lab_ChartJS_01 > lab.html)
https://www.chartjs.org/
(1)安装 / 引用 Chart.js
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/Chart.min.js"></script>
(2)建立画布、画笔
<canvas id="chartCanvas"></canvas>
var cityPopulationList = [3800, 2570, 2374, 2106, 1859];
var cityPopulationList2030 = [3719, 3606, 3075, 2344, 1988];
var cityNameList = ["Tokyo", "Delhi", "Shanghai", "Sao Paulo", "New York"];
(3)画画
https://www.chartjs.org/docs/latest/api/interfaces/ChartTypeRegistry.html
var populationChart = new Chart(ctx, {
type: "bar", //"bar"物件
data: {
labels: cityNameList, // X 轴项目清单
//datasets 阵列
datasets: [
{
label: "population",
data: cityPopulationList, //阵列
// 着色:
backgroundColor: "rgba(14,72,100,0.2)",
borderColor: "rgba(14,72,100,1.0)",
borderWidth: 1,
},
{
label: "population",
data: cityPopulationList, //阵列
// 着色:
backgroundColor: "rgba(14,72,100,0.5)",
borderColor: "rgba(14,72,100,0.5)",
borderWidth: 10,
},
],
},
});
7.ChartJS - 直线图 (Lab_ChartJS_02 > lab.html)
type: "line"
8.ChartJS - pie圆饼 + doughnut甜甜圈 (Lab_ChartJS_03 > lab.html)
type: "doughnut"
var pieChart = new Chart(ctx, {
type: "doughnut", //"pie"
data: {
labels: cityNameList,
datasets: [
{
data: cityPopulationList,
backgroundColor: ["#3e95cd", "#8e5ea2", "#3cba9f", "#e8c3b9", "#c45850"],
},
//第二圈
{
data: cityPopulationList2030,
backgroundColor: ["#3e95cd", "#8e5ea2", "#3cba9f", "#e8c3b9", "#c45850"],
},
],
},
options: {
title: {
display: true,
text: "Population",
},
cutoutPercentage: 30, //粗细
},
});
9.ChartJS - scatter散布图 + bubble气泡图 (Lab_ChartJS_04 > lab.html)
var dataList = [];
for (let i = 1; i <= 10; i++) {
let dataItem = {
x: Math.floor(Math.random() * 100),
y: Math.floor(Math.random() * 100),
r: Math.floor(Math.random() * 20), //半径
};
dataList.push(dataItem);
}
// console.log(JSON.stringify(dataList));
var ctx = document.getElementById("chartCanvas");
var labChart = new Chart(ctx, {
type: "bubble", // bubble使用到r ; scatter
data: {
datasets: [
{
label: "random X-Y",
data: dataList,
backgroundColor: "rgba(14,72,100,0.2)",
borderColor: "rgba(14,72,100,1.0)",
borderWidth: 1,
},
],
},
});
10.three.js (Lab_Three.js > lab.html)
https://threejs.org/
(1)引用
<script src="js/three.min.js"></script>
(2)制作画布
<div id="cinema"></div>
(3)画布 加入 canvas 元素
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.getElementById("cinema").appendChild(renderer.domElement);
(4)建立 Scene (场景)
var scene = new THREE.Scene();
scene.background = new THREE.Color(0x000000);
(5)建立 Camera (照相机)
相机参数
https://www.script-tutorials.com/webgl-with-three-js-lesson-9/
const camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 0.1, 10000);
camera.position.set(0, 0, 500);
scene.add(camera);
(6)拍照
https://www.script-tutorials.com/webgl-with-three-js-lesson-9/
const camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 0.1, 10000);
camera.position.set(0, 0, 500); //距离远近
scene.add(camera);
var sphere = new THREE.SphereGeometry(200, 50, 50);
var material = new THREE.MeshNormalMaterial();
var mesh = new THREE.Mesh(sphere, material);
mesh.position.z = -300;
scene.add(mesh);
(7)照片放到画布上
Render(输出/算图/描绘/渲染) 影像,呼叫 Renderer 描绘出作品:
renderer.render(scene, camera);
(8)包地球外皮,材质下载
var loader = new THREE.TextureLoader();
loader.load("images/earth.jpg", function (texture) {
mesh.material = new THREE.MeshBasicMaterial({ map: texture, overdraw: 0.5 });
renderer.render(scene, camera);
});
(9)转动
自己转转 似setInterval/setTimeout每秒动
requestAnimationFrame(doRender);
function doRender() {
try {
mesh.rotation.y += 0.01;
} catch (e) {}
renderer.render(scene, camera);
requestAnimationFrame(doRender);
}
键盘转转
document.onkeydown = function (e) {
switch (event.keyCode) {
case 38: // up
mesh.rotation.x -= 0.2;
break;
case 40: // down
mesh.rotation.x += 0.2;
break;
case 37: // left
mesh.rotation.y -= 0.2;
break;
case 39: // right
mesh.rotation.y += 0.2;
break;
}
event.preventDefault();
};
滑鼠转转
var lastMove = {
x: window.innerWidth / 2,
y: window.innerHeight / 2,
};
var isMouseDown = false;
document.onmousedown = function () {
isMouseDown = true;
lastMove.x = event.clientX;
lastMove.y = event.clientY;
};
document.onmouseup = function () {
isMouseDown = false;
};
document.onmousemove = function () {
if (isMouseDown == false) {
return;
}
var moveX = event.clientX - lastMove.x;
var moveY = event.clientY - lastMove.y;
mesh.rotation.y += moveX * 0.0002;
mesh.rotation.x += moveY * 0.0002;
lastMove.x = e.clientX;
lastMove.y = e.clientY;
};
11.WebCam - 拍照 (WebCam > lab.html)
(1)引用webcam
<script src="webcam.min.js"></script>
(2)WebCam 启动程序
Webcam.set({
width: 320,
height: 240,
image_format: 'jpeg',
jpeg_quality: 90
});
Webcam.attach('#cameraDiv');
(3)照片怎麽存
//制作画布
var viewContext = viewPort.getContext('2d')
Webcam.snap(function (snappedImage) {
// console.log(snappedImage);
let bufferImage = new Image();
bufferImage.src = snappedImage;
bufferImage.onload = function () {
viewContext.drawImage(bufferImage, 0, 0, 320, 240);
}
}); // End of Webcam.snap
>>: 在 Debian 11 上直接用 Fcitx 5 与呒虾米
在写程序时,我们可能需要重复执行某些程序,总不可能每行程序一直复制贴上,这时候就会用到我们的回圈(l...
延续昨日 今天来讲讲我们要做的新功能 叫做功能测试 这个功能的目的是 我们公司的大佬希望能够把 测试...
前言 各位早安,书接上回我们已经能够成功抓到整页的文章标题了,今天我们要来破解 PTT 某些版上的是...
今天来介绍一个酷东西:GitBook 图片取自 GitBook 官网 GitBook GitBook...
前言 接着昨天分享的话题,针对成为 Scrum Master 的经历与想法再进行补充。 大家从标题「...