今天正式进入Canvas的世界了!
老样子先看成品:
今天来做点科技感的画面,橘色是滑鼠的游标,这个是满常看到的:
但在这之前,想先谈一下到底是什麽时候该用SVG,或是Canvas呢?
如果想赶快看code的,就请自行跳过下一环节~
之前在六角的直播上看到P5.js的直播,传送门
其中讲者分享了这一篇日文文章)
讲述在制作动画时, 该选择 CSS , SVG 还是 Canvas。
我再把作者的概念整理了一下:
总之就是CSS&SVG都做不到的时候就用Canvas啦 XDD
不过还满清楚的就是~
CSS就是个直来直往的单脑门家伙,只能给他直球
(直线&圈圈)
SVG是个心思细腻的抖S,所以最适合S曲线
Canvas像是个无所不能的完美情人,可以做到整体的变形~
不过Canvas有个缺点就是不能选DOM
(接受我的全部不然就拉倒)
大家之後做动画也可以参考下~
我是个偷吃步的人嘿嘿,
今天主要参考的教学影片在这里
和这里
JS主要Function和相互关系:
1.点点制造机:构造函数模型做点点!包含以下函式:
- update—>更新座标 让球球移动,然後呼叫border & draw
- border—>判断是不是跑超过边缘了,超过的话让他换个方向
- draw—>画球球
2.画线:让点跟其他点连在一起!
- 2.1 取得距离
- 2.2 取得rgba 数字,再加上算好的透明度,让距离越近,线越深
3.开始绘制 init:呼叫点点制造机,然後呼叫4.的重复绘制
4.重复绘制:一直画点点,重复呼叫自己
- 4.1 画点点
- 4.2 画滑鼠的点点
- 滑鼠移动监听器
来看code吧!
//JS
//这边都先宣告全域变数
var w, h, loopId, id, canvas, ctx, particles, mouseParticle, color;
const options = {
mouseColor : 'rgba(255, 165, 0)', //滑鼠的颜色,让他不一样
particleColor: "rgb(255,255,255)",
lineColor: "rgb(0,181,255)",
particleAmount: 50, //想要多少点点
defaultRadius: 2,
variantRadius: 2,
defaultSpeed: 1,
variantSpeed: 1,
linkRadius: 300,
};
const mouse = {
x: null,
y: null,
}
//5. 监听器
window.addEventListener('mousemove', function(e){
mouse.x = event.x;
mouse.y = event.y;
})
//3. 开始绘制
function init(){
//canvas起手式
canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
//让画布和视窗一样宽高
h = canvas.height = window.innerHeight;
w = canvas.width = window.innerHeight;
//点点制造机
particles = [];
for(var i = 0; i < options.particleAmount; i++){
particles.push(new Particle());
}
mouseParticle = new Particle(true);
animationLoop();
}
//4.重复绘制
function animationLoop(){
ctx.clearRect(0,0,w,h); //要先清除画布~才画新的
drawParticle();
drawMouseParticle();
requestAnimationFrame(animationLoop); //一直叫自己
}
//4.1 画点点
function drawParticle(){
for (var i = 0; i < particles.length; i++){
particles[i].update(); //更新位置
linkPoints(particles[i], particles); //画线
}
}
//4.2 画滑鼠的点点
function drawMouseParticle(){
mouseParticle.update(true);
const isMouse = true;
linkPoints(mouseParticle, particles, isMouse);
}
//2. 画线
//point就是特定一点,hubs就是全部的点
function linkPoints(point, hubs, isMouse){
for (var i = 0; i < hubs.length; i ++){
//计算目前的距离
var distance = checkDistance(point.x, point.y, hubs[i].x, hubs[i].y);
//以我们定义好的options.linkRadius为一个评量单位,算出距离的一个介於0~1的衡量单位
//将透明度定为衡量单位的指标
//正数-->距离越近,opacity越大,线越明显。负数-->就不画线
var opacity = 1 - distance / options.linkRadius;
if(opacity > 0){
//画线宽度
ctx.lineWidth = 0.5;
//将评量单位当成透明度画线
ctx.strokeStyle = `rgba(${getRgbNumber(options.lineColor)[0]},${getRgbNumber(options.lineColor)[1]}, ${getRgbNumber(options.lineColor)[2]}, ${opacity})`;
//如果是滑鼠那一个点的话,就用指定的颜色就好
if(isMouse) ctx.strokeStyle = options.mouseColor;
ctx.beginPath();
ctx.moveTo(point.x, point.y);
ctx.lineTo(hubs[i].x, hubs[i].y);
ctx.closePath();
ctx.stroke();
}
}
}
//2.1 判断距离
function checkDistance(x1, y1, x2, y2){
//就是找直角三角形的斜边距离呀
//pow-->乘幂,这里做2次方, 找sqrt平方根
return Math.sqrt(Math.pow(x2 - x1, 2)+ Math.pow(y2 - y1, 2))
}
//2.2. 取得颜色的数字
function getRgbNumber(color){
//让里面的色彩变成阵列
//正规表达式//是叙述起手式
//\d --> 吻合数字,写法等同於 [0-9]
// + --> 匹配前一字元 1 至多次
// /g -->全部搜寻回传全部结果
return color.match(/\d+/g);
}
// 1. 构造函数模型做点点!
Particle = function(isMouse){
//多做一个isMouse判断是不是滑鼠的点
this.isMouse = isMouse ? isMouse : null;
this.x = isMouse ? mouse.x : Math.random() * w;
this.y = isMouse ? mouse.y : Math.random () * h;
this.color = options.particleColor;
this.radius = isMouse ? 4 : options.defaultRadius * Math.random() * options.variantRadius;
//这边是要前进的方向和速度
this.speed = options.defaultSpeed* Math.random() * options.variantSpeed;
//将想要的角度算成弧度才能丢到Math.cos()& Math.sin()里面算出将要移动的距离
this.directionAngle = Math.floor(Math.random()*360);
this.vector = {
//是要丢弧度进去,2*PI/360*角度
x : Math.cos(this.directionAngle) * this.speed,
y : Math.sin(this.directionAngle) * this.speed
}
this.update = function(){
this.border();
if(this.isMouse){
this.x = mouse.x;
this.y = mouse.y;
}else{
this.x += this.vector.x;
this.y += this.vector.y;
}
this.draw();
}
this.border = function(){
//超过边界时往反方向跑
if(this.x >= w || this.x <= 0){
this.vector.x *= -1
}
if(this.y >= h || this.y <= 0){
this.vector.y *= -1
}
}
this.draw = function(){
ctx.beginPath();
//画个圆点点~(起始点,结束点,半径,起始角度,结束角度)
ctx.arc(this.x, this.y, this.radius , 0, Math.PI * 2);
ctx.closePath();
ctx.fillStyle = this.color;
ctx.fill();
}
}
init();
要考虑的事情很多,满复杂的 XD
如果有更简单的写法也请让我知道!
今天的code在这里
请多多指教!
前言 今天来设置 RecipeList APP 的 tab。 实作 我将要做两个选项卡, 第一个是一...
大家好,昨天我们把图片抓下来之後也标记完了(我个人是用了10000张图片),接下来就是丢进模型训练啦...
首先,先从比较常见的机器学习方法开始,也就是随机森林方法,帮大家快速讲解一下大概(因为主要目的是在写...
从官网的攻略介绍来看,因为安全考量,所以平常都应该使用send_from_directory(),而...
2021/10/5是我在铁人赛发文到达200篇的日子,这四年多来,不知不觉的就这样累积了200篇的文...