Initial project files: BESCMS full source
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,733 @@
|
||||
/**
|
||||
* jQuery photoClip v1.8.0
|
||||
* 依赖插件
|
||||
* - iscroll-zoom.js
|
||||
* - hammer.js
|
||||
* - lrz.all.bundle.js
|
||||
*
|
||||
* @author 白俊杰 625603381@qq.com 2014/07/31
|
||||
* https://github.com/baijunjie/jQuery-photoClip
|
||||
*
|
||||
* @brief 支持手势的裁图插件
|
||||
* 在移动设备上双指捏合为缩放,双指旋转可根据旋转方向每次旋转90度
|
||||
* 在PC设备上鼠标滚轮为缩放,每次双击则顺时针旋转90度
|
||||
* @option_param {array} size 截取框的宽和高组成的数组。默认值为[260,260]
|
||||
* @option_param {array} outputSize 输出图像的宽和高组成的数组。默认值为[0,0],表示输出图像原始大小
|
||||
* //@option_param {string} outputType 指定输出图片的类型,可选 "jpg" 和 "png" 两种种类型,默认为 "jpg"
|
||||
* @option_param {string} file 上传图片的<input type="file">控件的选择器或者DOM对象
|
||||
* @option_param {string} view 显示截取后图像的容器的选择器或者DOM对象
|
||||
* @option_param {string} ok 确认截图按钮的选择器或者DOM对象
|
||||
* @option_param {function} loadStart 开始加载的回调函数。this指向 fileReader 对象,并将正在加载的 file 对象作为参数传入
|
||||
* @option_param {function} loadComplete 加载完成的回调函数。this指向图片对象,并将图片地址作为参数传入
|
||||
* @option_param {function} loadError 加载失败的回调函数。this指向 fileReader 对象,并将错误事件的 event 对象作为参数传入
|
||||
* @option_param {function} clipFinish 裁剪完成的回调函数。this指向原图片对象,会将裁剪出的图像数据DataURL作为参数传入
|
||||
*/
|
||||
|
||||
(function(root, factory) {
|
||||
"use strict";
|
||||
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define(["jquery", "iscroll-zoom", "hammer", "lrz"], factory);
|
||||
} else if (typeof exports === "object") {
|
||||
module.exports = factory(require("jquery"), require("iscroll-zoom"), require("hammer"), require("lrz"));
|
||||
} else {
|
||||
root.bjj = root.bjj || {};
|
||||
root.bjj.PhotoClip = factory(root.jQuery, root.IScroll, root.Hammer, root.lrz);
|
||||
}
|
||||
|
||||
}(this, function($, IScroll, Hammer, lrz) {
|
||||
"use strict";
|
||||
|
||||
var defaultOption = {
|
||||
size: [260, 260],
|
||||
outputSize: [0, 0],
|
||||
//outputType: "jpg",
|
||||
file: "",
|
||||
view: "",
|
||||
ok: "",
|
||||
loadStart: function() {},
|
||||
loadComplete: function() {},
|
||||
loadError: function() {},
|
||||
clipFinish: function() {}
|
||||
}
|
||||
|
||||
function PhotoClip(container, option) {
|
||||
if (!window.FileReader) {
|
||||
dr_tips(0, "您的浏览器不支持 HTML5 的 FileReader API, 因此无法初始化图片裁剪插件,请更换最新的浏览器!");
|
||||
return;
|
||||
}
|
||||
|
||||
var opt = $.extend({}, defaultOption, option);
|
||||
var returnValue = photoClip(container, opt);
|
||||
|
||||
this.destroy = returnValue.destroy;
|
||||
}
|
||||
|
||||
function photoClip(container, option) {
|
||||
var size = option.size,
|
||||
outputSize = option.outputSize,
|
||||
file = option.file,
|
||||
view = option.view,
|
||||
ok = option.ok,
|
||||
//outputType = option.outputType || "image/jpeg",
|
||||
outputType = "image/jpeg",
|
||||
loadStart = option.loadStart,
|
||||
loadComplete = option.loadComplete,
|
||||
loadError = option.loadError,
|
||||
clipFinish = option.clipFinish;
|
||||
|
||||
if (!isArray(size)) {
|
||||
size = [260, 260];
|
||||
}
|
||||
|
||||
if (!isArray(outputSize)) {
|
||||
outputSize = [0, 0];
|
||||
}
|
||||
|
||||
var clipWidth = size[0] || 260,
|
||||
clipHeight = size[1] || 260,
|
||||
outputWidth = Math.max(outputSize[0], 0),
|
||||
outputHeight = Math.max(outputSize[1], 0);
|
||||
|
||||
/*if (outputType === "jpg") {
|
||||
outputType = "image/jpeg";
|
||||
} else if (outputType === "png") {
|
||||
outputType = "image/png";
|
||||
}*/
|
||||
|
||||
var $file = $(file);
|
||||
if (!$file.length) return;
|
||||
|
||||
var $img,
|
||||
imgWidth, imgHeight, //图片当前的宽高
|
||||
imgLoaded; //图片是否已经加载完成
|
||||
|
||||
$file.attr("accept", "image/*");
|
||||
$file.on("change", function() {
|
||||
if (!this.files.length) return;
|
||||
var files = this.files[0];
|
||||
if (!/image\/\w+/.test(files.type)) {
|
||||
dr_tips(0, "图片格式不正确,请选择正确格式的图片文件!");
|
||||
return false;
|
||||
} else {
|
||||
var fileReader = new FileReader();
|
||||
fileReader.onprogress = function(e) {
|
||||
//console.log((e.loaded / e.total * 100).toFixed() + "%");
|
||||
};
|
||||
|
||||
fileReader.onload = function(e) {
|
||||
//console.log(typeof lrz);
|
||||
|
||||
lrz(files)
|
||||
.then(function (rst) {
|
||||
// 处理成功会执行
|
||||
createImg(rst.base64);
|
||||
})
|
||||
.catch(function (err) {
|
||||
// 处理失败会执行
|
||||
dr_tips(0, "图片处理失败");
|
||||
loadError.call(this, err);
|
||||
});
|
||||
};
|
||||
fileReader.onerror = function(e) {
|
||||
dr_tips(0, "图片加载失败");
|
||||
loadError.call(this, e);
|
||||
};
|
||||
fileReader.readAsDataURL(files); // 读取文件内容
|
||||
|
||||
loadStart.call(fileReader, files);
|
||||
}
|
||||
});
|
||||
|
||||
$file.click(function() {
|
||||
this.value = "";
|
||||
});
|
||||
|
||||
var $container, // 容器,包含裁剪视图层和遮罩层
|
||||
$clipView, // 裁剪视图层,包含移动层
|
||||
$moveLayer, // 移动层,包含旋转层
|
||||
$rotateLayer, // 旋转层
|
||||
$view, // 最终截图后呈现的视图容器
|
||||
canvas, // 图片裁剪用到的画布
|
||||
hammerManager,
|
||||
myScroll, // 图片的scroll对象,包含图片的位置与缩放信息
|
||||
containerWidth,
|
||||
containerHeight;
|
||||
|
||||
init();
|
||||
initScroll();
|
||||
initEvent();
|
||||
initClip();
|
||||
|
||||
var $ok = $(ok);
|
||||
if ($ok.length) {
|
||||
$ok.click(function() {
|
||||
clipImg();
|
||||
});
|
||||
}
|
||||
|
||||
var $win = $(window);
|
||||
resize();
|
||||
$win.resize(resize);
|
||||
|
||||
var atRotation, // 是否正在旋转中
|
||||
curX, // 旋转层的当前X坐标
|
||||
curY, // 旋转层的当前Y坐标
|
||||
curAngle; // 旋转层的当前角度
|
||||
|
||||
function imgLoad() {
|
||||
imgLoaded = true;
|
||||
|
||||
$rotateLayer.append(this);
|
||||
|
||||
hideAction.call(this, $img, function() {
|
||||
imgWidth = this.naturalWidth;
|
||||
imgHeight = this.naturalHeight;
|
||||
});
|
||||
|
||||
hideAction($moveLayer, function() {
|
||||
resetScroll();
|
||||
});
|
||||
|
||||
|
||||
loadComplete.call(this, this.src);
|
||||
}
|
||||
|
||||
function initScroll() {
|
||||
var options = {
|
||||
zoom: true,
|
||||
scrollX: true,
|
||||
scrollY: true,
|
||||
freeScroll: true,
|
||||
mouseWheel: true,
|
||||
wheelAction: "zoom"
|
||||
}
|
||||
myScroll = new IScroll($clipView[0], options);
|
||||
}
|
||||
function resetScroll() {
|
||||
curX = 0;
|
||||
curY = 0;
|
||||
curAngle = 0;
|
||||
|
||||
$rotateLayer.css({
|
||||
"width": imgWidth,
|
||||
"height": imgHeight
|
||||
});
|
||||
setTransform($rotateLayer, curX, curY, curAngle);
|
||||
|
||||
calculateScale(imgWidth, imgHeight);
|
||||
myScroll.zoom(myScroll.options.zoomStart);
|
||||
refreshScroll(imgWidth, imgHeight);
|
||||
|
||||
var posX = (clipWidth - imgWidth * myScroll.options.zoomStart) * .5,
|
||||
posY = (clipHeight - imgHeight * myScroll.options.zoomStart) * .5;
|
||||
myScroll.scrollTo(posX, posY);
|
||||
}
|
||||
function refreshScroll(width, height) {
|
||||
$moveLayer.css({
|
||||
"width": width,
|
||||
"height": height
|
||||
});
|
||||
// 在移动设备上,尤其是Android设备,当为一个元素重置了宽高时
|
||||
// 该元素的offsetWidth/offsetHeight、clientWidth/clientHeight等属性并不会立即更新,导致相关的js程序出现错误
|
||||
// iscroll 在刷新方法中正是使用了 offsetWidth/offsetHeight 来获取scroller元素($moveLayer)的宽高
|
||||
// 因此需要手动将元素重新添加进文档,迫使浏览器强制更新元素的宽高
|
||||
$clipView.append($moveLayer);
|
||||
myScroll.refresh();
|
||||
}
|
||||
|
||||
function initEvent() {
|
||||
var is_mobile = !!navigator.userAgent.match(/mobile/i);
|
||||
|
||||
if (is_mobile) {
|
||||
hammerManager = new Hammer($moveLayer[0]);
|
||||
hammerManager.add(new Hammer.Rotate());
|
||||
|
||||
var rotation, rotateDirection;
|
||||
hammerManager.on("rotatemove", function(e) {
|
||||
if (atRotation) return;
|
||||
rotation = e.rotation;
|
||||
if (rotation > 180) {
|
||||
rotation -= 360;
|
||||
} else if (rotation < -180) {
|
||||
rotation += 360 ;
|
||||
}
|
||||
rotateDirection = rotation > 0 ? 1 : rotation < 0 ? -1 : 0;
|
||||
});
|
||||
hammerManager.on("rotateend", function(e) {
|
||||
if (atRotation) return;
|
||||
|
||||
if (Math.abs(rotation) > 30) {
|
||||
if (rotateDirection == 1) {
|
||||
// 顺时针
|
||||
rotateCW(e.center);
|
||||
} else if (rotateDirection == -1) {
|
||||
// 逆时针
|
||||
rotateCCW(e.center);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$moveLayer.on("dblclick", function(e) {
|
||||
rotateCW({
|
||||
x: e.clientX,
|
||||
y: e.clientY
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
function rotateCW(point) {
|
||||
rotateBy(90, point);
|
||||
}
|
||||
function rotateCCW(point) {
|
||||
rotateBy(-90, point);
|
||||
}
|
||||
function rotateBy(angle, point) {
|
||||
if (atRotation) return;
|
||||
atRotation = true;
|
||||
|
||||
var loacl;
|
||||
if (!point) {
|
||||
loacl = loaclToLoacl($moveLayer, $clipView, clipWidth * .5, clipHeight * .5);
|
||||
} else {
|
||||
loacl = globalToLoacl($moveLayer, point.x, point.y);
|
||||
}
|
||||
var origin = calculateOrigin(curAngle, loacl), // 旋转中使用的参考点坐标
|
||||
originX = origin.x,
|
||||
originY = origin.y,
|
||||
|
||||
// 旋转层以零位为参考点旋转到新角度后的位置,与以当前计算的参考点“从零度”旋转到新角度后的位置,之间的左上角偏移量
|
||||
offsetX = 0, offsetY = 0,
|
||||
// 移动层当前的位置(即旋转层旋转前的位置),与旋转层以当前计算的参考点从当前角度旋转到新角度后的位置,之间的左上角偏移量
|
||||
parentOffsetX = 0, parentOffsetY = 0,
|
||||
|
||||
newAngle = curAngle + angle,
|
||||
|
||||
curImgWidth, // 移动层的当前宽度
|
||||
curImgHeight; // 移动层的当前高度
|
||||
|
||||
|
||||
if (newAngle == 90 || newAngle == -270)
|
||||
{
|
||||
offsetX = originX + originY;
|
||||
offsetY = originY - originX;
|
||||
|
||||
if (newAngle > curAngle) {
|
||||
parentOffsetX = imgHeight - originX - originY;
|
||||
parentOffsetY = originX - originY;
|
||||
} else if (newAngle < curAngle) {
|
||||
parentOffsetX = (imgHeight - originY) - (imgWidth - originX);
|
||||
parentOffsetY = originX + originY - imgHeight;
|
||||
}
|
||||
|
||||
curImgWidth = imgHeight;
|
||||
curImgHeight = imgWidth;
|
||||
}
|
||||
else if (newAngle == 180 || newAngle == -180)
|
||||
{
|
||||
offsetX = originX * 2;
|
||||
offsetY = originY * 2;
|
||||
|
||||
if (newAngle > curAngle) {
|
||||
parentOffsetX = (imgWidth - originX) - (imgHeight - originY);
|
||||
parentOffsetY = imgHeight - (originX + originY);
|
||||
} else if (newAngle < curAngle) {
|
||||
parentOffsetX = imgWidth - (originX + originY);
|
||||
parentOffsetY = (imgHeight - originY) - (imgWidth - originX);
|
||||
}
|
||||
|
||||
curImgWidth = imgWidth;
|
||||
curImgHeight = imgHeight;
|
||||
}
|
||||
else if (newAngle == 270 || newAngle == -90)
|
||||
{
|
||||
offsetX = originX - originY;
|
||||
offsetY = originX + originY;
|
||||
|
||||
if (newAngle > curAngle) {
|
||||
parentOffsetX = originX + originY - imgWidth;
|
||||
parentOffsetY = (imgWidth - originX) - (imgHeight - originY);
|
||||
} else if (newAngle < curAngle) {
|
||||
parentOffsetX = originY - originX;
|
||||
parentOffsetY = imgWidth - originX - originY;
|
||||
}
|
||||
|
||||
curImgWidth = imgHeight;
|
||||
curImgHeight = imgWidth;
|
||||
}
|
||||
else if (newAngle == 0 || newAngle == 360 || newAngle == -360)
|
||||
{
|
||||
offsetX = 0;
|
||||
offsetY = 0;
|
||||
|
||||
if (newAngle > curAngle) {
|
||||
parentOffsetX = originX - originY;
|
||||
parentOffsetY = originX + originY - imgWidth;
|
||||
} else if (newAngle < curAngle) {
|
||||
parentOffsetX = originX + originY - imgHeight;
|
||||
parentOffsetY = originY - originX;
|
||||
}
|
||||
|
||||
curImgWidth = imgWidth;
|
||||
curImgHeight = imgHeight;
|
||||
}
|
||||
|
||||
// 将触摸点设为旋转时的参考点
|
||||
// 改变参考点的同时,要计算坐标的偏移,从而保证图片位置不发生变化
|
||||
if (curAngle == 0) {
|
||||
curX = 0;
|
||||
curY = 0;
|
||||
} else if (curAngle == 90 || curAngle == -270) {
|
||||
curX -= originX + originY;
|
||||
curY -= originY - originX;
|
||||
} else if (curAngle == 180 || curAngle == -180) {
|
||||
curX -= originX * 2;
|
||||
curY -= originY * 2;
|
||||
} else if (curAngle == 270 || curAngle == -90) {
|
||||
curX -= originX - originY;
|
||||
curY -= originX + originY;
|
||||
}
|
||||
curX = curX.toFixed(2) - 0;
|
||||
curY = curY.toFixed(2) - 0;
|
||||
setTransform($rotateLayer, curX, curY, curAngle, originX, originY);
|
||||
|
||||
// 开始旋转
|
||||
setTransition($rotateLayer, curX, curY, newAngle, 200, function() {
|
||||
atRotation = false;
|
||||
curAngle = newAngle % 360;
|
||||
// 旋转完成后将参考点设回零位
|
||||
// 同时加上偏移,保证图片位置看上去没有变化
|
||||
// 这里要另外要加上父容器(移动层)零位与自身之间的偏移量
|
||||
curX += offsetX + parentOffsetX;
|
||||
curY += offsetY + parentOffsetY;
|
||||
curX = curX.toFixed(2) - 0;
|
||||
curY = curY.toFixed(2) - 0;
|
||||
setTransform($rotateLayer, curX, curY, curAngle);
|
||||
// 相应的父容器(移动层)要减去与旋转层之间的偏移量
|
||||
// 这样看上去就好像图片没有移动
|
||||
myScroll.scrollTo(
|
||||
myScroll.x - parentOffsetX * myScroll.scale,
|
||||
myScroll.y - parentOffsetY * myScroll.scale
|
||||
);
|
||||
calculateScale(curImgWidth, curImgHeight);
|
||||
if (myScroll.scale < myScroll.options.zoomMin) {
|
||||
myScroll.zoom(myScroll.options.zoomMin);
|
||||
}
|
||||
|
||||
refreshScroll(curImgWidth, curImgHeight);
|
||||
});
|
||||
}
|
||||
|
||||
function initClip() {
|
||||
canvas = document.createElement("canvas");
|
||||
}
|
||||
function clipImg() {
|
||||
if (!imgLoaded) {
|
||||
dr_tips(0, "当前没有图片可以裁剪!");
|
||||
return;
|
||||
}
|
||||
var local = loaclToLoacl($moveLayer, $clipView);
|
||||
var scale = myScroll.scale;
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.save();
|
||||
|
||||
if (!outputWidth || !outputHeight) {
|
||||
canvas.width = clipWidth / scale;
|
||||
canvas.height = clipHeight / scale;
|
||||
} else {
|
||||
canvas.width = outputWidth;
|
||||
canvas.height = outputHeight;
|
||||
ctx.scale(outputWidth / clipWidth * scale, outputHeight / clipHeight * scale);
|
||||
}
|
||||
|
||||
ctx.translate(curX - local.x / scale, curY - local.y / scale);
|
||||
ctx.rotate(curAngle * Math.PI / 180);
|
||||
|
||||
ctx.drawImage($img[0], 0, 0);
|
||||
ctx.restore();
|
||||
|
||||
var dataURL = canvas.toDataURL(outputType, 1);
|
||||
$view.css("background-image", "url("+ dataURL +")");
|
||||
clipFinish.call($img[0], dataURL);
|
||||
}
|
||||
|
||||
|
||||
function resize() {
|
||||
hideAction($container, function() {
|
||||
containerWidth = $container.width();
|
||||
containerHeight = $container.height();
|
||||
});
|
||||
}
|
||||
function loaclToLoacl($layerOne, $layerTwo, x, y) { // 计算$layerTwo上的x、y坐标在$layerOne上的坐标
|
||||
x = x || 0;
|
||||
y = y || 0;
|
||||
var layerOneOffset, layerTwoOffset;
|
||||
hideAction($layerOne, function() {
|
||||
layerOneOffset = $layerOne.offset();
|
||||
});
|
||||
hideAction($layerTwo, function() {
|
||||
layerTwoOffset = $layerTwo.offset();
|
||||
});
|
||||
return {
|
||||
x: layerTwoOffset.left - layerOneOffset.left + x,
|
||||
y: layerTwoOffset.top - layerOneOffset.top + y
|
||||
};
|
||||
}
|
||||
function globalToLoacl($layer, x, y) { // 计算相对于窗口的x、y坐标在$layer上的坐标
|
||||
x = x || 0;
|
||||
y = y || 0;
|
||||
var layerOffset;
|
||||
hideAction($layer, function() {
|
||||
layerOffset = $layer.offset();
|
||||
});
|
||||
return {
|
||||
x: x + $win.scrollLeft() - layerOffset.left,
|
||||
y: y + $win.scrollTop() - layerOffset.top
|
||||
};
|
||||
}
|
||||
function hideAction(jq, func) {
|
||||
var $hide = $();
|
||||
$.each(jq, function(i, n){
|
||||
var $n = $(n);
|
||||
var $hidden = $n.parents().addBack().filter(":hidden");
|
||||
var $none;
|
||||
for (var i = 0; i < $hidden.length; i++) {
|
||||
if (!$n.is(":hidden")) break;
|
||||
$none = $hidden.eq(i);
|
||||
if ($none.css("display") == "none") $hide = $hide.add($none.show());
|
||||
}
|
||||
});
|
||||
if (typeof(func) == "function") func.call(this);
|
||||
$hide.hide();
|
||||
}
|
||||
function calculateOrigin(curAngle, point) {
|
||||
var scale = myScroll.scale;
|
||||
var origin = {};
|
||||
if (curAngle == 0) {
|
||||
origin.x = point.x / scale;
|
||||
origin.y = point.y / scale;
|
||||
} else if (curAngle == 90 || curAngle == -270) {
|
||||
origin.x = point.y / scale;
|
||||
origin.y = imgHeight - point.x / scale;
|
||||
} else if (curAngle == 180 || curAngle == -180) {
|
||||
origin.x = imgWidth - point.x / scale;
|
||||
origin.y = imgHeight - point.y / scale;
|
||||
} else if (curAngle == 270 || curAngle == -90) {
|
||||
origin.x = imgWidth - point.y / scale;
|
||||
origin.y = point.x / scale;
|
||||
}
|
||||
return origin;
|
||||
}
|
||||
function getScale(w1, h1, w2, h2) {
|
||||
var sx = w1 / w2;
|
||||
var sy = h1 / h2;
|
||||
return sx > sy ? sx : sy;
|
||||
}
|
||||
function calculateScale(width, height) {
|
||||
myScroll.options.zoomMin = getScale(clipWidth, clipHeight, width, height);
|
||||
myScroll.options.zoomMax = Math.max(1, myScroll.options.zoomMin);
|
||||
myScroll.options.zoomStart = Math.min(myScroll.options.zoomMax, getScale(containerWidth, containerHeight, width, height));
|
||||
}
|
||||
|
||||
function clearImg() {
|
||||
if ($img && $img.length) {
|
||||
// 删除旧的图片以释放内存,防止IOS设备的webview崩溃
|
||||
$img.remove();
|
||||
delete $img[0];
|
||||
}
|
||||
}
|
||||
|
||||
function createImg(src) {
|
||||
clearImg();
|
||||
$img = $("<img>").css({
|
||||
"user-select": "none",
|
||||
"pointer-events": "none"
|
||||
});
|
||||
$img.on('load', imgLoad);
|
||||
$img.attr("src", src); // 设置图片base64值
|
||||
}
|
||||
|
||||
function setTransform($obj, x, y, angle, originX, originY) {
|
||||
originX = originX || 0;
|
||||
originY = originY || 0;
|
||||
var style = {};
|
||||
style[prefix + "transform"] = "translateZ(0) translate(" + x + "px," + y + "px) rotate(" + angle + "deg)";
|
||||
style[prefix + "transform-origin"] = originX + "px " + originY + "px";
|
||||
$obj.css(style);
|
||||
}
|
||||
function setTransition($obj, x, y, angle, dur, fn) {
|
||||
// 这里需要先读取之前设置好的transform样式,强制浏览器将该样式值渲染到元素
|
||||
// 否则浏览器可能出于性能考虑,将暂缓样式渲染,等到之后所有样式设置完成后再统一渲染
|
||||
// 这样就会导致之前设置的位移也被应用到动画中
|
||||
$obj.css(prefix + "transform");
|
||||
$obj.css(prefix + "transition", prefix + "transform " + dur + "ms");
|
||||
$obj.one(transitionEnd, function() {
|
||||
$obj.css(prefix + "transition", "");
|
||||
fn.call(this);
|
||||
});
|
||||
$obj.css(prefix + "transform", "translateZ(0) translate(" + x + "px," + y + "px) rotate(" + angle + "deg)");
|
||||
}
|
||||
|
||||
// 判断一个对象是否为数组
|
||||
function isArray(obj) {
|
||||
return Object.prototype.toString.call(obj) === "[object Array]";
|
||||
}
|
||||
|
||||
function init() {
|
||||
// 初始化容器
|
||||
$container = $(container).css({
|
||||
"user-select": "none",
|
||||
"overflow": "hidden"
|
||||
});
|
||||
if ($container.css("position") == "static") $container.css("position", "relative");
|
||||
|
||||
// 创建裁剪视图层
|
||||
$clipView = $("<div class='photo-clip-view'>").css({
|
||||
"position": "absolute",
|
||||
"left": "50%",
|
||||
"top": "50%",
|
||||
"width": clipWidth,
|
||||
"height": clipHeight,
|
||||
"margin-left": -clipWidth/2,
|
||||
"margin-top": -clipHeight/2
|
||||
}).appendTo($container);
|
||||
|
||||
$moveLayer = $("<div class='photo-clip-moveLayer'>").appendTo($clipView);
|
||||
|
||||
$rotateLayer = $("<div class='photo-clip-rotateLayer'>").appendTo($moveLayer);
|
||||
|
||||
// 创建遮罩
|
||||
var $mask = $("<div class='photo-clip-mask'>").css({
|
||||
"position": "absolute",
|
||||
"left": 0,
|
||||
"top": 0,
|
||||
"width": "100%",
|
||||
"height": "100%",
|
||||
"pointer-events": "none"
|
||||
}).appendTo($container);
|
||||
var $mask_left = $("<div class='photo-clip-mask-left'>").css({
|
||||
"position": "absolute",
|
||||
"left": 0,
|
||||
"right": "50%",
|
||||
"top": "50%",
|
||||
"bottom": "50%",
|
||||
"width": "auto",
|
||||
"height": clipHeight,
|
||||
"margin-right": clipWidth/2,
|
||||
"margin-top": -clipHeight/2,
|
||||
"margin-bottom": -clipHeight/2,
|
||||
"background-color": "rgba(0,0,0,.5)"
|
||||
}).appendTo($mask);
|
||||
var $mask_right = $("<div class='photo-clip-mask-right'>").css({
|
||||
"position": "absolute",
|
||||
"left": "50%",
|
||||
"right": 0,
|
||||
"top": "50%",
|
||||
"bottom": "50%",
|
||||
"margin-left": clipWidth/2,
|
||||
"margin-top": -clipHeight/2,
|
||||
"margin-bottom": -clipHeight/2,
|
||||
"background-color": "rgba(0,0,0,.5)"
|
||||
}).appendTo($mask);
|
||||
var $mask_top = $("<div class='photo-clip-mask-top'>").css({
|
||||
"position": "absolute",
|
||||
"left": 0,
|
||||
"right": 0,
|
||||
"top": 0,
|
||||
"bottom": "50%",
|
||||
"margin-bottom": clipHeight/2,
|
||||
"background-color": "rgba(0,0,0,.5)"
|
||||
}).appendTo($mask);
|
||||
var $mask_bottom = $("<div class='photo-clip-mask-bottom'>").css({
|
||||
"position": "absolute",
|
||||
"left": 0,
|
||||
"right": 0,
|
||||
"top": "50%",
|
||||
"bottom": 0,
|
||||
"margin-top": clipHeight/2,
|
||||
"background-color": "rgba(0,0,0,.5)"
|
||||
}).appendTo($mask);
|
||||
// 创建截取区域
|
||||
var $clip_area = $("<div class='photo-clip-area'>").css({
|
||||
"border": "1px dashed #ddd",
|
||||
"position": "absolute",
|
||||
"left": "50%",
|
||||
"top": "50%",
|
||||
"width": clipWidth,
|
||||
"height": clipHeight,
|
||||
"margin-left": -clipWidth/2 - 1,
|
||||
"margin-top": -clipHeight/2 - 1
|
||||
}).appendTo($mask);
|
||||
|
||||
// 初始化视图容器
|
||||
$view = $(view);
|
||||
if ($view.length) {
|
||||
$view.css({
|
||||
"background-color": "#666",
|
||||
"background-repeat": "no-repeat",
|
||||
"background-position": "center",
|
||||
"background-size": "contain"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function destroy() {
|
||||
$file.off("change");
|
||||
$file = null;
|
||||
|
||||
if (hammerManager) {
|
||||
hammerManager.off("rotatemove");
|
||||
hammerManager.off("rotateend");
|
||||
hammerManager = null;
|
||||
} else {
|
||||
$moveLayer.off("dblclick");
|
||||
}
|
||||
|
||||
myScroll.destroy();
|
||||
myScroll = null;
|
||||
|
||||
$container.empty();
|
||||
$container = null;
|
||||
$clipView = null;
|
||||
$moveLayer = null;
|
||||
$rotateLayer = null;
|
||||
|
||||
$view.css({
|
||||
"background-color": "",
|
||||
"background-repeat": "",
|
||||
"background-position": "",
|
||||
"background-size": ""
|
||||
});
|
||||
$view = null;
|
||||
}
|
||||
|
||||
return {
|
||||
destroy: destroy
|
||||
};
|
||||
}
|
||||
|
||||
var prefix = '',
|
||||
transitionEnd;
|
||||
|
||||
(function() {
|
||||
|
||||
var eventPrefix,
|
||||
vendors = { Webkit: 'webkit', Moz: '', O: 'o' },
|
||||
testEl = document.documentElement,
|
||||
normalizeEvent = function(name) { return eventPrefix ? eventPrefix + name : name.toLowerCase() };
|
||||
|
||||
for (var i in vendors) {
|
||||
if (testEl.style[i + 'TransitionProperty'] !== undefined) {
|
||||
prefix = '-' + i.toLowerCase() + '-';
|
||||
eventPrefix = vendors[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
transitionEnd = normalizeEvent('TransitionEnd');
|
||||
|
||||
})();
|
||||
|
||||
return PhotoClip;
|
||||
}));
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user