123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763 |
- <template>
- <view class="vue-cropper" ref="cropper" :style="{ top : `${containerTop}px` }" v-show="show">
- <view class="cropper-box">
- <view class="cropper-box-canvas" @touchstart.stop.prevent="imgTouchStart" @touchmove.stop.prevent="imgMoveing" @touchend.stop.prevent="imgMoveEnd" :style="{
- 'width': imageWidth + 'px',
- 'height': imageHeight + 'px',
- 'transform': 'scale(' + scale + ',' + scale + ') ' + 'translate3d('+ x / scale + 'px,' + y / scale + 'px,' + '0)'
- + 'rotateZ('+ rotate * 90 +'deg)'
- }">
- <image :src="link" alt="cropper-img" ref="cropperImg" mode="scaleToFill" class="uni-image"></image>
- </view>
- </view>
- <view class="cropper-drag-box cropper-modal cropper-move pointer-events"></view>
- <view class="cropper-crop-box" :class="{'pointer-events': cropFixed}" :style="{'width': cropW + 'px','height': cropH + 'px','transform': 'translate3d('+ cropOffsertX + 'px,' + cropOffsertY + 'px,' + '0)'}">
- <view class="cropper-view-box">
- <image :style="{'width': imageWidth + 'px','height': imageHeight + 'px','transform': 'scale(' + scale + ',' + scale + ') ' + 'translate3d('+ (x - cropOffsertX) / scale + 'px,' + (y - cropOffsertY) / scale + 'px,' + '0)' + 'rotateZ('+ rotate * 90 +'deg)'}" mode="scaleToFill" :src="link" alt="cropper-img"></image>
- </view>
- <view v-if="!cropFixed" class="cropper-face cropper-move" @touchstart.stop.prevent="touchStart" @touchmove.stop.prevent="cropMoveing"></view>
- <view class="crop-line line-w"></view>
- <view class="crop-line line-a"></view>
- <view class="crop-line line-s"></view>
- <view class="crop-line line-d"></view>
- <block v-if="!cropFixed">
- <view class="crop-point point-lt" @touchstart.stop.prevent="touchStart" @touchmove.stop.prevent="dragMove($event, 'left-top')"></view>
- <view class="crop-point point-mt" @touchstart.stop.prevent="touchStart" @touchmove.stop.prevent="dragMove($event, 'middle-top')"></view>
- <view class="crop-point point-rt" @touchstart.stop.prevent="touchStart" @touchmove.stop.prevent="dragMove($event, 'right-top')"></view>
- <view class="crop-point point-ml" @touchstart.stop.prevent="touchStart" @touchmove.stop.prevent="dragMove($event, 'middle-left')"></view>
- <view class="crop-point point-mr" @touchstart.stop.prevent="touchStart" @touchmove.stop.prevent="dragMove($event, 'middle-right')"></view>
- <view class="crop-point point-lb" @touchstart.stop.prevent="touchStart" @touchmove.stop.prevent="dragMove($event, 'left-bottom')"></view>
- <view class="crop-point point-mb" @touchstart.stop.prevent="touchStart" @touchmove.stop.prevent="dragMove($event, 'middle-bottom')"></view>
- <view class="crop-point point-rb" @touchstart.stop.prevent="touchStart" @touchmove.stop.prevent="dragMove($event, 'right-bottom')"></view>
- </block>
- </view>
- <canvas canvas-id="myCanvas" class="cropper-canvas" :style="{ 'width': cropW + 'px','height': cropH + 'px' }"></canvas>
- <view class="btn-group">
- <view class="btn-item rotate-btn" v-show="showRotateBtn" @tap="rotateHandler"></view>
- </view>
- <view class="uni-info__ft">
- <view class="uni-modal__btn uni-modal__btn_default" style="color: #9A9ABF;" @tap="cancel">取消</view>
- <view class="uni-modal__btn uni-modal__btn_default" style="color: #9A9ABF;" @tap="init">还原</view>
- <view class="uni-modal__btn uni-modal__btn_primary" style="color: #FFFFFF;" @tap="confirm">下一步</view>
- </view>
- </view>
- </template>
- <script>
- export default {
- name: 'image-cropper',
- props: {
- cropWidth: {
- type: Number,
- default: 200,
- },
- cropHeight: {
- type: Number,
- default: 200
- },
- cropFixed: {
- type: Boolean,
- default: false,
- },
- link: {
- type: String,
- },
- showResetBtn: {
- type: Boolean,
- default: true,
- },
- showRotateBtn: {
- type: Boolean,
- default: true,
- }
- },
- data() {
- const sysInfo = uni.getSystemInfoSync();
- const pixelRatio = sysInfo.pixelRatio
- return {
- show: false,
- scale: 1,
- rotate: 0,
- cropW: 0,
- cropH: 0,
- cropOldW: 0,
- cropOldH: 0,
- sysInfo: sysInfo,
- pixelRatio: pixelRatio,
- imageRealWidth: 0,
- imageRealHeight: 0,
- cropOffsertX: 0,
- cropOffsertY: 0,
- startX: 0,
- startY: 0,
- // 裁剪框与边界间距
- border: 5,
- x: 0,
- y: 0,
- startL: 0,
- oldScale: 1,
- }
- },
- watch: {
- link(val) {
- if(val.length > 0) {
- this.init()
- }
- },
- show(val) {
- if(!val) {
- this.link = ''
- }
- }
- },
- computed: {
- containerTop() {
- let top = 0
- // #ifdef H5
- top = 44
- // #endif
- return top;
- },
- // 容器高度
- containerHeight() {
- return this.windowHeight - 48;
- },
- // 屏幕宽度
- windowWidth() {
- return this.sysInfo.windowWidth;
- },
- windowHeight() {
- return this.sysInfo.windowHeight;
- },
- // 图片宽高比
- imageRatio() {
- if (this.imageRealHeight > 0) {
- return this.imageRealWidth / this.imageRealHeight
- }
- return 0
- },
- // 等比缩放后的宽度
- imageWidth() {
- if (this.imageRatio >= 1) {
- return this.windowWidth
- }
- return this.windowWidth * this.imageRatio
- },
- // 等比缩放后的高度
- imageHeight() {
- if (this.imageRatio >= 1) {
- return this.windowWidth / this.imageRatio
- }
- return this.windowWidth
- },
- },
- methods: {
- rotateHandler() {
- if(this.rotate == 3) {
- this.rotate = 0;
- } else {
- ++this.rotate
- }
- },
- init() {
- this.rotate = 0;
- this.scale = 1;
- this.cropW = this.cropWidth
- this.cropH = this.cropHeight
- uni.showLoading({
- title: '图片加载中...',
- })
- this.loadImage(this.link).then((e) => {
- uni.hideLoading()
- }).catch((e) => {
- uni.hideLoading()
- uni.showModal({
- title: '标题',
- content: '图片加载失败'
- })
- })
- },
- loadImage(link) {
- const _this = this
- return new Promise((resolve, reject) => {
- uni.getImageInfo({
- src: link,
- success: (res) => {
- _this.imageRealWidth = res.width
- _this.imageRealHeight = res.height
- _this.cropOffsertX = _this.windowWidth / 2 - _this.cropW / 2
- _this.cropOffsertY = _this.windowHeight / 2 - _this.cropH / 2
- _this.show = true
- _this.$nextTick(() => {
- _this.x = _this.windowWidth / 2 - _this.imageWidth / 2
- _this.y = _this.containerHeight / 2 - _this.imageHeight / 2
- });
- resolve(res)
- },
- fail: (e) => {
- _this.show = false
- reject(e)
- }
- })
- });
- },
- cancel() {
- this.show = false
- this.$emit('cancel')
- },
- confirm(event) {
- uni.showLoading({
- title: '裁剪中...',
- })
- const _this = this
- const ctx = uni.createCanvasContext('myCanvas', _this);
- const pixelRatio = _this.pixelRatio
- const imgage = _this.link
- const imgW = _this.imageWidth * _this.scale;
- const imgH = _this.imageHeight * _this.scale
- const rotate = _this.rotate
- let dx = _this.cropOffsertX - _this.x - (_this.imageWidth - imgW) / 2;
- let dy = _this.cropOffsertY - _this.y - (_this.imageHeight - imgH) / 2;
- ctx.setFillStyle('white')
- ctx.fillRect(0, 0, imgW, imgH)
- ctx.save()
- ctx.rotate((rotate * 90 * Math.PI) / 180);
- switch (rotate) {
- case 1:
- dx += (imgH-imgW) / 2
- dy -= (imgH-imgW) / 2
- ctx.drawImage(imgage, -dy, dx, imgW, -imgH);
- break;
- case 2:
- ctx.drawImage(imgage, dx, dy, -imgW, -imgH);
- break;
- case 3:
- dx += (imgH-imgW) / 2
- dy -= (imgH-imgW) / 2
- ctx.drawImage(imgage, dy, -dx, -imgW, imgH);
- break;
- default:
- ctx.drawImage(imgage, -dx, -dy, imgW, imgH);
- break;
- }
- ctx.restore()
- ctx.draw(false, () => {
- uni.canvasToTempFilePath({
- canvasId: 'myCanvas',
- destWidth: _this.cropW * pixelRatio,
- destHeight: _this.cropH * pixelRatio,
- success: (res) => {
- uni.hideLoading()
- event.detail.tempFilePath = res.tempFilePath
- _this.show = false
- _this.$emit('confirm', event)
- },
- fail: (e) => {
- uni.hideLoading()
- uni.showModal({
- title: '提示',
- content: '裁剪失败'
- })
- }
- }, _this);
- })
- },
- imgTouchStart(e) {
- if(e.touches.length == 2) {
- this.oldScale = this.scale
- this.scaling = true
- const x = e.touches[0].pageX - e.touches[1].pageX
- const y = e.touches[0].pageY - e.touches[1].pageY
- const hypotenuse = Math.sqrt(
- Math.pow(x, 2) +
- Math.pow(y, 2)
- )
- this.startL = Math.max(x, y, hypotenuse)
- uni.showModal({
- content: this.startL
- })
- } else {
- this.startX = e.touches[0].pageX - this.x
- this.startY = e.touches[0].pageY - this.y
- }
- },
- imgMoveing(e) {
- if(this.scaling) {
- let scale = this.oldScale
- const x = e.touches[0].pageX - e.touches[1].pageX
- const y = e.touches[0].pageY - e.touches[1].pageY
- const hypotenuse = Math.sqrt(
- Math.pow(x, 2) +
- Math.pow(y, 2)
- )
- const newL = Math.max(x, y, hypotenuse)
- const cha = newL - this.startL;
- // 根据图片本身大小 决定每次改变大小的系数, 图片越大系数越小
- // 1px - 0.2
- let coe = 1;
- coe =
- coe / this.imageWidth > coe / this.imageHeight
- ? coe / this.imageHeight
- : coe / this.imageWidth;
- coe = coe > 0.1 ? 0.1 : coe;
- const num = coe * cha;
- if (cha > 0) {
- scale += Math.abs(num);
- } else if (cha < 0) {
- scale > Math.abs(num) ? (scale -= Math.abs(num)) : scale;
- }
- this.scale = scale;
- } else {
- const moveX = e.touches[0].pageX - this.startX
- const moveY = e.touches[0].pageY - this.startY
- this.x = moveX
- this.y = moveY
- }
- },
- imgMoveEnd() {
- setTimeout(() => {
- this.scaling = false
- }, 100)
- },
- touchStart(e) {
- this.startX = e.touches[0].pageX - this.cropOffsertX;
- this.startY = e.touches[0].pageY - this.cropOffsertY;
- this.cropOldW = this.cropW
- this.cropOldH = this.cropH
- },
- cropMoveing(e) {
- const moveX = this._cropX(e.touches[0].pageX - this.startX)
- const moveY = this._cropY(e.touches[0].pageY - this.startY)
- this.cropOffsertX = moveX
- this.cropOffsertY = moveY
- },
- dragMove(e, type) {
- if(this.cropFixed) {
- return false
- }
- const moveX = e.touches[0].pageX - this.startX
- const moveY = e.touches[0].pageY - this.startY
- switch (type) {
- case 'left-top':
- this._cropMoveLeft(moveX)
- this._cropMoveTop(moveY)
- break;
- case 'middle-top':
- this._cropMoveTop(moveY)
- break;
- case 'right-top':
- this._cropMoveTop(moveY)
- this._cropMoveRight(moveX)
- break;
- case 'middle-right':
- this._cropMoveRight(moveX)
- break;
- case 'right-bottom':
- this._cropMoveRight(moveX)
- this._cropMoveBottom(moveY)
- break;
- case 'middle-bottom':
- this._cropMoveBottom(moveY)
- break;
- case 'left-bottom':
- this._cropMoveBottom(moveY)
- this._cropMoveLeft(moveX)
- break;
- case 'middle-left':
- this._cropMoveLeft(moveX)
- break;
- default:
- break;
- }
- },
- _cropMoveTop(y) {
- const topY = this._cropY(y)
- this.cropH += this.cropOffsertY - topY
- this.cropOffsertY = topY
- },
- _cropMoveRight(x) {
- if(this.cropOldW + x >= this.windowWidth - this.border) {
- return false;
- }
- this.cropW = this.cropOldW + (x - this.cropOffsertX)
- },
- _cropMoveBottom(y) {
- if(this.cropOldH + y >= this.windowHeight - this.containerTop - this.border) {
- return false;
- }
- this.cropH = this.cropOldH + (y - this.cropOffsertY)
- },
- _cropMoveLeft(x) {
- const leftX = this._cropY(x)
- this.cropW += this.cropOffsertX - leftX
- this.cropOffsertX = leftX
- },
- _cropX(x) {
- if(x <= this.border) {
- return this.border
- }
- if(x + this.cropW >= this.windowWidth - this.border) {
- return this.windowWidth - this.cropW - this.border
- }
- return x
- },
- _cropY(y) {
- if(y <= this.border) {
- return this.border
- }
- if(y + this.cropH >= this.windowHeight - this.containerTop - this.border) {
- return this.windowHeight - this.cropH - this.containerTop - this.border
- }
- return y
- }
- }
- }
- </script>
- <style scoped lang="css">
- @font-face {
- font-family: "iconfont";
- src: url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAR4AAsAAAAACKgAAAQsAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDBgqEfIRGATYCJAMMCwgABCAFhG0HShugB8gOJUHBwAAAAAFEBNmwzd4dtatSmmpFoVAEhUThEAYkCozFKDCqCVO6RfH/89v869awDnTR1qrSANFt4GG4SNxreBn91fmV9f3+53J613ieHba+N1zmGM8PA7oXTaCAxpjei8IoLWFsGLu4jPME6vWJJdovqmgAO4U2LRBnep0K7GJmpYQWanXVOWuLuAFrtenK4haAa/f38QnKsCOpyrRFh6eFWsh5KXnfYcn958BGQNKfE8wmMmaAQpzkuo9Z+ukZluoltVV5abUipL5i/ysArlhWVut/eCRBVNPUjYg6oUo7JTHFoaYDSvdacnKTq9GAB4AY5y2dtL3qpFh1DENdnJC6Hq+xYb7pyRMDMzc/fYoJjY8flwO3m98rMucF+IZHj6Cagw5UeKpxyFbt2rHGY/8jpa7CYMvLfcIesLjY3bdqhaf+nqgQs2qT/+rjCH/VfA0VFGuAC3iE8NEr/Vau8vZsXiUy7+V3c3tQQXMAuNjDCC89KDIHH0OFhnUi81GEPwyc7wZUaN7DnUf4g+ZLQsMKYV/94NjK7R7TEM4niTY1oJ5zEU62aNVaasUub08YLUEam5EnT6a61/I17dNk+vTu9jpJjXhsTFwjqTtpCBxBIIgS6iQnc/Zod1YGKp0rAwsD8kkyP6AwcK0hcAwkiQmBhWvxPZWKDu86aUH2nLEdi9rGX1eXq5P6A1SrnAucMVMdZH/GKi/jyfCqJyucfK3mXpVujXOPfFf5LC4Dvx0X/943JyOq4HuCTZ8KiIPPAb6ro8akpT6ufiq39BQrNlk5mp8pO0JlJLk8f5QalRjoP60IMx0N8n7wGhSD3n6/F1zlcTVz/cR+Ev0lkLSTd7UiPbD/wCxGRMA2Krwro2O0bTQtImbwhjAJc0S3N4ROx15/PH60IzaIOjCbEelqkDOfETNxb/FMixnWNzeJp2KPQw9A5d76jGUOQOUvH7RE/o2RfkNatd3OGf9q0QKbnq8WB7qy+hVqJRjJn1BQgP/iErks0yy5iGJTrOayW7C/z0IoZH0qNH+7N+31XXc7G2p1hZDU6IWs1ghaqDNQpcEKVKu1BfWmFW9u0IFhKUodpswCEFodgqTZHWStbqOF+hqqdPsG1VrDEuodhfueDcZCj+QzuIrFtZh6BNNraIowbCzi1dbhOlOfionKXHoTzgzoY5hCKk/minEKZ/pYMDCoU7IsgREM3Y8Vgcvwvj4aMzK0AdewUpJljWkyGZH3IKmG7gfEHgZOhYXTwqiNwOhp0CiE3ZiFpL5fB6dj0keFKcGV+JvgGAP0vWMUpOQ10GI1VQt3LoMHDNJRYrEIPInAoPXDFEEnrk9P0zDG/FEGOA2WFNkiaZRGhuoRddXS8bX917cL6mn9c6TIUXSekybKHKQfJXFq2KSiRklLYU8dNKWDIX0cAA==') format('woff2');
- }
- .vue-cropper {
- position: fixed;
- left: 0;
- right: 0;
- bottom: 0;
- z-index: 2000;
- box-sizing: border-box;
- user-select: none;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- direction: ltr;
- touch-action: none;
- text-align: left;
- /* background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC");
- */
- background-color: #000000;
- }
- .cropper-canvas {
- position: absolute;
- top: -9999px;
- left:-9999px;
- z-index: -998;
- }
- .vue-cropper .uni-info__ft {
- position: absolute;
- line-height: 48px;
- font-size: 18px;
- display: -webkit-box;
- display: -webkit-flex;
- background-color: #000000;
- padding-bottom: 34rpx;
- display: flex;
- bottom: 0;
- left: 0;
- right: 0;
- z-index: 2001;
- }
- .btn-group {
- position: absolute;
- right: 30px;
- bottom: 78px;
- z-index: 2001;
- }
- .btn-item {
- position: relative;
- width: 40px;
- height: 40px;
- background: #fff;
- border-radius: 20px;
- padding: 10px;
- display: inline-block;
- margin-left: 10px;
- }
- .btn-item:active {
- background: #ccc;
- }
- .rotate-btn {
- font-family: "iconfont" !important;
- font-size: 24px;
- font-style: normal;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- line-height: 20px;
- }
- .rotate-btn:before {
- content: "\e65c";
- margin-left: -2px;
- }
- .reset-btn {
- font-family: "iconfont" !important;
- font-size: 24px;
- font-style: normal;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- line-height: 20px;
- }
- .reset-btn:before {
- content: "\e648";
- margin-left: -2px;
- }
- .vue-cropper .uni-info__ft:after {
- content: " ";
- position: absolute;
- left: 0;
- top: 0;
- right: 0;
- height: 1px;
- border-top: 1px solid #d5d5d6;
- color: #d5d5d6;
- -webkit-transform-origin: 0 0;
- transform-origin: 0 0;
- -webkit-transform: scaleY(.5);
- transform: scaleY(.5);
- z-index: 2001;
- }
- .vue-cropper .uni-modal__btn {
- display: block;
- -webkit-box-flex: 1;
- -webkit-flex: 1;
- flex: 1;
- font-size:28rpx;
- text-decoration: none;
- -webkit-tap-highlight-color: rgba(0,0,0,0);
- position: relative;
- text-align: center;
- background-color: #000000;
- z-index: 2001;
- }
- /*
- .vue-cropper .uni-modal__btn:first-child:after { display: none }
- .vue-cropper .uni-modal__btn:after {
- content: " ";
- position: absolute;
- left: 0;
- top: 0;
- width: 1px;
- bottom: 0;
- border-left: 1px solid #d5d5d6;
- color: #d5d5d6;
- -webkit-transform-origin: 0 0;
- transform-origin: 0 0;
- -webkit-transform: scaleX(.5);
- transform: scaleX(.5);
- z-index: 998;
- } */
- .vue-cropper .uni-modal__btn:active {
- background-color: #eee;
- }
- .cropper-box,
- .cropper-box-canvas,
- .cropper-drag-box,
- .cropper-crop-box,
- .cropper-face {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- user-select: none;
- z-index: 2001;
- }
- .uni-image {
- width: 100%;
- height: 100%;
- }
- .cropper-box-canvas image {
- position: relative;
- text-align: left;
- user-select: none;
- transform: none;
- max-width: none;
- max-height: none;
- z-index: 2001;
- }
- .cropper-box {
- overflow: hidden;
- }
- .cropper-move {
- cursor: move;
- }
- .cropper-crop {
- cursor: crosshair;
- }
- .cropper-modal {
- background: rgba(0, 0, 0, 0.5);
- }
- .pointer-events {
- pointer-events:none;
- }
- .cropper-crop-box {
- /*border: 2px solid #39f;*/
- }
- .cropper-view-box {
- display: block;
- overflow: hidden;
- width: 100%;
- height: 100%;
- outline: 1px solid #39f;
- outline-color: rgba(51, 153, 255, 0.75);
- user-select: none;
- }
- .cropper-view-box image {
- user-select: none;
- text-align: left;
- max-width: none;
- max-height: none;
- }
- .cropper-face {
- top: 0;
- left: 0;
- background-color: #fff;
- opacity: 0.1;
- }
- .crop-line {
- position: absolute;
- display: block;
- width: 100%;
- height: 100%;
- opacity: 0.1;
- z-index: 2001;
- }
- .line-w {
- top: -3px;
- left: 0;
- height: 5px;
- cursor: n-resize;
- }
- .line-a {
- top: 0;
- left: -3px;
- width: 5px;
- cursor: w-resize;
- }
- .line-s {
- bottom: -3px;
- left: 0;
- height: 5px;
- cursor: s-resize;
- }
- .line-d {
- top: 0;
- right: -3px;
- width: 5px;
- cursor: e-resize;
- }
- .crop-point {
- position: absolute;
- width: 8px;
- height: 8px;
- opacity: 0.75;
- background-color: #39f;
- border-radius: 100%;
- z-index: 2001;
- }
- .point-lt {
- top: -4px;
- left: -4px;
- cursor: nw-resize;
- }
- .point-mt {
- top: -5px;
- left: 50%;
- margin-left: -3px;
- cursor: n-resize;
- }
- .point-rt {
- top: -4px;
- right: -4px;
- cursor: ne-resize;
- }
- .point-ml {
- top: 50%;
- left: -4px;
- margin-top: -3px;
- cursor: w-resize;
- }
- .point-mr {
- top: 50%;
- right: -4px;
- margin-top: -3px;
- cursor: e-resize;
- }
- .point-lb {
- bottom: -5px;
- left: -4px;
- cursor: sw-resize;
- }
- .point-mb {
- bottom: -5px;
- left: 50%;
- margin-left: -3px;
- cursor: s-resize;
- }
- .point-rb {
- bottom: -5px;
- right: -4px;
- cursor: se-resize;
- }
- </style>
|