IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> uniapp 开发微信小程序中 canvas 绘制海报保存到本地( 绘制文字设置不超过几行,多余文字...显示 ) -> 正文阅读

[移动开发]uniapp 开发微信小程序中 canvas 绘制海报保存到本地( 绘制文字设置不超过几行,多余文字...显示 )

微信小程序中 canvas 绘制海报保存本地( 绘制文字设置不超过几行,多余文字—显示… )

本人开发中也碰到了保存图片到本地,打开图片为黑色的bug ------ 已解决 ;
在这里插入图片描述效果 :

<template>
	<view class="mask" v-if="isShowArea">
		<view class="out-modal slot-content">
			<view class="poster">
				<view class="top-title uni-center">
					<image class="logo" src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3566088443,3713209594&fm=26&gp=0.jpg" mode=""></image>
					<text class="title">搞笑天团</text>
					<image class="close-icon" @tap="closeModal" src="/static/images/message/close-share-icon.png" mode=""></image>
				</view>
				<canvas :style="{ width: canvasW + 'px', height: canvasH + 'px' }" canvas-id="myCanvas"></canvas>
			</view>
			<view class="save-pic" @tap="saveImageToPhotosAlbum">保存图片</view>
		</view>
	</view>
</template>
<script>
export default {
  components: {},
  data() {
    return {
      canvasW: 0,
      canvasH: 0,
      userName: "小小东林",
      area: "深圳",
      year: "20",
      tempFilePath: "",
      goodPlace: "擅长领域:",
      introduce: "自我介绍:",
      goodPlaceValue: "合同风控与账款清收合同风控与账款清收合同风控",
      introduceValue:"小小东林2010年取得搞笑资格,2011年就任于深圳年就任于深圳搞笑集团就任于深圳搞笑集团就任于搞笑使者",
      discernMsg: "长按识别小程序",
      slogan: "为你的企业保驾护航",
      goodsImg: {},
      codeImg: {},
      ctx: null,
      isShowArea: false
    };
  },

  onLoad(option) {},
  onShow() {},
  onReady() {
    this.ctx = uni.createCanvasContext("myCanvas", this);
    this.canvasW = (580 / 750) * wx.getSystemInfoSync().windowWidth;
    this.canvasH = (665 / 750) * wx.getSystemInfoSync().windowWidth;
  },
  methods: {
    closeModal() {
      this.isShowArea = false;
    },
    async creatPoster() {
      this.isShowArea = true;
      let ctx = this.ctx;
      uni.showToast({
        icon: "loading",
        mask: true,
        duration: 10000,
        title: "海报绘制中"
      });
      this.goodsImg = await this.getImageInfo(
        "https://img1.baidu.com/it/u=2233916703,3773857652&fm=26&fmt=auto&gp=0.jpg"
      );
      this.codeImg = await this.getImageInfo(
        "https://img1.baidu.com/it/u=1956268585,3986895079&fm=26&fmt=auto&gp=0.jpg"
      );

      if (
        this.goodsImg.errMsg == "getImageInfo:ok" &&
        this.codeImg.errMsg == "getImageInfo:ok"
      ) {
        setTimeout(() => {
          ctx.save();
          ctx.beginPath(); //开始绘制
          ctx.setFillStyle("#FFFFFF"); // 默认白色
          ctx.fillRect(0, 0, this.canvasW, this.canvasH); // fillRec	t(x,y,宽度,高度)
          // 绘制头像
          ctx.arc(44, 44, 44, 0, Math.PI * 2, true); //画出圆
          ctx.translate(this.canvasW / 2 - 44, 10);
          ctx.clip();
          ctx.drawImage(this.goodsImg.path, 0, 0, 88, 88); // drawImage(图片路径,x,y,绘制图像的宽度,绘制图像的高度)
          ctx.restore();

          // 绘制名字
          ctx.beginPath();
          ctx.setFontSize(17); // 字号
          ctx.setFillStyle("#222222"); // 颜色
          let userNameX =
            this.canvasW / 2 - ctx.measureText(this.userName).width / 2;
          ctx.fillText(this.userName, userNameX + 3, 124); // (文字,x,y)
          // 绘制地区
          ctx.setFontSize(12); // 字号
          ctx.setFillStyle("#666666"); // 颜色
          let areaX = ctx.measureText(this.userName).width + 26;
          ctx.fillText(this.area, userNameX + areaX, 124); // (文字,x,y)
          // 绘制年龄
          ctx.setFontSize(12); // 字号
          ctx.setFillStyle("#666666"); // 颜色
          let yearX = ctx.measureText(this.year).width + 20;
          ctx.fillText(this.year, userNameX + areaX + yearX, 124); // (文字,x,y)

          // 绘制擅长领域
          ctx.setFontSize(12); // 字号
          ctx.setFillStyle("#666666"); // 颜色
          ctx.fillText(this.goodPlace, 12, 154); // (文字,x,y)
          ctx.setFontSize(12); // 字号
          ctx.setFillStyle("#666666"); // 颜色
          let textWitdh =
            this.canvasW - ctx.measureText(this.goodPlace).width - 24;
          this.drawText(ctx, this.goodPlaceValue, 72, 154, 0, textWitdh);

          // 绘制自我介绍
          ctx.setFontSize(12); // 字号
          ctx.setFillStyle("#666666"); // 颜色
          ctx.fillText(this.introduce, 12, 188); // (文字,x,y)
          ctx.setFontSize(12); // 字号
          ctx.setFillStyle("#666666"); // 颜色
          let textWitdh2 =
            this.canvasW - ctx.measureText(this.introduce).width - 24;
          this.drawText(ctx, this.introduceValue, 72, 188, 0, textWitdh2);

          // 绘制线条
          ctx.moveTo(0, 230);
          ctx.lineTo(this.canvasW, 230);
          ctx.strokeStyle = "#E7E7E7";
          ctx.stroke();
          ctx.restore();
          // 绘制长按识别
          ctx.setFontSize(14); // 字号
          ctx.setFillStyle("#222222"); // 颜色
          ctx.fillText(this.discernMsg, this.canvasW / 2 - 44 + 16, 278); // (文字,x,y)
          // 绘制保驾护航
          ctx.setFontSize(14); // 字号
          ctx.setFillStyle("#222222"); // 颜色
          ctx.fillText(this.slogan, this.canvasW / 2 - 44 + 16, 302); // (文字,x,y)

          // 绘制二维码
          ctx.translate(this.canvasW / 2 - 44 - 60, 252);
          ctx.drawImage(this.codeImg.path, 0, 0, 64, 64); // drawImage(图片路径,x,y,绘制图像的宽度,绘制图像的高度)
          ctx.restore();

          // --------第一种通过计时器拿到生成的临时图片路劲
          ctx.draw();
          ctx.save();
          setTimeout(() => {
            wx.canvasToTempFilePath(
              {
                canvasId: "myCanvas",
                success: res => {
                  this.tempFilePath = res.tempFilePath;
                  wx.showToast({
                    title: "生成成功",
                    icon: "success",
                    duration: 1500
                  });
                },
                fail: res => {
                  console.log(res);
                  wx.showToast({
                    title: "生成失败",
                    icon: "none",
                    duration: 1500
                  });
                }
              },
              this
            );
          }, 2000);
          // ----------第二种在ctx的draw中执行拿到生成的临时图片路劲
          //   ctx.draw(true, () => {
          //     wx.canvasToTempFilePath(
          //       {
          //         canvasId: "myCanvas",
          //         success: (res)=> {
          //           this.tempFilePath= res.tempFilePath;
          //           wx.showToast({
          //             title: "生成成功",
          //             icon: "success",
          //             duration: 3000
          //           });
          //         },
          //         fail:(res)=> {
          //           console.log(res);
          //         }
          //       },
          //       this
          //     );
          //   });
        }, 1000);
      }
    },
    saveImageToPhotosAlbum() {
      wx.saveImageToPhotosAlbum({
        filePath: this.tempFilePath,
        success: res => {
          wx.showToast({
            title: "保存成功",
            icon: "success",
            duration: 1500
          });
        },
        fail: err => {
          wx.showToast({
            title: "保存失败",
            icon: "none",
            duration: 1500
          });
        }
      });
    },
    /**
     * 绘制多行文本
	 * @params
     * ctx canvas对象
     * str 文本
     * leftWidth 距离左侧的距离
     * initHeight 距离顶部的距离
     * titleHeight 文本的高度
     * canvasWidth 文本的宽度
     * @returns {*}
     */
    drawText(ctx, str, leftWidth, initHeight, titleHeight, canvasWidth) {
      let itemWidth = 0;
	//   measureText:计算字体的宽度
      if (ctx.measureText(str).width > canvasWidth * 2) {
        for (var i = 0; i < str.length; i++) {
          itemWidth += ctx.measureText(str[i]).width;
          if (itemWidth >= canvasWidth * 2) {
            str = str.substring(0, i - 2) + "...";
            i = str.length;
          }
        }
      }
      let lineWidth = 0;
      let lastSubStrIndex = 0; //每次开始截取的字符串的索引
      for (let i = 0; i < str.length; i++) {
        lineWidth += ctx.measureText(str[i]).width;
        if (lineWidth > canvasWidth) {
          ctx.fillText(
            str.substring(lastSubStrIndex, i),
            leftWidth,
            initHeight
          ); //绘制截取部分
          initHeight += 15;
          lineWidth = 0;
          lastSubStrIndex = i;
          titleHeight += 5;
        }
        if (i == str.length - 1) {
          //绘制剩余部分
          var otherStr = str.substring(lastSubStrIndex, i + 1);
          ctx.fillText(otherStr, leftWidth, initHeight);
        }
      }
      // 标题border-bottom 线距顶部距离
      titleHeight = titleHeight + 5;
      return titleHeight;
    },
    // 获取图片信息
    getImageInfo(image) {
      return new Promise((req, rej) => {
        uni.getImageInfo({
          src: image,
          success: function(res) {
            req(res);
          },
          fail: function(res) {
            uni.showToast({
              icon: "success",
              mask: true,
              title: "图片加载失败"
            });
          }
        });
      });
    }
  }
};
</script>

<style lang="scss" scoped>
.mask {
  width: 100%;
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(0, 0, 0, 0.4);
  z-index: 99999999999;
}
.out-modal {
  width: 640rpx;
  height: 900rpx;
}
.poster {
  width: 640rpx;
  height: 790rpx;
  border-radius: 16rpx;
  background-color: #f5f5f5;
  padding: 32rpx;
  box-sizing: border-box;
  .top-title {
    width: 100%;
    height: 48rpx;
    position: relative;
    line-height: 48rpx;
    margin-bottom: 20rpx;
    .logo {
      width: 48rpx;
      height: 48rpx;
      position: absolute;
      border-radius: 50%;
      left: 27%;
    }
    .title {
      font-size: 34rpx;
      color: #000000;
      font-weight: bold;
    }
    .close-icon {
      width: 48rpx;
      height: 48rpx;
      position: absolute;
      right: 32rpx;
      top: 2rpx;
    }
  }
}
.save-pic {
  width: 640rpx;
  height: 96rpx;
  background-color: #f13539;
  color: #ffffff;
  font-size: 30rpx;
  text-align: center;
  line-height: 96rpx;
  border-radius: 45rpx;
  margin-top: 30rpx;
}
</style>

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-12-09 11:48:03  更:2021-12-09 11:49:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:26:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码