资讯专栏INFORMATION COLUMN

前端初学基础知识 3

Chao / 3145人阅读

摘要:根据浏览器设备的绘制限制来更新动画,回调的次数常是每秒次。鼠标移入则停止自动改变树枝状态,转为由鼠标的横纵坐标控制。基本的深拷贝方法数组,等方法,新增运算符对象思路是把对象拆开分别赋值,同样可以使用新增运算符,循环等。

canvas动画

       动画的形成:先画出一幅图,改变其中的一些参数,重新绘制图片...不断的重复形成动画。

fillStyle:设置或返回填充绘画的颜色,渐变或模式

strokeStyle:设置或返回用于笔触的颜色,渐变或模式

fill(): 填充当前路径(如果路径未关闭则会从路径结束点到开始点之间添加一条线)

stroke():绘制已定义的路径。

moveTo():把路径移动到画布中的指定点,不创建线条

beginPath():起始一条路径或重置当前路径

closePath():创建从当前点回到起始点的路径

lineTo():添加一个新点,创建一条连接至该点的线条

clearRect():清除指定矩形内的像素

arc():创建弧或曲线

rotate():创建两点之间的弧或曲线

translate():重新映射画布上的(0,0)位置

drawImage():绘制图像、画布或视频

save():保存当前环境状态

restore():返回之前保存过的路径和状态

getContext():返回一个用于在画布上绘图的环境

requestAnimationFrame():回调例程调用 requestAnimationFrame()。根据浏览器设备的绘制限制,来更新动画,回调的次数常是每秒60次。

canvas学习——树镜
整体逻辑

创建一个类,实例化根元素,递归创建分支直到层数,每层分支长度(length)递减,直至层数>=5;

调用drawBranch生成一张图片

改变树枝展开角度以及位置执行requestA nimationFrame();重复执行;形成动画

将12个不同旋转角度的动画canvas添加到canvas2.围成一圈。

鼠标移入则停止自动改变树枝状态,转为由鼠标的横纵坐标控制。

关键代码理解
class Branch {
    /**
     * 分枝类,以下为参数,都带有默认值
     * 位置 position
     * 长度 length
     * 分支位置 divergeAt
     * 展开角度 angle
     * 层数 depth
     * 分支展开角度变化量 spread
     */
  constructor(position = {x : 0, y: 0}, length = 100, divergeAt = 0.5, angle = 0, depth = 0, spread = 45 * TO_RADIAN) {
    this.position = position;
    this.length = length;
    this.divergeAt = divergeAt;
    this.angle = angle;
    this.depth = depth;

    this.color = "#000";
    this.spread = spread;
    this.branches = [];

    this.grow();
  }

  grow() {
      /**
       * 创建分支,如果canBranch = true(未达到最大分支数量)
       * 新分支长度为父级的0.75,深度加1
       * 展开角度变化spread
       * 由于构造方法中调用了grow方法,所以会不断重复创建上述过程
       */
    if (!this.canBranch) {
      return;
    }

    this.branches = [];

    const nextLength = this.length * 0.75;
    const nextDepth = this.depth + 1;

    this.branches.push(
      new Branch(
        this.growPosition,
        nextLength,
        this.divergeAt,
        this.angle + this.spread,
        nextDepth,
        this.spread
      ),
      new Branch(
        this.growPosition,
        nextLength,
        this.divergeAt,
        this.angle - this.spread,
        nextDepth,
        this.spread
      )
    );
  }

  update(spread, divergeAt) {
    this.spread = spread;
    this.divergeAt = divergeAt;

    this.grow();
  }

  get growPosition() {
    const dl = this.length * this.divergeAt;

    return {
      x: this.position.x + (Math.cos(this.angle) * dl),
      y: this.position.y + (Math.sin(this.angle) * dl),
    };
  }

  get canBranch() {
    return this.depth < maxDepth;
  }
}
    /**
     * 保存当前状态
     * 根据branch类中的数据画图(颜色,直线和圆点)
     * 递归对分支进行绘图
     */
const drawBranch = (branch, phase) => {
  const h = ~~(200 + (160 * phase));
  const l = 50 + ~~(((branch.depth / (maxDepth + 1))) * 50);

  const endX = branch.length;
  const endY = 0;
  const r = 2;

  ctx.save();

  ctx.strokeStyle = `hsl(${h}, 100%, ${l}%)`;
  ctx.translate(branch.position.x, branch.position.y);
  ctx.rotate(branch.angle);

  ctx.beginPath();
  ctx.moveTo(0, 0);
  ctx.lineTo(endX, endY);
  ctx.stroke();
  ctx.closePath();

  ctx.beginPath();
  ctx.fillStyle = `hsl(${h}, 100%, 50%)`;
  ctx.arc(endX, endY, r, 0, PI * 2, false);
  ctx.fill();
  ctx.closePath();

  ctx.restore();

  branch.branches.forEach((b) => {
    drawBranch(b, phase);
  });
};
const loop = () => {
    /**
     * 改变类中参数的值
     * 将第一个canvas添加到在第二个canvas中循环12次每次旋转2PI/12的角度,形成一个环状
     * 调用requestAnimationFrame() 重新根据类中的数据画图
     */
  let phase = rootBranch.spread / maxSpread;

  clear(phase);

  if (autoAnimate) {
    phase = map(Math.sin(autoTick), -1, 1, 0, 1);

    spread = phase * maxSpread;
    divergeAt = map(Math.sin(autoTick), -1, 1, 0, 0.5);

    autoTick += autoSpeed;
  }

  rootBranch.update(spread, divergeAt);

  drawBranch(rootBranch, phase);

  const numSegments = 12;
  const angleInc = PI * 2 / numSegments;
  let angle = tick;

  for (let i = 0; i < numSegments; i++) {
    ctx2.save();
    ctx2.translate(midX, midY);
    ctx2.rotate(angle);
    ctx2.drawImage(canvas, -w / 2, -h / 2);
    ctx2.restore();
    angle += angleInc;
  }

  tick += 0.002;

  requestAnimationFrame(loop);
};
element-ui 安装

npm安装: npm i element-ui -s

cdn

引入
完整引入
import ElementUI from "element-ui";
import "element-ui/lib/theme-chalk/index.css";
Vue.use(ElementUI);
按需引入

需要安装 babel-plugin-component:

npm install babel-plugin-component -D

在.babelrc中添加:

"plugins": [
    "transform-vue-jsx", "transform-runtime",
    [
      "component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
import {Loading, Tabs, TabPane,} from "element-ui";

Vue.use(Loading);
Vue.use(Tabs);
Vue.use(TabPane);
自定义主题 在项目中直接改变scss变量
/* 改变主题色变量 */
$--color-primary: teal;

/* 改变 icon 字体路径变量,必需 */
$--font-path: "~element-ui/lib/theme-chalk/fonts";

@import "~element-ui/packages/theme-chalk/src/index";
命令行主题工具
npm i element-theme -g

之后步骤为:

安装主题

初始化变量文件

修改变量

编译成css

引入

JavaScript 对象的深拷贝

       在星盘改版的时候遇到了相关的问题,数据从父组件传递到子组件,当时没考虑到这方面的问题,只是对数据进行了一层的拷贝,因为当时传进来的数据是有很多层的,所以还是会导致源数据改变。所以总结一下,写成一个方法,这个应该会比较常用。

       Object属于引用类型,对它进行简单赋值(obj1 = obj2)的话只是创建一个指针指向原数据的地址,改变它的值也会改变源数据的值,会造成很多问题。

基本的深拷贝方法
数组

concat,slice 等方法,es6 新增运算符‘...’

对象

思路是把对象拆开分别赋值,同样可以使用es6 新增运算符‘...’,for循环等。

深拷贝的实现

运用递归逐层拷贝。

function depCopy(obj){
    let value;
    if(typeof obj === "object"){
      if(Object.prototype.toString.call(obj).slice(8,-1)==="Array"){
        // debugger;
        value = [];
        for(let i = 0, length = obj.length; i           
               
                                           
                       
                 

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/94178.html

相关文章

  • 我是如何从零开始学习前端

    摘要:相关频道最后的坦白最后我得承认这一次我又标题党了无非是想吸引更多前端初学者进来,希望大家都能少走一些弯路,也希望那些从零开始自学前端的同学更有勇气去面对自己的选择。 我是怎么走上前端开发这条路? 首先,我是个文科生,大学里只学过vb,觉得计算机编程这东西太玄乎,不是我玩得转的。 后来机缘巧合去做了一家互联网创业公司的HR,阅了上千份程序员的简历,面了上百个不同水平不同领域的程序员。跟程...

    mykurisu 评论0 收藏0
  • 前端——基础

    摘要:思路屡清楚后,我们就开始说零基础如何自学前端开发。首先,了解前端是干什么用的,简单来说就是负责把网站的页面以一种更好的用户体验提供给客户的一份工作,就是做网站开发的。其实这个问题很简单,我用最简单的语言给大家描述一下,学习一样东西就要了解这样东西学完了要干什么事情,有什么作用。然后就是应该学习哪些必要的内容,该如何运用得当的方法进行有效率的学习不至于自己摸不着头脑,然后就是一直坚持下去,直到...

    番茄西红柿 评论0 收藏0
  • Java 初学者做的第一个微信小程序总结--关于Java基础

    摘要:官方资料微信公众平台注册小程序。官网开发文档社区开发工具部署微信小程序微信小程序本身不需要部署,在微信开发工具中直接上传代码就行。 为什么 学习 Java 三年,目前已经工作了2年,因为自学,基础差,所以打算年末总结一下常见的基础知识和面试点; 也可以通过独立做一个项目整合自己工作期间学习的知识,加深印象。 但是想着回家或是平时手机用的多,做一款APP和小程序很方便查看。 项目展示 本...

    mudiyouyou 评论0 收藏0
  • 基础前端开发初学者应如何系统地学习?

    摘要:在有了基础之后,进一步学习内容包括框架。前端学习交流群禁止闲聊,非喜勿进。代码提交前必须做的三个事情检查所有变更跑一边单元测试手动运行一遍所有 网站开发开发大致分为前端和后端,前端主要负责实现视觉和交互效果,以及与服务器通信,完成业务逻辑。其核心价值在于对用户体验的追求。可以按如下思路学习系统学习: 基础知识: html + css 这部分建议在 w3school 在线教程上学习,边...

    JouyPub 评论0 收藏0
  • 基础前端开发初学者应如何系统地学习?

    摘要:在有了基础之后,进一步学习内容包括框架。前端学习交流群禁止闲聊,非喜勿进。代码提交前必须做的三个事情检查所有变更跑一边单元测试手动运行一遍所有 网站开发开发大致分为前端和后端,前端主要负责实现视觉和交互效果,以及与服务器通信,完成业务逻辑。其核心价值在于对用户体验的追求。可以按如下思路学习系统学习: 基础知识: html + css 这部分建议在 w3school 在线教程上学习,边...

    funnyZhang 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<