Antecedents to review
I published in the earlier article “how to achieve micro channel small program change avatar? Three steps to help you fix!” , mentioned that there are three steps to achieve wechat mini program to change the avatar:
- Get user profile picture
- Image template
- Image synthesis
The previous article has been on the user profile picture and image template two steps to explain, this article will elaborate on how to synthesize images.
A very important part of the picture composition process is to cut the picture. This function point is very fixed, mostly after dragging and zooming the picture, cut out a fixed length and width picture in a certain area. This kind of function in THE APP end and H5 have a lot of mature plug-ins for use, next to see me in the dolphin interesting picture small program in the head cut plug-in is how to achieve, welcome your comments.
To better understand the following code, I recommend that you scan and experience the cropping effect of the image.
Implementation effect
Interface implementation
Dragging and zooming images in H5 requires a bunch of code, and there are many implementations on the web. Small programs are much easier to implement, with
and
<view class="clip-view">
<! ImgHeight, imgWidth imgUrl is the url of the clipped image -->
<movable-area class="moveare" style="height: {{clipHeight}}rpx; width: {{clipWidth}}rpx; ">
<movable-view scale="true" scale-min="{{1}}" damping="1000" style="height: {{imgHeight}}px; width: {{imgWidth}}px; " direction="all" x="{{x}}" y="{{y}}" bindchange="_onChange" bindscale="_onScale">
<image class="clip-img" src="{{imgUrl}}" />
</movable-view>
</movable-area>
<! -- Trim box decoration -->
<view class="clip-box" style="height: {{clipHeight}}rpx; width: {{clipWidth}}rpx; ">
<! -- Clipbox four corners -->
<view class="clip-border clip-border-lt"></view>
<view class="clip-border clip-border-rt"></view>
<view class="clip-border clip-border-lb"></view>
<view class="clip-border clip-border-rb"></view>
</view>
<! -- Canvas for clipping images -->
<canvas class="clip-canvas" id="img_clip_canvas" canvas-id="img_clip_canvas" style="height: {{clipHeight}}rpx; width: {{clipWidth}}rpx; "></canvas>
</view>
Copy the code
Component attributes
The input parameter to the component only needs the address of the original image and the width and height of the image clipbox
/** * Component property list */
properties: {
// The path of the original image (the image to cut)
imgUrl: {
type: String.value: ' '
},
// The width of the clip (RPX)
clipWidth: {
type: Number.value: 500
},
// Cut height (RPX)
clipHeight: {
type: Number.value: 500}}Copy the code
The component data
The component’s data will record more data about the drag and zoom of the picture. It should be noted that the initial position of the picture and the drag position are not stored in the same variable, in order to prevent jitter in the drag process.
/** * The initial data of the component */
data: {
baseScale: 1.imgPath: ' '.imgWidth: 0./ / picture width
imgHeight: 0./ / picture
x: 0.// The image starts with the X-axis position
y: 0.// The y position of the image does not share the same variable as top, because if y value is changed frequently, the image will flicker, the same as x
left: 0.// Drag the image to the X-axis position
top: 0.// Drag the image to the Y-axis position
scale: 1 // Zoom after drag and drop
}
Copy the code
Component initialization
The component’s initialization method is used to scale the image to the appropriate size and center the clipbox
/** * Initialization method * After obtaining the width and height of the image, scale the image to the size of the clipbox, * and place the clipbox in the center of the image **/
_init() {
if (!this.data.imgUrl) return
// Get the screen width
let {
screenWidth
} = wx.getSystemInfoSync()
// Calculate screen RPX
const rpx = screenWidth / 750
// Get the image width and height, then scale to the clipbox size
wx.getImageInfo({
src: this.data.imgUrl,
success: ({
width,
height,
path
}) => {
const cw = this.data.clipWidth * rpx
const ch = this.data.clipHeight * rpx
let scale = Math.max(cw / width, ch / height)
const imgWidth = width * scale
const imgHeight = height * scale
this.setData({
imgPath: path,
imgWidth,
imgHeight,
baseScale: scale,
x: (cw - imgWidth) / 2.y: (ch - imgHeight) / 2})}})}Copy the code
Picture drag and zoom processing
After initialization, you can monitor the user’s drag and zoom operations, mainly recording the position of drag and zoom ratio, specific to the code implementation is to monitor the bindchange and bindscale events of
// Drag the event response function
_onChange: function(e) {
this.setData({
x: e.detail.x,
y: e.detail.y
})
}
// Scale the event response function
_onScale: function(e) {
this.setData({
x: e.detail.x,
y: e.detail.y,
scale: e.detail.scale
})
}
Copy the code
Image clipping implementation
After dragging and zooming, it will be clipped. Clipping is to redraw the clipping area of the picture using
/** ** image clipping entry method */
clip() {
const scale = this.data._scale * this.data._baseScale
const canvasId = 'img_clip_canvas'
imageClip(canvasId, this.data.imgPath, {
x: this.data._left * - 1.y: this.data._top * - 1,
scale,
width: this.data.clipWidth,
height: this.data.clipHeight
}, this)}** @param canvas canvas component id, Used to draw the clipped image * @param img The image to be clipped * @param option.left Clipped image left margin * @param option.top Clipped image top margin * @param option.left clipped image left margin * @param option.top Clipped image top margin * @param option.width Cut image width * @param option.height Cut image height * @param context component instance object * * @return new Promise(resolve=> CTX) * /
imageClip(canvas, img, option, context) {
return new Promise((resolve, reject) = > {
option = Object.assign({
left: 0.top: 0.scale: 1.width: 0.height: 0
}, option)
let x = option.left / option.scale
let y = option.top / option.scale
let clipW = option.width / option.scale
let clipH = option.height / option.scale
const ctx = wx.createCanvasContext(canvas, context)
ctx.drawImage(img,
x,
y,
clipW,
clipH,
0.0,
option.width,
option.height)
ctx.draw(false, (e) => {
console.log(e)
resolve()
})
})
},
/** * Canvas is saved as temporary file */
function saveCanvasToTemp(canvas, option) {
return new Promise((resolve, reject) = >{ wx.canvasToTempFilePath({ ... option,canvasId: canvas,
success:resolve,
fail:reject
}, this)})}Copy the code
Write in the last
This is the main code implementation of the small program version of the image clipping, there are a few minor points to note
<movable-view>
Set the value of damping to uppercase, otherwise it may be dragged out of bounds- Call in custom components
wx.createCanvasContext(string canvasId, Object this)
Method, the second parameter this cannot be omitted, otherwise the canvas will not respond - Remember to convert to the actual size of the image when cutting
About us
The front end team of Kuaigou Taxi focuses on sharing front-end technology and regularly pushes high-quality articles, which are welcome to be praised. This article will be published on our official account, just scan it!