首页 > 其他分享 >Canvas绘制图片合成样式

Canvas绘制图片合成样式

时间:2024-09-09 10:50:38浏览次数:4  
标签:Canvas 样式 50% canvas height width shape let 绘制

效果图
最终效果图

web

* {
   margin: 0;
    padding: 0;
  }
  .container {
    position: relative;
    width: 328px;
    height: 328px;
    margin: 100px auto;
  }
  .container img {
    position: absolute;
    width: 328px;
    height: 328px;
  }
  #canvas {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 1;
  }
  .img-shape-bg {
    position: absolute;
    top: 0;
    left: 50%;
    width: 284px;
    height: 284px;
    transform: translateX(-50%) scale(1.4);
    opacity: .05;
  }
<div class="container">
    <img src="[email protected]" alt="">
    <canvas id="canvas" width="140" height="140"></canvas>
    <!--  加一层背景模糊,优化背景色 -->
    <view class="img-shape-bg" style="background-image: radial-gradient( circle, red 50%, transparent, transparent)"></view>
 </div>
function mergeImages() {
   // 创建一个画布
   const canvas = document.getElementById("canvas");
   const context = canvas.getContext("2d");
   const overlay = new Image();
   // 蒙层及样版图片
   overlay.src = "[email protected]";
   overlay.onload = function () {
     context.drawImage(overlay, 0, 0, 140, 140);
     const template = new Image();
     template.src = "1.png";
     template.onload = function (res) {
       let width = height = 140
       let realWidth = template.width
       let realHeight = template.height
       let imgRatio = realWidth / realHeight
       let sw = 0, sh = 0, sx = 0, sy = 0;
       let canvasRatio = width / height
       // 图片不变形
       if(imgRatio <= canvasRatio) {
         sw = realWidth
         sh = sw / canvasRatio
         sx = 0
         sy = (realHeight - sh) / 2
       } else { 
         sh = realHeight
         sw = sh * canvasRatio
         sx = (realWidth - sw) / 2 
         sy = 0
       } 
       // 仅在新形状和目标画布重叠的地方绘制新形状。其他的都是透明的
       context.globalCompositeOperation = "source-in";
       context.drawImage(template, sx, sy, sw, sh, 0, 0, 140, 140);
     };
   };
 }
 mergeImages()

miniprogram

.note-top-shape {
    box-sizing: border-box;
    position: relative;
    width: 284rpx;
    height: 284rpx;
    margin: auto;
    .img-shape-main {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -52%);
      width: 120rpx;
      height: 120rpx;
      z-index: 2;
    }
    .img-shape {
      position: relative;
      z-index: 1;
    }
    .img-shape-bg {
      position: absolute;
      top: 0;
      left: 50%;
      width: 284rpx;
      height: 284rpx;
      transform: translateX(-50%) scale(1.5);
      opacity: .05;
    }
  }
// 水晶
 <view class="note-top-shape">
    <image class="img-shape" src="{{ baseImageUrl }}{{ kindShape }}" mode="aspectFit" lazy-load="false" style="width: 284rpx;height: 284rpx;" binderror="" bindload="" />
    // canvas 在上面显示,因为canvas在小程序中层级太高,所以需要转化为image src展示
    <canvas type="2d" id="canvas_{{listItem.id}}" style="position: fixed;top: -9999px;left: -9999px;width: 240rpx;height: 240rpx;"></canvas>
    <block>
      <image class="img-shape-main" src="{{ imgPath }}" mode="aspectFit" lazy-load="false" binderror="" bindload=""></image>
    </block>
    // 加一层背景模糊
    <view class="img-shape-bg" style="background-image: radial-gradient( ellipse at top, {{ listItem.style }} 50%, transparent, transparent)"></view>
  </view>
Component({
  properties: {
    listItem: {
      type: Object,
      default: {
        //shape: 0,
        //style: red,
      }
    }
  },
  observers: {
    'listItem': function(item) {
      let shape = item.shape
      var shapeImage = ''
      switch (shape) {
        case '0':
          shapeImage = 'pyramid'
          break
        case '1':
          shapeImage = 'cube'
          break
        case '2':
          shapeImage = 'diamond'
          break
        case '3':
          shapeImage = 'hexsphere'
          break
        case '4':
          shapeImage = 'icosphere'
          break
      }
      // 水晶图片是根据接口数据显示的
      let src = `shape/${shapeImage}_${item.style}@2x.png`
      this.setData({
        kindShape: src
      })
    }
  },
  data: {
    imgPath: ''
  },
  attached() {
    let item = this.data.listItem
    this.mergeImagesMiniProgram(item.id, '/assets/images/[email protected]', item.photos[0])
  },
  methods: {
    mergeImagesMiniProgram(id, maskPath, filePath) {
    let that = this
    let query = wx.createSelectorQuery().in(this)
        query.select(`#canvas_${id}`).fields({ node: true, size: true }).exec((rescanvas) => {
        let canvas = rescanvas[0].node
        let ctx = canvas.getContext('2d')
        const overlay = canvas.createImage()
              overlay.src = maskPath
        let width = canvas.width = 120
        let height = canvas.height = 120

        let canvasRatio = width / height
        overlay.onload = function () {
          ctx.drawImage(overlay, 0, 0, width, height)
          const template = canvas.createImage()
          template.src = filePath

          template.onload = function () {
            let realWidth = template.width
            let realHeight = template.height
            // cover
            let imgRatio = realWidth / realHeight
            let sw = 0, sh = 0, sx = 0, sy = 0;
            if(imgRatio <= canvasRatio) {
              sw = realWidth
              sh = sw / canvasRatio
              sx = 0
              sy = (realHeight - sh) / 2
            } else { 
              sh = realHeight
              sw = sh * canvasRatio
              sx = (realWidth - sw) / 2 
              sy = 0
            } 
            // ctx.globalCompositeOperation = "destination-in";
            ctx.globalCompositeOperation = "source-in";
            ctx.drawImage(template, sx, sy, sw, sh, 0, 0, width, height)
            // ctx.drawImage(template, 0, 0, width, height);
            wx.canvasToTempFilePath({
              canvas,
              width: width,
              height: height,
              destWidth: width * app.globalData.pixelRatio,
              destHeight: height * app.globalData.pixelRatio,
              success: async function(res) {
                let filePath = res.tempFilePath;
                that.setData({
                  imgPath: filePath
                })
              },
              fail: function (res) {
              }
            })
          }
        }
    })
  }
})

素材图片

水晶

蒙层

我不叫胖虎

有需要可+qq:2091545890

参考文档-canvas drawImage绘图实现contain和cover的效果
参考文档-CanvasRenderingContext2D

标签:Canvas,样式,50%,canvas,height,width,shape,let,绘制
From: https://www.cnblogs.com/lisaShare/p/18404106

相关文章

  • 前端css样式优先级问题
    一、常用选择器1.标签选择器(标签名{}),选中对应标签里的内容,例(div{})2.类选择器(.类名{}),选中对应类名的内容,例(.one{})   注:不可以数字开头,一个标签中可有多个类名3.id选择器(#id{}),选中对应id的内容,例(#one{})   注:不可以数字开头,一个标签里只能有一个id属性4.通配符选择器(*{}),......
  • Python Matplotlib绘制柏拉图以及在ax.table上绘制矩形、直线、椭圆
    快速入门指南官网官方网址:Matplotlib—VisualizationwithPython官方教程:Tutorials—Matplotlib3.9.2documentation官方指南:UsingMatplotlib—Matplotlib3.9.2documentation官方示例:Examples—Matplotlib3.9.2documentation官方API说明:APIReference—Mat......
  • 8章8节:绘制自定义的高质量动态图和交互式动态图
    在数据科学和数据可视化的领域,动态图和交互式图形越来越受到重视,因为它们可以帮助用户更好地理解数据并发现潜在的模式。R语言作为数据分析和可视化的强大工具,提供了丰富的功能来创建这些图形。一、认识动态图动态图,顾名思义,是一种可以随时间或某些变量的变化而动态呈现的......
  • 【HTML页面】 每周更新的HTML好玩样式和页面
    本周有些迟到下面直接看页面吧星空个人介绍页猜拳小球下楼梯(加载动画)更改鼠标指针(有尾巴的小黑球)星空个人介绍页<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-......
  • 【Canvas与钟表】干支表盘
    【成图】【代码】<!DOCTYPEhtml><htmllang="utf-8"><metahttp-equiv="Content-Type"content="text/html;charset=utf-8"/><head><title>387.干支表盘</title><styletype="text/css"......
  • Canvas绘制线条时断断续续的
    解决线条断断续续的关键代码如下:我们可以使用quadraticCurveTo来实现贝塞尔曲线使其变成光滑的曲线注意:ctx.value.lineCap="round";           ctx.value.lineJoin="round";   这两个属性是必须设置的      lastX,lastY:贝塞尔曲线的起始......
  • 鸿蒙HarmonyOS入门篇第一天 组件-样式-基础
    1.常用的系统组件Text显示文本lmage显示图片Colum列,内容垂直排列row行,内容水平排列button按钮 2.通用属性wight宽height高backgroundColor背景色3.尺寸单位1.px物理像素,也叫设备像素,设备实际拥有的像素点(出场设置、分辨率单位)问题:如果用px作为宽高单......
  • AWTK 如何用 OpenGL 绘制图形
    在有GPU的情况下,AWTK使用OpenGL绘制图形。但是你会发现,如果自己在paint事件中使用OpenGL绘制图形,图形是无法显示的。原因是,AWTK采用nanovg绘制图形,而nanovg并不是在绘制时立即执行的,而是在整个界面绘制完成(EndFrame中)集中提交给GPU执行的。所以,如果在paint事......
  • 【Canvas与艺术】四叶花
    【成图】【代码】<!DOCTYPEhtml><htmllang="utf-8"><metahttp-equiv="Content-Type"content="text/html;charset=utf-8"/><head><title>386.四叶花</title><styletype="text/css"&......
  • Canvas艺术之旅:了解几个绘制基本图形的 API
    了解几个绘制基本图形的APICanvas是HTML5提供的绘画API,可以用于在Web页面上绘制各种基本图形。本文介绍一些Canvas绘制基本图形的API:前置条件注意:本文章所提供的代码示例默认已经进行了canvas元素定义,DOM获取以及canvas的上下文获取,以下进行代码演示时将......