精华内容
下载资源
问答
  • 效果图 整体思路: 实现图片缩放和拖动;...实现缩放和拖动最初是使用touchStart和touhMove,处理触摸事件来实现图片缩放和拖动,但是这样的实现在小程序上会很卡。后来无意中发现了小程序提...

    效果图

    在这里插入图片描述

    整体思路:

    1. 实现图片的缩放和拖动;
    2. 在图片上方盖上中间镂空的半透明遮罩;
    3. 根据截取方框区域的图片。截图时,在方框区域将截取的图片绘制出来,然后使用wx.canvasToTempFilePath截取图片。

    实现过程和遇到的问题:

    1. 实现缩放和拖动最初是使用touchStarttouhMove,处理触摸事件来实现图片的缩放和拖动,但是这样的实现在小程序上会很卡。后来无意中发现了小程序提供的movable-areamovable-view可以很方便地实现控件的拖动和缩放。
    2. 使用canvas绘制图片上方的半透明遮罩,最初我是把canvas放在movable-aread的上方,也就是在wxml文件中排在movable-area后面,这样会导致图片监听不了拖动事件和缩放事件。后来我将canvas前置,利用小程序中canvas在最上层的特点,实现遮罩,而又不影响图片的拖动和缩放。
    3. 使用给canvas设置rgb(0,0,0,0.5)来实现canvas的半透明,而不是使用其opacity属性。因为在小程序中实现截图,需要先通过canvas将图片绘制出来。如果使用opacity绘制出来的图片也是半透明的,由于尺寸的误差,canvas绘制的图片和后面显示的图片会出现重影,效果不佳。
    4. canvas不对底部栏覆盖。我这里是使用绝对定位,canvas相对屏幕底部120rpx,底部栏的高度正好也是120rpx。这里也可以使用canvasclearRect方法实现。
    5. canvas准确绘制要截取的图片。关键在于以下几个参数:源图片的大小尺寸,当前图片显示的尺寸、方框在显示的图片中的位置和大小。而方框在显示的图片中的位置又是通过方框和显示的图片分别相对于屏幕的位置得到。根据方框在显示图片中的位置和显示图片的尺寸求得一个比例,然后乘以源图片的位置,就拿到了方框在源图片中的位置和大小。
    6. 在实现原微信截图终端"还原"的问题,在小程序上缩放和拖动不能同时进行,一步到位。具体原因在代码注释中有解释。
    7. 解决截取图片拿不到文件的问题。重要的是要对canvas绘制图片加上监听,在canvas绘制图片完成后才提取图片文件。

    依然存在的问题

    1. 由于js计算的尺寸上的误差或者其他未知原因,用canvas绘制的图片和显示的图片会有个垂直方向上的轻微偏移。所以仔细看在点击完成时会有一个错位移动的现象。这个误差怎么解决,希望有心的网友可以告诉我。
    2. 前面也提到了,点击“撤销”(微信里叫“还原”),只能分两步撤销拖动和缩放,回到原来的位置。
    3. 受限于movable-area图片拖动能超出边界的范围不多,这应该可以通过放大movable-area解决,不过这样的话后面的一系列定位算法都要更改。网友有需要的话可以自己实现。

    核心代码

    Page({
    
      data: {
        // movable-view左上角相对于movable-area的坐标x,y,
        // 由于movable-area左上角位于屏幕原点,因此x,y也是movable-view相对于屏幕的坐标
        x: 0,
        y: 0,
        scale: 1, // 用来控制moveable-view的缩放比例,回撤重置时需要
    
        src: {
          // 图片的源文件数据
          path: '',
          orientation: 'up',
          // width和height在最初时和屏幕尺寸做比较,做一个合适的缩放
          // 在截图的时候,计算方框在源图片的位置也需要用到width和height
          width: 0,
          height: 0,
          ratio: 1, // 图片的长宽比,最开始需要根据ratio判断图片的形状是长图还是宽图,进行合适的居中放置
        },
        image: {
          // 最初图片在屏幕上显示的宽度和高度
          // 经过缩放后也是基于这两个尺寸计算新的尺寸
          initialWidth: 0,
          initialHeight: 0,
          // 控制最初图片在屏幕中的位置
          initialX: 0,
          initialY: 0,
          // 经过缩放移动后图片在屏幕中的位置
          // 截图时找方框在源图片中的位置,是基于屏幕坐标系,所以需要图片的当前位置
          curX: 0,
          curY: 0,
          // 图片当前的缩放比例,用于计算图片当前显示的尺寸大小
          curScale: 1
        },
        // 屏幕尺寸windowWidth和windowHeight
        windowWidth: 0,
        windowHeight: 0,
        cropBorder: {
          // 截图的方框相对于屏幕中的位置
          x: 0,
          y: 0,
          // 截图方框的尺寸
          size: 0
        },
      },
    
      /**
       * 生命周期函数--监听页面加载
       */
      onLoad: function(options) {
        let that = this;
        let _src = JSON.parse(options.data);
        _src.ratio = _src.height / _src.width;
        let systemInfo = wx.getSystemInfoSync();
        // 屏幕内框范围(这里定义左右边界30,上下边际50)
        // 但是因为movable-view能超出movable-area的范围太小,为了尽量放大图片的活动范围,这里取消了这个边界
        // let borderWidth = systemInfo.windowWidth - 2 * 30
        // let borderHeight = systemInfo.windowHeight - 2 * 50
        let _image = that.data.image
        if (_src.width > systemInfo.windowWidth && _src.height > systemInfo.windowHeight) {
          // 如果图片尺寸大于屏幕尺寸,需要缩放
          if (_src.ratio > 1) {
            // 如果是长图,按照宽度进行缩放
            _image.initialWidth = systemInfo.windowWidth
            // >> 0用来取整
            _image.initialHeight = (_src.ratio * systemInfo.windowWidth) >> 0
          } else {
            // 如果是宽图,按照高度进行缩放
            _image.initialWidth = systemInfo.windowHeight,
              _image.initialHeight = (systemInfo.windowHeight / _src.ratio) >> 0
          }
        } else {
          _image.initialWidth = _src.width
          _image.initialHeight = _src.height
        }
        // 控制图片在屏幕居中
        _image.initialX = (systemInfo.windowWidth - _image.initialWidth) >> 1
        _image.initialY = (systemInfo.windowHeight - _image.initialHeight) >> 1
        console.log(JSON.stringify(_image))
        // 定义方框的位置和尺寸
        let _cropBorder = {}
        _cropBorder.size = systemInfo.windowWidth * 0.9
        _cropBorder.x = (systemInfo.windowWidth - _cropBorder.size) >> 1
        _cropBorder.y = (systemInfo.windowHeight - _cropBorder.size) >> 1
        that.setData({
          src: _src,
          image: _image,
          cropBorder: _cropBorder,
          windowWidth: systemInfo.windowWidth,
          windowHeight: systemInfo.windowHeight
        })
      },
    
      /**
       * 移动movable-view的回调
       */
      onChange(e) {
        console.log(e.detail)
        let that = this;
        that.setData({
          'image.curX': e.detail.x,
          'image.curY': e.detail.y
        })
      },
    
      /**
       * 缩放moveable-view的回调
       */
      onScale(e) {
        console.log(e.detail)
        let that = this;
        that.setData({
          'image.curX': e.detail.x,
          'image.curY': e.detail.y,
          'image.curScale': e.detail.scale
        })
      },
    
      /**
       * 生命周期函数--监听页面初次渲染完成
       */
      onReady: function() {
        let that = this;
        let cropBorder = that.data.cropBorder
        this.context = wx.createCanvasContext('myCanvas')
        // 设置背景黑色透明度0.5,不要使用opacity,会导致后期截出来的图片也是半透明
        this.context.setFillStyle('rgba(0,0,0,0.5)')
        this.context.fillRect(0, 0, that.data.windowWidth, that.data.windowHeight)
        // 挖出来一个方框,这个方框区域就是全透明了
        this.context.clearRect(cropBorder.x, cropBorder.y, cropBorder.size, cropBorder.size)
        // 画方框的外框
        this.context.setStrokeStyle('white')
        // 往外画大一圈,这样在canvas上填充图片的时候框线就不会变细啦
        this.context.strokeRect(cropBorder.x - 1, cropBorder.y - 1, cropBorder.size + 2, cropBorder.size + 2)
        this.context.draw()
      },
    
      /**
       * 取消截图
       */
      cancel(event) {
        wx.navigateBack()
      },
    
      /**
       * 回撤,这地方有个问题:
       * 本来是想图片一次性移动和缩放回到最初的位置和大小,但是发现点击第一次只能实现图片移动到初始点
       * 点击第二次才是缩放到初始大小
       * 后来发现小程序移动有一个过程,会不停地回调onChange(),
       * 如果一定要实现,只能是当onChange中x,y归0之后再控制缩放,
       * 但是x和y是浮点数,零判断不精确而且影响性能,所以放弃了。
       */
      reset(event) {
        let that = this;
        that.setData({
          scale: 1,
          x: 0,
          y: 0,
        })
      },
    
      /**
       * 点击完成的回调
       * 完成截图,回传图片到上一页
       */
      complete(event) {
        let that = this
        let src = that.data.src
        console.log(src)
        let cropBorder = this.data.cropBorder
        let image = that.data.image
        // 当前图片显示的大小
        let curImageWidth = image.initialWidth * image.curScale
        let curImageHeight = image.initialHeight * image.curScale
        // 将方框位置换算到源图片中的位置srcX,srcY
        let srcX = (cropBorder.x - image.curX) / curImageWidth * src.width
        // canvas的height是100%,而bottom是120rpx,因此canvas的位置不是在原点,需要减去这个120rpx
        // 置于这里为什么要有个120,因为底部栏也是透明的,但字是亮的,我想呈现底部栏在上方不被遮罩挡住的效果
        // 经过测试,这里-4可以解决canvas绘制的图片向上偏移的问题,为什么是-4我也不知道,与边框的厚度有关?
        let srcY = (cropBorder.y - image.curY - 120 / 750 * that.data.windowWidth-4) / curImageHeight * src.height
        // 方框区域映射到源图片中的尺寸
        let srcWidth = cropBorder.size / curImageWidth * src.width
        let srcHeight = cropBorder.size / curImageHeight * src.height
        console.log('srcX = ' + srcX + ', srcY = ' + srcY + ', srcWidth = ' + srcWidth + ', srcHeight = ' + srcHeight + ', cropX = ' + cropBorder.x + ', cropY = ' + cropBorder.y + ', cropSize = ' + cropBorder.size)
        // 绘制图片不要透明啦,不然会看到重影
        this.context.setFillStyle('rgba(0,0,0,1)')
        // 鉴于尺寸的精确度,方框内图片的覆盖在y方向会有微微的偏移,
        // 但是一旦截图就返回上一页了,强迫症患者没有后悔的余地。
        this.context.drawImage(src.path, srcX, srcY, srcWidth, srcHeight, cropBorder.x, cropBorder.y, cropBorder.size, cropBorder.size)
        // 这里绘图一定要有回调,不然图片还没绘制完成就截图那就GG了
        this.context.draw(true, function(res) {
          wx.canvasToTempFilePath({
            canvasId: 'myCanvas',
            x: cropBorder.x,
            y: cropBorder.y,
            width: cropBorder.size,
            height: cropBorder.size,
            destWidth: cropBorder.size,
            destHeight: cropBorder.size,
            fileType: 'jpg',
            success: function(data) {
              console.log(data)
              // 将图片回传到上一页
              var pages = getCurrentPages();
              if (pages.length > 1) {
                var prePage = pages[pages.length - 2];
                prePage.setData({
                  newAvatar: data.tempFilePath
                })
              }
              wx.navigateBack()
            },
            fail: function(err) {
              console.log(err)
            }
          })
        })
      },
    })
    

    源代码

    https://github.com/sheaye/wx-avatar-cropper

    展开全文
  • 微信小程序图片缩放、移动

    千次阅读 2018-11-16 15:36:22
    一波干货 .wxml <!--scale.wxml--> <view class="container">...scroll-view子元素缩放&...说明:双指缩放开发工具上并不支持,需要在真机上进行。 &am

    一波干货

    .wxml

    <!--scale.wxml-->
    <view class="container">
      <view class="tip">
        <text>scroll-view子元素缩放</text>
        <text>说明:双指缩放开发工具上并不支持,需要在真机上进行。 </text>
      </view>
    
      <scroll-view class="img" bindtouchstart="touchstartCallback"  bindtouchmove="touchmoveCallback" bindtouchend="touchendCallback" scroll-x="true"  scroll-y="true" >
          <image style="zoom:{{stv.scale}};" src="https://avatar.csdn.net/0/2/1/1_qq_36742720.jpg?1542353573"></image>
      </scroll-view>
    
      <view>
        <text>x: {{stv.offsetX}}</text>, 
        <text>y: {{stv.offsetY}}</text>, 
        <text>d: {{stv.distance}}</text>, 
        <text>s: {{stv.scale}}</text>, 
      </view>
    </view>
    

     

    .wxss

    /**scale.wxss**/
    .img {
      width: 100%;
      height: 500rpx;
      background: #AAA;
      text-align: center;
    }
    .img image {
      /* height: 800rpx;
      width: 600rpx; */
    }
    
    

     

    .js

    //scale.js
    //获取应用实例
    var app = getApp()
    Page({
      data: {
        stv: {
          offsetX: 0,
          offsetY: 0,
          zoom: false, //是否缩放状态
          distance: 0,  //两指距离
          scale: 1,  //缩放倍数
        }
      },
      //事件处理函数
      touchstartCallback: function (e) {
        //触摸开始
        console.log('touchstartCallback');
        console.log(e);
    
        if (e.touches.length === 1) {
          let { clientX, clientY } = e.touches[0];
          this.startX = clientX;
          this.startY = clientY;
          this.touchStartEvent = e.touches;
        } else {
          let xMove = e.touches[1].clientX - e.touches[0].clientX;
          let yMove = e.touches[1].clientY - e.touches[0].clientY;
          let distance = Math.sqrt(xMove * xMove + yMove * yMove);
          this.setData({
            'stv.distance': distance,
            'stv.zoom': true, //缩放状态
          })
        }
    
      },
      touchmoveCallback: function (e) {
        //触摸移动中
        console.log('touchmoveCallback');
        console.log(e);
    
        if (e.touches.length === 1) {
          //单指移动
          if (this.data.stv.zoom) {
            //缩放状态,不处理单指
            return;
          }
          let { clientX, clientY } = e.touches[0];
          let offsetX = clientX - this.startX;
          let offsetY = clientY - this.startY;
          this.startX = clientX;
          this.startY = clientY;
          let { stv } = this.data;
          stv.offsetX += offsetX;
          stv.offsetY += offsetY;
          stv.offsetLeftX = -stv.offsetX;
          stv.offsetLeftY = -stv.offsetLeftY;
          this.setData({
            stv: stv
          });
    
        } else {
          //双指缩放
          let xMove = e.touches[1].clientX - e.touches[0].clientX;
          let yMove = e.touches[1].clientY - e.touches[0].clientY;
          let distance = Math.sqrt(xMove * xMove + yMove * yMove);
    
          let distanceDiff = distance - this.data.stv.distance;
          let newScale = this.data.stv.scale + 0.005 * distanceDiff;
          // 为了防止缩放得太大,所以scale需要限制,同理最小值也是 
          if (newScale >= 2) {
            newScale = 2
          }
          if (newScale <= 0.6) {
            newScale = 0.6
          }
          this.setData({
            'stv.distance': distance,
            'stv.scale': newScale,
          })
        }
    
      },
      touchendCallback: function (e) {
        //触摸结束
        console.log('touchendCallback');
        console.log(e);
    
        if (e.touches.length === 0) {
          this.setData({
            'stv.zoom': false, //重置缩放状态
          })
        }
      },
      onLoad: function () {
        console.log('onLoad');
      }
    })
    

     

    展开全文
  • 微信图片点击可以放大,可以随意缩放,拖拉浏览,这样的代码应该怎么写出来啊,求解答,帮帮忙
  • 微信小程序 图片缩放和裁剪

    千次阅读 2018-09-24 17:01:57
    下面博主将会通过图文讲解的方式跟大家分享微信小程序开发过程中关于图片缩放和裁剪,最后附上源码! 要设置了的高宽才会有缩放的概念(不然就会使用小程序的默认高宽320) aspectfill,会将图片变成你设置的image...

    下面博主将会通过图文讲解的方式跟大家分享微信小程序开发过程中关于图片的缩放和裁剪,最后附上源码!

    在这里插入图片描述

    要设置了的高宽才会有缩放的概念(不然就会使用小程序的默认高宽320)
    aspectfill,会将图片变成你设置的image高宽,(小于就)放大或者(大于)裁剪

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    以下是微信小程序项目源码:点击可以进入gitee直接下载源码包喔
    微信小程序演示程序

    版权所有,禁止转载,违者必究。
    喜欢的朋友可以点赞评论喔,您的支持是我更新最大的动力~

    展开全文
  • 二、样式及背景图片显示问题 1、修改单个页面的背景色: 在页面的wxss里面加上这句代码: page{ background-color: lightcyan; } 2、小程序中的颜色设置 //颜色不要加引号,也可以直接是英文 border-top:1...

    ##一、背景

    下面这些都是在开发的过程中,记录下来的笔记。

    ##二、样式及背景图片显示问题

    1、修改单个页面的背景色:
    在页面的wxss里面加上这句代码:

    page{
      background-color: lightcyan;
    }
    

    2、小程序中的颜色设置

    //颜色不要加引号,也可以直接是英文
    border-top:1rpx solid  #e5e5e5;
    

    3、小程序中的rpx和px的区别

          rpx单位是微信小程序中css的尺寸单位,rpx可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0

    4、关于背景图片

    本地资源无法通过 WXSS 获取
    background-image:可以使用网络图片,或者 base64,或者使用标签

    但是可以在wxml中,通过style设置

    <view class='bg' style="background-image: url('../../img/bg.png');">
    

    也可以访问网络图片,比如把图片上传到阿里的OSS,直接使用阿里返回的路径也可以

    5、关于小程序中的flex布局,可以参考阮一峰的文章:

    http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html

    6、关于本地背景图片在手机上无法显示的问题

          这个问题在网上百度了一下,大多数人都建议,不要用本地资源。最好是用网络资源,也就是把图片上传到OSS上,访问。

    我这边是把图片上传到阿里云的OSS,返回图片的网络路径,直接使用即可。

      <view class='bg' style="background-image: url('http://pzsh.oss-cn-shanghai.aliyuncs.com/xxx/xx.png');background-size: cover">
    

    这里的background-size: cover是为了让图片等比例缩放,铺满整个屏幕。

    end

    展开全文
  • 微信朋友圈图片显示缩放

    千次阅读 2014-11-13 09:12:00
    感觉最麻烦的就是在图片缩放的部分,结果发现微信在朋友圈图片点击放大的地方是渐入的,可是再次点击的时候是闪出的,没有渐变背景效果,所以修复了一下,如今分享给大家。(仅仅是个demo)详细应用到程序中,还须要...
  • 微信小程序怎么插图背景图片Placing text on top of an image requires careful attention to color and contrast to maintain legibility. Print designers have traditionally used partially opaque backgrounds ...
  • 先来一个效果图 ...手指下拉图片图片会被移动并且缩小,同时背景也有个透明度的变化; 正常状态按下,往上移动,是不能对图片进行移动的,但是往下拉一下之后就可以上下左右随便移动; 要实现...
  • 图片在网站上转换为base64格式,然后再设置 【将图片转换为base64网站】http://imgbase64.duoshitong.com/ .userInfo{ width: 800rpx; /*高宽大小根据个人情况自己调试*/ height: 1150rpx; background-...
  • 小程序遇到包大小超出限制时,可以首先检查下是否有过大的图片,采用处理成网络图片的方式就可以快速解决这个问题。...本博客包含了三种添加背景图片的方式:base64,图片标签和网络图片,推荐使用第三种。
  • 背景图片的制作       我相信有很多人和我一样,在制作背景图片是遇到了困难,比如图片为何显示扭曲,不是按给与图片大小显示的,又比如为何图片无法置顶显示,而是有一定的空间隔开...
  • 微信小程序——button添加背景图片

    万次阅读 热门讨论 2018-08-02 14:51:44
    &lt;button class="weui-btn" form-type='submit' plain='true'&gt; &lt;image src='../../images/bm_btn.png' mode='widthFix'&gt;&lt;/image&... button的padding设...
  • wxml: <image class="lecturer_head"mode="aspectFill"src="XXXX/Public/Uploads/2019-06-18/5d0883e70b422.jpg"></image> ...主要是下面四行代码css: ... background: no-repeat center 0rpx...
  • --图片宽高大于屏幕宽高--&gt; &lt;image style="width: {{imagewidth}}px; height: {{imageheight}}px;" src="{{imageSrc}}" bindload="imageLoad"&gt;&lt;/image&...
  • 可以进行图片的多张选择,拍照添加图片,以及进行图片的预览,预览时可以进行缩放,并且可以删除选中状态的图片 。很不错的源码,大家有需要可以下载看看 。 微信 微信 微信 微信 下载地址 : ...
  • 微信小程序实现对图片缩放与裁剪

    万次阅读 多人点赞 2019-03-17 18:19:29
    实现图片缩放 wx.chooseImage上传图片 wx.getImageInfo获取图片宽高等信息 bindtouchstart,bindtouchmove记录双指事件 通过双指移动的距离与初始距离的关系判断缩放 规定阈值,最大与最小缩放 实现对图片的...
  • 思路 wx.chooseImage上传图片 wx.getImageInfo获取图片宽高等信息 bindtouchstart,...由于上传的图片需要放大与缩小,所以我们首先要在style动态绑定width 和height,其次要设置overflow为scroll。 然后开...
  • 仿照微信,朋友圈分享图片功能 。可以进行图片的多张选择,拍照添加图片,以及进行图片的预览,预览时可以进行缩放,并且可以删除选中状态的图片 。很不错的源码,大家有需要可以下载看看 。 如果不知道...
  • 微信公众号H5里面可能会遇到点击图片预览,还可以放大缩小微信内置有这个功能可以实现 用vue写项目的话,先 cnpm install weixin-js-sdk --save 接着给图片一个点击事件 <img src="" alt="" @click="preview...
  • 微信小程序常见问题】view标签设置背景图片手机无法预览解决方案二:将本地图片路径修改为网络图片链接。
  • 微信小程序:利用canvas缩小图片

    万次阅读 2017-12-15 17:54:14
    功能分两部分:展示、提交 ...压缩原理:选择图片后,利用canvas的drawImage方法重新定义图片大小,再利用canvasToTempFilePath方法下载到缩小图片。// 利用绝对定位 隐藏canvas <canvas canvas-id="photo
  • 拍照,相册获取图片,高仿微信裁切图片
  • 友盟分享圆角icon到微信时会显示黑边,原因是微信对于透明背景会裁剪掉. 对于一般情况是可以通过给图片设置为PNG解决. umImage = new UMImage(url); umImage.compressFormat = Bitmap.CompressFormat.PNG; ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,646
精华内容 3,458
关键字:

微信背景图片缩小