Skip to content

Commit f97d82d

Browse files
authored
Merge pull request dai-siki#63 from yangfan0095/master
vue2 增加图片旋转功能,修复透明图片黑边
2 parents 1c406da + b2c0498 commit f97d82d

File tree

1 file changed

+123
-32
lines changed

1 file changed

+123
-32
lines changed

upload-2.vue

Lines changed: 123 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@
5353
<i @mousedown="startZoomSub" @mouseout="endZoomSub" @mouseup="endZoomSub" class="vicp-icon5"></i>
5454
<i @mousedown="startZoomAdd" @mouseout="endZoomAdd" @mouseup="endZoomAdd" class="vicp-icon6"></i>
5555
</div>
56+
<div class="vicp-range" style="margin-top: -20px;">
57+
<i @mousedown="startRotateLeft" @mouseout="endRotate" @mouseup="endRotate" class="vicp-icon7">↺</i>
58+
<i @mousedown="startRotateRight" @mouseout="endRotate" @mouseup="endRotate" class="vicp-icon8">↻</i>
59+
</div>
5660
</div>
5761
<div class="vicp-crop-right" v-show="true">
5862
<div class="vicp-preview">
@@ -251,7 +255,10 @@ export default {
251255
scale: {
252256
zoomAddOn: false, //按钮缩放事件开启
253257
zoomSubOn: false, //按钮缩放事件开启
258+
rotateLeft: false,//按钮向左旋转事件开启
259+
rotateRight: false,//按钮向右旋转事件开启
254260
range: 1, //最大100
261+
degree: 0, // 旋转度数
255262
x: 0,
256263
y: 0,
257264
width: 0,
@@ -287,7 +294,12 @@ export default {
287294
top,
288295
left,
289296
width: scale.width + 'px',
290-
height: scale.height + 'px'
297+
height: scale.height + 'px',
298+
transform: 'rotate(' + scale.degree + 'deg)',// 旋转时 左侧原始图旋转样式
299+
'-ms-transform': 'rotate(' + scale.degree + 'deg)', // 兼容IE9
300+
'-moz-transform': 'rotate(' + scale.degree + 'deg)', // 兼容FireFox
301+
'-webkit-transform': 'rotate(' + scale.degree + 'deg)',// 兼容Safari 和 chrome
302+
'-o-transform': 'rotate(' + scale.degree + 'deg)',// 兼容 Opera
291303
}
292304
},
293305
// 原图蒙版属性
@@ -573,6 +585,50 @@ export default {
573585
scale.x = rX;
574586
scale.y = rY;
575587
},
588+
// 按钮按下开始向右旋转
589+
startRotateRight(e) {
590+
let that = this,
591+
{
592+
scale
593+
} = that;
594+
scale.rotateLeft = true;
595+
function rotate() {
596+
if (scale.rotateLeft) {
597+
let degree = ++scale.degree;
598+
that.createImg(degree);
599+
setTimeout(function () {
600+
rotate();
601+
}, 60);
602+
}
603+
}
604+
rotate();
605+
},
606+
// 按钮按下开始向右旋转
607+
startRotateLeft(e) {
608+
let that = this,
609+
{
610+
scale
611+
} = that;
612+
scale.rotateLeft = true;
613+
function rotate() {
614+
if (scale.rotateLeft) {
615+
let degree = --scale.degree;
616+
that.createImg(degree);
617+
setTimeout(function () {
618+
rotate();
619+
}, 60);
620+
}
621+
}
622+
rotate();
623+
},
624+
// 停止旋转
625+
endRotate() {
626+
let {
627+
scale
628+
} = this;
629+
scale.rotateLeft = false;
630+
scale.rotateRight = false;
631+
},
576632
// 按钮按下开始放大
577633
startZoomAdd(e) {
578634
let that = this,
@@ -681,32 +737,41 @@ export default {
681737
}
682738
}, 300);
683739
},
684-
// 生成需求图片
685-
createImg(e) {
686-
let that = this,
687-
{
688-
mime,
689-
sourceImg,
690-
scale: {
691-
x,
692-
y,
693-
width,
694-
height
695-
},
696-
sourceImgMasking: {
697-
scale
698-
}
699-
} = that,
700-
canvas = that.$refs.canvas,
701-
ctx = canvas.getContext('2d');
702-
if (e) {
703-
// 取消鼠标按下移动状态
704-
that.sourceImgMouseDown.on = false;
705-
}
706-
ctx.clearRect(0, 0, that.width, that.height);
707-
ctx.drawImage(sourceImg, x / scale, y / scale, width / scale, height / scale);
708-
that.createImgUrl = canvas.toDataURL(mime);
709-
},
740+
// 生成需求图片
741+
createImg(e) {
742+
let that = this,
743+
{
744+
mime,
745+
sourceImg,
746+
scale: {
747+
x,
748+
y,
749+
width,
750+
height,
751+
degree
752+
},
753+
sourceImgMasking: {
754+
scale
755+
}
756+
} = that,
757+
canvas = that.$refs.canvas,
758+
ctx = canvas.getContext('2d');
759+
if (e) {
760+
// 取消鼠标按下移动状态
761+
that.sourceImgMouseDown.on = false;
762+
}
763+
canvas.width = that.height;
764+
canvas.height = that.width;
765+
ctx.clearRect(0, 0, that.width, that.height);
766+
// 将透明区域设置为白色底边
767+
ctx.fillStyle = "#fff";
768+
ctx.fillRect(0, 0, that.width, that.height);
769+
ctx.translate(canvas.width * 0.5, canvas.height * 0.5);
770+
ctx.rotate(Math.PI * degree / 180);
771+
ctx.translate(-canvas.height * 0.5, -canvas.width * 0.5);
772+
ctx.drawImage(sourceImg, x / scale, y / scale, width / scale, height / scale);
773+
that.createImgUrl = canvas.toDataURL(mime);
774+
},
710775
prepareUpload(){
711776
let {
712777
url,
@@ -1012,20 +1077,26 @@ export default {
10121077
width: 240px;
10131078
height: 18px; }
10141079
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon5,
1015-
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon6 {
1080+
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon6,
1081+
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon7,
1082+
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon8
1083+
{
10161084
position: absolute;
10171085
top: 0;
10181086
width: 18px;
10191087
height: 18px;
10201088
border-radius: 100%;
10211089
background-color: rgba(0, 0, 0, 0.08); }
10221090
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon5:hover,
1023-
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon6:hover {
1091+
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon6:hover,
1092+
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon7:hover,
1093+
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon8:hover{
10241094
-webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12);
1025-
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12);
1095+
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12);
10261096
cursor: pointer;
10271097
background-color: rgba(0, 0, 0, 0.14); }
1028-
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon5 {
1098+
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon5,
1099+
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon7 {
10291100
left: 0; }
10301101
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon5::before {
10311102
position: absolute;
@@ -1036,7 +1107,8 @@ export default {
10361107
width: 12px;
10371108
height: 2px;
10381109
background-color: #fff; }
1039-
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon6 {
1110+
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon6,
1111+
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon8 {
10401112
right: 0; }
10411113
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon6::before {
10421114
position: absolute;
@@ -1056,6 +1128,25 @@ export default {
10561128
width: 2px;
10571129
height: 12px;
10581130
background-color: #fff; }
1131+
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon7 {
1132+
transform: rotate(10deg);
1133+
-webkit-transform: rotate(10deg);
1134+
-moz-transform: rotate(-10deg);
1135+
-ms-transform: rotate(-10deg);
1136+
-o-transform: rotate(-10deg);}
1137+
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon8 {
1138+
transform: rotate(10deg);
1139+
-webkit-transform: rotate(10deg);
1140+
-moz-transform: rotate(-10deg);
1141+
-ms-transform: rotate(-10deg);
1142+
-o-transform: rotate(-10deg);
1143+
}
1144+
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon7,
1145+
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon8 {
1146+
color: rgb(255, 255, 255);
1147+
line-height: 20px;
1148+
font-weight: bold;
1149+
}
10591150
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range input[type=range] {
10601151
display: block;
10611152
padding-top: 5px;

0 commit comments

Comments
 (0)