当前位置: 首页 > news >正文

UNIAPP利用canvas绘制图片和文字,并跟随鼠标移动

最近有个项目,要触摸组件,产生一条图片跟随移动,并显示相应的文字,在网上找了一些资料,终于完成构想,废话少说,直接上代码(测试通过)

<template>
    <view>
        <view class="btnBox">
            <view class="btn" style="background-color: blue;" @click="moveImage">移动图片</view>
        </view>
        <canvas canvas-id="myCanvas" id="myCanvas" @touchstart="handleTouchStart" @touchmove="handleTouchMove"
            @touchend="handleTouchEnd"></canvas>
    </view>
</template>

<script>
    export default {
        data() {
            return {
                ctx: '',
                beginX: '',
                beginY: '',
                movedX: '',
                movedY: '',
                layers: [],
                toBase64Url: "",
                bloburl: "",
            }
        },
        onLoad() {
            this.ctx = uni.createCanvasContext('myCanvas')
        },
        methods: {
            moveImage() {
                let that = this;
                var Image = "";
                //var Image="https://www.small-helper.com/account.png";//网络图片地址
                //Image="http://localhost:8080/static/images/wx_img/dkk.png"//本地服务器内图片直接地址
                uni.getImageInfo({
                    src: '/static/images/wx_img/dkk.png',
                    success: function(res) {
                    //    console.log(res);
                        Image = res.path;
                        var contentWidth = res.width;
                        var contentHeight = res.height;
                        //
                        let layer = {
                            type: 'photo',
                            resoure: Image,
                            //resoure:"http://localhost:8080/static/images/wx_img/dkk.png",
                            x: 0,
                            y: 0,
                            w: 150,
                            h: 150,
                            isDrag: false
                        }
                        that.layers.push(layer);
                        that.darwImages(Image, layer.x, layer.y, layer.w, layer.h);
                    },
                    fail() {
                        that.$Common.toast(";获取图片失败")
                    }
                });
                
                /*从相册获取图片进行移动
                uni.chooseImage({
                    success: (res) => {
                        let layer = {
                            type: 'photo',
                            resoure: res.tempFilePaths[0],
                            x: 0,
                            y: 0,
                            w: 200,
                            h: 150,
                            isDrag: false
                        }
                        //console.log(res.tempFilePaths[0]);
                        that.urlTobase64("/static/images/wx_img/dkk.png");
                        console.log(that.toBase64Url);
                        //let bloburl=that.dataURLToBlob(url);
                        that.layers.push(layer);
                        this.darwImages(res.tempFilePaths[0],layer.x,layer.y,layer.w,layer.h)
                     
                    }
                })*/
            },
            darwImages(url, x, y, w, h) {
                this.ctx.drawImage(url, x, y, w, h);//设置图片初始位置
                this.ctx.setFontSize(uni.upx2px(40));//设置字体尺寸
                this.ctx.setFillStyle("#5500ff");
                //this.ctx.font = "songti";
                this.ctx.fillText('nihao',x+50,y-1);
                this.ctx.draw(true);
            },
             draw() {
                //var ctx = document.getElementById('canvas').getContext('2d');
                var img = new Image();
                img.onload = function() {
                    //this.ctx.drawImage(img, 0, 0);
                    this.ctx.beginPath();
                    this.ctx.moveTo(30, 96);
                    this.ctx.lineTo(70, 66);
                    this.ctx.lineTo(103, 76);
                    this.ctx.lineTo(170, 15);
                    this.ctx.stroke();
                    this.ctx.fillText('nihao',10,100);

                };
                img.src = "/static/images/wx_img/dkk.png";
                //img.src = 'https://mdn.mozillademos.org/files/5395/backdrop.png';
            },
            
            //可通过此方法对本地路径 如: …/…/static/img/01.png 或者网络路径图片转为base64
            urlTobase64(url) {
                var that = this;
                //var toBase64Url;
                uni.request({
                    url: url,
                    method: 'GET',
                    responseType: 'arraybuffer',
                    success: async res => {
                        let base64 = wx.arrayBufferToBase64(res.data); //把arraybuffer转成base64
                        that.toBase64Url = 'data:image/jpeg;base64,' + base64; //不加上这串字符,在页面无法显示
                        //console.log(that.toBase64Url);
                        //return toBase64Url ;

                        return (that.dataURLToBlob(that.toBase64Url));

                    }
                });
            },
          
            

            // DataURL转Blob对象
            dataURLToBlob(dataurl) {
                console.log(dataurl);
                var arr = dataurl.split(',');
                var mime = arr[0].match(/:(.*?);/)[1];
                var bstr = atob(arr[1]);
                var n = bstr.length;
                var u8arr = new Uint8Array(n);
                while (n--) {
                    u8arr[n] = bstr.charCodeAt(n);
                }
                var dataURL1 = this.windowURL.createObjectURL(new Blob([u8arr], {
                    type: mime
                }));
            //    console.log(dataURL1);
                return new Blob([u8arr], {
                    type: mime
                });
                //console.log(new Blob([u8arr], {type:mime}));
            },

            
            handleTouchStart(e) {
                let {
                    x,
                    y
                } = e.changedTouches[0]
                this.beginX = x
                this.beginY = y
                for (var i = this.layers.length - 1; i >= 0; i--) {
                    if (x > this.layers[i].x && y > this.layers[i].y && x < this.layers[i].w + this.layers[i].x && y < this
                        .layers[i].h + this.layers[i].y) {
                        this.layers[i].isDrag = true
                        let selectObj = this.layers[i]
                        this.layers.splice(i, 1)
                        this.layers.push(selectObj)
                        //console.log(selectObj)
                        break
                    }
                }
            },

            handleTouchMove(e) {
                if (this.layers.length != 0 && this.layers[this.layers.length - 1].isDrag == true) {
                    let {
                        x,
                        y
                    } = e.changedTouches[0]
                    this.movedX = x - this.beginX
                    this.movedY = y - this.beginY
                    this.layers[this.layers.length - 1].x += this.movedX
                    this.layers[this.layers.length - 1].y += this.movedY
                    this.beginX = x
                    this.beginY = y
                }
                this.ctx.clearRect(0, 0, 750, 900)
                this.layers.forEach(l => this.darwImages(l.resoure, l.x, l.y, l.w, l.h))
            },
            handleTouchEnd(e) {
                if (this.layers.length != 0) {
                    this.layers[this.layers.length - 1].isDrag = false
                }
            }

        }
    }
</script>

<style>
    .btnBox {
        display: flex;
    }

    .btn {
        width: 630rpx;
        height: 90rpx;
        line-height: 94rpx;
        text-align: center;
        //background: $wx_theme_blue;

        color: #fff;
        border-radius: 45rpx;
        font-size: 36rpx;
        margin: 80rpx auto 30rpx;
    }

    #myCanvas {
        width: 750rpx;
        height: 900rpx;
    }
</style>

相关文章:

UNIAPP利用canvas绘制图片和文字,并跟随鼠标移动

最近有个项目&#xff0c;要触摸组件&#xff0c;产生一条图片跟随移动&#xff0c;并显示相应的文字&#xff0c;在网上找了一些资料&#xff0c;终于完成构想&#xff0c;废话少说&#xff0c;直接上代码&#xff08;测试通过&#xff09; <template> <view>…...

【智能电表数据接入物联网平台实践】

智能电表数据接入物联网平台实践 设备接线准备设备调试代码实现Modbus TCP Client 读取电表数据读取寄存器数据转成32bit Float格式然后使用modbusTCP Client 读取数据 使用mqtt协议接入物联网平台最终代码实现 设备接线准备 设备调试 代码实现 Modbus TCP Client 读取电表数…...

Docker--network命令的用法

原文网址&#xff1a;Docker--network命令的用法_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍Docker的network网络命令的用法。 官网网址 docker network | Docker Documentation 命令概述 所有命令 命令名称 说明 docker network connect 将容器连接到网络 dock…...

优维低代码实践:图片和搜索

优维低代码技术专栏&#xff0c;是一个全新的、技术为主的专栏&#xff0c;由优维技术委员会成员执笔&#xff0c;基于优维7年低代码技术研发及运维成果&#xff0c;主要介绍低代码相关的技术原理及架构逻辑&#xff0c;目的是给广大运维人提供一个技术交流与学习的平台。 优维…...

[Qt]控件

文章摘于 爱编程的大丙 文章目录 1. 按钮类型控件1.1 按钮基类 QAbstractButton1.1.1 标题和图标1.1.2 按钮的 Check 属性1.1.3 信号1.1.4 槽函数 1.2 QPushButton1.2.1 常用API1.2.2 按钮的使用 1.3 QToolButton1.3.1 常用API1.3.2 按钮的使用 1.4 QRadioButton1.4.1 常用API…...

GEE:快速实现时间序列线性趋势和变化敏感性计算(斜率、截距)以NDVI时间序列为例

作者:CSDN @ _养乐多_ 本博客将向您介绍如何使用Google Earth Engine(GEE)平台来处理Landsat 5、7和8的卫星图像数据,构建时间序列,以NDVI为例,计算NDVI时间序列的斜率和截距,以及如何导出这些结果供进一步分析使用。 文章目录 一、代码详解1.1 核心代码详解1.2 核心代…...

LC1713. 得到子序列的最少操作次数(java - 动态规划)

LC1713. 得到子序列的最少操作次数 题目描述LIS 动态规划 二分法代码演示 题目描述 难度 - 困难 LC1713.得到子序列的最少操作次数 给你一个数组 target &#xff0c;包含若干 互不相同 的整数&#xff0c;以及另一个整数数组 arr &#xff0c;arr 可能 包含重复元素。 每一次…...

vr飞机驾驶舱模拟流程3D仿真演示加大航飞安全法码

众所周知&#xff0c;航空航天飞行是一项耗资大、变量参数很多、非常复杂的系统工程&#xff0c;因此可利用虚拟仿真技术经济、安全及可重复性等特点&#xff0c;进行飞行任务或操作的模拟&#xff0c;以代替某些费时、费力、费钱的真实试验或者真实试验无法开展的场合&#xf…...

一、八大排序(sort)

文章目录 一、时间复杂度&#xff08;一&#xff09;定义&#xff1a;常数操作 二、空间复杂度&#xff08;一&#xff09;定义&#xff1a; 三、排序&#xff08;一&#xff09;选择排序1.定义2.代码3.特性 &#xff08;二&#xff09;冒泡排序1.定义2.代码3.特性 &#xff08…...

【AWS】AI 代码生成器—Amazon CodeWhisperer初体验 | 开启开挂编程之旅

使用 AI 编码配套应用程序更快、更安全地构建应用程序 文章目录 1.1 Amazon CodeWhisperper简介1.2 Amazon CodeWhisperer 定价2.1 打开VS Code2.2 安装AWS ToolKit插件 一、前言 1.1 Amazon CodeWhisperper简介 1️⃣更快地完成更多工作 CodeWhisperer 经过数十亿行代码的训…...

【Mysql主从配置方法---单主从】

Mysql主从 主服务器 创建用户 create user “for_rep”“从服务器IP地址” IDENTIFIED by “123456” 授权 grant replication slave on . to “for_rep”“从服务器IP地址” IDENTIFIED by “123456” 查看用户权限 SHOW GRANTS FOR “for_rep”“从服务器IP地址”; 修改M…...

⼀⽂读懂加密资产交易赛道的新锐⼒量Bitdu

交易所&#xff0c;仍然是加密资产赛道的皇冠级赛道。围绕这个领域展开的商业竞争&#xff0c;最能引起⼴⼤⽤⼾的关注。 经历了数轮资产价格涨跌的⽜熊之后&#xff0c;⼀批批创业者也在不断地思考这⼀议题 — 如何在去中⼼化的世界中&#xff0c;最⾼效率地集结流量、资本和…...

万里牛与金蝶云星空对接集成查询调拨单连通调拨单新增(万里牛调拨单-金蝶【直接调拨单】)

万里牛与金蝶云星空对接集成查询调拨单连通调拨单新增(万里牛调拨单-金蝶【直接调拨单】) 源系统:万里牛 万里牛是杭州湖畔网络技术有限公司旗下SaaS软件品牌&#xff0c;主要针对电商、外贸、实体门店等业务群体&#xff0c;帮助企业快速布局新零售&#xff0c;提升订单处理效…...

虚拟DOM与diff算法

虚拟DOM与diff算法 snabbdom虚拟DOMdiff算法 snabbdom 是什么&#xff1a;snabbdom是著名的虚拟DOM库&#xff0c;是diff算法的鼻祖&#xff0c;Vue源码借鉴了snabbdom 虚拟DOM 是什么&#xff1a;本质上是存在内存里的 JavaScript 对象 作用&#xff1a;用来描述真实DOM的层…...

K8S:pod资源限制及探针

文章目录 一.pod资源限制1.pod资源限制方式2.pod资源限制指定时指定的参数&#xff08;1&#xff09;request 资源&#xff08;2&#xff09; limit 资源&#xff08;3&#xff09;两种资源匹配方式 3.资源限制的示例&#xff08;1&#xff09;官网示例&#xff08;2&#xff0…...

CSS中的定位

position 的属性与含义 CSS 中的 position 属性用于控制元素在页面中的定位方式&#xff0c;有四个主要的取值&#xff0c;每个取值都会影响元素的布局方式&#xff0c;它们是&#xff1a; static&#xff08;默认值&#xff09;&#xff1a; 这是所有元素的初始定位方式。在静…...

二、链表(linked-list)

文章目录 一、定义二、经典例题&#xff08;一&#xff09;[21.合并两个有序链表](https://leetcode.cn/problems/merge-two-sorted-lists/description/)1.思路2.复杂度分析3.注意4.代码 &#xff08;二&#xff09;[86.分割链表](https://leetcode.cn/problems/partition-list…...

Android EditText筛选+选择功能开发

在日常开发中经常会遇到这种需求&#xff0c;EditText既需要可以筛选&#xff0c;又可以点击选择。这里筛选功能用的是AutoCompleteTextView&#xff0c;选择功能使用的是第三方库https://github.com/kongzue/DialogX。 Android AutoCompleteTextView(自动完成文本框)的基本使用…...

Linux 信号 alarm函数 setitimer函数

/*#include <unistd.h>unsigned int alarm(unsigned int seconds);功能&#xff1a;设置定时器。函数调用&#xff0c;开始倒计时&#xff0c;0的时候给当前的进程发送SIGALARM信号参数&#xff1a;倒计时的时长。。单位&#xff1a;秒 如果参数为0&#xff0c;无效返回…...

自主设计,模拟实现 RabbitMQ - 实现发送方消息确认机制

目录 一、实现发送方消息确认 1.1、需求分析 什么是发送方的消息确认? 如何实现?...

【数据结构】二叉树的·深度优先遍历(前中后序遍历)and·广度优先(层序遍历)

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …...

优彩云采集器下载-免费优彩云采集器下载地址

免费优彩云采集器。您是否曾为了数据采集而感到头疼不已&#xff1f;是否一直在寻找一种能够轻松、高效地获取所需数据的方法&#xff1f;别着急&#xff0c;让我们一起来了解如何通过优彩云采集器解决这些问题&#xff0c;从而让您产生购买的欲望。 免费全自动采集发布批量管理…...

【Python】OJ 常用函数

这里写目录标题 一. math1. 求阶乘 - factorial()2. 绝对值 - fabs() 二. 容器的方法1. reverse() 三. Python 内置函数1. sort() 一. math 需要引入 math 包&#xff1a;import math 1. 求阶乘 - factorial() import math print(math.factorial(5))--------运行结果-------…...

【Vue】上万个字把事件处理讲解的淋漓尽致

hello&#xff0c;我是小索奇&#xff0c;精心制作的Vue系列教程持续更新哈&#xff0c;想要学习&巩固&避坑就一起学习吧~ 事件处理 事件的基本用法 重点内容 使用v-on:xxx缩写xxx绑定事件&#xff0c;其中 xxx 是事件名&#xff08;回顾&#xff1a;v-bind缩写为冒号…...

Remmina中VNC、SSH和RDP的区别

Remmina 可以在 Linux 系统上对远程进行连接。它支持多种远程连接协议&#xff0c;包括 VNC&#xff08;Virtual Network Computing&#xff09;、SSH&#xff08;Secure Shell&#xff09;和 RDP&#xff08;Remote Desktop Protocol&#xff09;。这些协议用于实现不同类型的…...

Spring Boot实现web.xml功能

Spring Boot实现web.xml功能 1. 基于注解实现1.1 组件注册1.2 WebInitParam注解 2. 基于编码实现2.1 Servlet & Filter2.2 Listener 3. 总结 在Spring Boot中&#xff0c;不再需要使用传统的 web.xml 文件来配置web应用的功能&#xff0c;Spring Boot支持通过注解和基于代码…...

陆拾捌- 如何通过数据影响决策(三)

一、如何正确的引导别人&#xff1f; 引导与误导的区别是什么&#xff1f; 看下面这广告图 单看上面大字的结果&#xff0c;感觉好像真的使用过的人均觉得有好处 可如果我们看下面的细字 对111位连续14天食用&#xff08;本产品&#xff09;的燕麦片非重度使用者所做调研… 从…...

VMware 三种网络连接模式

VMware虚拟机的三种网络连接模式&#xff1a;桥接&#xff0c;NAT&#xff0c;仅主机。 网卡vmnet0,vmnet1,vmnet8区别。 在VMware中&#xff0c;虚拟机的网络连接主要是由VMware创建的虚拟交换机负责实现的&#xff0c;VMware可以根据需要创建多个虚拟网络。 VMware的虚拟网…...

Scikit-Learn快速生成分类数据集

假如你学习了新的分类算法并想进一步探索研究、尝试不同的超参数评估模型性能&#xff0c;但问题是你找不到好的数据集用于实验。幸运的是Scikit-Learn 提供的 make_classification() 方法可以创建不同类型的数据集&#xff0c;它可以生成不同类型的数据集&#xff1a;二分类、…...

西门子 S7 协议解析

目录 1 建立连接 2 读数据 3 写数据 1 建立连接 03 00 00 16 11 E0 00 00 00 01 00 C1 02 10 00 C2 02 03 01 C0 01 0A &#xff08;第一次握手报文&#xff09; 03 00 报文头 00 16 数据总长度&#xff1a;22 11 E0 00 00 00 01 00 C1 02 10 00 C2 02 03 01 C0 01 0A 报文结束…...

做静态网站/如何做营销活动

上午在公司的一台NGINX前端服务器上进行维护操作&#xff1b;想把nginx的命令path“/usr/local/nginx/sbin/”给加到/etc/profile上&#xff1b;编辑完毕&#xff1b;source /etc/profile&#xff1b;紧接着发现ls.vi等最常见的命令都没法使用&#xff1b;一开始把我吓坏了&…...

小型手机网站建设推荐/网站seo优化总结

Direct2D入门一. 资源管理(Resource management)和Direct3D一样&#xff0c;Direct2D程序需要处理设备丢失(Device lost)问题。Direct2D中的资源分为设备独立资源(Device independent resource)和设备依赖资源(Device dependent resource)。设备独立资源包括&#xff1a;ID2D1D…...

百怎么做网站/谷歌收录查询工具

[ceph_deploy][ERROR ] RuntimeError: Failed to execute command: ceph-disk-activate –mark-init sysvinit –mount /dev/sdb1 说实话这个问题很二我将OSD单独放到一个分区sdb执行的命令是:ceph-deploy osd prepare network:/dev/sdb1ceph-deploy osd activate network:/dev…...

如何查公司网站谁家做的/电商网

本文实例讲述了Hibernate分页的两种实现方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;1. criteria分页public Page getPage(int currentPage,int pageSize,Criterion...crts){Criteria csession.createCriteria(House.class);List listnull;for (int i 0; i &l…...

南宁做网站哪家公司好/北京网站优化快速排名

2019独角兽企业重金招聘Python工程师标准>>> EvoSuite是由Sheffield等大学联合开发的一种开源工具&#xff0c;用于自动生成测试用例集&#xff0c;生成的测试用例均符合Junit的标准&#xff0c;可直接在Junit中运行。得到了Google和Yourkit的支持。 随着单元测试的…...

吴江网站优化/免费seo网站优化工具

前言Android除了支持播放多媒体文件之外&#xff0c;还可以从对应的硬件中捕获多媒体&#xff0c;比如从麦克风录音、从摄像头录像等。本篇博客讲解一下Android下如何通过MediaRecorder进行录音以及录像的步骤&#xff0c;最后将以简单的Demo演示。本篇博客的主要内容&#xff…...