canvas画布

使用canvas步骤:

1. 创建canvas标签

2. 给canvas标签设置 width height 属性

3. 通过js 获取canvas标签

4. 通过canvas标签获取context画布上下文(画布对象)

5. 通过context绘制画布

<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>canvas {border: 3px solid #000;/* 样式的宽高也可以设置canvas标签的大小,但不是真实的像素值而是拉伸后的大小 */width: 800px;height: 600px;}</style>
</head><body><canvas width="400" height="300"></canvas>
</body><script>const canvas = document.querySelector('canvas')// 获取canvas标签的画布对象// 可以通过操作画布对象来进行绘画const ctx = canvas.getContext('2d')// 绘制一个实心矩形ctx.fillRect(100, 50, 100, 100)
</script>

绘制矩形

<script>const canvas = document.querySelector('canvas')const ctx = canvas.getContext('2d')// 改颜色ctx.fillStyle = '#f00'// 绘制实心矩形(rectangle)// ctx.fillRect(x, y, w, h)// x: 水平坐标// y: 竖直坐标// 坐标原点在canvas左上角// w: 宽度// h: 高度ctx.fillRect(50, 100, 150, 50)// 镂空矩形// 参数和实心矩形相同ctx.strokeRect(300, 100, 200, 100)// 清空矩形, 用于清空画布ctx.clearRect(0, 0, 800, 600)
</script>

绘制文本

<script>const canvas = document.querySelector('canvas')const ctx = canvas.getContext('2d')// 修改字体大小和字体库ctx.font = '32px 华文琥珀'ctx.fillStyle = '#f00'// 绘制实心文字// 语法:ctx.fillText(text, x, y, max-width)// text: 要渲染的文本// x,y: 文本渲染的坐标位置// max-width: 文本最大宽度,当大于该宽度,文本字体将自动缩小以自适应宽度// ctx.fillText('祖国万岁!!', 200, 100, 100)ctx.fillText('祖国万岁!!', 200, 100)ctx.strokeStyle = '#0f0'// 镂空文字// 参数和实心文本相同ctx.strokeText('祖国万岁!!', 200, 300)</script>

画线

<script>const canvas = document.querySelector('canvas')const ctx = canvas.getContext('2d')// 设置颜色和线宽ctx.strokeStyle = '#ff0'ctx.lineWidth = 15// 画线分两个步骤:// 1. 描点(设置路径)// 2. 画线(将所描的点连接起来)// 步骤一// 使用 beginPath 开启路径ctx.beginPath()// 移动笔头但不会记录路径上的线条ctx.moveTo(400, 100)// 用线绘制到下一个点ctx.lineTo(200, 200)ctx.lineTo(600, 200)ctx.lineTo(400, 100)// 将路径封闭ctx.closePath()// 注意:beginPath在画新的路径的时候必须调用,closePath选择性调用// 步骤二// 为了显示图形需要调用以下函数// 将路径所包围的图形用纯色来填充// ctx.fill()// 将路径用镂空线条进行绘制ctx.stroke()ctx.strokeStyle = '#f00'ctx.beginPath()ctx.moveTo(400, 400)ctx.lineTo(500, 400)// 角度转弧度的公式: rad = (PI / 180) * deg// 弧线// ctx.arc(x, y, r, start, end)// x: 圆心横坐标// y: 圆心纵坐标// r: 圆半径// start: 起始弧度 0度时的方向为水平向右 顺时针为正方向// end: 结束弧度ctx.arc(400, 400, 100, 0, Math.PI / 180 * 30)ctx.closePath()ctx.fill()// ctx.stroke()
</script>

swiper布局和初始化配置

<body><div class="swiper"><!-- swiper-wrapper 展示内容的包装器 --><div class="swiper-wrapper"><!-- swiper-slide 每一个 swiper-slide 就是一个滑动块 --><div class="swiper-slide">Slide 1</div><div class="swiper-slide">Slide 2</div><div class="swiper-slide">Slide 3</div></div><!-- 分页工具节点 --><div class="swiper-pagination"></div><!-- 导航按钮节点 --><div class="swiper-button-prev"></div><div class="swiper-button-next"></div><!-- 滚动条节点 --><div class="swiper-scrollbar"></div></div>
</body>
<script>// 初始化创建 swiper 对象// 第一个参数:代表swiper容器的选择器// 第二个参数:初始化配置项,是一个json对象// 初始化swiper https://swiperjs.com/get-started#initialize-swiper// 配置项参考地址:https://swiperjs.com/swiper-api#parametersconst swiper = new Swiper('.swiper', {// 滚动方向direction: 'horizontal',// 循环loop: false,// 特效effect: 'coverflow',// allowSlideNext: false,// 分页模块pagination: {el: '.swiper-pagination',},// 导航模块navigation: {nextEl: '.swiper-button-next',prevEl: '.swiper-button-prev',},// 滚动条模块scrollbar: {el: '.swiper-scrollbar',},});
</script>

正则表达式

<script>let regex = /^$/// \ 斜杠:转义// 转义的意思就是转变字符原有的含义regex = /\$$/console.log(regex.test('agsddgsdf$'))// ^ :匹配字符串的开头regex = /^star/console.log(regex.test('star war'))// $ :匹配字符串的结尾regex = /end$/console.log(regex.test('legend'))// ------------------- 匹配字符个数的符号// 这些匹配字符个数的符号,代表的意思是:匹配前一个字符多少次// * :匹配任意次regex = /^a*bc/console.log(regex.test('bc')) // => trueconsole.log(regex.test('abc')) // => trueconsole.log(regex.test('aaabc')) // => trueconsole.log(regex.test('1bc')) // => false// ? : 匹配0次或1次regex = /^go?d$/console.log(regex.test('god')); // => trueconsole.log(regex.test('gd')); // => trueconsole.log(regex.test('good')); // => false// + : 匹配至少1次regex = /^go+d/console.log(regex.test('god')); // => trueconsole.log(regex.test('good')); // => trueconsole.log(regex.test('goood')); // => trueconsole.log(regex.test('gd')); // => false// {n} : 匹配指定次数regex = /^go{3}d/console.log(regex.test('goood')); // => trueconsole.log(regex.test('gooood')); // => falseconsole.log(regex.test('good')); // => false// {n,} : 匹配至少n次regex = /^go{3,}d/console.log(regex.test('goood')); // => trueconsole.log(regex.test('gooood')); // => trueconsole.log(regex.test('good')); // => false// {n,m} : 匹配至少n次,之多m次regex = /^go{2,4}d/console.log(regex.test('good')); // => trueconsole.log(regex.test('goood')); // => trueconsole.log(regex.test('gooood')); // => trueconsole.log(regex.test('god')); // => falseconsole.log(regex.test('goooood')); // => false// ------------------- 匹配字符个数的符号 - end// [xyz]: 匹配字符集合,匹配一个字符,该字符在方括号内regex = /^[xyz]ok/console.log(regex.test('xok')); // => trueconsole.log(regex.test('yok')); // => trueconsole.log(regex.test('zok')); // => trueconsole.log(regex.test('aok')); // => false// x|y : 或regex = /^(good|bad)$/console.log(regex.test('good')); // => trueconsole.log(regex.test('bad')); // => trueconsole.log(regex.test('ok')); // => false// [^xyz]: 匹配负值集合,匹配一个字符,该字符不在方括号内regex = /^[^xyz]ok/console.log(regex.test('xok')); // => falseconsole.log(regex.test('yok')); // => falseconsole.log(regex.test('zok')); // => falseconsole.log(regex.test('aok')); // => true// [a-z] [0-9] : 取范围值,匹配一个字符,该字符在指定范围内regex = /^[a-z][A-Z][0-9]/console.log(regex.test('vE6')); // => trueconsole.log(regex.test('eU4')); // => trueconsole.log(regex.test('AU4')); // => false// [^5-7]: 取范围负值,匹配一个字符,该字符不在指定范围内regex = /^[^5-7]/console.log(regex.test('1')); // => trueconsole.log(regex.test('2')); // => trueconsole.log(regex.test('6')); // => false// ------------------- 分组 (pattern)// (pattern): 将pattern里面的所有字符当作一个字符处理regex = /^(abc)d/console.log(regex.test('abcd')); // => true// 站在字符串的角度看,圆括号不仅有分组的作用,同时,它将被取值console.log('abcd'.match(regex))// (?:pattern): 匹配分组内容,但不获取圆括号中的值regex = /^(?:abc)d/console.log(regex.test('abcd')); // => trueconsole.log('abcd'.match(regex))// -------------------- 预查询// 预查询:正则表达式会去匹配预查询中的内容,但不会进行取值// 预查询分方向:前后方向// (?=pattern) :后置预查询regex = /Windows(?=95|97|2000)/console.log('Windows95'.match(regex))// (?!pattern): 负后置预查询regex = /Windows(?!95|97|2000)/console.log('WindowsVista'.match(regex))// (?<=pattern) : 前置预查询regex = /(?<=95|97|2000)Windows/console.log('97Windows'.match(regex))// (?<!pattern) 负前置预查询regex = /(?<!95|97|2000)Windows/console.log('XPWindows'.match(regex))

微信小程序

小程序项目结构

components: 小程序的自定义组件

images: 图片文件夹

pages: 存放页面文件的文件夹

index: 页面文件夹

index.js: 页面的js代码

index.json: 页面的配置

index.wxml: html模板文件

index.wxss: 页面的样式文件

app.js: 微信小程序的程序入口(程序入口:开始执行代码的地方)

app.json: 小程序应用程序的全局配置文件

app.wxss: 小程序的全局样式(.wxss文件是小程序的样式文件)

envList.js: 小程序云环境列表

project.config.json: 小程序项目的配置

sitemap.json: 小程序路由配置

常用标签

<!-- page 标签相当于 html 中的 body -->
<page></page><!-- view 标签相当于 html 中的 div -->
<view></view><!-- text 相当于 html 中的 span -->
<text></text><!-- image 相当于 html 中的 img -->
<image></image><!-- block 是一个自身不会显示的标签 -->
<block></block>

模板语法

循环渲染作用:可以将数组数据循环显示到页面中语法:<!-- wx: 开头的写在标签头部的东西 称为指令 -->
<!-- array: 来自js data中的数组 -->
<!-- 使用 wx:for 一定要加上 wx:key,wx:key的值是array对象中的不可重复的属性 -->
<view wx:for="{{array}}" wx:key="id"><!-- index: 是 wx:for 中隐式声明的变量,代表循环遍历array时的当前索引 --><!-- item: 是 wx:for 中隐式声明的变量,代表循环遍历array时的当前数组成员 -->{{index}}: {{item}}
</view>## 条件渲染可以根据条件判断,选择性的渲染页面语法:<view wx:for="{{table}}" wx:key="name"><text>{{index}}: 姓名 = {{item.name}}; 年龄 = {{item.age}}; 性别 = </text><!-- wx:if 指令的值为布尔表达式,为true是渲染该节点,否则不渲染 --><text wx:if="{{item.sex==='male'}}">男</text><!-- wx:if 可以和 wx:elif、wx:else 连用 --><text wx:elif="{{item.sex==='female'}}">女</text><text wx:else>其他</text>
</view>

小程序配置

1.全局配置

app.json 文件中的配置是全局配置 影响所有页面

- entryPagePath 小程序启动页的路径

- pages 页面的路径列表

- window 全局窗口的配置

- tabBar 底部选项卡

- debug 开启调试模式

2.页面配置

全局配置下,window中的所有内容,每个页面自身也可以配置

- disableScroll 禁止用户上下滚动页面

- usingComponents 使用组件

云函数


## 定义云函数
1. 在编辑器的 cloudFunctions 文件夹中右键 新建node.js云函数
2. 编辑index.js中的main函数 返回想要的返回值```js// index.js 是入口文件,云函数被调用时会执行该文件导出的 main 方法// event 包含了调用端(小程序端)调用该函数时传过来的参数,同时还包含了可以通过 getWXContext 方法获取的用户登录态 `openId` 和小程序 `appId` 信息const cloud = require('wx-server-sdk')exports.main = async (event, context) => {let a = event.a // 获取函数参数let b = event.b // 获取函数参数let { OPENID, APPID } = cloud.getWXContext() // 这里获取到的 openId 和 appId 是可信的let sum = a + breturn {OPENID,APPID,sum}}```## 调用云函数
1. 必须先初始化云环境
```js
// 在 app.js 的 onLaunch 中初始化云环境
onLaunch() {wx.cloud.init({// env 参数说明://   env 参数决定接下来小程序发起的云开发调用(wx.cloud.xxx)会默认请求到哪个云环境的资源//   此处请填入环境 ID, 环境 ID 可打开云控制台查看//   如不填则使用默认环境(第一个创建的环境)env: 'cloud1-xxxxxx',traceUser: true,})
}
```
2. 初始化完就可以使用 wx.cloud.callFunctions 调用函数了
```js
// 调用云函数
wx.cloud.callFunction({// 云函数名name: 'now',// 要传递的参数data: {x: 1,y: 2},// 通信成功的回调success(res) {console.log('success');console.log(res);console.log(new Date(res.result.now).toString());},// 通信失败回调fail(reason) {console.error('error');console.error(reason);},// 无论成功还是失败// 通信结束后都会调用completecomplete(res) {console.info('complete');console.info(res)}
})

云数据库

### 初始化数据库连接
1. 在 app.js 的 onLaunch 中 初始化数据库//app.js
App({onLaunch: function () {......this.globalData = {}// 初始化数据库const db = wx.cloud.database()// 在全局对象中保存db对象this.globalData.db = db}
})2. 在使用数据库的页面中获取db对象const db = getApp().globalData.db3. 获取要操作的数据库表// 获取数据库表 参数为表名
const collection = db.collection('collectionName')4. 通过表对象执行数据库操作### 插入数据insert() {// 获取插入数据的表格// 参数是表格名const students = db.collection('students')// 使用add函数插入数据students.add({// 要插入到数据库的数据data: {name: '法外狂徒张三',sex: 'other',age: 30},success(res) {console.log(res);},fail(reason) {console.error(reason);}})
}### 查询数据从形式上来分,可以分为 列表查询和分页查询列表查询:适用于手机等移动端查询一个数据列表的查询方法分页查询:用于将数据像书页一样分页码进行查询此处以列表查询为例// 获取数据库表
const students = db.collection('students')
// 查询数据并按照数据的更新时间进行排序
// orderBy 函数用于数据排序
// 第一个参数:排序字段
// 第二个参数:排序方法(是升序asc还是降序desc)
// limit 用于规定返回数据量
// get 查询函数 通常放在链式调用的尾部
students.orderBy('updateTime', 'desc').limit(2).get({success(res) {console.log(res);}
})// 添加查询条件和查询指令
// 查询指令:用于规定如何查询的一些查询方法const _ = db.command // 获取指令对象
// where 添加查询约束(where是约束的意思)
students.orderBy('updateTime', 'desc').limit(2).where({// 参数是个对象// key 要添加约束的对象// value 什么样的约束 此处的例子 是查询 updateTime 字段小于指定值的数据updateTime: _.lt(new Date('Mon Sep 13 2021 09:40:13 GMT+0800'))
}).get({success(res) {console.log(res);}
})### 更新数据update() {const students = db.collection('students')const _ = db.command // 获取指令对象// 获取对应id的文档对象const student = students.doc('cd045e75613eabf80d332db93f080137')student.update({// data 要修改的字段集合data: {// 规范的做法是使用 set 指令经行修改// name: _.set('修成正果张三'),name: '修成正果张三',updateTime: new Date() // 更新时间},success(res) {console.log(res);}})// 多条数据的更新如下// 调用表格的 where 函数添加查询条件students.where({sex: 'male'}).update({ // 调用 update 函数进行更新data: {age: 16},success(res){}})
}### 删除数据remove() {const students = db.collection('students')// 获取对应id的文档对象// 此处的id就是想要删除的数据的idconst student = students.doc('cd045e75613eabf80d332db93f080137')// remove 删除对应id的数据student.remove({success(res) {console.log(res);}})// 批量删除// 调用表格的 where 函数添加查询条件students.where({sex: 'male'}).remove({ // 调用 remove 函数进行删除success(res){}})
}

上传文件

### 选择图片wx.chooseImage({count: 1, // 上传数量sizeType: ['original'], // 图片大小 original 原始大小 compressed 压缩大小sourceType: ['album', 'camera'], // 图片源的类型 album 相册 camera 摄像头success: (res)=>{const filePath = res.tempFilePaths[0] // 零时文件路径urlconst file = res.tempFiles[0] // 文件对象 代表上传的文件},fail(reason) {// 失败的回调},complete() {// 完成的回调}
})### 上传图片// 打开加载中提示
wx.showLoading({title: '加载中'
})wx.cloud.uploadFile({cloudPath: fileName, // 上传到云上的文件路径filePath, // 要上传的文件路径 数据来自于chooseImage时获得的filePathsuccess: res => {console.log('[上传文件] 成功:', res)const fileID = res.fileID // 上传成功的文件id 作为文件的唯一标识符 用来读取图片},complete: () => {wx.hideLoading() // 隐藏加载提示}
})### 读取图片// 通过文件id获取零时文件的资源路径
wx.cloud.getTempFileURL({// fileList 要获取的文件列表 每个成员可以是对象fileList: [{fileID, // 文件idmaxAge: 60 * 60, // 有效期 单位:秒}],// fileList 的成员也可以是字符串// fileList: [//     fileID// ],success: res => {// fileList 是一个有如下结构的对象数组// [{//    fileID: 'cloud://xxx.png', // 文件 ID//    tempFileURL: '', // 临时文件网络链接//    maxAge: 120 * 60 * 1000, // 有效期// }]console.log(res.fileList)this.setData({ url: res.fileList[0].tempFileURL })},fail: console.error
})### 在页面中加入组件
<!-- upload-text 上传文本提示信息max-count 最大上传文件数file-list 组件用的文件列表bind:after-read 读取文件完成后事件bind:delete 点击删除按钮事件-->
<van-uploader upload-text="上传图片" max-count="1" file-list="{{ fileList }}" bind:after-read="afterRead" bind:delete="onDelete"/>### js 部分afterRead(ev) {// 获取用户选择的文件const file = ev.detail.file// 设置对象产生预览图this.data.fileList.push({url: file.url, // 预览图要显示的图片路径name: '图片',status: 'uploading', // 添加上传状态 uploading 上传中 fail 失败 done 完成message: '上传中...' // 当前状态下的文本提示})// 赋值this.setData({ fileList: this.data.fileList })// 获取文件名const fileName = file.url.match(/\/([^\/]+)$/)[1]const fileInfo = this.data.fileList[0]// 上传wx.cloud.uploadFile({cloudPath: 'framework/' + fileName, // 上传到云上的文件路径filePath: file.url, // 要上传的文件路径success: res => {console.log('[上传文件] 成功:', res)const fileID = res.fileID// 修改状态fileInfo.status = 'done'fileInfo.message = '上传成功'},fail: res => {// 修改状态fileInfo.status = 'fail'fileInfo.message = '上传失败'},complete: () => {this.setData({ fileList: this.data.fileList })}})
}// 删除图片
onDelete(ev) {// 获取要删除图片的索引const index = ev.detail.indexthis.data.fileList.splice(index, 1)this.setData({ fileList: this.data.fileList })
}

Web前端第三阶段学习相关推荐

  1. Web前端第三阶段--DOM

    Web前端第三阶段–DOM 文章目录 Web前端第三阶段--DOM DOM树 初识DOM DOM作用 固定元素的读取 标签读取元素 CSS选择器读取元素 class操作 classList 简单实例 ...

  2. react组件卸载调用的方法_好程序员web前端培训分享React学习笔记(三)

    好程序员web前端培训分享React学习笔记(三),组件的生命周期 React中组件也有生命周期,也就是说也有很多钩子函数供我们使用, 组件的生命周期,我们会分为四个阶段,初始化.运行中.销毁.错误处 ...

  3. 黑马程序员之Web前端全栈 · 阶段一 前端开发基础 (3)

    Web前端全栈 · 阶段一 前端开发基础 (3) 说明 三.HTML 标签 1. HTML 语法规范 1.1 基础语法概述 1.2 标签的关系 2. 基本结构标签 2.1 第一个 HTML 2.2 基 ...

  4. web前端大三实训网页设计:餐饮网站设计——烧烤美食山庄(7个页面) HTML+CSS+JavaScript

    web前端大三实训网页设计:餐饮网站设计--烧烤美食山庄(7个页面) HTML+CSS+JavaScript 临近期末, 你还在为HTML网页设计结课作业,老师的作业要求感到头大?HTML网页作业无从 ...

  5. 学习web前端开发,需要学习什么?

    如果要学习web前端开发,需要学习什么? 遇到很多新手,都会问,如果要学习web前端开发,需要学习什么?难不难?多久能入门?怎么能快速建一个网站?工资能拿到多少?还有些让我推荐一些培训机构什么的要去学 ...

  6. 好程序员Web前端教程分享Vue学习心得

    为什么80%的码农都做不了架构师?>>>    好程序员Web前端教程分享Vue学习心得,Vue是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向 ...

  7. 正则至少一个数字_好程序员web前端培训分享JavaScript学习笔记之正则

    好程序员web前端培训分享JavaScript学习笔记之正则,正则表达式,又名 "规则表达式" 由我们自己来书写 "规则",专门用来检测 字符串 是否符合 &q ...

  8. Web前端开发基础三剑客学习知识分享

    Web前端开发基础知识学习路线分享,前端开发入门学习三大基础:HTML.CSS.JavaScript.除此之外还要学习数据可视化.Vue.React.Angular相关框架,熟练运用框架提升开发效率, ...

  9. Web前端与移动开发学习路线图

    文章转载自「开发者圆桌」一个关于开发者入门.进阶.踩坑的微信公众号 这里整理的Web前端与移动开发学习路线图包含初中级两个部分,你可以通过百度云盘下载观看对应的视频 链接: http://pan.ba ...

最新文章

  1. 简述原型链是什么,有什么用处?
  2. python HTTP后台响应服务
  3. Security-OAuth2.0 密码模式之客户端实现
  4. 微软停止与华为合作:Windows暂停供应新订单
  5. MySQL操作权限整理
  6. 动态规划 —— 背包问题 —— 背包问题模版
  7. 记一些Python(Pymysql)建表、增删改查等基础操作(小白适用)
  8. python爬虫select用法_Python爬虫利器二之Beautiful Soup的用法
  9. 生产环境mysql主主同步主键冲突处理
  10. 《CLR Via C# 第3版》笔记之(二十一) - 异步编程模型(APM)
  11. /dev/mapper/centos-root 100% 虚拟机硬盘空间占满
  12. sql查询、删除重复相同数据的语句或只保留一条数据
  13. RV1109人脸识别门禁闸机主板方案
  14. 简历准备(一)—— TPLink
  15. 爬虫基本概念(新手必看)
  16. 2012-03-16
  17. 鸿蒙系统推广时间,鸿蒙系统将全面推广,目标覆盖3亿台设备,第三方IoT可达1亿台...
  18. mybatis动态查询字段、动态更新字段
  19. 苹果人机交互指南_苹果人机界面设计指南的10个见解
  20. synopsys 工具简介

热门文章

  1. abaqus切削为什么没有切屑_Abaqus切削仿真常见问题及其解决个人总结
  2. 详细探究一下何为数字孪生技术,它的来源与价值又为何?
  3. P-Link ARM Cortex-M脱机编程器开源前的一些准备工作----第四章 几个重要的结构体介绍
  4. python_机器学习—数据科学库_DAY01DAY02
  5. C# 使用ToolTip控件实现气泡消息提示
  6. 常用图标png、ico 图标下载,图片格式转换为ico
  7. Sizzle揭秘—Sizzle选择器引擎的入口
  8. NUC977 烧录裸机程序到DDR
  9. 新型冠状病毒的持续了解
  10. 简历之精通 熟练 掌握 熟悉 了解