H5 画布(canvas)的使用、元素的拖拽

2023-11-09

一、画布(canvas)的使用

1. 绘图:画布(canvas)的使用

2. 画布:页面中用于绘制图形的特殊区域,开发人员可以在这个区域内进行自定义图形的绘制

​ (1)创建画布的方法:

<canvas  id="画布的标识" width="宽度"  height="高度">
     您的浏览器不支持画布
</canvas>

(2)获取画布:getElementById(‘canvas的id’)

​(3)获取画笔:使用context对象,语法格式是:

let  context = canvas.getContext('2d')  //context代表的是一支笔

 (4)绘制直线:直线的起始点、直线的终点、描边(设置线条的颜色)

<script>
    let canvas = document.getElementById('canvas') //获取画布
    let context = canvas.getContext('2d') //获取画布
    context.moveTo(100,100) //确定起始点为(100,100) ,即将画笔移动到该点上。moveTo方法用来确定起始点
    context.lineTo(200,200) //确定线条的另一个端点,即终点(200,200)。
    context.stroke() //进行描边,让线条可见(默认的画笔颜色为黑色)
</script>

(5)设置描边的颜色:context.strokeStyle = ‘red’ //设置描边的颜色。颜色值可以是十六进制、颜色名

​ (6)设置端点的形状:使用 lineCap=“属性值” 来设置端点的形状,取值有三种

  • ​ butt:默认值,无端点,显示的是线条的方形边缘
  • ​ round:圆形端点
  • ​ square:方形端点

​ (7)路径的重置:beginPath()

​ (8)闭合路径:closePath()

​ (9)设置线宽:lineWidth = ‘数值’

​ (10)填充路径:fill()

​ (11)设置填充颜色:fillStyle = ‘颜色’

​ (12)画弧线或画圆:arc(x,y,r,开始角,结束角,方向)

  • ​ x,y:确定圆心的坐标
  • ​ r:表示圆形或弧线的半径
  • ​ 开始角:表示弧点的起始位置,通常用Math.PI表示(可以理解为180度)
  • ​ 结束角:表示弧点的结束位置
  •  ​方向:表示绘图的方向(逆时针、顺时针)。默认值为true,表示逆时针,默认值为false,表示顺时针
<body>
    <canvas id="huabu" width="1000" height="1000">
        您的浏览器不支持画布
    </canvas>

    <script>
        //开启画布专属提示
        /** @type {HTMLCanvasElement} */
        let bu = document.getElementById('huabu')//获取画布
        let pen = huabu.getContext('2d')//获取画笔
        pen.lineWidth = 10
        pen.lineCap = 'round'
       
        pen.moveTo(100,100)//确定起始点为(100,100)点,将画笔移动到(100,100)点。moveTo方法用来确定起始点
        
        pen.lineTo(100,200)//确定线条的另一个端点为(200,200)点,即终点。lineTo方法用来确定终点
        pen.lineTo(200,200)
        pen.lineTo(100,100)

        pen.strokeStyle = 'green'
        pen.fillStyle= "blue";
        pen.stroke()
        pen.closePath()
        pen.strokeStyle = 'red'//设置描边的颜色值,可以是16进制,也可以是普通的颜色名字 
        pen.fillStyle = "blue"
        pen.fill()
        pen.stroke()//进行描边,让线条可见(默认的画笔颜色为黑色)
        
        pen.arc(150, 150, 100, 0, Math.PI*2, false);
        pen.fill()

        pen.arc(400,100,30,0,Math.PI*2,false)
        pen.lineWidth = '3'
        pen.stroke()
    </script>
</body>

 (13)画矩形:rect(x,y,width,height),x和y表示矩形左上角的坐标

​ (14)填充矩形:fillRect(x,y,width,height),x和y表示矩形左上角的坐标

​ (15)绘制文本:context.fillText(text,x,y),text表示要绘制的文本,x和y表示坐标位置

​ (16)平移当前的坐标系:context.translate(x,y)

​ (17)设置坐标系的旋转角度:context.rotate(deg)

<body>
    <canvas id="canvas" width="1000" height="1000">
        您的浏览器不支持画布
    </canvas>

    <script>
        let ctx = document.getElementById
            ('canvas').getContext('2d')

        //矩形的框
        ctx.translate(-100, 0)//平移
        ctx.rotate(0.02*Math.PI)
        ctx.rect(120, 120, 180, 100)

        ctx.strokeStyle = 'red'
        ctx.stroke()

        //矩形的块
        ctx.fillStyle = 'green'
        //ctx.rotate(10)
        ctx.fillRect(230, 230, 180, 100)

        //绘制文本
        //ctx.rotate(10)
        ctx.fillStyle = 'skyBlue'
        ctx.fillText('白鹿原', 300, 100)
    </script>
</body>

​ (18)绘制图像:fillImage(image,x,y)

         练习:笑脸

<body>
    <canvas id="xiaolian" width="1000" height="1000">
        笑脸
    </canvas>
    <script>
        let huabu = document.getElementById('xiaolian')
        let pen = xiaolian.getContext('2d')

        //笑脸
        pen.beginPath()
        pen.arc(100, 100, 80, 0, Math.PI * 2, false)
        pen.closePath()
        pen.fillStyle = 'green'
        pen.fill()

        //左眼
        pen.beginPath()
        pen.arc(70, 80, 20, 0, Math.PI, true)
        // pen.closePath()
        pen.lineWidth = 2
        pen.strokeStyle = 'white'
        pen.stroke()

        //左眼珠
        pen.beginPath()
        pen.arc(70,80,10,0,Math.PI*2)
        pen.fillStyle = 'black'
        pen.fill()

        //右眼
        pen.beginPath()
        pen.arc(130,80,20,0,Math.PI,true)
        pen.lineWidth = 2
        pen.strokeStyle ='white'
        pen.stroke()

        //右眼珠
        pen.beginPath()
        pen.arc(130,80,10,0,Math.PI*2)
        pen.fillStyle = 'black'
        pen.fill()

        //嘴巴
        pen.beginPath()
        pen.arc(100,110,50,Math.PI/6,Math.PI/1.2,false)
        pen.lineWidth = 2
        pen.strokeStyle ='white'
        pen.stroke()
    </script>
</body>

         练习:绘制验证码

​ (1)随机颜色:随机生成 r、g、b 值

         ​ a、定义生成随机数函数:

function rn(min,max){ //随机数函数
    return  parseInt(Math.random()*(max-min)+min);
}

         b、随机生成 r、g、b颜色值

function rc(min,max){ //随机颜色的函数
    var r=rn(min,max);
    var g=rn(min,max);
    var b=rn(min,max);
  return `rgb(${r},${g},${b})`;
 }

          c、设置绘制验证码的区域:矩形、浅色背景

var w=120;
var h=40;
var ctx=document.getElementById('canvas').getContext("2d");
ctx.fillStyle=rc(180,230);
ctx.fillRect(0,0,w,h); //在0,0的位置填充一个120*40的矩形

(2)随机文本:随机生成下标,通过下标在字符串或数组中拿到对应的字符

 var pool="ABCDEFGHIJKLIMNOPQRSTUVWSYZ1234567890";
            for(var i=0;i<4;i++){ //生成4个随机的字符
                var c=pool[rn(0,pool.length)];//随机的字符
                var fs=rn(18,40);//字体的大小
                var deg=rn(-30,30);//字体的旋转角度
                ctx.font=fs+'px Simhei'; //设置字号、字体
                ctx.textBaseline="top"; //绘制文本的基线:以上边线为界
                ctx.fillStyle=rc(80,150); //设置填充颜色
                ctx.save(); //保存前面对画笔的设置
                ctx.translate(30*i+15,15); //平移坐标系
                ctx.rotate(deg*Math.PI/180); //设置偏转角度
                ctx.fillText(c,-15+5,-15); //绘制文本
                ctx.restore(); //清除前面画笔的设置,画笔恢复到初始状态
            }

(3)随机画线条(干扰线):端点坐标随机生成、线条的角度随机设置

for(var i=0;i<5;i++){
   ctx.beginPath(); //重置路径
   ctx.moveTo(rn(0,w),rn(0,h)); //设置线条的起点
   ctx.lineTo(rn(0,w),rn(0,h)); //设置线条的终点
   ctx.strokeStyle=rc(180,230); //设置线条的随机颜色
   ctx.closePath(); //关闭路径
   ctx.stroke(); //描边
}

(4)随机画点:圆心坐标随机

for(var i=0;i<40;i++){
      ctx.beginPath();
      ctx.arc(rn(0,w),rn(0,h),1,0,2*Math.PI); //随机确定圆心坐标
      ctx.closePath();
      ctx.fillStyle=rc(150,200); //随机的填充色
      ctx.fill(); //进行填充
}

          练习:在文本框中输入验证码,判断是否正确。设置文本框的样式和验证码在一行中

<head>
    <script src="../12-3周作业/movie/movie_client/js/jquery-3.4.1.js"></script>
</head>
<style>
    input{
        height: 40px;
        margin-top: 40px;
    }
    canvas{
        vertical-align: middle;
        margin-bottom: -110px;
    }
    button{
        margin-left: 200px;
    }
</style>
<body>
    <div>
    请输入验证码:<input type="text" id="input">
    <canvas id="canvas">
        您的浏览器不支持画布
    </canvas>
    <br><br>
    <button type="button" id="btn">验证</button>
    </div>
    <script>
        $(function(){
            var arr = [];
        newchar(arr);
 
        $('canvas').on('click',function(){
            newchar(arr);
        })
        $("#btn").on('click',function(){
            var val = $("#input").val().toLowerCase();
            var num = arr.join("");
            if(val==''){
                alert('请输入验证码!');
            }else if(val == num){
                alert('提交成功!');
                $("#input").val('');
            }else{
                alert('验证码错误!请重新输入!');
                $("#input").val('');
            }
        })
    })
        // 1.随机数
        function random(min,max){
            return parseInt(Math.random()*(max-min)+min)
        }
        // 2.随机颜色
        function color(min,max){
            var r = random(min,max)
            var g = random(min,max)
            var b = random(min,max)
            return `rgb(${r},${g},${b})`
        }
        // 3.绘制验证码区域
        // 3.1设置宽高
        var width = 120
        var height = 40
        // 3.2获取画笔
        let context = document.getElementById('canvas').getContext('2d')
        // 3.3设置填充颜色,浅色
        context.fillStyle = color(180,230)
        // 3.4设置区域形状大小
        context.fillRect(0,0,width,height)
        // 4.随机字符串
        function newchar(arr){
            var str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
            for (let i = 0; i < 4; i++) {   //生成4个随机的字符
                var char = str[random(0,str.length)]   //随机的字符
                
                var font_size = random(18,40)   //字体大小
                var deg = random(-30,30)    //旋转角度
                context.font = font_size + 'px Simhei'  //设置字号、字体
                context.textBaseline = 'top'    //设置文本基线:以上边框为界
                context.fillStyle = color(80,150)   //设置填充颜色
                context.save()  //保存前面对画笔的设置
 
                context.translate(30*i+15,15)   //平移坐标系
                context.rotate(deg*Math.PI/180)     //绘制偏转角度
                context.fillText(char,-15+5,-15)    //绘制文本
                context.restore()   //清除前面画笔的设置,画笔恢复到初始状态
 
                arr[i] = char.toLowerCase()
            }
        }       
        // 5.随机线条
        for (let i = 0; i < 5; i++) {
            context.beginPath() //重置路径
            context.moveTo(random(0,width),random(0,height))    //设置线条的起点
            context.lineTo(random(0,width),random(0,height))    //设置线条的终点
            context.strokeStyle = color(180,230)    //设置线条的随机颜色
            context.closePath()     //关闭路径
            context.stroke()    //描边
        }
        // 6.随机产生的干扰小点
        for (let i = 0; i < 40; i++) {
            context.beginPath()
            context.arc(random(0,width),random(0,height),1,0,2*Math.PI)     //随机确定圆心坐标
            context.closePath()
            context.fillStyle = color(150,200)  //随机填充颜色
            context.fill()  //进行填充
        }       
    </script>
</body>

二、元素的拖拽 (Drag和 Drop)

        元素的拖拽是H5的一个新的特性,是在页面中通过鼠标将元素从一个位置拖放到另一个位置。在 HTML5 中,拖放是标准的一部分,任何元素都能够拖放。
1. 实现过程:
(1)设置元素为可拖放:为了使元素可拖动,设置元素的draggable属性为true

<img src='' draggable='true'>

(2)拖动什么:给document注册一个ondragstart事件

        ondragstart事件调用了一个函数,它规定了被拖动的数据
        a.将被拖放的对象保存起来(即让document记忆下来)

        b.在拖放的过程中可以设置被拖放对象的透明度

(3)放到何处:给document注册一个ondragover事件

        ondragover 事件规定在何处放置被拖动的数据。默认地,无法将数据/元素放置到其他元素中。如果需要设置允许放置,我们必须阻止对元素的默认处理方式。这要通过调用 ondragover 事件的 event,preventDefault) 方法(即: 浏览器会默认阻ondrop事件,所以必须在ondragover事件中阻止默认行为)

(4)当将被拖放的对象放到指定位置后,拖放的动作完成(拖放结束):给document注册一个ondrop事件

2. 拖拽元素支持的事件

  • ondrag: 应用于拖拽元素,在整个拖拽过程中都会调用
  • ondragstart: 应用于拖拽元素,当拖拽开始时调用
  • ondragleave: 应用于拖搜元素,当鼠标离开拖拽元素时调用
  • ondragend: 应用于拖拽元素,当拖拽结束时调用

3. 目标元素支持的事件

  • ondragenter: 应用于目标元素,当拖拽元素进入时调用
  • ondragover: 应用于目标元素,当停留在目标元素上方时调用
  • ondrop: 应用于目标元素,当在目标元素上方松开鼠标时调用
  • ondragleave: 应用于目标元素,当鼠标离开目标元素时调用

4. 基本思想
(1)在拖放开始时在document中保存被拖放元素的id
(2)拖放结束时通过id找到被拖放的元素追加到文档流中

<style>
    * {
        padding: 0;
        margin: 0;
    }
    .div1,
    .div2,
    .div3 {
        margin: 0 20px;
        float: left;
        width: 200px;
        height: 200px;
        border: 1px solid #ccc;
    }
    div,
    p {
        display: flex;
        flex-direction: column;
        align-items: center;
    }
    .p1 {
        width: 50px;
        background-color: darksalmon;
        margin: 5px 0;
    }
    .p2 {
        width: 70px;
        background-color: gold;
        margin: 5px 0;
    }
    .p3 {
        width: 90px;
        background-color: yellowgreen;
        margin: 5px 0;
    }
    .p4 {
        width: 100px;
        background-color: seagreen;
        margin: 5px 0;
    }
    .p5 {
        width: 150px;
        background-color: blueviolet;
        margin: 5px 0;
    }
    .p6 {
        width: 170px;
        background-color: firebrick;
        margin: 5px 0;
    }
</style>

<body>
    <div id="div1" class="div1">
        <p id="pe3" class="p3" draggable="true">3</p>
        <p id="pe2" class="p2" draggable="true">2</p>
        <p id="pe5" class="p5" draggable="true">5</p>
        <p id="pe1" class="p1" draggable="true">1</p>
        <p id="pe4" class="p4" draggable="true">4</p>
        <p id="pe6" class="p6" draggable="true">6</p>
        <a href="http://www.baidu.com" id="a1">百度一下</a>
    </div>
    <div id="div2" class="div2"></div>
    <div id="div3" class="div3"></div>

    <script>
        document.ondragstart = function (e) {
            e.dataTransfer.setData('text', e.target.id)//将被拖放的元素保存起来
            e.target.style.opacity = 0.2//设置被拖放元素的透明度
        }
        document.ondragend = function (e) {
            e.target.style.opacity = 1//拖放结束后,恢复拖放对象的透明度
        }
        document.ondragover = function (e) {//关闭浏览器默认的行为:默认情况下,浏览器不允许拖放
            e.preventDefault()
        }
        document.ondrop = function (e) {
            let id = e.dataTransfer.getData('text')
            e.target.appendChild(document.getElementById(id))
        }
    </script>
</body>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

H5 画布(canvas)的使用、元素的拖拽 的相关文章

随机推荐

  • Linux进程隐藏问题————显示隐藏进程

    阿里云云监控到有两台redis服务器CPU被某进程消耗400 cpu资源 系统查看Top 情况并未找到高消耗进程X7但CPU100 ni Netstat 查找到了一些异常请求 初步判断出组件被提权入侵了 尝试查找异常进程X7关联的文件 排查
  • 解决flutter showDialog下拉框,复选框等无法及时响应的问题

    使用StatefulBuilder showDialogr showDialog context context builder BuildContext ctx return StatefulBuilder builder BuildCo
  • Web Worker API

    Web Worker API Web Worker 使得在一个独立于 Web 应用程序主执行线程的后台线程中运行脚本操作成为可能 这样做的好处是可以在独立线程中执行费时的处理任务 使主线程 通常是 UI 线程 的运行不会被阻塞 放慢 Web
  • Kali 更换源(超详细,附国内优质镜像源地址)

    1 进入管理员下的控制台 2 输入密码后点击 授权 3 在控制台内输入下面的内容 vim etc apt sources list 4 敲击回车后会进入下面的页面 5 来到这个页面后的第一部是按键盘上的 i 键 左下角出现 插入 后说明操作
  • 使用APIKey定向加密对外接口案例

    使用API Key定向加密对外接口案例 整体思路 前端通过某种方式生成一个动态字段 例如时间戳 随机数 UUID 等 前端将动态字段和其他请求参数一起发送给后端 并对请求参数进行加密 后端通过相同的加密算法 使用动态字段生成 API KEY
  • Python解析库lxml与xpath用法总结

    本文主要围绕以xpath和lxml库进行展开 一 xpath 概念 xpath节点 xpath语法 xpath轴 xpath运算符 二 lxml的安装 lxml的使用 lxml案例 一 xpath 1 xpath概念 XPath 是一门在
  • 通用分页的详解(Java后端常用)

    目录 一 通用分页 1 1通用分页是什么 1 2使用通用分页有什么好处 1 3经常在哪使用通用分页 二 往常的通用分页实现及代码 三 通用分页的讲解 思路 具体实现代码 四 JUnit框架的使用 4 1JUnit框架是什么 4 2JUnit
  • 动态加载 JS 文件

    动态加载JS文件是指在网页运行过程中通过JavaScript代码向页面中动态添加外部JS文件 这种方式能够提高页面加载速度和用户体验 并且可以帮助网站实现更多的功能和特效 本文将详细介绍动态加载JS文件的基本原理 优势 注意事项以及具体实现
  • MySQL Workbench 报错 Cannot connect to Database Server

    MySQL Workbench是一款专为MySQL设计的ER 数据库建模工具 可以使用MySQL Workbench设计和创建新的数据库图示 建立数据库文档 以及进行复杂的MySQL迁移 MySQL Workbench是下一代的可视化数据库
  • lstm with attention_一文搞懂NLP中的Attention机制(附详细代码讲解)

    公众号关注 ML NLP 设为 星标 重磅干货 第一时间送达 机器学习算法与自然语言处理出品 公众号原创专栏作者 Don hub 单位 京东算法工程师 学校 帝国理工大学 Outline Intuition Analysis Pros Co
  • 细谈select函数(C语言)

    文章目录 1 介绍 2 例程 例程1 例程2 1 介绍 select 在socket编程中还是比较重要的 可是对于初学Socket的人来说都不太爱用Select写程序 他们只是习惯写诸如connect accept recv 或 recvf
  • C++实现sqrt

    1 题目 给定接口double sqrt int x double delta 请你实现开平方 其中x为底数 delta为最大误差 2 分析实现 直觉 gt 二分法 为了方便处理 将范围砍掉一半 认为0 lt x 0 5 sqrt x lt
  • python算法中的字符串算法(详解)

    目录 学习目标 学习内容 字符串匹配算法 Brute Force算法 KMP算法
  • Vue2中如何使用vue.use对自定义组件/指令进行快速注册?

    在Vue js中 使用 Vue use 方法可以快速注册自定义组件和指令 下面是使用 Vue use 方法进行注册的示例 自定义组件的示例 const MyComponent 组件的选项 template div My Custom Com
  • Java工程师的职业规划(转载牛客)

    作者 牛客229127715号 链接 https www nowcoder com discuss 353149180384321536 sourceSSR search 来源 牛客网 Java工程师的职业规划 最全版本 第一篇 1 初级程
  • C++容器与算法

    容器 某一类型数据的集合 C 标准顺序容器包括 vector list queue 容器初始化 vector
  • QThread定时器

    如何在子线程中启动定时器 MyThread MyThread QObject parent QThread parent printf d construct n this gt currentThreadId MyThread MyThr
  • 【数据结构与算法】leetcode200.岛屿数量

    链接 题目 给你一个由 1 陆地 和 0 水 组成的的二维网格 请你计算网格中岛屿的数量 岛屿总是被水包围 并且每座岛屿只能由水平方向和 或竖直方向上相邻的陆地连接形成 此外 你可以假设该网格的四条边均被水包围 解题 利用深度优先搜索 遍历
  • JAVA环境、Tomcat、Mysql安装,创建IDEA JavaEE项目并使用JDBC连接Mysql

    1 Java环境安装配置 1 下载JDK 下载地址为http www oracle com technetwork java javase downloads index html 下载自己电脑所对应的版本 2 安装JDK和JRE 安装路径
  • H5 画布(canvas)的使用、元素的拖拽

    一 画布 canvas 的使用 1 绘图 画布 canvas 的使用 2 画布 页面中用于绘制图形的特殊区域 开发人员可以在这个区域内进行自定义图形的绘制 1 创建画布的方法