渡一学习笔记:canvas必会、css滤镜、特效、svg

最近菜鸟没来写文章,一是因为被一些bug搞得焦头烂额,二是因为在查漏补缺,感觉自己太菜了,感觉收藏的很多,但是会的很少。

所以菜鸟就把收藏的渡一的教程都刷了一遍,能写代码的就写了,要记的就准备每天都看,感觉渡一的短视频确实不错!但是长视频质量感觉不咋地,反正之前花钱买了几个做活动的课,长的视频就讲得没有短视频好了!

这是我学习的一些成果,代码已经上传到 GitHub 了,感兴趣的可以来看看:github

下面就是我实现的一些效果,代码什么的都在 GitHub 上,注释也很详细,所以这里就展示效果了!

弧形选项卡

弧形选项卡

在这里插入图片描述

其实这是一个长方形设置了上方的border-radius,旁边两个是伪元素,是正方形减去两个半圆(锥型渐变),然后通过旋转得到的!

瀑布流布局

瀑布流布局

在这里插入图片描述

这里的思路就是循环创建图片元素,在图片 onload 之后,设置每个图片的定位!

定位就是要根据图片宽度,看整个屏幕有多少列 + 间隙多大,并根据列数生成一个记录高度的数组(一开始都为0),每次选择最短的列加上图片,并根据图片高度,设置数组数据+父元素高度(因为定位不会撑大父元素)!

手写钉钉动画

手写钉钉动画

在这里插入图片描述

这里的思路可以看我的博客:前端三件套配合MarsCode实现钉钉官网动画 # 豆包MarsCode

鼠标移动的高亮边框效果

鼠标移动的高亮边框效果

在这里插入图片描述

这里的思路就是使用三层实现,边框其实是父元素背景色,内容是子元素缩小一点在父元素里面居中,而高亮就是子元素的 before伪元素,伪元素设置成圆形渐变并根据鼠标位置设置偏移量就行了!

头像超出边框特效

头像超出边框特效

在这里插入图片描述

这个效果一开始看见以为很简单,但是其实有点难,因为边框会被头像盖住,这里没有用渡一的思路,感觉太复杂了,这是菜鸟自己的思路写的!

菜鸟设置了两个容器,把父容器设置得高一点,子容器放到父容器的底部,就可以做到下面超出隐藏,上面不隐藏了,然后边框就是用伪元素设置的,不能使用 border,会被 img挡住!

透明盒子的渐变阴影(clip-path)

透明盒子的渐变阴影(clip-path)

在这里插入图片描述

这里大家一看可能会感觉很简单,直接用一个白色的盒子,放在一个渐变的盒子上不就行了?

但是这里不一样,这里的内容里面是没设置背景色的,也可以实现该效果,具体使用的是背景裁剪!

裁剪思路

在这里插入图片描述

图片3D_Hover倾斜

图片3D_Hover倾斜

在这里插入图片描述

这里的盒子阴影看起来像渐变,其实不是,和上面的效果没有关系,这里就是简单的设置了四个方向的纯色 box-shadow

.card:hover {
  box-shadow: -3px -3px 10px #a1f541, 3px 3px 10px #f1597a,
    -3px 3px 10px #a1f541, 3px -3px 10px #f1597a;
}

这里主要是鼠标移入后改变 css变量,去设置图片的 transform !

图片3D突显效果

图片3D突显效果

在这里插入图片描述

这里就是纯css效果了,和上面没关系,不用跟随鼠标改变偏移量!

就是人物元素一开始看不见,hover 后设置可见并设置 transform,卡片和文字也是设置移入就 transform!

图片9宫格效果

图片9宫格效果

在这里插入图片描述

这里的思路很巧妙,没有用到 js,就纯css 实现的,巧妙的就在于 css 后面的会覆盖前面的,然后通过 列和行 的选择,依次设置好了全部图片的偏移量,用scss可能很简单,但是纯css 能想到很难!

.imgItem {
  width: 200px;
  height: 200px;
  background-image: url(../img/11.png);
  background-size: 600px 600px;
  /* 鼠标划入的偏移 */
  position: relative;
  transition: all 0.3s;
}
/* n 的有关问题见 问题img */
/* 第一列 */
.imgItem:nth-child(3n + 1) {
  left: -20px;
  background-position-x: 0;
}
/* 第二列 */
.imgItem:nth-child(3n + 2) {
  left: 0;
  background-position-x: -200px;
}
/* 第三列 */
.imgItem:nth-child(3n) {
  left: 20px;
  background-position-x: -400px;
}

/* 选横着的不好选,取巧办法 */
/* 1-9 会被 1-6 覆盖,1-6 会被 1-3 覆盖 */
/* 注意 n 的位置不能乱放,见:问题img */
.imgItem {
  top: 20px;
  background-position-y: -400px;
}
.imgItem:nth-child(-n + 6) {
  top: 0;
  background-position-y: -200px;
}
.imgItem:nth-child(-n + 3) {
  top: -20px;
  background-position-y: 0;
}

图片锯齿菱形边缘(mask)

图片锯齿菱形边缘(mask)

在这里插入图片描述

这里设置的思路很难,反正主要是:使用锥形渐变实现一个一个小方块,然后使用线性渐变旋转设置出菱形,再通过mask蒙版显示菱形加小方块,最后背景裁剪,把多余的小方块去掉!

只能说这里菜鸟并不能举一反三,这种还是太牛了!

图片轮播(不无限循环,思路教学)

图片轮播(不无限循环,思路教学)

轮播是前端特效过不去的坎,这里我照着渡一也只学到了不无限循环的思路,循环确实不知道咋搞,只知道要复制元素,但是不知道咋复制,这个感兴趣的读者可以实现了留言,感谢!

在这里插入图片描述

反正思路一般就是这样:

  1. 获取轮播的图片
  2. 设置一个变量记录当前图片索引(表示当前显示的第几张)
  3. 根据当前的索引设置布局(暂不写,整个轮播就是完成这个函数)–> 除了这个基本都是通用的
  4. 获取两个按钮
  5. 按钮添加事件
  6. 添加点击轮播图事件

其中3就是要循环图片元素,针对每个图片按照需求设置样式就行了。

图片上下视差滚动

图片上下视差滚动

在这里插入图片描述

这里的思路就是,先写出css,能通过添加class 实现上下滚动的效果!然后就是设置index,并通过index 每次都准备三个元素,前一张、当前一张、后一张,然后监听鼠标滚动,实时的去修改index,等transitionend 事件结束就移除加的class就行!

图片旋转视差效果

图片旋转视差效果

在这里插入图片描述

这里就是使用grad布局,然后让其旋转,而里面的图片反向旋转就行了!

需要学习的是,当动画是类似的时候,只是方向、角度等不一样,完全可以使用css 变量,共用同一个动画

/* 动画 */
.container {
  --r: 360deg;
}
.item img {
  --r: -360deg;
}
@keyframes ratation {
  to {
    transform: rotate(var(--r));
  }
}

文字标题丝滑动画

文字标题丝滑动画

在这里插入图片描述

只要搞定一个文字的运动,其他的都延时就行了!

p 元素内容转成 span

这里主要是要学会将 p 元素内容转成 span !

const pArr = document.querySelectorAll(".title");

let time = 0;
for (let i of pArr) {
  // 将 p 转成 span 通用函数
  i.innerHTML = i.textContent
    .split("")
    .map((e, i, arr) => {
      // console.log(time);
      time = time + 0.2;
      return `<span style='--delay:${time}s'>${e}</span>`;
    })
    .join("");
}

连续阴影

连续阴影

/* 不能直接设置6px,会分离 */
text-shadow: 1px 1px #333, 2px 2px #333, 3px 3px #333, 4px 4px #333,
  5px 5px #333, 6px 6px #333;

文字交错排列

文字交错排列

在这里插入图片描述

这里用到的和上面一样的思路,还是要把p转成span!设置letter-spacing为负数,让文字可以层叠,然后使用 定位+阴影 让前面的压在上面!

.overlap span {
  letter-spacing: -20px;
  /* 用阴影,后面的盖住前面的 --> 想到定位 */
  text-shadow: 10px 0px 5px red;
  position: relative;
}
const text = document.querySelector(".overlap");
// 不能用 outerHTML --> 有标签+class之类的东西
// 将 p 转成 span 通用函数
text.innerHTML = text.textContent
  .split("")
  .map((t, i, arr) => `<span style="z-index:${arr.length - i}">${t}</span>`)
  .join("");

文字交融展开

文字交融展开

在这里插入图片描述

这里的思路也是设置letter-spacing为负数,让文字可以层叠,重点是filter: blur(10px); filter: contrast(30);

文字连续光影效果

文字连续光影效果

在这里插入图片描述
这里也是要把p换成span,然后设置一个span的样式出来了,其他的设置延时就都可以了。

这里看着是慢慢渐变,但是对于一个span来说,其实就是由白色变成红色!

span {
  font-size: 10vw;
  color: #fff;
  /* alternate 表示无穷动画的时候,间隔位置的动画要反向 */
  animation: spread 2s var(--delay) ease-in-out infinite alternate;
}
@keyframes spread {
  to {
    color: red;
    text-shadow: 20px 0 70px red;
  }
}

文字镂空

文字镂空

在这里插入图片描述

这里思路其实很简单,就是把背景盖住,然后文字的背景也搞成背后的背景,然后使用background-clip: text;并设置文字颜色为透明就行!

文字下划线动画

文字下划线动画

在这里插入图片描述

这里看着很简单,其实很难!必须用span这种行盒,块盒无法实现,行盒的背景才是跟随文字的

知道了这个特性其实就不难了,剩下的就是设置背景了!

.title span {
  /* 思考什么东西可以跟着行盒的方向一行行走:background */
  background-image: linear-gradient(90deg, greenyellow, red);
  background-repeat: no-repeat;
  /* 一开始是: bottom left,但是鼠标移出是回退回去,和效果不符合!*/
  background-position: bottom right;
  background-size: 0px 2px;
  transition: background-size 0.5s linear;
}

.title:hover span {
  background-position: bottom left;
  background-size: 100% 2px;
}

文字自动适配背景

文字自动适配背景

在这里插入图片描述

这里主要就是使用了css的滤镜 mix-blend-mode: difference;

下拉菜单过渡效果

下拉菜单过渡效果

在这里插入图片描述

这里的思路适用于很多,高度未知的内容显示问题

菜鸟这里使用了4种方式,个人感觉js方式还是最好的:

const input = document.querySelector(".text");
const select = document.querySelector(".select");

input.onfocus = function () {
  select.style.height = "auto";
  // 获取设置自动高度后的select的高度
  const selectHeight = select.offsetHeight;
  // 这两句必须有,不然过渡效果有问题
  select.style.height = 0;
  select.offsetHeight; // --> 强制触发重排
  // 将值赋值给select的style
  select.style.height = selectHeight + "px";
};

input.onblur = function () {
  select.style.height = 0;
};

圆形放大的hover效果

圆形放大的hover效果

在这里插入图片描述

这里思路是三层,图片元素作为最底层,然后before元素作为遮盖层,最后after元素设置clip-path即可完成

.card::after {
  /* 继承父元素的背景图 */
  background: inherit;
  clip-path: circle(0% at 50% 50%);
  transition: all 0.3s;
}
/* 书写顺序不能反 见 问题img */
.card:hover::after {
  clip-path: circle(50% at 50% 50%);
}

animation-delay实现动画

animation-delay(动画延时) 实现动画

这里的思路可能对一些复杂动画有帮助!

在这里插入图片描述

这里的思路是,将动画提前多少秒执行,那么现在就是执行多少秒时的状态!

.aniBox {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background-color: red;
  /* 注意:1s、paused都必须加上;滑块得max和1s保持一致,这里多少秒那边就多大! */
  /* 不带1s,那么var(--delay)就变成动画时间了 */
  /* 不加paused,那么直接完成动画了,就不会停住 */
  animation: move 1s var(--delay) linear forwards paused;
}

@keyframes move {
  to {
    transform: translateX(200px);
  }
}
const range = document.querySelector(".range");
const aniBox = document.querySelector(".aniBox");

// 避免js进行复杂计算,不管实现什么延时实现动画,基本上都是这个js就行!
const calc = () => {
  aniBox.style.setProperty("--delay", `-${range.value}s`);
};
range.oninput = calc;
calc();

canvas 常用方法

1、初始化

初始化canvas

const canvas = document.querySelector(".canvas");
const ctx = canvas.getContext("2d");

// 解决清晰度问题
canvas.width = window.innerWidth * devicePixelRatio;
canvas.height = window.innerHeight * devicePixelRatio;

这个是一般做法,要是想画图片或者视频,就要设置宽高为图片或者视频的宽高,eg:

在这里插入图片描述

在这里插入图片描述

2、重置坐标系

重置坐标系

canvas的坐标系,初始是容器左上角!

// 今后可以用这种方式重置坐标系!
// 对画布进行变形,让画布原点在底部中心位置
ctx.translate(canvas.width / 2, canvas.height);
// 此时的y轴指向下,反向一下
ctx.scale(1, -1);

3、遍历像素点

遍历像素点

// w --> canvas宽度    h --> canvas高度
for (let i = 0; i < w; i++) {
  for (let j = 0; j < h; j++) {
    // 获取index
    let index = (i + w * j) * 4;
    const r = data[index];
    const g = data[index + 1];
    const b = data[index + 2];
    const a = data[index + 3];
  }
}

这里的 data 由 5 获取!

4、获取点击点 index+rgba

获取点击点 index+rgba

// 点击处的 x,y 和 imgdata 的 index 的对应关系
function point2Index(x, y) {
  return (x + y * canvas.width) * 4;
}

// 获取图片点击地方的rgba值
function getRgba(x, y, imgData) {
  const index = point2Index(x, y);
  return {
    r: imgData.data[index],
    g: imgData.data[index + 1],
    b: imgData.data[index + 2],
    a: imgData.data[index + 3],
  };
}

这里的 imgData 由 5 获取!

5、获取canvas图片

获取canvas图片

// 获取imgdata --> 设置获取区域
const { width, height, data } = ctx.getImageData(
  0,
  0,
  canvas.width,
  canvas.height
);

或者

// 获取imgdata
const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);

6、画 图片/视频 到canvas

画 图片/视频 到canvas

ctx.drawImage(img/video, 0, 0, canvas.width, canvas.height);

这里的 img/video,都是document对象!

7、修改canvas

修改canvas

// 简写:从index开始,替换成changeColor数组中的几个值 --> 一般四个,对应rgba
imgData.data.set(changeColor, index);

// 修改后绘制
ctx.putImageData(imgData, 0, 0);

这里的 imgData 由 5 获取!

canvas 处理图片

在这里插入图片描述

这里使用的就是 1、4、5、7

剩下的 canvas 我只放效果,没有效果的我就只放一个标题,具体代码去 GitHub 上学习就行!

canvas画随机树

canvas画随机树

在这里插入图片描述

canvas获取视频帧

canvas获取视频帧

canvas阴影画出图片

canvas阴影画出图片

这里不是canvas画出图片,而是canvas根据获取到图片的像素,然后设置一个 1px X 1px 的元素的阴影,让其显示出和图片一样的效果!

在这里插入图片描述

生成的html

在这里插入图片描述

canvas粒子时钟

canvas粒子时钟
在这里插入图片描述

canvas动画(点+线)

canvas动画(点+线)
在这里插入图片描述
动画的思路就是在一小断时间内更新坐标,清空画布重新画内容就行!

draw() {
    // 添加动画
    requestAnimationFrame(() => {
      // 如何保证点运动 --> 点的class里面
      this.draw();
    });
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ....
}

svg描边动画 (通用)

在这里插入图片描述
这里的思路就是设置svg的 stroke-dasharraystroke-dashoffset 都为其本身长度,然后设置动画结束时 stroke-dashoffset: 0; 即可!

获取svg长度

const path = document.querySelectorAll(".p");
for (let i of path) {
  // 获取 svg 的长度
  const l = i.getTotalLength();
  i.style.setProperty("--l", `${l}`);
}

剩下的两个菜鸟也是无法举一反三,其中还有一个压根不生效,读者可以看看能不能解决,希望解决的大佬可以留言!

svg实现按钮故障波纹

在这里插入图片描述

svg实现文字适应纹理(无效,求助)

学习地址:www.bilibili.com/video/BV1Yx4y1h7kC

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PBitW

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值