最近有个需求需要实现图片的水平、垂直翻转功能,开发完之后感觉挺有意思的,就来总结一下
css实现图片翻转功能
- 利用css动画属性rotate旋转来实现:
- 水平翻转:transform: rotateY(180deg); /* 水平镜像翻转 */
- 垂直翻转:transform: rotateX(180deg); /* 垂直镜像翻转 */
这里rotateY(180deg) 表示元素以Y轴镜像翻转,即水平翻转;同理, rotateX(180deg) 表示以X轴为镜像翻转,即垂直翻转。
- 各个浏览器对镜像翻转的兼容写法来实现:
- 水平翻转
-moz-transform:scaleX(-1);
-webkit-transform:scaleX(-1);
-o-transform:scaleX(-1);
transform:scaleX(-1);
/*兼容IE*/
filter:FlipH;
- 垂直翻转
-moz-transform:scaleY(-1);
-webkit-transform:scaleY(-1);
-o-transform:scaleY(-1);
transform:scaleY(-1);
/*兼容IE*/
filter:FlipV;
注:镜像翻转和普通旋转不同,镜像翻转以轴为镜像,普通旋转以点为镜像。
css具体代码实现如下:
// html
<div class="box">
<div>css实现图片水平、垂直翻转功能</div>
<div @click="cssFilpLevel">
<div>水平翻转</div>
<img style="width:500px;height:300px;" src="http://img2.imgtn.bdimg.com/it/u=1814943828,1963988006&fm=26&gp=0.jpg" alt="" id="level">
</div>
<div @click="cssFlipVer">
<div>垂直翻转</div>
<img style="width:500px;height:300px;" src="http://img2.imgtn.bdimg.com/it/u=1814943828,1963988006&fm=26&gp=0.jpg" alt="" id="vertical">
</div>
</div>
// js
let count = 0;
cssFilpLevel(){
let levelId = document.getElementById('level')
// 点击按钮图片可反复进行翻转
if(count === 1){
levelId.style.transform = "rotateY(0deg)";
count = 0;
}else{
levelId.style.transform = "rotateY(180deg)";
count++
}
},
cssFlipVer(){
let verticalId = document.getElementById('vertical')
if(count === 1){
verticalId.style.transform = "rotateX(0deg)";
count = 0;
}else{
verticalId.style.transform = "rotateX(180deg)";
count++
}
}
css实现效果如下
canvas实现图片翻转功能
首先如果要通过canvas实现对图片沿x轴或者y轴进行翻转,那么我们可以通过canvas2d的接口进行实现。
使用到的api如下所示:
- ctx.scale(x, y)方法进行翻转
- ctx.translate(x,y),由于翻转的xy轴使用的是原点,即canvas的左上角的位置的轴,所以,我们还需要用到translate方法,来移动将翻转后的图片移动到canvas的显示区域
- ctx.getContext获取canvas对象
- 沿x轴进行翻转
ctx.scale(-1, 1);
ctx.translate(-canvas.width, 0); - 沿y轴进行翻转
ctx.scale(1, -1);
ctx.translate(0, -canvas.height);
canvas具体代码实现如下:
// html
<div class="box">
<div class="type-title">canvas实现图片水平垂直翻转</div>
<div @click="levelEvent">
<div>水平翻转</div>
<canvas id="levelImg"></canvas>
</div>
<div @click="verticalEvent">
<div>垂直翻转</div>
<canvas id="verticalImg"></canvas>
</div>
</div>
// js
export default {
name: 'rotate',
data(){
return{
levelObj: {},
verticalObj: {}
}
},
mounted(){
this.levelObj = this.canvasDrawImg("levelImg", "http://img2.imgtn.bdimg.com/it/u=1814943828,1963988006&fm=26&gp=0.jpg");
this.verticalObj = this.canvasDrawImg("verticalImg", "http://img2.imgtn.bdimg.com/it/u=1814943828,1963988006&fm=26&gp=0.jpg");
},
methods:{
// canvas上绘制画布
canvasDrawImg (canvasId, imgSrc){
let canvas = document.getElementById(canvasId);
let ctx = canvas.getContext('2d');
// 画布大小宽高500、300px
canvas.width = 500;
canvas.height = 300;
let img = new Image();
img.src = imgSrc;
img.setAttribute("crossOrigin",'Anonymous');
img.onload = function () {
// 默认按比例显示
let w = img.width, h = img.height;
let scale = 1, tt = 500; // 根据具体要求设定
if(w > tt || h > tt){
if(w > h){
scale = tt / w
}else{
scale = tt / h
}
}
canvas.width = w * scale;
canvas.height = h * scale;
ctx.clearRect(0, 0, canvas.width, canvas.height); // 在给定矩形内清空一个矩形
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
}
return{
context: ctx,
canvas: canvas,
imgSrc: imgSrc,
}
},
// 水平、垂直翻转方法封装
commFlip(obj,type){
return new Promise((resolve) => {
let scale = -1;
let img = new Image();
img.setAttribute("crossOrigin",'anonymous')
img.src = obj.imgSrc;
img.onload = function () {
obj.context.clearRect(0, 0, obj.canvas.width, obj.canvas.height);
if(type === 1){ // 水平翻转
// 坐标参考调整
obj.context.translate((obj.canvas.width - img.width * scale) / 2, 0);
obj.context.scale(scale, 1);
}else{ // 垂直翻转
obj.context.translate(0, (obj.canvas.height - img.height * scale) / 2);
obj.context.scale(1, scale);
}
obj.context.drawImage(img, 0, 0, obj.canvas.width, obj.canvas.height);
// 坐标参考还原
obj.context.setTransform(1, 0, 0, 1, 0, 0);
resolve(obj.canvas.toDataURL('image/jpeg', 1));
}
img.src = obj.canvas.toDataURL('image/jpeg', 1);
})
},
async levelEvent(){
let _ = this.levelObj;
let s = await this.commFlip(_, 1); // 获取图片实时base64
},
async verticalEvent(){
let _ = this.verticalObj;
let ss = await this.commFlip(_, 2);
}
}
canvas实现效果如下
基本上就这么多了,总的来说如果不需要翻转之后的图片base64,可以直接使用css来实现,简单方便,如果需要获取图片翻转之后的base64,则可以通过canvas实现,上述两个方法都支持点击图片时循环翻转,有问题欢迎大家随时指出。