分享画布绘制矩形

news2025/2/25 3:28:58

简介

实现功能,在画布上绘制矩形,移动矩形。

2b8e2dd8156e4e09ab856385ec93dbbc.png

在线演示

绘制矩形

实现代码

<!DOCTYPE html>

<html>

<head>
<title>绘制矩形</title>
</head>

<body>

<div style="margin: 10px">
     <input type="color" />
</div>

<div style="background: #ccc;margin: 10px">
     <canvas></canvas>
</div>

<script>

//获取调色板

const colorPicker=document.querySelector('input')

//获取画布

const cvs=document.querySelector('canvas')

//获取画布上下文

const ctx=cvs.getContext('2d')


init()

//初始化画布

function init(){

    const w = window.innerWidth-50,h=window.innerHeight-80
    //dpr保证高清屏绘制的清晰度
    cvs.width=w*window.devicePixelRatio

    cvs.height=h*window.devicePixelRatio

    cvs.style.width=w+'px'

    cvs.style.height=h+'px'

}

//存储图形数组

const shapes = []

//矩形类

class Rectangle{

    constructor(color,startX,startY){

        //矩形颜色

        this.color = color

        //矩形起始坐标

        this.startX = startX

        this.startY = startY

        //矩形结束坐标

        this.endX = startX

        this.endY = startY

    }

    //get为访问器属性

    //矩形左上角坐标

    get minX(){

        return Math.min(this.startX,this.endX)

    }

    get minY(){

        return Math.min(this.startY,this.endY)

    }

    //矩形右下角坐标

    get maxX(){

        return Math.max(this.startX,this.endX)

    }

    get maxY(){

        return Math.max(this.startY,this.endY)

    }

    //绘制矩形

    draw(){

        //开启路径

        ctx.beginPath()

        //移动到左上角

        ctx.moveTo(this.minX*window.devicePixelRatio,this.minY*window.devicePixelRatio)
        
        //绘制直线到左上角
        
        ctx.lineTo(this.minX*window.devicePixelRatio,this.minY*window.devicePixelRatio)

        //绘制直线到右上角

        ctx.lineTo(this.maxX*window.devicePixelRatio,this.minY*window.devicePixelRatio)

        //绘制直线到右下角

        ctx.lineTo(this.maxX*window.devicePixelRatio,this.maxY*window.devicePixelRatio)

        //绘制直线到左下角

        ctx.lineTo(this.minX*window.devicePixelRatio,this.maxY*window.devicePixelRatio)

        //绘制直线到左上角

        ctx.lineTo(this.minX*window.devicePixelRatio,this.minY*window.devicePixelRatio)

        ctx.save()
        //设置填充颜色

        ctx.fillStyle=this.color

        ctx.fill()

        ctx.strokeStyle='#fff'

        ctx.lineGap='square'

        ctx.lineWidth=3*window.devicePixelRatio

        ctx.stroke()
        ctx.restore()

    }

}

cvs.onmousedown = (e)=>{
    //画布左上角坐标

    const bouding = cvs.getBoundingClientRect()

    const rect=new Rectangle(colorPicker.value,e.offsetX,e.offsetY)

    const shape=getShape(e.offsetX,e.offsetY)

    if(shape){

        //拖动

        const {startX,startY,endX,endY}=shape
        //鼠标的坐标

        const mouseX=e.offsetX

        const mouseY=e.offsetY

        window.onmousemove=(e)=>{

            const disX=e.clientX-bouding.left-mouseX

            const disY=e.clientY-bouding.top-mouseY

            shape.startX=startX+disX

            shape.startY=startY+disY

            shape.endX=endX+disX

            shape.endY=endY+disY

        }

    }else{

        //新增绘制矩形

        shapes.push(rect)

        window.onmousemove=(e)=>{

            rect.endX=e.clientX-bouding.left

            rect.endY=e.clientY-bouding.top

        }

    }

    window.onmouseup=()=>{

        window.onmousemove=null

        window.onmouseup=null

    }

}

function getShape(x,y){
    //画布的绘制顺序倒着来循环,
    for(let i=shapes.length-1;i>=0;i--){
        if(x>=shapes[i].minX&&x<=shapes[i].maxX&&y>=shapes[i].minY&&y<=shapes[i].maxY){
           return shapes[i]
        }

    }
}


function draw(){
    //每一帧注册绘制方法

    requestAnimationFrame(draw)
    //清空画布

    ctx.clearRect(0,0,cvs.width,cvs.height)

    for(const shape of shapes){

         shape.draw()

    }

}

draw()

function emptyCanvas(){
    shapes = []
}
function undo(){
    shapes.pop()
}

</script>

</body>

</html>

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1880981.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot异常处理机制之自定义404、500错误提示页面 - 518篇

历史文章&#xff08;文章累计500&#xff09; 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 《国内最全的Spring Boot系列之六》 《…

Redis持久化(RDB AOF)

Redis持久化 MySQL的事务&#xff0c;有四个比较核心的特性&#xff1a; 原子性一致性持久性&#xff08;和持久化一样&#xff09;&#xff0c;将数据存储在硬盘上&#xff0c;重启主机之后数据仍然存在隔离性 redis是一个内存数据库&#xff0c;把数据存储在内存中&#xff0…

基于SpringBoot的超市进销存系统

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot框架 工具&#xff1a;MyEclipse、Tomcat 系统展示 首页 首页界面图 个人中心 个人中心…

Kafka~特殊技术细节设计:分区机制、重平衡机制、Leader选举机制、高水位HW机制

分区机制 Kafka 的分区机制是其实现高吞吐和可扩展性的重要特性之一。 Kafka 中的数据具有三层结构&#xff0c;即主题&#xff08;topic&#xff09;-> 分区&#xff08;partition&#xff09;-> 消息&#xff08;message&#xff09;。一个 Kafka 主题可以包含多个分…

【OpenREALM学习笔记:13】pose_estimation.cpp和pose_estimation.h

UML Class Diagram 图中红色框为头文件中所涉及到的函数、变量和结构体 核心函数 PoseEstimation::process() 其核心作用为执行位姿估计的处理流程&#xff0c;并返回是否在此循环中进行了任何处理。 在这个函数中判断并完成地理坐标的初始化或这地理坐标的更新。 这里需要…

【算法专题--栈】用队列实现栈 -- 高频面试题(图文详解,小白一看就懂!!)

目录 一、前言 二、题目描述 三、解题方法 ⭐两个队列实现栈 &#x1f95d;解题思路 &#x1f34d;案例图解 ⭐用一个队列实现栈 &#x1f347;解题思路 &#x1f34d;案例图解 四、总结与提炼 五、共勉 一、前言 用队列实现栈 这道题&#xff0c;可以说是--栈…

springcloud第4季 分布式事务seata实现AT模式案例2【经典案例】

一 seata案例 1.1 背景说明 本案例使用seata的at模式&#xff0c;模拟分布式事务场景&#xff1a;【下订单&#xff0c;减库存&#xff0c;扣余额&#xff0c;改状态】 AT模式原理&#xff1a;是2pc方案的演变&#xff0c; 一阶段&#xff1a;业务数据和回滚日志记录在同一…

【MotionCap】conda 链接缺失的cuda库

conda 安装的环境不知道为啥python 环境里的 一些cuda库是空的要自己链接过去。ln 前面是已有的,后面是要新创建的 ln -s <path to the file/folder to be linked> cuda 有安装 libcublas 已经在cuda中 (base) zhangbin@ubuntu-server:~/miniconda3/envs/ai-mocap/lib/…

转让无区域商业管理公司基本流程和要求

无区域公司转让的条件和要求取决于您的业务需求和目标。我们的专业团队将与您合作&#xff0c;深入了解您的公司背景、行业情况和发展计划&#xff0c;为您量身定制适合您的转让方案。无论是公司规模、经营期限、资产状况还是法律形式&#xff0c;我们都将综合考虑确保达到您的…

学习C语言第一步:300行代码实现输出“Hello World“

学习所有语言的第一步几乎都是在控制台输出"Hello World",C语言也是如此&#xff0c;C语言支持结构化编程、词汇范围和递归等特性&#xff0c;C语言编写的代码在稍作修改或无需修改的情况下可以在多种不同的操作系统和平台上编译和运行&#xff0c;同时运行速度极快。…

如何为数据库中的位图添加动态水印

许多数据库存储了以blob或文件形式保存的位图&#xff0c;其中包括照片、文档扫描、医学图像等。当这些位图被各种数据库客户端和应用程序检索时&#xff0c;为了日后的识别和追踪&#xff0c;有时需要在检索时为它们添加唯一的水印。在某些情况下&#xff0c;人们甚至希望这些…

【数组】- 螺旋矩阵 II

1. 对应力扣题目连接 螺旋矩阵 II 题目简述&#xff1a; 给你一个正整数 n &#xff0c;生成一个包含 1 到 n2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。如图&#xff1a; 2. 实现案例代码 public class SpiralMatrix {public static…

网页搜索如何优化效果最好?

可以使用长尾关键词策略&#xff0c;长尾关键词策略是指在SEO优化中&#xff0c;除了使用常规的短关键词外&#xff0c;还深入挖掘和使用那些更长、更具体的关键词。虽然这些关键词的搜索量较低&#xff0c;但竞争也较少&#xff0c;且更具针对性&#xff0c;因此往往能带来更高…

我的世界服务器-高版本服务器-MC服务器-生存服务器-RPG服务器-幻世星辰

生存为主&#xff0c;RPG乐趣为辅&#xff0c;重视每位玩家的建议&#xff0c;一起打造心目中的服务器&#xff0c;与小伙伴一起探险我的世界&#xff01; 服务器版本: 1.18.2 ~ 1.20.4 Q群&#xff1a; 338238381 服务器官网: 星辰毛毛雨-Minecraft高版本生存服务器我的世界…

PMBOK® 第六版 结束项目或阶段

目录 读后感—PMBOK第六版 目录 不论是阶段的收尾还是项目整体的收尾&#xff0c;都应是令人振奋的事。然而&#xff0c;在实际生活中&#xff0c;收尾工作却相当艰难。会遭遇负责人调离、换任&#xff0c;导致不再需要已购产品&#xff1b;项目收尾时对照招标文件或合同&…

[AIGC] 深入了解标准与异常重定向输出

在操作系统和编程环境下&#xff0c;有时我们需要更加精细地控制程序的输入或输出过程&#xff0c;这就涉及到了标准输入输出流&#xff0c;以及重定向的概念。接下来&#xff0c;我们将详细介绍标准输出、标准错误输出&#xff0c;以及如何进行输出重定向。 文章目录 1. 标准输…

企业im(即时通讯)作为安全专属的移动数字化平台的重要工具

企业IM即时通讯作为安全专属的移动数字化平台的重要工具&#xff0c;正在越来越多的企业中发挥着重要的作用。随着移动技术和数字化转型的发展&#xff0c;企业对于安全、高效的内部沟通和协作工具的需求也越来越迫切。本文将探讨企业IM即时通讯作为安全专属的移动数字化平台的…

坏越的小世界的一些修改调整

留言区感觉不够高大上&#xff0c;功能也比较简单。我想了想还是仿照小红书设计一个。 先写个静态 这边想了想是将留言和评论各放一个表和首次加载的放在一个表好。想了想还是选择了后者 不过在sql上这样可能会很麻烦&#xff0c;还是建议分表&#xff0c;看下布局 每次展开会…

QT加载安装外围依赖库的翻译文件后翻译失败的现象分析:依赖库以饿汉式的形式暴露单例接口导致该现象的产生

1、前提说明 VS2019 QtClassLibaryDll是动态库,QtWidgetsApplication4是应用程序。 首先明确:动态库以饿汉式的形式进行单例接口暴露; 然后,应用程序加载动态库的翻译文件并进行全局安装; // ...QTranslator* trans = new QTranslator();//qDebug() << trans->…

支付宝支付之收款码支付

文章目录 收款码支付接入流程安全设计系统交互流程交易状态统一收单交易支付接口请求参数测试结果查询支付撤销支付退款支付退款结果退款说明 收款码支付 继&#xff1a;支付宝支付之入门支付 接入流程 安全设计 支付宝为了保证交易安全采取了一系列安全手段以保证交易安全。…