trace.img.js
支持拖动、缩放等,看演示,(使用缩放请把代码"operate.show()"取消注释),因方便使用了部分es6语法,需要兼容性的请自行修改
效果演示:
(function(root, factory) {
if(typeof define === 'function' && define.amd) {
define(['jquery']);
} else if(typeof exports === 'object') {
module.exports = factory(require('jquery'));
} else {
root.TraceImg = factory(root.jQuery);
}
}(this, function($) {
let util = {
windowHeight: $(window).height(),
windowWidth: $(window).width(),
bodyHeight: $(document.body).outerHeight(true),
bodyWidth: $(document.body).outerWidth(true)
},
imageCut = (() => {
let files = {},
cutoutimg = (e) => {
let dom = $(e.dom),
w = e.cut.width,
h = e.cut.height,
time = new Date().getTime(),
showW = e.show.width,
showH = e.show.height,
imgZoom = 1,
_img = null,
_img_info = {},
canvasId = null,
showDom = (() => {
dom.after(`<div id='show_${time}'></div>`)
return $(`#show_${time}`)
})(),
operate = (() => {
showDom.after(`<div style='width:${showW}px;display:none;' id='operate_${time}'><a href='javascript:;'><img alt='缩小'/></a><a href='javascript:;'><img alt='放大'/></a></div>`)
return $(`#operate_${time}`)
})(),
nowImg = (() => {
let defaultStyle = {
width: w,
height: h,
position: "relative"
},
parentArea = (() => {
showDom.after(`<div id='nowimg_${time}'><img width='100%;height:100%;'/><canvas style='display:none;' width='${w}' height='${h}'></canvas></div>`)
return $(`#nowimg_${time}`)
})()
return {
parentArea: parentArea,
dom: $(parentArea.children()[0]),
canvasJsDom: parentArea.children()[1],
parentBottomStyle: $.extend({
top: 10,
left: 0
}, defaultStyle),
parentRightStyle: $.extend({
bottom: showH,
left: showW + 10
}, defaultStyle)
}
})(),
showStyle = {
width: showW,
height: showH,
overflow: "hidden",
position: "relative"
},
overstory = null,
overstoryOffetShowDomX = (showW - w)/2,
overstoryOffetShowDomY = (showH - h)/2,
overstoryStyle = {
width: w,
height: h,
position: "absolute",
top: 0,
left: 0,
'border-top': overstoryOffetShowDomY + "px solid #ccc",
'border-bottom': overstoryOffetShowDomY + "px solid #ccc",
'border-left': overstoryOffetShowDomX + "px solid #ccc",
'border-right': overstoryOffetShowDomX + "px solid #ccc",
'border-style': "solid",
opacity: 0.5
},
addOverstory = () => {
showDom.append(`<div id='overstory_${time}'></div>`)
overstory = $(`#overstory_${time}`)
overstory.css(overstoryStyle)
overstory.append(`<div class='hr_${time}'></div><div class='hr_${time}'></div><div class='hr_${time}'></div><div class='hr_${time}'></div><div class='hr_${time}'></div><div class='hr_${time}'></div><div class='hr_${time}'></div><div class='hr_${time}'></div>`)
let hr_dashed = $(`.hr_${time}`),
hr_top = h/3,
hr_left = w/3,
hrStyle = {
position: "absolute"
},
crosswiseStyle = {
width: "100%",
height: 0,
'border-bottom': "1px solid #fff",
'border-style': "none none dashed none",
left: 0
},
verticalStyle = {
width: 0,
height: "100%",
'border-right': "1px solid #fff",
'border-style': "none dashed none none",
top: 0,
}
hr_dashed.css(hrStyle)
$(hr_dashed[0]).css($.extend(crosswiseStyle, {top: 0}))
$(hr_dashed[1]).css($.extend(crosswiseStyle, {top: hr_top}))
$(hr_dashed[2]).css($.extend(crosswiseStyle, {top: hr_top*2}))
$(hr_dashed[3]).css($.extend(crosswiseStyle, {top: h - 1}))
$(hr_dashed[4]).css($.extend(verticalStyle, {left: 0}))
$(hr_dashed[5]).css($.extend(verticalStyle, {left: hr_left}))
$(hr_dashed[6]).css($.extend(verticalStyle, {left: hr_left*2}))
$(hr_dashed[7]).css($.extend(verticalStyle, {left: w - 1}))
bindImgDrag()
},
bindImgDrag = () => {
let deltaX = 0,
deltaY = 0,
ol = overstory.offset().left,
ot = overstory.offset().top,
_img_ol = _img.offset().left,
_img_ot = _img.offset().top,
start = (e) => {
_img_ol = _img.offset().left,
_img_ot = _img.offset().top,
deltaX = e.pageX - _img_ol + ol,
deltaY = e.pageY - _img_ot + ot
overstory.bind({
'mousemove': move,
'mouseup': stop
})
return false
},
_imgDragX = 0,
_imgDragY = 0,
move = (e) => {
_img_info.n_x = e.pageX - deltaX,
_img_info.n_y = e.pageY - deltaY,
_imgDragX = (showW - _img_info.width)*imgZoom,
_imgDragY = (showH - _img_info.height)*imgZoom
if(_img_info.n_x > 0) {
_img_info.n_x = 0
}
if(_img_info.n_x < _imgDragX) {
_img_info.n_x = _imgDragX
}
if(_img_info.n_y > 0) {
_img_info.n_y = 0
}
if(_img_info.n_y < _imgDragY) {
_img_info.n_y = _imgDragY
}
_img.css({
"left": _img_info.n_x,
"top": _img_info.n_y
})
drawImg()
return false
},
stop = () => {
overstory.unbind({
'mousemove': move,
'mouseup': stop
})
}
overstory.bind('mousedown', start)
},
addOriginalDraw = (e) => {
showDom.append(`<canvas style='display:none;' width='${_img_info.width}' height='${_img_info.height}' id='draw_area_${time}'></canvas>`)
canvasId = `draw_area_${time}`
let canvasJsDom = document.getElementById(`draw_area_${time}`),
context = canvasJsDom.getContext('2d')
context.drawImage(e, 0, 0)
},
drawImg = () => {
let canvas = document.getElementById(canvasId),
cot1 = canvas.getContext("2d"),
drawData = cot1.getImageData(_img_info.n_x == undefined ? overstoryOffetShowDomX : -_img_info.n_x + overstoryOffetShowDomX, _img_info.n_y == undefined ? 50 : -_img_info.n_y + overstoryOffetShowDomY, showW - overstoryOffetShowDomX, showH - overstoryOffetShowDomY)
cot2 = nowImg.canvasJsDom.getContext("2d")
cot2.putImageData(drawData, 0, 0, 0, 0, w, h)
files.base64 = nowImg.canvasJsDom.toDataURL()
nowImg.dom.attr("src", files.base64)
},
domChange = () => {
let jsdom = dom[0],
f = jsdom.files[0],
reader = new FileReader(),
img = new Image(),
oparates = operate.children(),
bindOperate = () => {
$(oparates[0]).unbind().click(() => {
imgZoom = imgZoom - 0.1
img.style.zoom = imgZoom
})
$(oparates[1]).unbind().click(() => {
imgZoom = imgZoom + 0.1
img.style.zoom = imgZoom
})
},
imgStyle = {
zoom: 1,
position: "absolute",
top: 0,
left: 0
},
imgSet = (e) => {
showDom.html(e)
_img = $(e)
_img_info.width = _img.width()
_img_info.height = _img.height()
_img.css(imgStyle)
addOriginalDraw(e)
drawImg()
}
(() => {
files.name = f.name
let flag = false,
tsfx = f.name.substring(f.name.lastIndexOf(".")+1)
for(let i in e.suffix) {
if(e.suffix[i] == tsfx) {
flag = true
break
}
}
if(!flag) {
alert("Unsupported file type. " + f.type)
throw new Error("Unsupported file type. " + f.type)
}
})()
reader.onload = function(e) {
img.onload = function() {
imgSet(img)
addOverstory()
bindOperate()
}
img.src = e.target.result
// operate.show()
}
reader.readAsDataURL(f)
showDom.css(showStyle)
},
on = () => {
dom.on("change", domChange)
},
go = () => {
e.cut.place == "bottom" ? nowImg.parentArea.css(nowImg.parentBottomStyle) : nowImg.parentArea.css(nowImg.parentRightStyle)
on()
}
go()
},
get = (t) => {
file.t = t == "png" ? t : "jpg"
let binary = atob(files.base64.split(',')[1]),
arr = []
for(var i = 0; i < binary.length; i++) {
arr.push(binary.charCodeAt(i))
}
files.file = new Blob([new Uint8Array(arr)], {type: t})
return files
},
init = (e) => {
let dp = {
dom: '#imgfile',
suffix: ["jpg", "png", "bmp", "gif", "jpeg"],
cut: {
width: 200,
height: 200,
place: "right"
},
show: {
width: 300,
height: 300
}
}
$.extend(dp, e)
if(dp.cut.width > dp.show.width) {
throw new Error('The "width" in the parameter cannot be greater than the "show.width"')
}
if(dp.cut.height > dp.show.height) {
throw new Error('The "height" in the parameter cannot be greater than the "show.height"')
}
cutoutimg(dp)
}
return {
init: init,
get: get
}
})()
return {
imageCut: imageCut
}
}));
使用说明
let imageCut = TraceImg.imageCut;
步骤1: 初始化
/**
* 支持参数
* {
* dom: "String",//字符串,input框的id或者class,默认为"#imgfile",
* suffix: [],//数组,支持的图片格式,默认为["jpg", "png", "bmp", "gif", "jpeg"]【注意】:添加此属性会覆盖默认的属性,需要自行添加时请务必写全
* cut: {
* width: Number,//需要截取区域的宽,必须小于原始区域宽,默认为200
* height: Number,//需要截取区域的高,必须小于原始区域高,默认为200
* place: "String"//值为"bottom"或者"right",默认为right
* },
* show: {//原始图片显示区域的属性
* width: Number,//区域宽度,默认为300
* height: Number//区域高度,默认为300
* },
* }
*/
imageCut.init({
dom: '#imgfile'
});
步骤2: 获取图片
/**
* 获取file,在上传图片的时候调用
* imgType: "String"//值只支持"png"或者"jpg",默认为"jpg"
* @return {
* file://图片数据
* name://fileName
* 其余属性请用console.log()查看
* }
*/
imageCut.get(imgType)
测试dome: test.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script src="js/jquery.min.js"></script>
<script src="js/trace.img.js"></script>
<title></title>
</head>
<body>
<div>
<input type="file" id="imgfile"/>
</div>
</body>
<script type="text/javascript">
/**
* 支持参数
* {
* dom: "String",//字符串,input框的id或者class,默认为"#imgfile"
* cut: {
* width: Number,//需要截取区域的宽,必须小于原始区域宽,默认为200
* height: Number,//需要截取区域的高,必须小于原始区域高,默认为200
* place: "String"//值为"bottom"或者"right",默认为right
* },
* show: {//原始图片显示区域的属性
* width: Number,//区域宽度,默认为300
* height: Number//区域高度,默认为300
* },
* }
*/
TraceImg.imageCut.init({
dom: '#imgfile',
cut: {
width: 160,
height: 160,
place: "right"
},
show: {
width: 200,
height: 200
}
});
/**
* 获取file
* imgType: "String"//值只支持"png"或者"jpg",默认为"jpg"
* @return {
* file://图片数据
* name://fileName
* }
*/
TraceImg.imageCut.get(imgType)
</script>
</html>