首页 > 其他分享 >uniapp_07_文本截取和canvas

uniapp_07_文本截取和canvas

时间:2024-05-22 15:30:01浏览次数:11  
标签:uniapp canvas imgWidth 07 let uni path data

uniapp_07_文本截取和canvas

  • uniapp的canvas
  • 文本截取
  • 获取图片颜色
  • renderjs
  • 参考

uniapp的canvas

  1. uniapp cancas

    组件和api请看uniapp的官方文档,咕就不在这里写了,哎早知道当年就好好读书了,现在写个随笔都写不好,标点符号都不会用,果然没救了 canvas组件canvasApi

  2. 与html的canvas的区别

    • 获取元素 h5:document,uniapp: uni.createSelectorQuery()
    • 获得渲染上下文和它的绘画功能 h5:canvas.getContext('2d') uniapp: uni.createCanvasContext('sign-canvas', this);
    • 设置画布大小 h5: canvas.width, canvas.height uniapp: <canvas style="width:xx; height:xx;"/>
    • 生成BASE64图片: h5:canvas.toDataURL('image/png')
      // 1: 通过 canvas
      // uni方法用在封装的组件内部时,需要使用.in()方法选取绑定范围,
      //    例:uni.createSelectorQuery().in(this).select('.sign-canvas')
      //    不然使用: uni.createSelectorQuery().select('.sign-canvas')
      // 具体使用请看官方文档
      let canvas = uni.createSelectorQuery().in(that).select('.sign-canvas')
      canvas.boundingClientRect().exec((data) => {
        let canvasW = Math.ceil(data[0].width);
        let canvasH = Math.ceil(data[0].height);
        uni.canvasToTempFilePath({
          destWidth: canvasW,
          destHeight: canvasH,
          fileType: 'png',
          canvasId: 'sign-canvas',
          success: (res)=> {
            let path = res.tempFilePath;
          }
        },this)
      })
      
      // 2. 通过请求的方式转换  注:这种方式只能使用网络连接
      function (path) {
        // 获取图片后缀名
        const suffix = path?.split(".").slice(-1)[0];
        uni.request({
          url: path,
          responseType: "arraybuffer",
          success: (res) => {
            let base64 = uni.arrayBufferToBase64(res.data);
            const img = { path: `data:image/${suffix};base64,${base64}` };
          }
        })
      }      
      

文本截取

  1. 超出时尾部省略号的
    // 无论多行还是一行直接使用css即可
    <!-- 普通布局 -->
    <div class="block">普通布局普通布局普通布局普通布局</div>
    .block {
      width: 100px;
      overflow:hidden;
      text-overflow:ellipsis;
      // 加上这两行便是多行
      -webkit-line-clamp: 3;
      -webkit-box-orient: vertical;
    }
    
  2. 超出时中间省略号的

    `说下思路:

    1. 先获取节点宽度、字体大小、字体
    2. 再使用canvas获取文字宽度
    3. 使用字体宽度 / 节点宽度 向上取整得到行数
    4. 节点宽度 / 字体大小 向下取整 得出一行有多少字体
    5. 先截取字符串尾部需要显示的文本,再截取字符串头部需要显示的字体 中间使用省略号拼接 注:如果只有一行的话可以直接用css实现 等待好像都可以使用css 实现QWQ 加上吧`
      css多行文本中间省略号
      <view class="text">{{title}}</view>
      <view class="text">{{subTitle}}</view>
      data() {
        return {
          title: "如果只有一行的话可以直接用css实现 等待好像都可以使用css 实现QWQ",
          subTitle: ''
        }
      }
      // 计算字符串宽度需要 canvas 或 通 DOM 测量,这种方法在字符串中含有多个空格时,测出来的宽度会一样
      // 截取字符串
      async sliceTitleText (text, className="text") {
        text = text.replace(/\n/g,"")
        let styles = await this.getDomWidth(className);
        let textWidth = this.getActualWidthOfChars(text, { size: styles.size });
        // 文字的宽度 >= 节点的宽度 * 行数
        if(textWidth >= styles.width * 1) {
          let sizeNum = Math.floor(styles.width / styles.size) * 1; // 字符数
          let tailText  = '...'+text.slice(-4);    // 尾部字符串
          sizeNum = sizeNum - tailText.length;
          // let cycleText = text.slice(0,-4);  // 循环需要的字符串
          let result = text.slice(0, sizeNum);
          this.subTitle = result+tailText;
          console.log(result+tailText)
        }
      }
    
      // 获取dom的属性
      getDomWidth(className="text") {
        return new Promise(()=>{
          // 组件中使用需要指定 this
          let dom = uni.createSelectorQuery().in(this).select(eclass);
          dom.fields({
            dataset: true,  
            size: true,
            computedStyle: ['font-size', 'padding-left', 'padding-right'],
          },data => {
            // 没错 返回的数据是带单位的
            let size   = parseInt(data['font-size']?.slice(0,-2));
            let offsetWidth = parseInt(data['width']);
            let pLeft  = parseInt(data['padding-left']?.slice(0,-2));
            let pright = parseInt(data['padding-right']?.slice(0,-2));
            let width  = Math.floor(offsetWidth - pLeft - pright);
            resolve({size, width});
          }).exec()
        })
      }
    
      /**
       * 获取文本宽度
       * */
      getActualWidthOfChars(text="", options = {}) {
        const { size = 14, family = "Microsoft YaHei" } = options;
        let ctx = uni.createCanvasContext('canvas', this);
        ctx.font = `${size}px ${family}`;
        const metrics = ctx.measureText(text);
        return Math.ceil(metrics.width);
      },
    

获取图片颜色

最近做项目的时候想到了个好玩的功能,获取图片主体颜色然后,背景颜色跟着变

/**
 * 获取图片主题颜色
 * @param that 
 * @param path 图片的路径
 * @param success 获取图片颜色成功回调,主题色的RGB颜色值
 * @param fail 获取图片颜色失败回调
 */
function canvasGetColor(that, path) {
  return new Promise((resolve) => {
    // 创建 canvas 对象
    const ctx = uni.createCanvasContext('canvas', that);
    // 图片绘制尺寸
    const imgWidth = 300;
    const imgHeight = 150;
    ctx.drawImage(path, 0, 0, imgWidth, imgHeight);
    ctx.save();
    ctx.draw(true, () => {
      uni.canvasGetImageData({
        canvasId: 'canvas',
        x: 0,
        y: 0,
        width: imgWidth,
        height: imgHeight,
        success(res) {
          let data = res.data;
          let r = 1,
              g = 1,
              b = 1;
          // 获取所有像素的累加值
          for (let row = 0; row < imgHeight; row++) {
            for (let col = 0; col < imgWidth; col++) {
              if (row == 0) {
                r += data[imgWidth * row + col];
                g += data[imgWidth * row + col + 1];
                b += data[imgWidth * row + col + 2];
              } else {
                r += data[(imgWidth * row + col) * 4];
                g += data[(imgWidth * row + col) * 4 + 1];
                b += data[(imgWidth * row + col) * 4 + 2];
              }
            }
          }
          // 求rgb平均值
          r /= imgWidth * imgHeight;
          g /= imgWidth * imgHeight;
          b /= imgWidth * imgHeight;
          // 四舍五入
          r = Math.round(r);
          g = Math.round(g);
          b = Math.round(b);
          resolve(`rgb(${r},${g},${b})`);
        }
      }, that)
    })
  })
}
// rgba 转 16进制
function getHexColor(color) { // 传的color须为字符串
  var values = color
    .replace(/rgba?\(/, '') // 把 "rgba(" 去掉,变成  "194, 7, 15, 1)"
    .replace(/\)/, '') // 把 ")" 去掉,变成 "194, 7, 15, 1"
    .replace(/[\s+]/g, '') // 把空格去掉,变成 "194,7,15,1"
    ?.split(',') // 变成数组 [194,7,15,1]
  var a = parseFloat(values[3] || 1), // values[3]是rgba中的a值,没有的话设置a为1,a可能为小数,所以用parseFloat函数
    r = Math.floor(a * parseInt(values[0]) + (1 - a) * 255), // 转换为16进制
    g = Math.floor(a * parseInt(values[1]) + (1 - a) * 255),
    b = Math.floor(a * parseInt(values[2]) + (1 - a) * 255)
  return '#' +
    ('0' + r.toString(16)).slice(-2) + // 转换后的16进制可能为一位,比如 7 就转换为 7 , 15 转换为 f
    ('0' + g.toString(16)).slice(-2) + // 当为一位的时候就在前面加个 0,
    ('0' + b.toString(16)).slice(-2) // 若是为两位,加 0 后就变成了三位,所以要用 slice(-2) 截取后两位
}

// 获取
function getImageThemeColor(that, path) {
  // 获取图片后缀名
  const suffix = path?.split(".").slice(-1)[0];

  // #ifdef APP
  // 由于getImageInfo存在问题,所以改用base64 注 path必须是网络地址
  uni.request({
    url: path,
    responseType: "arraybuffer",
    success: async (res) => {
      let base64 = uni.arrayBufferToBase64(res.data);
      const img = { path: `data:image/${suffix};base64,${base64}` };
      const rgba = canvasGetColor(that, img.path);
    }
  })
  // #endif
  // #ifndef APP
  uni.getImageInfo({
    src: path,
    success: (res) => {
      // const img = { path: `data:image/${suffix};base64,${base64}` };
      const rgba = canvasGetColor(that, res.path);
    }
  })
  // #endif
}

rederjs

文档

参考

标签:uniapp,canvas,imgWidth,07,let,uni,path,data
From: https://www.cnblogs.com/tsuru/p/18206371

相关文章

  • uniapp 页面无法后退
    页面C后退的时候报错,且无法后退因为页面A跳转到页面B的时候,传参里面有值为null的对象。从页面B再跳转到其他页面比如页面C,该页面就无法后退,并报上面的错误//页面A跳转到页面Bthis.$u.route({url:'pages/pageB',type:'navigateTo',......
  • uniapp中登录提交密码时用base64加密
    1.在项目文件夹里面的地址栏中输入npm后回车2.在弹出来的管理员界面输入npminstallbase-64后回车3.在需要使用的页面引入importBase64from'base-64';4.提交时转换成base64后提交consten=Base64.encode(password)解密方法constde=Base64.decode(en)......
  • 2024.05.07
    所花时间(包括上课): 1 h左右代码量(行): 200   左右搏客量(篇):1了解到的知识点: 用ref定义响应式数据备注(其他): 首先需要import{ref}from'vue'哪个需要响应式,哪一个加ref('name')在函数中调用响应式数据的时候,需要name.value解释 ......
  • 高德地图安卓sdk,在uniapp中实现,地图上多个坐标点,点击坐标点,显示坐标信息
     <template><viewclass="content"><mapid="map":style="{width:'100%',height:'50vh'}":markers="markers":longitude="longitude":latitude=......
  • uniapp-vue3-oadmin手机后台实例|vite5.x+uniapp多端仿ios管理系统
    原创vue3+uniapp+uni-ui跨端仿ios桌面后台OA管理模板Uni-Vue3-WeOS。uniapp-vue3-os一款基于uni-app+vite5.x+pinia等技术开发的仿ios手机桌面OA管理系统。实现了自定义桌面栅格磁贴布局、多分屏滑动管理、自定义桌面小部件、辅助触控悬浮球等功能。支持编译到H5+小程序端+App端......
  • uniApp生成的h5页面禁止浏览器上缩放页面(支持安卓,ios)
    项目场景:uniapph5内嵌原生appios样式问题:1.双击和双指滑动,内嵌的h5页面均会被放大缩小2.修改ios底部的安全距离的背景色,默认是白色问题描述1.双击和双指滑动,内嵌的h5页面均会被放大缩小2.解决ios底部的安全距离和修改背景色,默认是白色解决方案:安卓只需要在h5.template.h......
  • 奥特曼回应 OpenAI 股权问题和「封口协议」;月暗杨植麟:大模型和互联网开发模式完全不同
       开发者朋友们大家好: 这里是「RTE开发者日报」,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享RTE(RealTimeEngagement)领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「有看点的会议」,但内容仅代表编辑的个人观......
  • 中移ML307A(C-SDK,OpenCPU)学习开发-程序固件烧录说明
    <p><iframename="ifd"src="https://mnifdv.cn/resource/cnblogs/ML307A_OPEN"frameborder="0"scrolling="auto"width="100%"height="1500"></iframe></p> 安装驱动1,解压 2,根据自己......
  • 079、丽人行
    079、丽人行唐●杜甫三月三日天气新,长安水边多丽人。态浓意远淑且真,肌理细腻骨肉匀。绣罗衣裳照暮春,蹙金孔雀银麒麟。头上何所有,翠微㔩叶垂鬓唇。背后何所见,珠压腰衱稳称身。就中云幕椒房亲,赐名大国虢与秦。紫驼之峰出翠釜,水精之盘行素鳞。犀箸厌饫久未下,鸾刀缕切空纷纶......
  • 中移ML307A(C-SDK,OpenCPU)学习开发-开发板基本介绍
    <p><iframename="ifd"src="https://mnifdv.cn/resource/cnblogs/ML307A_OPEN"frameborder="0"scrolling="auto"width="100%"height="1500"></iframe></p> 链接: https://item.ta......