canvas实现图片裁剪,
<head lang="en">
<meta charset="UTF-8">
<title>仿知乎头像裁剪</title>
<link rel="stylesheet" href="imgCut.css" type="text/css" />
<style>
.su_body{
border:1px solid blue;
position:relative;
width:500px;
height:500px;
padding:20px 0;
}
.su_imgCut{
border:1px solid green;
width:300px;
height:300px;
margin: 0 auto 30px;
cursor: move;
position: relative;
}
/*.mark{*/
/*position:absolute;*/
/*height:100px;*/
/*width:100px;*/
/*left:50%;*/
/*top:50%;*/
/*margin:-50px -50px;*/
/*z-index:10;*/
/*border:1px solid #000;*/
/*cursor:move;*/
/*}*/
</style>
</head>
<body>
边界 有bug
<input type="range" step="0.1" min="1" max="2" class="RangeInput" value="1" id="rangIput" oninput="canvasSize()">
<div class="su_body">
<div class="su_imgCut" id = "su_imgCut">
<canvas id="c1" style="width: 300px; height: 300px;"></canvas>
</div>
<input type="file" value="上传文件" >
<div class="su_scale">
<span class="su_scale_left" onClick="scaleAdd(-10, 200, 0)"> - </span>
<!--进度条-->
<div id="su_scale_down">
<!--条-->
<div id="su_scale_top" style="width:10px;">
</div>
<!-- 点-->
<span id="su_scale_dot"></span>
</div>
<span class="su_scale_right" onClick="scaleAdd(+10, 200, 0)"> + </span>
</div>
</div>
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="../imgCut.js"></script>
</body>
</html>
</body>
</html>
body{
padding:50px;
}
#c1, #c3{
padding: 50px;
border: 1px solid red;
}
.su_scale{
display: -webkit-flex; /* Safari */
display: flex;
flex-flow: row nowrap;
align-items: center;
border:1px solid red;
height:50px;
}
.su_scale .su_scale_left,
.su_scale .su_scale_right{
width:40px;
height:40px;
margin: 0 10px;
border-radius:50%;
background-color:#f4f4f4;
font-size:40px;
text-align:center;
line-height:40px;
color:red;
}
.su_scale div{
width:209px;
height: 5px;
background-color:#f4f4f4;
}
.su_scale #su_scale_down{
display: -webkit-flex; /* Safari */
display: flex;
flex-flow: row nowrap;
}
.su_scale #su_scale_top{
background-color:red;
}
.su_scale #su_scale_dot{
width: 10px;
height: 10px;
position: relative;
top: -2.5px;
left: -1px;
display: block;
border-radius:50%;
background-color: red;
cursor:pointer;
}
var urlData;
$('input[type=file]').change(function(){
var file=this.files[0];
var reader=new FileReader();
reader.function(){
// 通过 reader.result 来访问生成的 DataURL
var url=reader.result;
urlData = url;
showImg()
};
reader.readAsDataURL(file);
});
var canvas1 = document.getElementById("c1")//原图
var oMark = document.getElementById("mark")//裁剪框
canvas1.height = 300;
canvas1.width=300;
var imgurl = "";
/**
* 裁剪图片 关键代码
* 避免 canvas.getImageData() 画布污染跨域问题 改为传入Base64
* [showImg description]
* @param {[type]} url_a [description]
* @return {[type]} [description]
*/
//x y 位置, w h 大小
const img_x = 50, img_y =50, img_w = 200, img_h = 200; //裁剪图片位置大小
var x = img_x, y = img_y, w = img_w, h = img_h;//canvas内图片 位置 大小
function showImg(){
var cxt1 = canvas1.getContext("2d")
var img = new Image();
img.src = urlData;
var canvas2 = document.createElement("canvas")
var cxt2=canvas2.getContext("2d")
img.onload = function(){
canvas1.height=canvas1.height;//清空 画布
console.log(" 画图时 x:"+x + " y"+y + " w" + w +" h"+h);
cxt1.drawImage(img,x,y,w, h);
var dataImg = cxt1.getImageData(img_x,img_y,img_w,img_h)
canvas2.width =img_w ;
canvas2.height = img_h;
cxt2.putImageData(dataImg,0,0);
var img2 = canvas2.toDataURL("image/png");
var img3 = new Image();
img3.src = img2;
img3.onload = function(){
//设置模糊边框
cxt1.globalAlpha=0.8;
cxt1.fillStyle="#f4f4f4";
cxt1.fillRect(0,0,canvas1.width,canvas1.height);
cxt1.drawImage(img3,img_x,img_y,img_w,img_h);
console.log(img2)
$("body").append("<img src='"+img2+"'>");
}
}
}
/**
* 剪切 框 移动事件(canvas 大小)
* [windowMove description]
* @return {[type]} [description]
*/
// oMark.function(ev){
// console.log(ev);
// var disX=ev.clientX-oMark.offsetLeft
// var disY=ev.clientY-oMark.offsetTop
//
// console.log("disX:"+disX + " disY:"+disY);
// document.function(ev){
// var l=ev.clientX-disX
// var t=ev.clientY-disY
// console.log("l:"+l + " t:"+t);
// oMark.style.left=l+'px'
// oMark.style.top=t+'px'
//
// cutCanvas();
// }
// document.function(){
// document.null;
// document.null
// }
// }
/**
* 裁剪canvas 事件
*/
function cutCanvas(){
var srcX = oMark.offsetLeft-canvas1.getBoundingClientRect().left;
var srcY = oMark.offsetTop-canvas1.getBoundingClientRect().top;
var sWidth = oMark.offsetWidth;
var sHeight = oMark.offsetHeight;
var canvas2 = document.createElement("canvas")
var cxt2=canvas2.getContext("2d")
canvas2.width = sWidth;
canvas2.height = sHeight;
var cxt1 = canvas1.getContext("2d");
var dataImg = cxt1.getImageData(srcX,srcY,sWidth,sHeight);
cxt2.putImageData(dataImg,0,0,0,0,canvas2.width,canvas2.height)
var img2 = canvas2.toDataURL("image/png");
var cxt3=canvas3.getContext("2d")
var img3 = new Image();
img3.src = img2;
img3.onload = function(){
cxt3.drawImage(img3,0,0,canvas3.width,canvas3.height)
// console.log(canvas3.toDataURL("image/png"))
}
}
/**
* 通过Id 获取标签
* @param id
* @returns {Element}
*/
var getId = function(id){return document.getElementById(id)}
/**
* 进度条 变大变小
* @param w change
* @param max 最大长度
* @param min 最小长度
*/
function scaleAdd(w, max, min ){
let top = getId("su_scale_top");//进度条 条
console.log("width:"+top.style.width+" w:"+w)
let width= parseInt(parseInt(top.style.width) + w );
top.style.width= ( (width <= max && width >= min) ? width : (width < min ? min : (width > max ? max : width) ) ) +'px';
}
/**
* 标签移动
* @param ev 鼠标
* @param e 标签
* @param callback 移动过程中回调函数
*/
function eleMove(ev, e, callback){
let disX=ev.clientX-e.offsetLeft
let disY=ev.clientY-e.offsetTop
console.log("disX:"+disX + " disY:"+disY);
document.function(ev){
let l=ev.clientX-disX
let t=ev.clientY-disY
console.log("l:"+l + " t:"+t);
e.style.left=l+'px'
e.style.top=t+'px'
//判断callback是否为 function
if(callback instanceof Function ){
callback();
}
}
document.function(){
document.null;
document.null
}
}
/**
* 剪切框移动事件
* @param ev
*/
// oMark.onmousedown = function(ev){
// eleMove(ev, oMark, cutCanvas);
// }
getId("su_imgCut").onmousedown = function(ev){
let disX=ev.clientX;
let disY=ev.clientY;
console.log("disX:"+disX + " disY:"+disY);
document.function(ev){
let l=ev.clientX-disX
let t=ev.clientY-disY
console.log("l:"+l + " t:"+t);
console.log("移动前 x:"+x + " y:"+y);
x = x + l ;
y = y + t;
// x = x > (img_x*imgSize) ? (img_x*imgSize) : x;
// y = y > (img_y*imgSize) ? (img_y*imgSize) : y;
//
// x = x < - (img_x*imgSize) ? -(img_x*imgSize) : x;
// y = y < - (img_y*imgSize) ? -(img_y*imgSize) : y;
//向右下 移动时边界
x = x > img_x ? img_x : x;
y = y > img_y ? img_y : y;
//向左上移动事边界
y = y < -( ( h-img_h ) / 2 )? -( ( h-img_h ) / 2 ) : y;
x = x < -( (w-img_w) / 2) ? -( (w-img_w) / 2) : x;
// x = x < img_x ? img_x : x;
// y = y < img_y ? img_y : y;
console.log("移动后 x:"+ x+" y:"+y);
showImg();//图片移动事件
}
document.function(){
document.null;
document.null
}
}
/**
* 点移动事件
* @param ev
*/
getId("su_scale_dot").function(ev){
var e = getId("su_scale_dot");
let disX=ev.clientX-e.offsetLeft
let disY=ev.clientY-e.offsetTop
console.log("disX:"+disX + " disY:"+disY);
document.function(ev){
let c_width=ev.clientX-disX-getId("su_scale_top").offsetLeft;
getId("su_scale_top").style.width= Math.max(0, Math.min( 200,c_width)) +'px';
}
document.function(){
document.null;
document.null
}
}
/**
* canvas 图片 放大缩小
*/
var imgSize ;
function canvasSize(){
var value = document.getElementById('rangIput').value ;
console.log(value)
imgSize = (1- value) ;
let w2 = w, h2 = h;//变化前 图片大小
w = img_w *value;
h = img_h *value;//canvas 位置 大小
console.log("放大前 x:"+ x+" y:"+y);
x = x + ((w2 - w) / 2);
y = y + ((h2 - h) / 2);
//左上缩小放大 后 防止图片越界
x = x > img_x ? img_x :x;
y = y > img_y ? img_y : y;
//右下缩小放大 后 防止图片越界
// y = y < -( ( h-img_h ) / 2 ) + img_y ? -( ( h-img_h ) / 2 ) + img_y : y;
// x = x < -( (w-img_w) / 2) + img_x ? -( (w-img_w) / 2) + img_x : x;
y = y < -( ( h-img_h ) ) + img_y ? -( ( h-img_h ) ) + img_y : y;
x = x < -( (w-img_w)) + img_x ? -( (w-img_w) ) + img_x : x;
console.log("放大后 x:"+ x+" y:"+y);
showImg();
}
待完善