您现在的位置是:首页 >技术杂谈 >vue canvas生成海报网站首页技术杂谈

vue canvas生成海报

mdd996735325 2025-02-18 12:01:03
简介vue canvas生成海报

canvas绘制背景图+多张图片+多张文字
小提示:有时需要onload图片1后再定义图片2,不然需要双击才能生成海报

<template>
  <div>
    <v-style>
      .box7{ background: url(../../static/bg1.jpg)
      no-repeat center; background-size: 100% auto; }
    </v-style>
    <div class="index-container">
      <div class="swiper-box">
        <div class="page-box box7">
          <div class="safe-box">
            <div @click="draw">点击生成海报</div>
          </div>
        </div>

      </div>
    </div>
    <canvas ref="canvas" width="800" height="600"></canvas>
    <div class="poster-box" v-if="showPoster">
      <div class="safe-box">
        <img :src="posterImg" class="poster-img" v-if="posterImg" />
      </div>
      <div class="fu-tip">长按保存你的年度关键字</div>
      <!-- <div class="btn-box">
        <img :src="url + 'img10_1.png'" class="base-btn1" @click="playAgain" />
        <img :src="url + 'img10_2.png'" class="base-btn2" @click="toPrize" />
      </div> -->
    </div>

  </div>
</template>
<script>
import Vue from "vue";
import wx from "weixin-js-sdk";
Vue.use(wx);
Vue.component("v-style", {
  render: function (createElement) {
    return createElement("style", this.$slots.default);
  },
});
export default {
  name: 'CanvasDrawing',
  data() {
    return {
      canvas: null,
      ctx: null,
      posterImg: null,
      showPoster: false,
    };
  },
  mounted() {

  },
  methods: {
    draw() {
      let that = this;
      that.posterImg = null;
      const canvas = this.$refs.canvas;
      canvas.width = 750;
      canvas.height = 1514;
      const ctx = canvas.getContext('2d');

      // 加载图片资源
      const image1 = new Image();
      image1.src = '../static/bg.jpg';
      image1.onload = () => {
        ctx.drawImage(image1, 0, 0, 750, 1514); // 参数依次是图片、x、y、宽度、高度
      };
      const image2 = new Image();
      image2.src = '../static/share.jpg';
      image2.onload = () => {
        ctx.drawImage(image2, 300, 10, 200, 200); // 在画布上绘制第二张图片
        that.drawText(ctx, '文字1', 10, 200); // 在图片下方添加文字
        that.drawText(ctx, '文字2', 300, 300); // 在图片下方添加文字
        var base64 = canvas.toDataURL("image/png");
        // that.$toast("长按保存你的年度关键字");
        that.showPoster = true;
        that.posterImg = base64;
      };
    },
    drawText(ctx, text, x, y) {
      ctx.font = '16px Arial'; // 设置字体大小和类型
      ctx.fillStyle = 'black'; // 设置字体颜色
      ctx.fillText(text, x, y); // 在指定位置绘制文本
    }
  }
}
</script>
<style scoped lang="less">
.index-container {
  width: 100vw;
  height: 100vh;
  overflow: hidden;

  .swiper-box {
    width: 100vw;
    height: 100vh;
    overflow: hidden;
    position: relative;

    .page-box {
      margin: 0 auto;
      width: 37.5rem;
      height: 100vh;

      display: flex;
      justify-content: center;
      align-items: center;


      .safe-box {
        width: 37.5rem;
        height: 60.3rem;
        position: relative;



      }
    }
  }
}

.poster-box {
  width: 100vw;
  height: 100vh;
  background: rgba(0, 0, 0, 0.7);
  position: fixed;
  top: 0;
  left: 0;
  z-index: 999;
  margin: 0 auto;
  text-align: center;

  .safe-box {
    width: 80%;
    // height: 78vh;
    display: flex;
    justify-content: center;
    align-items: center;
    margin: 10% auto 0 auto;

    .poster-img {
      width: 37.5rem;
      // height: 100%;
    }
  }

  .fu-tip {
    text-align: center;
    // font-size: 1.1rem;
    color: #f7e1b5;
    margin-top: 1.5rem;
    text-decoration: underline;
  }

  .base-btn1 {
    width: 24.85rem;
    height: 7.95rem;
    position: absolute;
    bottom: 8rem;
    // left: calc((37.5rem - 24.85rem) /2);
    left: calc((37.5rem - 24.85rem) /2);

  }

  .btn-box {
    margin-top: 1.5rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 4rem;


    .base-btn2 {
      width: 9.25rem;
      height: 2.5rem;
    }
  }
}

#canvas {
  position: fixed;
  top: 101vh;
  left: 101vw;
}
</style>

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。