mirror of
https://gitlab.com/JKANetwork/CheckServer.git
synced 2026-03-11 13:02:01 +01:00
Start again
This commit is contained in:
65
vendors/cropper/.bower.json
vendored
Normal file
65
vendors/cropper/.bower.json
vendored
Normal 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
455
vendors/cropper/CHANGELOG.md
vendored
Normal 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
21
vendors/cropper/LICENSE
vendored
Normal 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
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
55
vendors/cropper/bower.json
vendored
Normal 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
379
vendors/cropper/dist/cropper.css
vendored
Normal 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
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
9
vendors/cropper/dist/cropper.min.css
vendored
Normal 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
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
53
vendors/cropper/package.json
vendored
Normal 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
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
87
vendors/cropper/src/js/bind.js
vendored
Normal 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
118
vendors/cropper/src/js/build.js
vendored
Normal 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
402
vendors/cropper/src/js/change.js
vendored
Normal 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
18
vendors/cropper/src/js/cropper.js
vendored
Normal 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
101
vendors/cropper/src/js/defaults.js
vendored
Normal 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
205
vendors/cropper/src/js/handlers.js
vendored
Normal 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
217
vendors/cropper/src/js/init.js
vendored
Normal 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
24
vendors/cropper/src/js/intro.js
vendored
Normal 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
790
vendors/cropper/src/js/methods.js
vendored
Normal 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
1
vendors/cropper/src/js/outro.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
});
|
||||
39
vendors/cropper/src/js/plugin.js
vendored
Normal file
39
vendors/cropper/src/js/plugin.js
vendored
Normal 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
100
vendors/cropper/src/js/preview.js
vendored
Normal 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
466
vendors/cropper/src/js/render.js
vendored
Normal 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
27
vendors/cropper/src/js/template.js
vendored
Normal 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
310
vendors/cropper/src/js/utilities.js
vendored
Normal 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
82
vendors/cropper/src/js/variables.js
vendored
Normal 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
253
vendors/cropper/src/scss/_main.scss
vendored
Normal 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
23
vendors/cropper/src/scss/_mixins.scss
vendored
Normal 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);
|
||||
}
|
||||
49
vendors/cropper/src/scss/_utilities.scss
vendored
Normal file
49
vendors/cropper/src/scss/_utilities.scss
vendored
Normal 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;
|
||||
}
|
||||
}
|
||||
19
vendors/cropper/src/scss/_variables.scss
vendored
Normal file
19
vendors/cropper/src/scss/_variables.scss
vendored
Normal 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
14
vendors/cropper/src/scss/cropper.scss
vendored
Normal 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";
|
||||
Reference in New Issue
Block a user