1
0
mirror of https://gitlab.com/JKANetwork/CheckServer.git synced 2026-03-11 13:02:01 +01:00

Start again

This commit is contained in:
2020-10-04 17:14:00 +02:00
parent c0d3912413
commit 091f119048
4382 changed files with 1762543 additions and 9606 deletions

65
vendors/cropper/.bower.json vendored Normal file
View File

@@ -0,0 +1,65 @@
{
"name": "cropper",
"description": "A simple jQuery image cropping plugin.",
"main": [
"dist/cropper.js",
"dist/cropper.css"
],
"keywords": [
"image",
"crop",
"cropper",
"cropping",
"move",
"zoom",
"rotate",
"scale",
"jquery",
"plugin",
"html",
"css",
"javascript",
"front-end",
"web",
"development"
],
"homepage": "https://github.com/fengyuanchen/cropper",
"authors": [
"Fengyuan Chen"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"tests",
"test",
"examples",
"assets",
"demo",
"docs",
"gulpfile.js",
"CONTRIBUTING.md",
"FAQ.md"
],
"dependencies": {
"jquery": ">= 1.9.1"
},
"devDependencies": {
"bootstrap": "~3.3.6",
"fontawesome": "~4.6.1",
"html5-boilerplate": "~5.3.0",
"jquery": "~1.12.3",
"qunit": "~1.22.0"
},
"version": "2.3.1",
"_release": "2.3.1",
"_resolution": {
"type": "version",
"tag": "v2.3.1",
"commit": "91547592292e2f296e40bbab4881e41013b80d27"
},
"_source": "https://github.com/fengyuanchen/cropper.git",
"_target": "^2.3.0",
"_originalSource": "cropper"
}

455
vendors/cropper/CHANGELOG.md vendored Normal file
View File

@@ -0,0 +1,455 @@
# Changelog
## 2.3.1 (May 28, 2016)
- Improved the rotate and scale transform behaviour (#633, idea by afeibus).
- Improved the `getCroppedCanvas` method to return the whole canvas if it is not cropped (#666, PR by @vinnymac).
- Check cross origin setting when load image by XMLHTTPRequest (#669)
## 2.3.0 (Feb 22, 2016)
- Added a new parameter to the `replace` method for applying filters.
- Improved the image initializing for Safari (#120, #509).
- Fixed incorrect size limitation of the crop box.
- Fixed incorrect cropped canvas when scaleX or scaleY great than 1 (#598).
## 2.2.5 (Jan 18, 2016)
- Fixed crossOriginUrl undefined error when exists the `crossOrigin` property.
## 2.2.4 (Jan 1, 2016)
- Fixed a dimension bug in the "getCroppedCanvas" method.
- Added an example for cropping round image.
## 2.2.3 (Dec 28, 2015)
- Supports to zoom from event triggering point.
## 2.2.2 (Dec 24, 2015)
- Limit wheel speed to prevent zoom too fast
- Improve the `setCropBoxData` method
## 2.2.1 (Dec 12, 2015)
- Handle Data URL (Fixed #540: avoid to use XMLHttpRequest to open a Data URL)
- Handle ajax error when load ArrayBuffer
- Not to transform the image to base64 when Orientation equals to `1`
## 2.2.0 (Dec 6, 2015)
- Added a new option: `checkOrientation` (#120, #509)
- Added a timestamp to the url of preview image (#531)
## 2.1.0 (Dec 2, 2015)
- Added new `restore` option
## 2.0.2 (Nov 30, 2015)
- Fixed #476: Floor the numerical parameters for `CanvasRenderingContext2D.drawImage`
## 2.0.1 (Nov 18, 2015)
- Improved new crop box creating
## 2.0.0 (Nov 11, 2015)
### Common
- Supports four modes
- Supports three drag modes
- Improved the experience of cropping
- Makes the crop box's borders and handlers visible when overflow
- Fixed an issue of canvas limitation
- Fixed an issue of cropping
### Options
- Added `viewMode`
- Added `dragMode`
- Renamed `touchDragZoom` to `zoomOnTouch`
- Renamed `mouseWheelZoom` to `zoomOnWheel`
- Renamed `doubleClickToggle` to `toggleDragModeOnDblclick`
- Renamed `checkImageOrigin` to `checkCrossOrigin`
- Removed `strict` (supported by `viewMode: 1`)
- Removed `dragCrop` (supported by `dragMode: 'crop'`)
### Methods
- Added `moveTo`
- Added `zoomTo`
- Added `rotateTo`
- Added `scaleX`
- Added `scaleY`
- Improved `getCanvasData` (added `naturalWidth` and `naturalHeight`)
### Events
- Improved `zoom` (changed `event.ratio` and added `event.oldRatio`)
## 1.0.0 (Oct 10, 2015)
- Improved canvas limitation
- Improved preview
- Improved test
- Fixed an error in the `clear` method (missed parameters)
- Fixed the issue of crop box limitation (#430)
## 1.0.0-rc.1 (Sep 5, 2015)
- Moved from Less to Sass
- Fixed the issue of `destroy` method (#434)
- Fixed the issue on IE8 (#319)
- Added an example for customizing preview
- Added download button to documentation
- Added FAQ
## 0.11.1 (Aug 22, 2015)
- Optimize "built" and "crop" events
- Improve the starting speed (#422)
- Improve the building process (#428)
- Fix event issue on IE8 (#319)
## 0.11.0 (Aug 10, 2015)
- Improve `setCropBoxData` method (#385)
- Fix event issue on IE10 (#394)
- Optimize code (use `var` for per variable)
### Options
- Add "scalable" option
- Add "wheelZoomRatio" option
- Convert "crop" option to "crop" event
### Methods
- Add "scale" method
- Improve "move" method (the `offsetY` parameter is optional now)
### Events
- Rename "dragstart" to "cropstart"
- Rename "dragmove" to "cropmove"
- Rename "dragend" to "cropend"
- Merge "zoomin" and "zoomout" to "zoom"
- Merge "crop" option and "change" event to "crop" event
## 0.10.1 (Jul 5, 2015)
- Add Pointer Events support (#328)
- Add RTL support (#342)
- Add one new option: "center" (#367)
- Allow cropper to grow vertically (#350)
## 0.10.0 (Jun 8, 2015)
- Add three new options: "change", "cropBoxMovable", "doubleClickToggle"
- Change "movable" option (only for image)
- Rename "resizable" to "cropBoxResizable"
- Add one new event: "change.cropper"
- Locking aspect ratio in "free mode" by holding shift key (#259)
- Sync drag mode to crop box when it is not movable (#300)
## 0.9.3 (May 10, 2015)
- Add one new option: "data"
- Add two new methods: "setData" (#290, #296), "crop" (#275)
- Fix incorrect minWidth/Height size of canvas (#295)
- Fix the strict mode bug (#280)
- Fix the crop box resizing bug (#277)
## 0.9.2 (Apr 18, 2015)
- Improve strict mode to show full image
- Add two new options: "minCanvasWidth" and "minCanvasHeight"
- Reverse mouse wheeling zoom
- Fix incorrect cursor in disabled state
## 0.9.1 (Mar 21, 2015)
- Fix the touch zoom issue (#206)
- Fix the reset issue (#246)
## 0.9.0 (Mar 15, 2015)
- Wraps image with a virtual canvas (for zooming and rotating).
- Limits image position and size in strict mode.
- Supports multiple global croppers by default.
- Outputs cropped canvas for display or get Data URL or get Blob
- Identifies drag events with "event.dragType" property
- Added zoom events for controlling the canvas (image) size.
- Improved responsiveness for window resizing.
### Options:
- Change "minContainerWidth" (default value: 300 -> 200)
- Change "minContainerHeight" (default value: 150 -> 100)
- Add "strict"
- Add "zoomin"
- Add "zoomout"
- remove "global"
### Methods:
- Change "replace" (not to change the original image any more)
- Change "getImageData" (move rotation-related properties to canvas data)
- Add "getContainerData"
- Add "getCanvasData"
- Add "setCanvasData"
- Add "getCroppedCanvas"
- Remove "setImageData" (replace with "getCanvasData")
- Remove "getDataURL" (replace with "getCroppedCanvas")
### Events:
- Add "event.dragType" property to drag events
- Add "zoomin.cropper"
- Add "zoomout.cropper"
## 0.8.0 (Feb 19, 2015)
- Refactored source code.
- Compiles CSS with [Less](http://lesscss.org) CSS preprocessors.
- Supports fixed container.
- Supports rotation with CSS3 2D Transforms.
### Options:
- Change the default value of "aspectRatio"
- Rename "done" to "crop"
- Rename "dashed" to "guides"
- Rename "multiple" to "global"
- Add "background"
- Add "highlight"
- Add "responsive"
- Add "mouseWheelZoom"
- Add "touchDragZoom"
- Add "minCropBoxWidth"
- Add "minCropBoxHeight"
- Add "minContainerWidth"
- Add "minContainerHeight"
- Remove "data"
- Remove "minWidth"
- Remove "minHeight"
- Remove "maxWidth"
- Remove "maxHeight"
### Methods:
- Change "reset"
- Add "setImageData"
- Add "getCropBoxData"
- Add "setCropBoxData"
- Add "move"
- Remove "setData"
## 0.7.9 (Feb 19, 2015)
- Improve preview.
- Improve rotation.
- Improve responsiveness (#157).
- Enable to move the image when the size of the crop box is the same as the container's (#186).
## 0.7.8 (Feb 8, 2015)
- Add two new options: "minContainerWidth" and "minContainerHeight".
- Improve three methods: "setAspectRatio", "destroy" and "disable".
- Improve mouse wheel zoom.
- Improve drag resizing.
## 0.7.7 (Jan 10, 2015)
- Fix a bug of "dragCrop" option.
- Add a timestamp to the url to bust cache when it's a cross-origin image (#148).
- Fix the issue of "autoCropArea" option (#144).
## 0.7.6 (Dec 20, 2014)
- Fix events binding bugs.
- Change the "done" option and the "getData" method (returns floating-point number) (#130).
- Fix the rotation issue after replace the image (#139).
## 0.7.5 (Nov 27, 2014)
- Reset the ratio when replace the image.
- Add a new option: "checkImageOrigin" (#119).
- Prevent to call the "done" option when it's disabled (#107).
- Improve the preview (#95).
## 0.7.4 (Nov 24, 2014)
- Improve "getDataURL" method, enable to customize the image sizes (#105).
- Fix the issue of destory (#101).
- Fix the issue of canvas (#106).
## 0.7.3 (Nov 15, 2014)
- Supports cross-origin image (#96, #97).
- Add a new option: "autoCropArea".
- Improve "movable" option.
- Output rotation degree by "getImageData" method (#94).
## 0.7.2 (Nov 11, 2014)
- Fix the image rotation error in Firefox (#92).
## 0.7.1 (Nov 8, 2014)
- Rebuild "rotate" method (#88).
- Fix the issue of free ratio (#87).
- Improve "getDataURL" method (#86).
- Optimize event listeners.
## 0.7.0 (Oct 12, 2014)
- Supports zoom (#36, #79).
- Supports rotation (#1, #81).
- Add two new options: "zoomable" and "rotatable".
- Add six new methods: "enable", "disable", "zoom", "rotate", "getDataURL" (#80) and "setDragMode".
- Rename "release" method to "clear".
- Rename "setImgSrc" method to "replace".
- Rename "getImgInfo" method to "getImageData".
- Some other improvements.
## 0.6.2 (Oct 11, 2014)
- Hide the modal when release the crop box.
- Improve touch events.
## 0.6.1 (Oct 3, 2014)
- Fix an event error.
## 0.6.0 (Sep 20, 2014)
- Add six new options: "dashed", "build", "built", "dragstart", "dragmove" and "dragend".
- Add three new events: "dragstart.cropper", "dragmove.cropper" and "dragend.cropper".
- Remove an old event: "render.cropper".
- Supports to toggle the dashed lines by "dashed" option (#68).
- Fix the issue of events (#71).
- Optimize the source code.
## 0.5.5 (Sep 8, 2014)
- Improve the render when the mouse out of the cropper container (#54).
## 0.5.4 (Aug 30, 2014)
- Fix typos: replace "resizeable" with "resizable" and "moveable" with "movable".
## 0.5.3 (Aug 23, 2014)
- Fix the issue (#64) that the crop box could not move after multiple touches.
## 0.5.2 (Aug 16, 2014)
- Fix a bug of type checking in the options.
- Compress the cropper template string.
## 0.5.1 (Aug 12, 2014)
- Supports canvas (#55).
## 0.5.0 (Aug 10, 2014)
- Add a new option: "multiple".
...
## 0.4.0 (Jul 26, 2014)
- Add eight new options: "autoCrop", "dragCrop", "moveable", "resizeable", "maxWidth", "maxHeight", "minWidth" and "minHeight".
- Add three new methods: "reset", "release" and "destroy".
- Add three new events: "build.cropper", "built.cropper" and "render.cropper".
- Remove two old methods: "enable" and "disable".
- Remove three old events: "dragstart", "dragmove" and "dragend".
- Supports no conflict with the "$.fn.cropper.noConflict" method.
...
## 0.3.0 (May 18, 2014)
- Supports touch.
- Supports events.
- Add three events: "dargstart", "dargmove" and "dargend".
- Add a new method: "setImgSrc".
...
## 0.2.0 (Apr 23, 2014)
- Supports free ratio.
- Add a new option: "data".
- Add four new methods: "getData", "setData", "getImgInfo" and "setAspectRatio".
...
## 0.1.0 (Feb 19, 2014)
- Supports four options: "aspectRatio", "done", "modal" and "preview".
- Supports two methods: "enable" and "disable".

21
vendors/cropper/LICENSE vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014-2016 Fengyuan Chen and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

1085
vendors/cropper/README.md vendored Normal file

File diff suppressed because it is too large Load Diff

55
vendors/cropper/bower.json vendored Normal file
View File

@@ -0,0 +1,55 @@
{
"name": "cropper",
"description": "A simple jQuery image cropping plugin.",
"main": [
"dist/cropper.js",
"dist/cropper.css"
],
"keywords": [
"image",
"crop",
"cropper",
"cropping",
"move",
"zoom",
"rotate",
"scale",
"jquery",
"plugin",
"html",
"css",
"javascript",
"front-end",
"web",
"development"
],
"homepage": "https://github.com/fengyuanchen/cropper",
"authors": [
"Fengyuan Chen"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"tests",
"test",
"examples",
"assets",
"demo",
"docs",
"gulpfile.js",
"CONTRIBUTING.md",
"FAQ.md"
],
"dependencies": {
"jquery": ">= 1.9.1"
},
"devDependencies": {
"bootstrap": "~3.3.6",
"fontawesome": "~4.6.1",
"html5-boilerplate": "~5.3.0",
"jquery": "~1.12.3",
"qunit": "~1.22.0"
}
}

379
vendors/cropper/dist/cropper.css vendored Normal file
View File

@@ -0,0 +1,379 @@
/*!
* Cropper v2.3.1
* https://github.com/fengyuanchen/cropper
*
* Copyright (c) 2014-2016 Fengyuan Chen and contributors
* Released under the MIT license
*
* Date: 2016-05-28T14:47:08.528Z
*/
.cropper-container {
font-size: 0;
line-height: 0;
position: relative;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
direction: ltr !important;
-ms-touch-action: none;
touch-action: none;
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
}
.cropper-container img {
display: block;
width: 100%;
min-width: 0 !important;
max-width: none !important;
height: 100%;
min-height: 0 !important;
max-height: none !important;
image-orientation: 0deg !important;
}
.cropper-wrap-box,
.cropper-canvas,
.cropper-drag-box,
.cropper-crop-box,
.cropper-modal {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.cropper-wrap-box {
overflow: hidden;
}
.cropper-drag-box {
opacity: 0;
background-color: #fff;
filter: alpha(opacity=0);
}
.cropper-modal {
opacity: .5;
background-color: #000;
filter: alpha(opacity=50);
}
.cropper-view-box {
display: block;
overflow: hidden;
width: 100%;
height: 100%;
outline: 1px solid #39f;
outline-color: rgba(51, 153, 255, .75);
}
.cropper-dashed {
position: absolute;
display: block;
opacity: .5;
border: 0 dashed #eee;
filter: alpha(opacity=50);
}
.cropper-dashed.dashed-h {
top: 33.33333%;
left: 0;
width: 100%;
height: 33.33333%;
border-top-width: 1px;
border-bottom-width: 1px;
}
.cropper-dashed.dashed-v {
top: 0;
left: 33.33333%;
width: 33.33333%;
height: 100%;
border-right-width: 1px;
border-left-width: 1px;
}
.cropper-center {
position: absolute;
top: 50%;
left: 50%;
display: block;
width: 0;
height: 0;
opacity: .75;
filter: alpha(opacity=75);
}
.cropper-center:before,
.cropper-center:after {
position: absolute;
display: block;
content: ' ';
background-color: #eee;
}
.cropper-center:before {
top: 0;
left: -3px;
width: 7px;
height: 1px;
}
.cropper-center:after {
top: -3px;
left: 0;
width: 1px;
height: 7px;
}
.cropper-face,
.cropper-line,
.cropper-point {
position: absolute;
display: block;
width: 100%;
height: 100%;
opacity: .1;
filter: alpha(opacity=10);
}
.cropper-face {
top: 0;
left: 0;
background-color: #fff;
}
.cropper-line {
background-color: #39f;
}
.cropper-line.line-e {
top: 0;
right: -3px;
width: 5px;
cursor: e-resize;
}
.cropper-line.line-n {
top: -3px;
left: 0;
height: 5px;
cursor: n-resize;
}
.cropper-line.line-w {
top: 0;
left: -3px;
width: 5px;
cursor: w-resize;
}
.cropper-line.line-s {
bottom: -3px;
left: 0;
height: 5px;
cursor: s-resize;
}
.cropper-point {
width: 5px;
height: 5px;
opacity: .75;
background-color: #39f;
filter: alpha(opacity=75);
}
.cropper-point.point-e {
top: 50%;
right: -3px;
margin-top: -3px;
cursor: e-resize;
}
.cropper-point.point-n {
top: -3px;
left: 50%;
margin-left: -3px;
cursor: n-resize;
}
.cropper-point.point-w {
top: 50%;
left: -3px;
margin-top: -3px;
cursor: w-resize;
}
.cropper-point.point-s {
bottom: -3px;
left: 50%;
margin-left: -3px;
cursor: s-resize;
}
.cropper-point.point-ne {
top: -3px;
right: -3px;
cursor: ne-resize;
}
.cropper-point.point-nw {
top: -3px;
left: -3px;
cursor: nw-resize;
}
.cropper-point.point-sw {
bottom: -3px;
left: -3px;
cursor: sw-resize;
}
.cropper-point.point-se {
right: -3px;
bottom: -3px;
width: 20px;
height: 20px;
cursor: se-resize;
opacity: 1;
filter: alpha(opacity=100);
}
.cropper-point.point-se:before {
position: absolute;
right: -50%;
bottom: -50%;
display: block;
width: 200%;
height: 200%;
content: ' ';
opacity: 0;
background-color: #39f;
filter: alpha(opacity=0);
}
@media (min-width: 768px) {
.cropper-point.point-se {
width: 15px;
height: 15px;
}
}
@media (min-width: 992px) {
.cropper-point.point-se {
width: 10px;
height: 10px;
}
}
@media (min-width: 1200px) {
.cropper-point.point-se {
width: 5px;
height: 5px;
opacity: .75;
filter: alpha(opacity=75);
}
}
.cropper-invisible {
opacity: 0;
filter: alpha(opacity=0);
}
.cropper-bg {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC');
}
.cropper-hide {
position: absolute;
display: block;
width: 0;
height: 0;
}
.cropper-hidden {
display: none !important;
}
.cropper-move {
cursor: move;
}
.cropper-crop {
cursor: crosshair;
}
.cropper-disabled .cropper-drag-box,
.cropper-disabled .cropper-face,
.cropper-disabled .cropper-line,
.cropper-disabled .cropper-point {
cursor: not-allowed;
}

3002
vendors/cropper/dist/cropper.js vendored Normal file

File diff suppressed because it is too large Load Diff

9
vendors/cropper/dist/cropper.min.css vendored Normal file
View File

@@ -0,0 +1,9 @@
/*!
* Cropper v2.3.1
* https://github.com/fengyuanchen/cropper
*
* Copyright (c) 2014-2016 Fengyuan Chen and contributors
* Released under the MIT license
*
* Date: 2016-05-28T14:47:08.528Z
*/.cropper-container{font-size:0;line-height:0;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;direction:ltr!important;-ms-touch-action:none;touch-action:none;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none}.cropper-container img{display:block;width:100%;min-width:0!important;max-width:none!important;height:100%;min-height:0!important;max-height:none!important;image-orientation:0deg!important}.cropper-canvas,.cropper-crop-box,.cropper-drag-box,.cropper-modal,.cropper-wrap-box{position:absolute;top:0;right:0;bottom:0;left:0}.cropper-wrap-box{overflow:hidden}.cropper-drag-box{opacity:0;background-color:#fff;filter:alpha(opacity=0)}.cropper-dashed,.cropper-modal{opacity:.5;filter:alpha(opacity=50)}.cropper-modal{background-color:#000}.cropper-view-box{display:block;overflow:hidden;width:100%;height:100%;outline:#39f solid 1px;outline-color:rgba(51,153,255,.75)}.cropper-dashed{position:absolute;display:block;border:0 dashed #eee}.cropper-dashed.dashed-h{top:33.33333%;left:0;width:100%;height:33.33333%;border-top-width:1px;border-bottom-width:1px}.cropper-dashed.dashed-v{top:0;left:33.33333%;width:33.33333%;height:100%;border-right-width:1px;border-left-width:1px}.cropper-center{position:absolute;top:50%;left:50%;display:block;width:0;height:0;opacity:.75;filter:alpha(opacity=75)}.cropper-center:after,.cropper-center:before{position:absolute;display:block;content:' ';background-color:#eee}.cropper-center:before{top:0;left:-3px;width:7px;height:1px}.cropper-center:after{top:-3px;left:0;width:1px;height:7px}.cropper-face,.cropper-line,.cropper-point{position:absolute;display:block;width:100%;height:100%;opacity:.1;filter:alpha(opacity=10)}.cropper-face{top:0;left:0;background-color:#fff}.cropper-line,.cropper-point{background-color:#39f}.cropper-line.line-e{top:0;right:-3px;width:5px;cursor:e-resize}.cropper-line.line-n{top:-3px;left:0;height:5px;cursor:n-resize}.cropper-line.line-w{top:0;left:-3px;width:5px;cursor:w-resize}.cropper-line.line-s{bottom:-3px;left:0;height:5px;cursor:s-resize}.cropper-point{width:5px;height:5px;opacity:.75;filter:alpha(opacity=75)}.cropper-point.point-e{top:50%;right:-3px;margin-top:-3px;cursor:e-resize}.cropper-point.point-n{top:-3px;left:50%;margin-left:-3px;cursor:n-resize}.cropper-point.point-w{top:50%;left:-3px;margin-top:-3px;cursor:w-resize}.cropper-point.point-s{bottom:-3px;left:50%;margin-left:-3px;cursor:s-resize}.cropper-point.point-ne{top:-3px;right:-3px;cursor:ne-resize}.cropper-point.point-nw{top:-3px;left:-3px;cursor:nw-resize}.cropper-point.point-sw{bottom:-3px;left:-3px;cursor:sw-resize}.cropper-point.point-se{right:-3px;bottom:-3px;width:20px;height:20px;cursor:se-resize;opacity:1;filter:alpha(opacity=100)}.cropper-point.point-se:before{position:absolute;right:-50%;bottom:-50%;display:block;width:200%;height:200%;content:' ';opacity:0;background-color:#39f;filter:alpha(opacity=0)}@media (min-width:768px){.cropper-point.point-se{width:15px;height:15px}}@media (min-width:992px){.cropper-point.point-se{width:10px;height:10px}}@media (min-width:1200px){.cropper-point.point-se{width:5px;height:5px;opacity:.75;filter:alpha(opacity=75)}}.cropper-invisible{opacity:0;filter:alpha(opacity=0)}.cropper-bg{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC)}.cropper-hide{position:absolute;display:block;width:0;height:0}.cropper-hidden{display:none!important}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed}

10
vendors/cropper/dist/cropper.min.js vendored Normal file

File diff suppressed because one or more lines are too long

53
vendors/cropper/package.json vendored Normal file
View File

@@ -0,0 +1,53 @@
{
"name": "cropper",
"description": "A simple jQuery image cropping plugin.",
"version": "2.3.1",
"main": "dist/cropper.js",
"license": "MIT",
"repository": "fengyuanchen/cropper",
"homepage": "https://fengyuanchen.github.io/cropper",
"author": {
"name": "Fengyuan Chen",
"url": "http://chenfengyuan.com"
},
"keywords": [
"image",
"crop",
"cropper",
"cropping",
"move",
"zoom",
"rotate",
"scale",
"jquery",
"plugin",
"jqueryplugin",
"html",
"css",
"javascript",
"front-end",
"web",
"development"
],
"dependencies": {
"jquery": ">= 1.9.1"
},
"devDependencies": {
"gulp": "^3.9.1",
"gulp-autoprefixer": "^3.1.0",
"gulp-concat": "^2.6.0",
"gulp-csscomb": "^3.0.6",
"gulp-csslint": "^0.3.0",
"gulp-htmlcomb": "^0.1.0",
"gulp-jscs": "^3.0.2",
"gulp-jshint": "^1.12.0",
"gulp-load-plugins": "^1.2.0",
"gulp-minify-css": "^1.2.4",
"gulp-qunit": "^1.3.0",
"gulp-rename": "^1.2.2",
"gulp-replace": "^0.5.4",
"gulp-sass": "^2.1.1",
"gulp-sourcemaps": "^1.6.0",
"gulp-uglify": "^1.5.3"
}
}

BIN
vendors/cropper/src/img/bg.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 B

87
vendors/cropper/src/js/bind.js vendored Normal file
View File

@@ -0,0 +1,87 @@
bind: function () {
var options = this.options;
var $this = this.$element;
var $cropper = this.$cropper;
if ($.isFunction(options.cropstart)) {
$this.on(EVENT_CROP_START, options.cropstart);
}
if ($.isFunction(options.cropmove)) {
$this.on(EVENT_CROP_MOVE, options.cropmove);
}
if ($.isFunction(options.cropend)) {
$this.on(EVENT_CROP_END, options.cropend);
}
if ($.isFunction(options.crop)) {
$this.on(EVENT_CROP, options.crop);
}
if ($.isFunction(options.zoom)) {
$this.on(EVENT_ZOOM, options.zoom);
}
$cropper.on(EVENT_MOUSE_DOWN, $.proxy(this.cropStart, this));
if (options.zoomable && options.zoomOnWheel) {
$cropper.on(EVENT_WHEEL, $.proxy(this.wheel, this));
}
if (options.toggleDragModeOnDblclick) {
$cropper.on(EVENT_DBLCLICK, $.proxy(this.dblclick, this));
}
$document.
on(EVENT_MOUSE_MOVE, (this._cropMove = proxy(this.cropMove, this))).
on(EVENT_MOUSE_UP, (this._cropEnd = proxy(this.cropEnd, this)));
if (options.responsive) {
$window.on(EVENT_RESIZE, (this._resize = proxy(this.resize, this)));
}
},
unbind: function () {
var options = this.options;
var $this = this.$element;
var $cropper = this.$cropper;
if ($.isFunction(options.cropstart)) {
$this.off(EVENT_CROP_START, options.cropstart);
}
if ($.isFunction(options.cropmove)) {
$this.off(EVENT_CROP_MOVE, options.cropmove);
}
if ($.isFunction(options.cropend)) {
$this.off(EVENT_CROP_END, options.cropend);
}
if ($.isFunction(options.crop)) {
$this.off(EVENT_CROP, options.crop);
}
if ($.isFunction(options.zoom)) {
$this.off(EVENT_ZOOM, options.zoom);
}
$cropper.off(EVENT_MOUSE_DOWN, this.cropStart);
if (options.zoomable && options.zoomOnWheel) {
$cropper.off(EVENT_WHEEL, this.wheel);
}
if (options.toggleDragModeOnDblclick) {
$cropper.off(EVENT_DBLCLICK, this.dblclick);
}
$document.
off(EVENT_MOUSE_MOVE, this._cropMove).
off(EVENT_MOUSE_UP, this._cropEnd);
if (options.responsive) {
$window.off(EVENT_RESIZE, this._resize);
}
},

118
vendors/cropper/src/js/build.js vendored Normal file
View File

@@ -0,0 +1,118 @@
build: function () {
var options = this.options;
var $this = this.$element;
var $clone = this.$clone;
var $cropper;
var $cropBox;
var $face;
if (!this.isLoaded) {
return;
}
// Unbuild first when replace
if (this.isBuilt) {
this.unbuild();
}
// Create cropper elements
this.$container = $this.parent();
this.$cropper = $cropper = $(Cropper.TEMPLATE);
this.$canvas = $cropper.find('.cropper-canvas').append($clone);
this.$dragBox = $cropper.find('.cropper-drag-box');
this.$cropBox = $cropBox = $cropper.find('.cropper-crop-box');
this.$viewBox = $cropper.find('.cropper-view-box');
this.$face = $face = $cropBox.find('.cropper-face');
// Hide the original image
$this.addClass(CLASS_HIDDEN).after($cropper);
// Show the clone image if is hidden
if (!this.isImg) {
$clone.removeClass(CLASS_HIDE);
}
this.initPreview();
this.bind();
options.aspectRatio = max(0, options.aspectRatio) || NaN;
options.viewMode = max(0, min(3, round(options.viewMode))) || 0;
if (options.autoCrop) {
this.isCropped = true;
if (options.modal) {
this.$dragBox.addClass(CLASS_MODAL);
}
} else {
$cropBox.addClass(CLASS_HIDDEN);
}
if (!options.guides) {
$cropBox.find('.cropper-dashed').addClass(CLASS_HIDDEN);
}
if (!options.center) {
$cropBox.find('.cropper-center').addClass(CLASS_HIDDEN);
}
if (options.cropBoxMovable) {
$face.addClass(CLASS_MOVE).data(DATA_ACTION, ACTION_ALL);
}
if (!options.highlight) {
$face.addClass(CLASS_INVISIBLE);
}
if (options.background) {
$cropper.addClass(CLASS_BG);
}
if (!options.cropBoxResizable) {
$cropBox.find('.cropper-line, .cropper-point').addClass(CLASS_HIDDEN);
}
this.setDragMode(options.dragMode);
this.render();
this.isBuilt = true;
this.setData(options.data);
$this.one(EVENT_BUILT, options.built);
// Trigger the built event asynchronously to keep `data('cropper')` is defined
setTimeout($.proxy(function () {
this.trigger(EVENT_BUILT);
this.isCompleted = true;
}, this), 0);
},
unbuild: function () {
if (!this.isBuilt) {
return;
}
this.isBuilt = false;
this.isCompleted = false;
this.initialImage = null;
// Clear `initialCanvas` is necessary when replace
this.initialCanvas = null;
this.initialCropBox = null;
this.container = null;
this.canvas = null;
// Clear `cropBox` is necessary when replace
this.cropBox = null;
this.unbind();
this.resetPreview();
this.$preview = null;
this.$viewBox = null;
this.$cropBox = null;
this.$dragBox = null;
this.$canvas = null;
this.$container = null;
this.$cropper.remove();
this.$cropper = null;
},

402
vendors/cropper/src/js/change.js vendored Normal file
View File

@@ -0,0 +1,402 @@
change: function (shiftKey, event) {
var options = this.options;
var aspectRatio = options.aspectRatio;
var action = this.action;
var container = this.container;
var canvas = this.canvas;
var cropBox = this.cropBox;
var width = cropBox.width;
var height = cropBox.height;
var left = cropBox.left;
var top = cropBox.top;
var right = left + width;
var bottom = top + height;
var minLeft = 0;
var minTop = 0;
var maxWidth = container.width;
var maxHeight = container.height;
var renderable = true;
var offset;
var range;
// Locking aspect ratio in "free mode" by holding shift key (#259)
if (!aspectRatio && shiftKey) {
aspectRatio = width && height ? width / height : 1;
}
if (this.limited) {
minLeft = cropBox.minLeft;
minTop = cropBox.minTop;
maxWidth = minLeft + min(container.width, canvas.left + canvas.width);
maxHeight = minTop + min(container.height, canvas.top + canvas.height);
}
range = {
x: this.endX - this.startX,
y: this.endY - this.startY
};
if (aspectRatio) {
range.X = range.y * aspectRatio;
range.Y = range.x / aspectRatio;
}
switch (action) {
// Move crop box
case ACTION_ALL:
left += range.x;
top += range.y;
break;
// Resize crop box
case ACTION_EAST:
if (range.x >= 0 && (right >= maxWidth || aspectRatio &&
(top <= minTop || bottom >= maxHeight))) {
renderable = false;
break;
}
width += range.x;
if (aspectRatio) {
height = width / aspectRatio;
top -= range.Y / 2;
}
if (width < 0) {
action = ACTION_WEST;
width = 0;
}
break;
case ACTION_NORTH:
if (range.y <= 0 && (top <= minTop || aspectRatio &&
(left <= minLeft || right >= maxWidth))) {
renderable = false;
break;
}
height -= range.y;
top += range.y;
if (aspectRatio) {
width = height * aspectRatio;
left += range.X / 2;
}
if (height < 0) {
action = ACTION_SOUTH;
height = 0;
}
break;
case ACTION_WEST:
if (range.x <= 0 && (left <= minLeft || aspectRatio &&
(top <= minTop || bottom >= maxHeight))) {
renderable = false;
break;
}
width -= range.x;
left += range.x;
if (aspectRatio) {
height = width / aspectRatio;
top += range.Y / 2;
}
if (width < 0) {
action = ACTION_EAST;
width = 0;
}
break;
case ACTION_SOUTH:
if (range.y >= 0 && (bottom >= maxHeight || aspectRatio &&
(left <= minLeft || right >= maxWidth))) {
renderable = false;
break;
}
height += range.y;
if (aspectRatio) {
width = height * aspectRatio;
left -= range.X / 2;
}
if (height < 0) {
action = ACTION_NORTH;
height = 0;
}
break;
case ACTION_NORTH_EAST:
if (aspectRatio) {
if (range.y <= 0 && (top <= minTop || right >= maxWidth)) {
renderable = false;
break;
}
height -= range.y;
top += range.y;
width = height * aspectRatio;
} else {
if (range.x >= 0) {
if (right < maxWidth) {
width += range.x;
} else if (range.y <= 0 && top <= minTop) {
renderable = false;
}
} else {
width += range.x;
}
if (range.y <= 0) {
if (top > minTop) {
height -= range.y;
top += range.y;
}
} else {
height -= range.y;
top += range.y;
}
}
if (width < 0 && height < 0) {
action = ACTION_SOUTH_WEST;
height = 0;
width = 0;
} else if (width < 0) {
action = ACTION_NORTH_WEST;
width = 0;
} else if (height < 0) {
action = ACTION_SOUTH_EAST;
height = 0;
}
break;
case ACTION_NORTH_WEST:
if (aspectRatio) {
if (range.y <= 0 && (top <= minTop || left <= minLeft)) {
renderable = false;
break;
}
height -= range.y;
top += range.y;
width = height * aspectRatio;
left += range.X;
} else {
if (range.x <= 0) {
if (left > minLeft) {
width -= range.x;
left += range.x;
} else if (range.y <= 0 && top <= minTop) {
renderable = false;
}
} else {
width -= range.x;
left += range.x;
}
if (range.y <= 0) {
if (top > minTop) {
height -= range.y;
top += range.y;
}
} else {
height -= range.y;
top += range.y;
}
}
if (width < 0 && height < 0) {
action = ACTION_SOUTH_EAST;
height = 0;
width = 0;
} else if (width < 0) {
action = ACTION_NORTH_EAST;
width = 0;
} else if (height < 0) {
action = ACTION_SOUTH_WEST;
height = 0;
}
break;
case ACTION_SOUTH_WEST:
if (aspectRatio) {
if (range.x <= 0 && (left <= minLeft || bottom >= maxHeight)) {
renderable = false;
break;
}
width -= range.x;
left += range.x;
height = width / aspectRatio;
} else {
if (range.x <= 0) {
if (left > minLeft) {
width -= range.x;
left += range.x;
} else if (range.y >= 0 && bottom >= maxHeight) {
renderable = false;
}
} else {
width -= range.x;
left += range.x;
}
if (range.y >= 0) {
if (bottom < maxHeight) {
height += range.y;
}
} else {
height += range.y;
}
}
if (width < 0 && height < 0) {
action = ACTION_NORTH_EAST;
height = 0;
width = 0;
} else if (width < 0) {
action = ACTION_SOUTH_EAST;
width = 0;
} else if (height < 0) {
action = ACTION_NORTH_WEST;
height = 0;
}
break;
case ACTION_SOUTH_EAST:
if (aspectRatio) {
if (range.x >= 0 && (right >= maxWidth || bottom >= maxHeight)) {
renderable = false;
break;
}
width += range.x;
height = width / aspectRatio;
} else {
if (range.x >= 0) {
if (right < maxWidth) {
width += range.x;
} else if (range.y >= 0 && bottom >= maxHeight) {
renderable = false;
}
} else {
width += range.x;
}
if (range.y >= 0) {
if (bottom < maxHeight) {
height += range.y;
}
} else {
height += range.y;
}
}
if (width < 0 && height < 0) {
action = ACTION_NORTH_WEST;
height = 0;
width = 0;
} else if (width < 0) {
action = ACTION_SOUTH_WEST;
width = 0;
} else if (height < 0) {
action = ACTION_NORTH_EAST;
height = 0;
}
break;
// Move canvas
case ACTION_MOVE:
this.move(range.x, range.y);
renderable = false;
break;
// Zoom canvas
case ACTION_ZOOM:
this.zoom((function (x1, y1, x2, y2) {
var z1 = sqrt(x1 * x1 + y1 * y1);
var z2 = sqrt(x2 * x2 + y2 * y2);
return (z2 - z1) / z1;
})(
abs(this.startX - this.startX2),
abs(this.startY - this.startY2),
abs(this.endX - this.endX2),
abs(this.endY - this.endY2)
), event);
this.startX2 = this.endX2;
this.startY2 = this.endY2;
renderable = false;
break;
// Create crop box
case ACTION_CROP:
if (!range.x || !range.y) {
renderable = false;
break;
}
offset = this.$cropper.offset();
left = this.startX - offset.left;
top = this.startY - offset.top;
width = cropBox.minWidth;
height = cropBox.minHeight;
if (range.x > 0) {
action = range.y > 0 ? ACTION_SOUTH_EAST : ACTION_NORTH_EAST;
} else if (range.x < 0) {
left -= width;
action = range.y > 0 ? ACTION_SOUTH_WEST : ACTION_NORTH_WEST;
}
if (range.y < 0) {
top -= height;
}
// Show the crop box if is hidden
if (!this.isCropped) {
this.$cropBox.removeClass(CLASS_HIDDEN);
this.isCropped = true;
if (this.limited) {
this.limitCropBox(true, true);
}
}
break;
// No default
}
if (renderable) {
cropBox.width = width;
cropBox.height = height;
cropBox.left = left;
cropBox.top = top;
this.action = action;
this.renderCropBox();
}
// Override
this.startX = this.endX;
this.startY = this.endY;
},

18
vendors/cropper/src/js/cropper.js vendored Normal file
View File

@@ -0,0 +1,18 @@
function Cropper(element, options) {
this.$element = $(element);
this.options = $.extend({}, Cropper.DEFAULTS, $.isPlainObject(options) && options);
this.isLoaded = false;
this.isBuilt = false;
this.isCompleted = false;
this.isRotated = false;
this.isCropped = false;
this.isDisabled = false;
this.isReplaced = false;
this.isLimited = false;
this.wheeling = false;
this.isImg = false;
this.originalUrl = '';
this.canvas = null;
this.cropBox = null;
this.init();
}

101
vendors/cropper/src/js/defaults.js vendored Normal file
View File

@@ -0,0 +1,101 @@
Cropper.DEFAULTS = {
// Define the view mode of the cropper
viewMode: 0, // 0, 1, 2, 3
// Define the dragging mode of the cropper
dragMode: 'crop', // 'crop', 'move' or 'none'
// Define the aspect ratio of the crop box
aspectRatio: NaN,
// An object with the previous cropping result data
data: null,
// A jQuery selector for adding extra containers to preview
preview: '',
// Re-render the cropper when resize the window
responsive: true,
// Restore the cropped area after resize the window
restore: true,
// Check if the current image is a cross-origin image
checkCrossOrigin: true,
// Check the current image's Exif Orientation information
checkOrientation: true,
// Show the black modal
modal: true,
// Show the dashed lines for guiding
guides: true,
// Show the center indicator for guiding
center: true,
// Show the white modal to highlight the crop box
highlight: true,
// Show the grid background
background: true,
// Enable to crop the image automatically when initialize
autoCrop: true,
// Define the percentage of automatic cropping area when initializes
autoCropArea: 0.8,
// Enable to move the image
movable: true,
// Enable to rotate the image
rotatable: true,
// Enable to scale the image
scalable: true,
// Enable to zoom the image
zoomable: true,
// Enable to zoom the image by dragging touch
zoomOnTouch: true,
// Enable to zoom the image by wheeling mouse
zoomOnWheel: true,
// Define zoom ratio when zoom the image by wheeling mouse
wheelZoomRatio: 0.1,
// Enable to move the crop box
cropBoxMovable: true,
// Enable to resize the crop box
cropBoxResizable: true,
// Toggle drag mode between "crop" and "move" when click twice on the cropper
toggleDragModeOnDblclick: true,
// Size limitation
minCanvasWidth: 0,
minCanvasHeight: 0,
minCropBoxWidth: 0,
minCropBoxHeight: 0,
minContainerWidth: 200,
minContainerHeight: 100,
// Shortcuts of events
build: null,
built: null,
cropstart: null,
cropmove: null,
cropend: null,
crop: null,
zoom: null
};
Cropper.setDefaults = function (options) {
$.extend(Cropper.DEFAULTS, options);
};

205
vendors/cropper/src/js/handlers.js vendored Normal file
View File

@@ -0,0 +1,205 @@
resize: function () {
var restore = this.options.restore;
var $container = this.$container;
var container = this.container;
var canvasData;
var cropBoxData;
var ratio;
// Check `container` is necessary for IE8
if (this.isDisabled || !container) {
return;
}
ratio = $container.width() / container.width;
// Resize when width changed or height changed
if (ratio !== 1 || $container.height() !== container.height) {
if (restore) {
canvasData = this.getCanvasData();
cropBoxData = this.getCropBoxData();
}
this.render();
if (restore) {
this.setCanvasData($.each(canvasData, function (i, n) {
canvasData[i] = n * ratio;
}));
this.setCropBoxData($.each(cropBoxData, function (i, n) {
cropBoxData[i] = n * ratio;
}));
}
}
},
dblclick: function () {
if (this.isDisabled) {
return;
}
if (this.$dragBox.hasClass(CLASS_CROP)) {
this.setDragMode(ACTION_MOVE);
} else {
this.setDragMode(ACTION_CROP);
}
},
wheel: function (event) {
var e = event.originalEvent || event;
var ratio = num(this.options.wheelZoomRatio) || 0.1;
var delta = 1;
if (this.isDisabled) {
return;
}
event.preventDefault();
// Limit wheel speed to prevent zoom too fast
if (this.wheeling) {
return;
}
this.wheeling = true;
setTimeout($.proxy(function () {
this.wheeling = false;
}, this), 50);
if (e.deltaY) {
delta = e.deltaY > 0 ? 1 : -1;
} else if (e.wheelDelta) {
delta = -e.wheelDelta / 120;
} else if (e.detail) {
delta = e.detail > 0 ? 1 : -1;
}
this.zoom(-delta * ratio, event);
},
cropStart: function (event) {
var options = this.options;
var originalEvent = event.originalEvent;
var touches = originalEvent && originalEvent.touches;
var e = event;
var touchesLength;
var action;
if (this.isDisabled) {
return;
}
if (touches) {
touchesLength = touches.length;
if (touchesLength > 1) {
if (options.zoomable && options.zoomOnTouch && touchesLength === 2) {
e = touches[1];
this.startX2 = e.pageX;
this.startY2 = e.pageY;
action = ACTION_ZOOM;
} else {
return;
}
}
e = touches[0];
}
action = action || $(e.target).data(DATA_ACTION);
if (REGEXP_ACTIONS.test(action)) {
if (this.trigger(EVENT_CROP_START, {
originalEvent: originalEvent,
action: action
}).isDefaultPrevented()) {
return;
}
event.preventDefault();
this.action = action;
this.cropping = false;
// IE8 has `event.pageX/Y`, but not `event.originalEvent.pageX/Y`
// IE10 has `event.originalEvent.pageX/Y`, but not `event.pageX/Y`
this.startX = e.pageX || originalEvent && originalEvent.pageX;
this.startY = e.pageY || originalEvent && originalEvent.pageY;
if (action === ACTION_CROP) {
this.cropping = true;
this.$dragBox.addClass(CLASS_MODAL);
}
}
},
cropMove: function (event) {
var options = this.options;
var originalEvent = event.originalEvent;
var touches = originalEvent && originalEvent.touches;
var e = event;
var action = this.action;
var touchesLength;
if (this.isDisabled) {
return;
}
if (touches) {
touchesLength = touches.length;
if (touchesLength > 1) {
if (options.zoomable && options.zoomOnTouch && touchesLength === 2) {
e = touches[1];
this.endX2 = e.pageX;
this.endY2 = e.pageY;
} else {
return;
}
}
e = touches[0];
}
if (action) {
if (this.trigger(EVENT_CROP_MOVE, {
originalEvent: originalEvent,
action: action
}).isDefaultPrevented()) {
return;
}
event.preventDefault();
this.endX = e.pageX || originalEvent && originalEvent.pageX;
this.endY = e.pageY || originalEvent && originalEvent.pageY;
this.change(e.shiftKey, action === ACTION_ZOOM ? event : null);
}
},
cropEnd: function (event) {
var originalEvent = event.originalEvent;
var action = this.action;
if (this.isDisabled) {
return;
}
if (action) {
event.preventDefault();
if (this.cropping) {
this.cropping = false;
this.$dragBox.toggleClass(CLASS_MODAL, this.isCropped && this.options.modal);
}
this.action = '';
this.trigger(EVENT_CROP_END, {
originalEvent: originalEvent,
action: action
});
}
},

217
vendors/cropper/src/js/init.js vendored Normal file
View File

@@ -0,0 +1,217 @@
Cropper.prototype = {
constructor: Cropper,
init: function () {
var $this = this.$element;
var url;
if ($this.is('img')) {
this.isImg = true;
// Should use `$.fn.attr` here. e.g.: "img/picture.jpg"
this.originalUrl = url = $this.attr('src');
// Stop when it's a blank image
if (!url) {
return;
}
// Should use `$.fn.prop` here. e.g.: "http://example.com/img/picture.jpg"
url = $this.prop('src');
} else if ($this.is('canvas') && SUPPORT_CANVAS) {
url = $this[0].toDataURL();
}
this.load(url);
},
// A shortcut for triggering custom events
trigger: function (type, data) {
var e = $.Event(type, data);
this.$element.trigger(e);
return e;
},
load: function (url) {
var options = this.options;
var $this = this.$element;
var read;
var xhr;
if (!url) {
return;
}
// Trigger build event first
$this.one(EVENT_BUILD, options.build);
if (this.trigger(EVENT_BUILD).isDefaultPrevented()) {
return;
}
this.url = url;
this.image = {};
if (!options.checkOrientation || !ArrayBuffer) {
return this.clone();
}
read = $.proxy(this.read, this);
// XMLHttpRequest disallows to open a Data URL in some browsers like IE11 and Safari
if (REGEXP_DATA_URL.test(url)) {
return REGEXP_DATA_URL_JPEG.test(url) ?
read(dataURLToArrayBuffer(url)) :
this.clone();
}
xhr = new XMLHttpRequest();
xhr.onerror = xhr.onabort = $.proxy(function () {
this.clone();
}, this);
xhr.onload = function () {
read(this.response);
};
if (options.checkCrossOrigin && isCrossOriginURL(url) && $this.prop('crossOrigin')) {
url = addTimestamp(url);
}
xhr.open('get', url);
xhr.responseType = 'arraybuffer';
xhr.send();
},
read: function (arrayBuffer) {
var options = this.options;
var orientation = getOrientation(arrayBuffer);
var image = this.image;
var rotate;
var scaleX;
var scaleY;
if (orientation > 1) {
this.url = arrayBufferToDataURL(arrayBuffer);
switch (orientation) {
// flip horizontal
case 2:
scaleX = -1;
break;
// rotate left 180°
case 3:
rotate = -180;
break;
// flip vertical
case 4:
scaleY = -1;
break;
// flip vertical + rotate right 90°
case 5:
rotate = 90;
scaleY = -1;
break;
// rotate right 90°
case 6:
rotate = 90;
break;
// flip horizontal + rotate right 90°
case 7:
rotate = 90;
scaleX = -1;
break;
// rotate left 90°
case 8:
rotate = -90;
break;
}
}
if (options.rotatable) {
image.rotate = rotate;
}
if (options.scalable) {
image.scaleX = scaleX;
image.scaleY = scaleY;
}
this.clone();
},
clone: function () {
var options = this.options;
var $this = this.$element;
var url = this.url;
var crossOrigin = '';
var crossOriginUrl;
var $clone;
if (options.checkCrossOrigin && isCrossOriginURL(url)) {
crossOrigin = $this.prop('crossOrigin');
if (crossOrigin) {
crossOriginUrl = url;
} else {
crossOrigin = 'anonymous';
// Bust cache (#148) when there is not a "crossOrigin" property
crossOriginUrl = addTimestamp(url);
}
}
this.crossOrigin = crossOrigin;
this.crossOriginUrl = crossOriginUrl;
this.$clone = $clone = $('<img' + getCrossOrigin(crossOrigin) + ' src="' + (crossOriginUrl || url) + '">');
if (this.isImg) {
if ($this[0].complete) {
this.start();
} else {
$this.one(EVENT_LOAD, $.proxy(this.start, this));
}
} else {
$clone.
one(EVENT_LOAD, $.proxy(this.start, this)).
one(EVENT_ERROR, $.proxy(this.stop, this)).
addClass(CLASS_HIDE).
insertAfter($this);
}
},
start: function () {
var $image = this.$element;
var $clone = this.$clone;
if (!this.isImg) {
$clone.off(EVENT_ERROR, this.stop);
$image = $clone;
}
getImageSize($image[0], $.proxy(function (naturalWidth, naturalHeight) {
$.extend(this.image, {
naturalWidth: naturalWidth,
naturalHeight: naturalHeight,
aspectRatio: naturalWidth / naturalHeight
});
this.isLoaded = true;
this.build();
}, this));
},
stop: function () {
this.$clone.remove();
this.$clone = null;
},

24
vendors/cropper/src/js/intro.js vendored Normal file
View File

@@ -0,0 +1,24 @@
/*!
* Cropper v@VERSION
* https://github.com/fengyuanchen/cropper
*
* Copyright (c) 2014-@YEAR Fengyuan Chen and contributors
* Released under the MIT license
*
* Date: @DATE
*/
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function ($) {
'use strict';

790
vendors/cropper/src/js/methods.js vendored Normal file
View File

@@ -0,0 +1,790 @@
// Show the crop box manually
crop: function () {
if (!this.isBuilt || this.isDisabled) {
return;
}
if (!this.isCropped) {
this.isCropped = true;
this.limitCropBox(true, true);
if (this.options.modal) {
this.$dragBox.addClass(CLASS_MODAL);
}
this.$cropBox.removeClass(CLASS_HIDDEN);
}
this.setCropBoxData(this.initialCropBox);
},
// Reset the image and crop box to their initial states
reset: function () {
if (!this.isBuilt || this.isDisabled) {
return;
}
this.image = $.extend({}, this.initialImage);
this.canvas = $.extend({}, this.initialCanvas);
this.cropBox = $.extend({}, this.initialCropBox);
this.renderCanvas();
if (this.isCropped) {
this.renderCropBox();
}
},
// Clear the crop box
clear: function () {
if (!this.isCropped || this.isDisabled) {
return;
}
$.extend(this.cropBox, {
left: 0,
top: 0,
width: 0,
height: 0
});
this.isCropped = false;
this.renderCropBox();
this.limitCanvas(true, true);
// Render canvas after crop box rendered
this.renderCanvas();
this.$dragBox.removeClass(CLASS_MODAL);
this.$cropBox.addClass(CLASS_HIDDEN);
},
/**
* Replace the image's src and rebuild the cropper
*
* @param {String} url
* @param {Boolean} onlyColorChanged (optional)
*/
replace: function (url, onlyColorChanged) {
if (!this.isDisabled && url) {
if (this.isImg) {
this.$element.attr('src', url);
}
if (onlyColorChanged) {
this.url = url;
this.$clone.attr('src', url);
if (this.isBuilt) {
this.$preview.find('img').add(this.$clone2).attr('src', url);
}
} else {
if (this.isImg) {
this.isReplaced = true;
}
// Clear previous data
this.options.data = null;
this.load(url);
}
}
},
// Enable (unfreeze) the cropper
enable: function () {
if (this.isBuilt) {
this.isDisabled = false;
this.$cropper.removeClass(CLASS_DISABLED);
}
},
// Disable (freeze) the cropper
disable: function () {
if (this.isBuilt) {
this.isDisabled = true;
this.$cropper.addClass(CLASS_DISABLED);
}
},
// Destroy the cropper and remove the instance from the image
destroy: function () {
var $this = this.$element;
if (this.isLoaded) {
if (this.isImg && this.isReplaced) {
$this.attr('src', this.originalUrl);
}
this.unbuild();
$this.removeClass(CLASS_HIDDEN);
} else {
if (this.isImg) {
$this.off(EVENT_LOAD, this.start);
} else if (this.$clone) {
this.$clone.remove();
}
}
$this.removeData(NAMESPACE);
},
/**
* Move the canvas with relative offsets
*
* @param {Number} offsetX
* @param {Number} offsetY (optional)
*/
move: function (offsetX, offsetY) {
var canvas = this.canvas;
this.moveTo(
isUndefined(offsetX) ? offsetX : canvas.left + num(offsetX),
isUndefined(offsetY) ? offsetY : canvas.top + num(offsetY)
);
},
/**
* Move the canvas to an absolute point
*
* @param {Number} x
* @param {Number} y (optional)
*/
moveTo: function (x, y) {
var canvas = this.canvas;
var isChanged = false;
// If "y" is not present, its default value is "x"
if (isUndefined(y)) {
y = x;
}
x = num(x);
y = num(y);
if (this.isBuilt && !this.isDisabled && this.options.movable) {
if (isNumber(x)) {
canvas.left = x;
isChanged = true;
}
if (isNumber(y)) {
canvas.top = y;
isChanged = true;
}
if (isChanged) {
this.renderCanvas(true);
}
}
},
/**
* Zoom the canvas with a relative ratio
*
* @param {Number} ratio
* @param {jQuery Event} _event (private)
*/
zoom: function (ratio, _event) {
var canvas = this.canvas;
ratio = num(ratio);
if (ratio < 0) {
ratio = 1 / (1 - ratio);
} else {
ratio = 1 + ratio;
}
this.zoomTo(canvas.width * ratio / canvas.naturalWidth, _event);
},
/**
* Zoom the canvas to an absolute ratio
*
* @param {Number} ratio
* @param {jQuery Event} _event (private)
*/
zoomTo: function (ratio, _event) {
var options = this.options;
var canvas = this.canvas;
var width = canvas.width;
var height = canvas.height;
var naturalWidth = canvas.naturalWidth;
var naturalHeight = canvas.naturalHeight;
var originalEvent;
var newWidth;
var newHeight;
var offset;
var center;
ratio = num(ratio);
if (ratio >= 0 && this.isBuilt && !this.isDisabled && options.zoomable) {
newWidth = naturalWidth * ratio;
newHeight = naturalHeight * ratio;
if (_event) {
originalEvent = _event.originalEvent;
}
if (this.trigger(EVENT_ZOOM, {
originalEvent: originalEvent,
oldRatio: width / naturalWidth,
ratio: newWidth / naturalWidth
}).isDefaultPrevented()) {
return;
}
if (originalEvent) {
offset = this.$cropper.offset();
center = originalEvent.touches ? getTouchesCenter(originalEvent.touches) : {
pageX: _event.pageX || originalEvent.pageX || 0,
pageY: _event.pageY || originalEvent.pageY || 0
};
// Zoom from the triggering point of the event
canvas.left -= (newWidth - width) * (
((center.pageX - offset.left) - canvas.left) / width
);
canvas.top -= (newHeight - height) * (
((center.pageY - offset.top) - canvas.top) / height
);
} else {
// Zoom from the center of the canvas
canvas.left -= (newWidth - width) / 2;
canvas.top -= (newHeight - height) / 2;
}
canvas.width = newWidth;
canvas.height = newHeight;
this.renderCanvas(true);
}
},
/**
* Rotate the canvas with a relative degree
*
* @param {Number} degree
*/
rotate: function (degree) {
this.rotateTo((this.image.rotate || 0) + num(degree));
},
/**
* Rotate the canvas to an absolute degree
* https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function#rotate()
*
* @param {Number} degree
*/
rotateTo: function (degree) {
degree = num(degree);
if (isNumber(degree) && this.isBuilt && !this.isDisabled && this.options.rotatable) {
this.image.rotate = degree % 360;
this.isRotated = true;
this.renderCanvas(true);
}
},
/**
* Scale the image
* https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function#scale()
*
* @param {Number} scaleX
* @param {Number} scaleY (optional)
*/
scale: function (scaleX, scaleY) {
var image = this.image;
var isChanged = false;
// If "scaleY" is not present, its default value is "scaleX"
if (isUndefined(scaleY)) {
scaleY = scaleX;
}
scaleX = num(scaleX);
scaleY = num(scaleY);
if (this.isBuilt && !this.isDisabled && this.options.scalable) {
if (isNumber(scaleX)) {
image.scaleX = scaleX;
isChanged = true;
}
if (isNumber(scaleY)) {
image.scaleY = scaleY;
isChanged = true;
}
if (isChanged) {
this.renderImage(true);
}
}
},
/**
* Scale the abscissa of the image
*
* @param {Number} scaleX
*/
scaleX: function (scaleX) {
var scaleY = this.image.scaleY;
this.scale(scaleX, isNumber(scaleY) ? scaleY : 1);
},
/**
* Scale the ordinate of the image
*
* @param {Number} scaleY
*/
scaleY: function (scaleY) {
var scaleX = this.image.scaleX;
this.scale(isNumber(scaleX) ? scaleX : 1, scaleY);
},
/**
* Get the cropped area position and size data (base on the original image)
*
* @param {Boolean} isRounded (optional)
* @return {Object} data
*/
getData: function (isRounded) {
var options = this.options;
var image = this.image;
var canvas = this.canvas;
var cropBox = this.cropBox;
var ratio;
var data;
if (this.isBuilt && this.isCropped) {
data = {
x: cropBox.left - canvas.left,
y: cropBox.top - canvas.top,
width: cropBox.width,
height: cropBox.height
};
ratio = image.width / image.naturalWidth;
$.each(data, function (i, n) {
n = n / ratio;
data[i] = isRounded ? round(n) : n;
});
} else {
data = {
x: 0,
y: 0,
width: 0,
height: 0
};
}
if (options.rotatable) {
data.rotate = image.rotate || 0;
}
if (options.scalable) {
data.scaleX = image.scaleX || 1;
data.scaleY = image.scaleY || 1;
}
return data;
},
/**
* Set the cropped area position and size with new data
*
* @param {Object} data
*/
setData: function (data) {
var options = this.options;
var image = this.image;
var canvas = this.canvas;
var cropBoxData = {};
var isRotated;
var isScaled;
var ratio;
if ($.isFunction(data)) {
data = data.call(this.element);
}
if (this.isBuilt && !this.isDisabled && $.isPlainObject(data)) {
if (options.rotatable) {
if (isNumber(data.rotate) && data.rotate !== image.rotate) {
image.rotate = data.rotate;
this.isRotated = isRotated = true;
}
}
if (options.scalable) {
if (isNumber(data.scaleX) && data.scaleX !== image.scaleX) {
image.scaleX = data.scaleX;
isScaled = true;
}
if (isNumber(data.scaleY) && data.scaleY !== image.scaleY) {
image.scaleY = data.scaleY;
isScaled = true;
}
}
if (isRotated) {
this.renderCanvas();
} else if (isScaled) {
this.renderImage();
}
ratio = image.width / image.naturalWidth;
if (isNumber(data.x)) {
cropBoxData.left = data.x * ratio + canvas.left;
}
if (isNumber(data.y)) {
cropBoxData.top = data.y * ratio + canvas.top;
}
if (isNumber(data.width)) {
cropBoxData.width = data.width * ratio;
}
if (isNumber(data.height)) {
cropBoxData.height = data.height * ratio;
}
this.setCropBoxData(cropBoxData);
}
},
/**
* Get the container size data
*
* @return {Object} data
*/
getContainerData: function () {
return this.isBuilt ? this.container : {};
},
/**
* Get the image position and size data
*
* @return {Object} data
*/
getImageData: function () {
return this.isLoaded ? this.image : {};
},
/**
* Get the canvas position and size data
*
* @return {Object} data
*/
getCanvasData: function () {
var canvas = this.canvas;
var data = {};
if (this.isBuilt) {
$.each([
'left',
'top',
'width',
'height',
'naturalWidth',
'naturalHeight'
], function (i, n) {
data[n] = canvas[n];
});
}
return data;
},
/**
* Set the canvas position and size with new data
*
* @param {Object} data
*/
setCanvasData: function (data) {
var canvas = this.canvas;
var aspectRatio = canvas.aspectRatio;
if ($.isFunction(data)) {
data = data.call(this.$element);
}
if (this.isBuilt && !this.isDisabled && $.isPlainObject(data)) {
if (isNumber(data.left)) {
canvas.left = data.left;
}
if (isNumber(data.top)) {
canvas.top = data.top;
}
if (isNumber(data.width)) {
canvas.width = data.width;
canvas.height = data.width / aspectRatio;
} else if (isNumber(data.height)) {
canvas.height = data.height;
canvas.width = data.height * aspectRatio;
}
this.renderCanvas(true);
}
},
/**
* Get the crop box position and size data
*
* @return {Object} data
*/
getCropBoxData: function () {
var cropBox = this.cropBox;
var data;
if (this.isBuilt && this.isCropped) {
data = {
left: cropBox.left,
top: cropBox.top,
width: cropBox.width,
height: cropBox.height
};
}
return data || {};
},
/**
* Set the crop box position and size with new data
*
* @param {Object} data
*/
setCropBoxData: function (data) {
var cropBox = this.cropBox;
var aspectRatio = this.options.aspectRatio;
var isWidthChanged;
var isHeightChanged;
if ($.isFunction(data)) {
data = data.call(this.$element);
}
if (this.isBuilt && this.isCropped && !this.isDisabled && $.isPlainObject(data)) {
if (isNumber(data.left)) {
cropBox.left = data.left;
}
if (isNumber(data.top)) {
cropBox.top = data.top;
}
if (isNumber(data.width)) {
isWidthChanged = true;
cropBox.width = data.width;
}
if (isNumber(data.height)) {
isHeightChanged = true;
cropBox.height = data.height;
}
if (aspectRatio) {
if (isWidthChanged) {
cropBox.height = cropBox.width / aspectRatio;
} else if (isHeightChanged) {
cropBox.width = cropBox.height * aspectRatio;
}
}
this.renderCropBox();
}
},
/**
* Get a canvas drawn the cropped image
*
* @param {Object} options (optional)
* @return {HTMLCanvasElement} canvas
*/
getCroppedCanvas: function (options) {
var originalWidth;
var originalHeight;
var canvasWidth;
var canvasHeight;
var scaledWidth;
var scaledHeight;
var scaledRatio;
var aspectRatio;
var canvas;
var context;
var data;
if (!this.isBuilt || !SUPPORT_CANVAS) {
return;
}
if (!this.isCropped) {
return getSourceCanvas(this.$clone[0], this.image);
}
if (!$.isPlainObject(options)) {
options = {};
}
data = this.getData();
originalWidth = data.width;
originalHeight = data.height;
aspectRatio = originalWidth / originalHeight;
if ($.isPlainObject(options)) {
scaledWidth = options.width;
scaledHeight = options.height;
if (scaledWidth) {
scaledHeight = scaledWidth / aspectRatio;
scaledRatio = scaledWidth / originalWidth;
} else if (scaledHeight) {
scaledWidth = scaledHeight * aspectRatio;
scaledRatio = scaledHeight / originalHeight;
}
}
// The canvas element will use `Math.floor` on a float number, so floor first
canvasWidth = floor(scaledWidth || originalWidth);
canvasHeight = floor(scaledHeight || originalHeight);
canvas = $('<canvas>')[0];
canvas.width = canvasWidth;
canvas.height = canvasHeight;
context = canvas.getContext('2d');
if (options.fillColor) {
context.fillStyle = options.fillColor;
context.fillRect(0, 0, canvasWidth, canvasHeight);
}
// https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.drawImage
context.drawImage.apply(context, (function () {
var source = getSourceCanvas(this.$clone[0], this.image);
var sourceWidth = source.width;
var sourceHeight = source.height;
var canvas = this.canvas;
var params = [source];
// Source canvas
var srcX = data.x + canvas.naturalWidth * (abs(data.scaleX || 1) - 1) / 2;
var srcY = data.y + canvas.naturalHeight * (abs(data.scaleY || 1) - 1) / 2;
var srcWidth;
var srcHeight;
// Destination canvas
var dstX;
var dstY;
var dstWidth;
var dstHeight;
if (srcX <= -originalWidth || srcX > sourceWidth) {
srcX = srcWidth = dstX = dstWidth = 0;
} else if (srcX <= 0) {
dstX = -srcX;
srcX = 0;
srcWidth = dstWidth = min(sourceWidth, originalWidth + srcX);
} else if (srcX <= sourceWidth) {
dstX = 0;
srcWidth = dstWidth = min(originalWidth, sourceWidth - srcX);
}
if (srcWidth <= 0 || srcY <= -originalHeight || srcY > sourceHeight) {
srcY = srcHeight = dstY = dstHeight = 0;
} else if (srcY <= 0) {
dstY = -srcY;
srcY = 0;
srcHeight = dstHeight = min(sourceHeight, originalHeight + srcY);
} else if (srcY <= sourceHeight) {
dstY = 0;
srcHeight = dstHeight = min(originalHeight, sourceHeight - srcY);
}
// All the numerical parameters should be integer for `drawImage` (#476)
params.push(floor(srcX), floor(srcY), floor(srcWidth), floor(srcHeight));
// Scale destination sizes
if (scaledRatio) {
dstX *= scaledRatio;
dstY *= scaledRatio;
dstWidth *= scaledRatio;
dstHeight *= scaledRatio;
}
// Avoid "IndexSizeError" in IE and Firefox
if (dstWidth > 0 && dstHeight > 0) {
params.push(floor(dstX), floor(dstY), floor(dstWidth), floor(dstHeight));
}
return params;
}).call(this));
return canvas;
},
/**
* Change the aspect ratio of the crop box
*
* @param {Number} aspectRatio
*/
setAspectRatio: function (aspectRatio) {
var options = this.options;
if (!this.isDisabled && !isUndefined(aspectRatio)) {
// 0 -> NaN
options.aspectRatio = max(0, aspectRatio) || NaN;
if (this.isBuilt) {
this.initCropBox();
if (this.isCropped) {
this.renderCropBox();
}
}
}
},
/**
* Change the drag mode
*
* @param {String} mode (optional)
*/
setDragMode: function (mode) {
var options = this.options;
var croppable;
var movable;
if (this.isLoaded && !this.isDisabled) {
croppable = mode === ACTION_CROP;
movable = options.movable && mode === ACTION_MOVE;
mode = (croppable || movable) ? mode : ACTION_NONE;
this.$dragBox.
data(DATA_ACTION, mode).
toggleClass(CLASS_CROP, croppable).
toggleClass(CLASS_MOVE, movable);
if (!options.cropBoxMovable) {
// Sync drag mode to crop box when it is not movable(#300)
this.$face.
data(DATA_ACTION, mode).
toggleClass(CLASS_CROP, croppable).
toggleClass(CLASS_MOVE, movable);
}
}
}
};

1
vendors/cropper/src/js/outro.js vendored Normal file
View File

@@ -0,0 +1 @@
});

39
vendors/cropper/src/js/plugin.js vendored Normal file
View File

@@ -0,0 +1,39 @@
// Save the other cropper
Cropper.other = $.fn.cropper;
// Register as jQuery plugin
$.fn.cropper = function (option) {
var args = toArray(arguments, 1);
var result;
this.each(function () {
var $this = $(this);
var data = $this.data(NAMESPACE);
var options;
var fn;
if (!data) {
if (/destroy/.test(option)) {
return;
}
options = $.extend({}, $this.data(), $.isPlainObject(option) && option);
$this.data(NAMESPACE, (data = new Cropper(this, options)));
}
if (typeof option === 'string' && $.isFunction(fn = data[option])) {
result = fn.apply(data, args);
}
});
return isUndefined(result) ? this : result;
};
$.fn.cropper.Constructor = Cropper;
$.fn.cropper.setDefaults = Cropper.setDefaults;
// No conflict
$.fn.cropper.noConflict = function () {
$.fn.cropper = Cropper.other;
return this;
};

100
vendors/cropper/src/js/preview.js vendored Normal file
View File

@@ -0,0 +1,100 @@
initPreview: function () {
var crossOrigin = getCrossOrigin(this.crossOrigin);
var url = crossOrigin ? this.crossOriginUrl : this.url;
var $clone2;
this.$preview = $(this.options.preview);
this.$clone2 = $clone2 = $('<img' + crossOrigin + ' src="' + url + '">');
this.$viewBox.html($clone2);
this.$preview.each(function () {
var $this = $(this);
// Save the original size for recover
$this.data(DATA_PREVIEW, {
width: $this.width(),
height: $this.height(),
html: $this.html()
});
/**
* Override img element styles
* Add `display:block` to avoid margin top issue
* (Occur only when margin-top <= -height)
*/
$this.html(
'<img' + crossOrigin + ' src="' + url + '" style="' +
'display:block;width:100%;height:auto;' +
'min-width:0!important;min-height:0!important;' +
'max-width:none!important;max-height:none!important;' +
'image-orientation:0deg!important;">'
);
});
},
resetPreview: function () {
this.$preview.each(function () {
var $this = $(this);
var data = $this.data(DATA_PREVIEW);
$this.css({
width: data.width,
height: data.height
}).html(data.html).removeData(DATA_PREVIEW);
});
},
preview: function () {
var image = this.image;
var canvas = this.canvas;
var cropBox = this.cropBox;
var cropBoxWidth = cropBox.width;
var cropBoxHeight = cropBox.height;
var width = image.width;
var height = image.height;
var left = cropBox.left - canvas.left - image.left;
var top = cropBox.top - canvas.top - image.top;
if (!this.isCropped || this.isDisabled) {
return;
}
this.$clone2.css({
width: width,
height: height,
marginLeft: -left,
marginTop: -top,
transform: getTransform(image)
});
this.$preview.each(function () {
var $this = $(this);
var data = $this.data(DATA_PREVIEW);
var originalWidth = data.width;
var originalHeight = data.height;
var newWidth = originalWidth;
var newHeight = originalHeight;
var ratio = 1;
if (cropBoxWidth) {
ratio = originalWidth / cropBoxWidth;
newHeight = cropBoxHeight * ratio;
}
if (cropBoxHeight && newHeight > originalHeight) {
ratio = originalHeight / cropBoxHeight;
newWidth = cropBoxWidth * ratio;
newHeight = originalHeight;
}
$this.css({
width: newWidth,
height: newHeight
}).find('img').css({
width: width * ratio,
height: height * ratio,
marginLeft: -left * ratio,
marginTop: -top * ratio,
transform: getTransform(image)
});
});
},

466
vendors/cropper/src/js/render.js vendored Normal file
View File

@@ -0,0 +1,466 @@
render: function () {
this.initContainer();
this.initCanvas();
this.initCropBox();
this.renderCanvas();
if (this.isCropped) {
this.renderCropBox();
}
},
initContainer: function () {
var options = this.options;
var $this = this.$element;
var $container = this.$container;
var $cropper = this.$cropper;
$cropper.addClass(CLASS_HIDDEN);
$this.removeClass(CLASS_HIDDEN);
$cropper.css((this.container = {
width: max($container.width(), num(options.minContainerWidth) || 200),
height: max($container.height(), num(options.minContainerHeight) || 100)
}));
$this.addClass(CLASS_HIDDEN);
$cropper.removeClass(CLASS_HIDDEN);
},
// Canvas (image wrapper)
initCanvas: function () {
var viewMode = this.options.viewMode;
var container = this.container;
var containerWidth = container.width;
var containerHeight = container.height;
var image = this.image;
var imageNaturalWidth = image.naturalWidth;
var imageNaturalHeight = image.naturalHeight;
var is90Degree = abs(image.rotate) === 90;
var naturalWidth = is90Degree ? imageNaturalHeight : imageNaturalWidth;
var naturalHeight = is90Degree ? imageNaturalWidth : imageNaturalHeight;
var aspectRatio = naturalWidth / naturalHeight;
var canvasWidth = containerWidth;
var canvasHeight = containerHeight;
var canvas;
if (containerHeight * aspectRatio > containerWidth) {
if (viewMode === 3) {
canvasWidth = containerHeight * aspectRatio;
} else {
canvasHeight = containerWidth / aspectRatio;
}
} else {
if (viewMode === 3) {
canvasHeight = containerWidth / aspectRatio;
} else {
canvasWidth = containerHeight * aspectRatio;
}
}
canvas = {
naturalWidth: naturalWidth,
naturalHeight: naturalHeight,
aspectRatio: aspectRatio,
width: canvasWidth,
height: canvasHeight
};
canvas.oldLeft = canvas.left = (containerWidth - canvasWidth) / 2;
canvas.oldTop = canvas.top = (containerHeight - canvasHeight) / 2;
this.canvas = canvas;
this.isLimited = (viewMode === 1 || viewMode === 2);
this.limitCanvas(true, true);
this.initialImage = $.extend({}, image);
this.initialCanvas = $.extend({}, canvas);
},
limitCanvas: function (isSizeLimited, isPositionLimited) {
var options = this.options;
var viewMode = options.viewMode;
var container = this.container;
var containerWidth = container.width;
var containerHeight = container.height;
var canvas = this.canvas;
var aspectRatio = canvas.aspectRatio;
var cropBox = this.cropBox;
var isCropped = this.isCropped && cropBox;
var minCanvasWidth;
var minCanvasHeight;
var newCanvasLeft;
var newCanvasTop;
if (isSizeLimited) {
minCanvasWidth = num(options.minCanvasWidth) || 0;
minCanvasHeight = num(options.minCanvasHeight) || 0;
if (viewMode) {
if (viewMode > 1) {
minCanvasWidth = max(minCanvasWidth, containerWidth);
minCanvasHeight = max(minCanvasHeight, containerHeight);
if (viewMode === 3) {
if (minCanvasHeight * aspectRatio > minCanvasWidth) {
minCanvasWidth = minCanvasHeight * aspectRatio;
} else {
minCanvasHeight = minCanvasWidth / aspectRatio;
}
}
} else {
if (minCanvasWidth) {
minCanvasWidth = max(minCanvasWidth, isCropped ? cropBox.width : 0);
} else if (minCanvasHeight) {
minCanvasHeight = max(minCanvasHeight, isCropped ? cropBox.height : 0);
} else if (isCropped) {
minCanvasWidth = cropBox.width;
minCanvasHeight = cropBox.height;
if (minCanvasHeight * aspectRatio > minCanvasWidth) {
minCanvasWidth = minCanvasHeight * aspectRatio;
} else {
minCanvasHeight = minCanvasWidth / aspectRatio;
}
}
}
}
if (minCanvasWidth && minCanvasHeight) {
if (minCanvasHeight * aspectRatio > minCanvasWidth) {
minCanvasHeight = minCanvasWidth / aspectRatio;
} else {
minCanvasWidth = minCanvasHeight * aspectRatio;
}
} else if (minCanvasWidth) {
minCanvasHeight = minCanvasWidth / aspectRatio;
} else if (minCanvasHeight) {
minCanvasWidth = minCanvasHeight * aspectRatio;
}
canvas.minWidth = minCanvasWidth;
canvas.minHeight = minCanvasHeight;
canvas.maxWidth = Infinity;
canvas.maxHeight = Infinity;
}
if (isPositionLimited) {
if (viewMode) {
newCanvasLeft = containerWidth - canvas.width;
newCanvasTop = containerHeight - canvas.height;
canvas.minLeft = min(0, newCanvasLeft);
canvas.minTop = min(0, newCanvasTop);
canvas.maxLeft = max(0, newCanvasLeft);
canvas.maxTop = max(0, newCanvasTop);
if (isCropped && this.isLimited) {
canvas.minLeft = min(
cropBox.left,
cropBox.left + cropBox.width - canvas.width
);
canvas.minTop = min(
cropBox.top,
cropBox.top + cropBox.height - canvas.height
);
canvas.maxLeft = cropBox.left;
canvas.maxTop = cropBox.top;
if (viewMode === 2) {
if (canvas.width >= containerWidth) {
canvas.minLeft = min(0, newCanvasLeft);
canvas.maxLeft = max(0, newCanvasLeft);
}
if (canvas.height >= containerHeight) {
canvas.minTop = min(0, newCanvasTop);
canvas.maxTop = max(0, newCanvasTop);
}
}
}
} else {
canvas.minLeft = -canvas.width;
canvas.minTop = -canvas.height;
canvas.maxLeft = containerWidth;
canvas.maxTop = containerHeight;
}
}
},
renderCanvas: function (isChanged) {
var canvas = this.canvas;
var image = this.image;
var rotate = image.rotate;
var naturalWidth = image.naturalWidth;
var naturalHeight = image.naturalHeight;
var aspectRatio;
var rotated;
if (this.isRotated) {
this.isRotated = false;
// Computes rotated sizes with image sizes
rotated = getRotatedSizes({
width: image.width,
height: image.height,
degree: rotate
});
aspectRatio = rotated.width / rotated.height;
if (aspectRatio !== canvas.aspectRatio) {
canvas.left -= (rotated.width - canvas.width) / 2;
canvas.top -= (rotated.height - canvas.height) / 2;
canvas.width = rotated.width;
canvas.height = rotated.height;
canvas.aspectRatio = aspectRatio;
canvas.naturalWidth = naturalWidth;
canvas.naturalHeight = naturalHeight;
// Computes rotated sizes with natural image sizes
if (rotate % 180) {
rotated = getRotatedSizes({
width: naturalWidth,
height: naturalHeight,
degree: rotate
});
canvas.naturalWidth = rotated.width;
canvas.naturalHeight = rotated.height;
}
this.limitCanvas(true, false);
}
}
if (canvas.width > canvas.maxWidth || canvas.width < canvas.minWidth) {
canvas.left = canvas.oldLeft;
}
if (canvas.height > canvas.maxHeight || canvas.height < canvas.minHeight) {
canvas.top = canvas.oldTop;
}
canvas.width = min(max(canvas.width, canvas.minWidth), canvas.maxWidth);
canvas.height = min(max(canvas.height, canvas.minHeight), canvas.maxHeight);
this.limitCanvas(false, true);
canvas.oldLeft = canvas.left = min(max(canvas.left, canvas.minLeft), canvas.maxLeft);
canvas.oldTop = canvas.top = min(max(canvas.top, canvas.minTop), canvas.maxTop);
this.$canvas.css({
width: canvas.width,
height: canvas.height,
left: canvas.left,
top: canvas.top
});
this.renderImage();
if (this.isCropped && this.isLimited) {
this.limitCropBox(true, true);
}
if (isChanged) {
this.output();
}
},
renderImage: function (isChanged) {
var canvas = this.canvas;
var image = this.image;
var reversed;
if (image.rotate) {
reversed = getRotatedSizes({
width: canvas.width,
height: canvas.height,
degree: image.rotate,
aspectRatio: image.aspectRatio
}, true);
}
$.extend(image, reversed ? {
width: reversed.width,
height: reversed.height,
left: (canvas.width - reversed.width) / 2,
top: (canvas.height - reversed.height) / 2
} : {
width: canvas.width,
height: canvas.height,
left: 0,
top: 0
});
this.$clone.css({
width: image.width,
height: image.height,
marginLeft: image.left,
marginTop: image.top,
transform: getTransform(image)
});
if (isChanged) {
this.output();
}
},
initCropBox: function () {
var options = this.options;
var canvas = this.canvas;
var aspectRatio = options.aspectRatio;
var autoCropArea = num(options.autoCropArea) || 0.8;
var cropBox = {
width: canvas.width,
height: canvas.height
};
if (aspectRatio) {
if (canvas.height * aspectRatio > canvas.width) {
cropBox.height = cropBox.width / aspectRatio;
} else {
cropBox.width = cropBox.height * aspectRatio;
}
}
this.cropBox = cropBox;
this.limitCropBox(true, true);
// Initialize auto crop area
cropBox.width = min(max(cropBox.width, cropBox.minWidth), cropBox.maxWidth);
cropBox.height = min(max(cropBox.height, cropBox.minHeight), cropBox.maxHeight);
// The width of auto crop area must large than "minWidth", and the height too. (#164)
cropBox.width = max(cropBox.minWidth, cropBox.width * autoCropArea);
cropBox.height = max(cropBox.minHeight, cropBox.height * autoCropArea);
cropBox.oldLeft = cropBox.left = canvas.left + (canvas.width - cropBox.width) / 2;
cropBox.oldTop = cropBox.top = canvas.top + (canvas.height - cropBox.height) / 2;
this.initialCropBox = $.extend({}, cropBox);
},
limitCropBox: function (isSizeLimited, isPositionLimited) {
var options = this.options;
var aspectRatio = options.aspectRatio;
var container = this.container;
var containerWidth = container.width;
var containerHeight = container.height;
var canvas = this.canvas;
var cropBox = this.cropBox;
var isLimited = this.isLimited;
var minCropBoxWidth;
var minCropBoxHeight;
var maxCropBoxWidth;
var maxCropBoxHeight;
if (isSizeLimited) {
minCropBoxWidth = num(options.minCropBoxWidth) || 0;
minCropBoxHeight = num(options.minCropBoxHeight) || 0;
// The min/maxCropBoxWidth/Height must be less than containerWidth/Height
minCropBoxWidth = min(minCropBoxWidth, containerWidth);
minCropBoxHeight = min(minCropBoxHeight, containerHeight);
maxCropBoxWidth = min(containerWidth, isLimited ? canvas.width : containerWidth);
maxCropBoxHeight = min(containerHeight, isLimited ? canvas.height : containerHeight);
if (aspectRatio) {
if (minCropBoxWidth && minCropBoxHeight) {
if (minCropBoxHeight * aspectRatio > minCropBoxWidth) {
minCropBoxHeight = minCropBoxWidth / aspectRatio;
} else {
minCropBoxWidth = minCropBoxHeight * aspectRatio;
}
} else if (minCropBoxWidth) {
minCropBoxHeight = minCropBoxWidth / aspectRatio;
} else if (minCropBoxHeight) {
minCropBoxWidth = minCropBoxHeight * aspectRatio;
}
if (maxCropBoxHeight * aspectRatio > maxCropBoxWidth) {
maxCropBoxHeight = maxCropBoxWidth / aspectRatio;
} else {
maxCropBoxWidth = maxCropBoxHeight * aspectRatio;
}
}
// The minWidth/Height must be less than maxWidth/Height
cropBox.minWidth = min(minCropBoxWidth, maxCropBoxWidth);
cropBox.minHeight = min(minCropBoxHeight, maxCropBoxHeight);
cropBox.maxWidth = maxCropBoxWidth;
cropBox.maxHeight = maxCropBoxHeight;
}
if (isPositionLimited) {
if (isLimited) {
cropBox.minLeft = max(0, canvas.left);
cropBox.minTop = max(0, canvas.top);
cropBox.maxLeft = min(containerWidth, canvas.left + canvas.width) - cropBox.width;
cropBox.maxTop = min(containerHeight, canvas.top + canvas.height) - cropBox.height;
} else {
cropBox.minLeft = 0;
cropBox.minTop = 0;
cropBox.maxLeft = containerWidth - cropBox.width;
cropBox.maxTop = containerHeight - cropBox.height;
}
}
},
renderCropBox: function () {
var options = this.options;
var container = this.container;
var containerWidth = container.width;
var containerHeight = container.height;
var cropBox = this.cropBox;
if (cropBox.width > cropBox.maxWidth || cropBox.width < cropBox.minWidth) {
cropBox.left = cropBox.oldLeft;
}
if (cropBox.height > cropBox.maxHeight || cropBox.height < cropBox.minHeight) {
cropBox.top = cropBox.oldTop;
}
cropBox.width = min(max(cropBox.width, cropBox.minWidth), cropBox.maxWidth);
cropBox.height = min(max(cropBox.height, cropBox.minHeight), cropBox.maxHeight);
this.limitCropBox(false, true);
cropBox.oldLeft = cropBox.left = min(max(cropBox.left, cropBox.minLeft), cropBox.maxLeft);
cropBox.oldTop = cropBox.top = min(max(cropBox.top, cropBox.minTop), cropBox.maxTop);
if (options.movable && options.cropBoxMovable) {
// Turn to move the canvas when the crop box is equal to the container
this.$face.data(DATA_ACTION, (cropBox.width === containerWidth && cropBox.height === containerHeight) ? ACTION_MOVE : ACTION_ALL);
}
this.$cropBox.css({
width: cropBox.width,
height: cropBox.height,
left: cropBox.left,
top: cropBox.top
});
if (this.isCropped && this.isLimited) {
this.limitCanvas(true, true);
}
if (!this.isDisabled) {
this.output();
}
},
output: function () {
this.preview();
if (this.isCompleted) {
this.trigger(EVENT_CROP, this.getData());
} else if (!this.isBuilt) {
// Only trigger one crop event before complete
this.$element.one(EVENT_BUILT, $.proxy(function () {
this.trigger(EVENT_CROP, this.getData());
}, this));
}
},

27
vendors/cropper/src/js/template.js vendored Normal file
View File

@@ -0,0 +1,27 @@
Cropper.TEMPLATE = (
'<div class="cropper-container">' +
'<div class="cropper-wrap-box">' +
'<div class="cropper-canvas"></div>' +
'</div>' +
'<div class="cropper-drag-box"></div>' +
'<div class="cropper-crop-box">' +
'<span class="cropper-view-box"></span>' +
'<span class="cropper-dashed dashed-h"></span>' +
'<span class="cropper-dashed dashed-v"></span>' +
'<span class="cropper-center"></span>' +
'<span class="cropper-face"></span>' +
'<span class="cropper-line line-e" data-action="e"></span>' +
'<span class="cropper-line line-n" data-action="n"></span>' +
'<span class="cropper-line line-w" data-action="w"></span>' +
'<span class="cropper-line line-s" data-action="s"></span>' +
'<span class="cropper-point point-e" data-action="e"></span>' +
'<span class="cropper-point point-n" data-action="n"></span>' +
'<span class="cropper-point point-w" data-action="w"></span>' +
'<span class="cropper-point point-s" data-action="s"></span>' +
'<span class="cropper-point point-ne" data-action="ne"></span>' +
'<span class="cropper-point point-nw" data-action="nw"></span>' +
'<span class="cropper-point point-sw" data-action="sw"></span>' +
'<span class="cropper-point point-se" data-action="se"></span>' +
'</div>' +
'</div>'
);

310
vendors/cropper/src/js/utilities.js vendored Normal file
View File

@@ -0,0 +1,310 @@
function isNumber(n) {
return typeof n === 'number' && !isNaN(n);
}
function isUndefined(n) {
return typeof n === 'undefined';
}
function toArray(obj, offset) {
var args = [];
// This is necessary for IE8
if (isNumber(offset)) {
args.push(offset);
}
return args.slice.apply(obj, args);
}
// Custom proxy to avoid jQuery's guid
function proxy(fn, context) {
var args = toArray(arguments, 2);
return function () {
return fn.apply(context, args.concat(toArray(arguments)));
};
}
function isCrossOriginURL(url) {
var parts = url.match(/^(https?:)\/\/([^\:\/\?#]+):?(\d*)/i);
return parts && (
parts[1] !== location.protocol ||
parts[2] !== location.hostname ||
parts[3] !== location.port
);
}
function addTimestamp(url) {
var timestamp = 'timestamp=' + (new Date()).getTime();
return (url + (url.indexOf('?') === -1 ? '?' : '&') + timestamp);
}
function getCrossOrigin(crossOrigin) {
return crossOrigin ? ' crossOrigin="' + crossOrigin + '"' : '';
}
function getImageSize(image, callback) {
var newImage;
// Modern browsers (ignore Safari, #120 & #509)
if (image.naturalWidth && !IS_SAFARI) {
return callback(image.naturalWidth, image.naturalHeight);
}
// IE8: Don't use `new Image()` here (#319)
newImage = document.createElement('img');
newImage.onload = function () {
callback(this.width, this.height);
};
newImage.src = image.src;
}
function getTransform(options) {
var transforms = [];
var rotate = options.rotate;
var scaleX = options.scaleX;
var scaleY = options.scaleY;
// Scale should come first before rotate (#633)
if (isNumber(scaleX) && isNumber(scaleY)) {
transforms.push('scale(' + scaleX + ',' + scaleY + ')');
}
if (isNumber(rotate)) {
transforms.push('rotate(' + rotate + 'deg)');
}
return transforms.length ? transforms.join(' ') : 'none';
}
function getRotatedSizes(data, isReversed) {
var deg = abs(data.degree) % 180;
var arc = (deg > 90 ? (180 - deg) : deg) * Math.PI / 180;
var sinArc = sin(arc);
var cosArc = cos(arc);
var width = data.width;
var height = data.height;
var aspectRatio = data.aspectRatio;
var newWidth;
var newHeight;
if (!isReversed) {
newWidth = width * cosArc + height * sinArc;
newHeight = width * sinArc + height * cosArc;
} else {
newWidth = width / (cosArc + sinArc / aspectRatio);
newHeight = newWidth / aspectRatio;
}
return {
width: newWidth,
height: newHeight
};
}
function getSourceCanvas(image, data) {
var canvas = $('<canvas>')[0];
var context = canvas.getContext('2d');
var dstX = 0;
var dstY = 0;
var dstWidth = data.naturalWidth;
var dstHeight = data.naturalHeight;
var rotate = data.rotate;
var scaleX = data.scaleX;
var scaleY = data.scaleY;
var scalable = isNumber(scaleX) && isNumber(scaleY) && (scaleX !== 1 || scaleY !== 1);
var rotatable = isNumber(rotate) && rotate !== 0;
var advanced = rotatable || scalable;
var canvasWidth = dstWidth * abs(scaleX || 1);
var canvasHeight = dstHeight * abs(scaleY || 1);
var translateX;
var translateY;
var rotated;
if (scalable) {
translateX = canvasWidth / 2;
translateY = canvasHeight / 2;
}
if (rotatable) {
rotated = getRotatedSizes({
width: canvasWidth,
height: canvasHeight,
degree: rotate
});
canvasWidth = rotated.width;
canvasHeight = rotated.height;
translateX = canvasWidth / 2;
translateY = canvasHeight / 2;
}
canvas.width = canvasWidth;
canvas.height = canvasHeight;
if (advanced) {
dstX = -dstWidth / 2;
dstY = -dstHeight / 2;
context.save();
context.translate(translateX, translateY);
}
if (rotatable) {
context.rotate(rotate * Math.PI / 180);
}
// Should call `scale` after rotated
if (scalable) {
context.scale(scaleX, scaleY);
}
context.drawImage(image, floor(dstX), floor(dstY), floor(dstWidth), floor(dstHeight));
if (advanced) {
context.restore();
}
return canvas;
}
function getTouchesCenter(touches) {
var length = touches.length;
var pageX = 0;
var pageY = 0;
if (length) {
$.each(touches, function (i, touch) {
pageX += touch.pageX;
pageY += touch.pageY;
});
pageX /= length;
pageY /= length;
}
return {
pageX: pageX,
pageY: pageY
};
}
function getStringFromCharCode(dataView, start, length) {
var str = '';
var i;
for (i = start, length += start; i < length; i++) {
str += fromCharCode(dataView.getUint8(i));
}
return str;
}
function getOrientation(arrayBuffer) {
var dataView = new DataView(arrayBuffer);
var length = dataView.byteLength;
var orientation;
var exifIDCode;
var tiffOffset;
var firstIFDOffset;
var littleEndian;
var endianness;
var app1Start;
var ifdStart;
var offset;
var i;
// Only handle JPEG image (start by 0xFFD8)
if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) {
offset = 2;
while (offset < length) {
if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) {
app1Start = offset;
break;
}
offset++;
}
}
if (app1Start) {
exifIDCode = app1Start + 4;
tiffOffset = app1Start + 10;
if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') {
endianness = dataView.getUint16(tiffOffset);
littleEndian = endianness === 0x4949;
if (littleEndian || endianness === 0x4D4D /* bigEndian */) {
if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) {
firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
if (firstIFDOffset >= 0x00000008) {
ifdStart = tiffOffset + firstIFDOffset;
}
}
}
}
}
if (ifdStart) {
length = dataView.getUint16(ifdStart, littleEndian);
for (i = 0; i < length; i++) {
offset = ifdStart + i * 12 + 2;
if (dataView.getUint16(offset, littleEndian) === 0x0112 /* Orientation */) {
// 8 is the offset of the current tag's value
offset += 8;
// Get the original orientation value
orientation = dataView.getUint16(offset, littleEndian);
// Override the orientation with its default value for Safari (#120)
if (IS_SAFARI) {
dataView.setUint16(offset, 1, littleEndian);
}
break;
}
}
}
return orientation;
}
function dataURLToArrayBuffer(dataURL) {
var base64 = dataURL.replace(REGEXP_DATA_URL_HEAD, '');
var binary = atob(base64);
var length = binary.length;
var arrayBuffer = new ArrayBuffer(length);
var dataView = new Uint8Array(arrayBuffer);
var i;
for (i = 0; i < length; i++) {
dataView[i] = binary.charCodeAt(i);
}
return arrayBuffer;
}
// Only available for JPEG image
function arrayBufferToDataURL(arrayBuffer) {
var dataView = new Uint8Array(arrayBuffer);
var length = dataView.length;
var base64 = '';
var i;
for (i = 0; i < length; i++) {
base64 += fromCharCode(dataView[i]);
}
return 'data:image/jpeg;base64,' + btoa(base64);
}

82
vendors/cropper/src/js/variables.js vendored Normal file
View File

@@ -0,0 +1,82 @@
// Globals
var $window = $(window);
var $document = $(document);
var location = window.location;
var navigator = window.navigator;
var ArrayBuffer = window.ArrayBuffer;
var Uint8Array = window.Uint8Array;
var DataView = window.DataView;
var btoa = window.btoa;
// Constants
var NAMESPACE = 'cropper';
// Classes
var CLASS_MODAL = 'cropper-modal';
var CLASS_HIDE = 'cropper-hide';
var CLASS_HIDDEN = 'cropper-hidden';
var CLASS_INVISIBLE = 'cropper-invisible';
var CLASS_MOVE = 'cropper-move';
var CLASS_CROP = 'cropper-crop';
var CLASS_DISABLED = 'cropper-disabled';
var CLASS_BG = 'cropper-bg';
// Events
var EVENT_MOUSE_DOWN = 'mousedown touchstart pointerdown MSPointerDown';
var EVENT_MOUSE_MOVE = 'mousemove touchmove pointermove MSPointerMove';
var EVENT_MOUSE_UP = 'mouseup touchend touchcancel pointerup pointercancel MSPointerUp MSPointerCancel';
var EVENT_WHEEL = 'wheel mousewheel DOMMouseScroll';
var EVENT_DBLCLICK = 'dblclick';
var EVENT_LOAD = 'load.' + NAMESPACE;
var EVENT_ERROR = 'error.' + NAMESPACE;
var EVENT_RESIZE = 'resize.' + NAMESPACE; // Bind to window with namespace
var EVENT_BUILD = 'build.' + NAMESPACE;
var EVENT_BUILT = 'built.' + NAMESPACE;
var EVENT_CROP_START = 'cropstart.' + NAMESPACE;
var EVENT_CROP_MOVE = 'cropmove.' + NAMESPACE;
var EVENT_CROP_END = 'cropend.' + NAMESPACE;
var EVENT_CROP = 'crop.' + NAMESPACE;
var EVENT_ZOOM = 'zoom.' + NAMESPACE;
// RegExps
var REGEXP_ACTIONS = /e|w|s|n|se|sw|ne|nw|all|crop|move|zoom/;
var REGEXP_DATA_URL = /^data\:/;
var REGEXP_DATA_URL_HEAD = /^data\:([^\;]+)\;base64,/;
var REGEXP_DATA_URL_JPEG = /^data\:image\/jpeg.*;base64,/;
// Data keys
var DATA_PREVIEW = 'preview';
var DATA_ACTION = 'action';
// Actions
var ACTION_EAST = 'e';
var ACTION_WEST = 'w';
var ACTION_SOUTH = 's';
var ACTION_NORTH = 'n';
var ACTION_SOUTH_EAST = 'se';
var ACTION_SOUTH_WEST = 'sw';
var ACTION_NORTH_EAST = 'ne';
var ACTION_NORTH_WEST = 'nw';
var ACTION_ALL = 'all';
var ACTION_CROP = 'crop';
var ACTION_MOVE = 'move';
var ACTION_ZOOM = 'zoom';
var ACTION_NONE = 'none';
// Supports
var SUPPORT_CANVAS = $.isFunction($('<canvas>')[0].getContext);
var IS_SAFARI = navigator && /safari/i.test(navigator.userAgent) && /apple computer/i.test(navigator.vendor);
// Maths
var num = Number;
var min = Math.min;
var max = Math.max;
var abs = Math.abs;
var sin = Math.sin;
var cos = Math.cos;
var sqrt = Math.sqrt;
var round = Math.round;
var floor = Math.floor;
// Utilities
var fromCharCode = String.fromCharCode;

253
vendors/cropper/src/scss/_main.scss vendored Normal file
View File

@@ -0,0 +1,253 @@
// Cropper
// =========================
.cropper-container {
position: relative;
font-size: 0;
line-height: 0;
direction: ltr !important; // Ignore global rtl
touch-action: none;
user-select: none;
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
img {
// Avoid margin top issue (Occur only when margin-top <= -height)
display: block;
// https://developer.mozilla.org/en-US/docs/Web/CSS/image-orientation
image-orientation: 0deg !important;
min-width: 0 !important;
min-height: 0 !important;
max-width: none !important;
max-height: none !important;
@include square(100%);
}
}
.cropper-wrap-box,
.cropper-canvas,
.cropper-drag-box,
.cropper-crop-box,
.cropper-modal {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.cropper-wrap-box {
overflow: hidden;
}
.cropper-drag-box {
background-color: #fff;
@include opacity(0);
}
.cropper-modal {
background-color: #000;
@include opacity(.5);
}
.cropper-view-box {
display: block;
overflow: hidden;
outline: 1px solid $color-brand;
outline-color: rgba($color-brand, .75);
@include square(100%);
}
.cropper-dashed {
position: absolute;
display: block;
border: 0 dashed #eee;
@include opacity(.5);
&.dashed-h {
top: percentage(1 / 3);
left: 0;
border-top-width: 1px;
border-bottom-width: 1px;
@include size(100%, percentage(1 / 3));
}
&.dashed-v {
top: 0;
left: percentage(1 / 3);
border-right-width: 1px;
border-left-width: 1px;
@include size(percentage(1 / 3), 100%);
}
}
.cropper-center {
position: absolute;
top: 50%;
left: 50%;
display: block;
width: 0;
height: 0;
@include opacity(.75);
&:before,
&:after {
position: absolute;
display: block;
background-color: #eee;
content: " ";
}
&:before {
top: 0;
left: -3px;
width: 7px;
height: 1px;
}
&:after {
top: -3px;
left: 0;
width: 1px;
height: 7px;
}
}
.cropper-face,
.cropper-line,
.cropper-point {
position: absolute;
display: block;
@include square(100%);
@include opacity(.1);
}
.cropper-face {
top: 0;
left: 0;
background-color: #fff;
}
.cropper-line {
background-color: $color-brand;
&.line-e {
top: 0;
right: -3px;
width: 5px;
cursor: e-resize;
}
&.line-n {
top: -3px;
left: 0;
height: 5px;
cursor: n-resize;
}
&.line-w {
top: 0;
left: -3px;
width: 5px;
cursor: w-resize;
}
&.line-s {
bottom: -3px;
left: 0;
height: 5px;
cursor: s-resize;
}
}
.cropper-point {
background-color: $color-brand;
@include square(5px);
@include opacity(.75);
&.point-e {
top: 50%;
right: -3px;
margin-top: -3px;
cursor: e-resize;
}
&.point-n {
top: -3px;
left: 50%;
margin-left: -3px;
cursor: n-resize;
}
&.point-w {
top: 50%;
left: -3px;
margin-top: -3px;
cursor: w-resize;
}
&.point-s {
bottom: -3px;
left: 50%;
margin-left: -3px;
cursor: s-resize;
}
&.point-ne {
top: -3px;
right: -3px;
cursor: ne-resize;
}
&.point-nw {
top: -3px;
left: -3px;
cursor: nw-resize;
}
&.point-sw {
bottom: -3px;
left: -3px;
cursor: sw-resize;
}
&.point-se {
right: -3px;
bottom: -3px;
cursor: se-resize;
@include square(20px);
@include opacity(1);
}
&.point-se:before {
position: absolute;
right: -50%;
bottom: -50%;
display: block;
content: " ";
background-color: $color-brand;
@include square(200%);
@include opacity(0);
}
@media (min-width: $screen-sm) {
&.point-se {
@include square(15px);
}
}
@media (min-width: $screen-md) {
&.point-se {
@include square(10px);
}
}
@media (min-width: $screen-lg) {
&.point-se {
@include square(5px);
@include opacity(.75);
}
}
}

23
vendors/cropper/src/scss/_mixins.scss vendored Normal file
View File

@@ -0,0 +1,23 @@
// Mixins
// =========================
// Opacity
// -------------------------
@mixin opacity($opacity) {
opacity: $opacity;
filter: alpha(opacity=#{$opacity * 100}); // IE8
}
// Sizing shortcuts
// -------------------------
@mixin size($width, $height) {
width: $width;
height: $height;
}
@mixin square($size) {
@include size($size, $size);
}

View File

@@ -0,0 +1,49 @@
// Helper classes for JavaScript
// =========================
// Visual
// -------------------------
.cropper-invisible {
@include opacity(0);
}
.cropper-bg {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC");
}
// Visibility
// -------------------------
.cropper-hide {
position: absolute;
display: block;
width: 0;
height: 0;
}
.cropper-hidden {
display: none !important;
}
// Cursors
// -------------------------
.cropper-move {
cursor: move;
}
.cropper-crop {
cursor: crosshair;
}
.cropper-disabled {
.cropper-drag-box,
.cropper-face,
.cropper-line,
.cropper-point {
cursor: not-allowed;
}
}

View File

@@ -0,0 +1,19 @@
// Variables
// =========================
// Colors
// -------------------------
$color-brand: #39f !default;
$color-black: #000 !default;
$color-white: #fff !default;
// Media queries breakpoints
// -------------------------
$screen-xs: 480px !default; // Extra small screen / phone
$screen-sm: 768px !default; // Small screen / tablet
$screen-md: 992px !default; // Medium screen / desktop
$screen-lg: 1200px !default; // Large screen / wide desktop

14
vendors/cropper/src/scss/cropper.scss vendored Normal file
View File

@@ -0,0 +1,14 @@
/*!
* Cropper v@VERSION
* https://github.com/fengyuanchen/cropper
*
* Copyright (c) 2014-@YEAR Fengyuan Chen and contributors
* Released under the MIT license
*
* Date: @DATE
*/
@import "variables";
@import "mixins";
@import "main";
@import "utilities";