更新前端文件
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "Jcrop",
|
||||
"version": "2.0.4",
|
||||
"homepage": "http://jcrop.org/",
|
||||
"authors": [
|
||||
"Tapmodo <khallman@tapmodo.com>"
|
||||
],
|
||||
"description": "jQuery image cropping plugin",
|
||||
"main": [
|
||||
"js/Jcrop.js",
|
||||
"css/Jcrop.css"
|
||||
],
|
||||
"keywords": [
|
||||
"images",
|
||||
"forms",
|
||||
"cropping",
|
||||
"crop",
|
||||
"select",
|
||||
"image",
|
||||
"form"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"_release": "2.0.4",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v2.0.4",
|
||||
"commit": "80f645b69fc938b3823d92d74e5019036d04a9ca"
|
||||
},
|
||||
"_source": "https://github.com/tapmodo/Jcrop.git",
|
||||
"_target": "~2.0.4",
|
||||
"_originalSource": "jcrop"
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
module.exports = function(grunt) {
|
||||
|
||||
// These are the files used in order to build the Jcrop.js source
|
||||
// variable is used in initConfig concat rule below
|
||||
// also used for the watch task
|
||||
var jcrop_sources = [
|
||||
'src/intro.js',
|
||||
'src/constructor.js',
|
||||
'src/static.js',
|
||||
'src/stage/Abstract.js',
|
||||
'src/stage/Image.js',
|
||||
//'src/stage/CssTransform.js',
|
||||
'src/stage/Canvas.js',
|
||||
'src/filter/BackoffFilter.js',
|
||||
'src/filter/ConstrainFilter.js',
|
||||
'src/filter/ExtentFilter.js',
|
||||
'src/filter/GridFilter.js',
|
||||
'src/filter/RatioFilter.js',
|
||||
'src/filter/RoundFilter.js',
|
||||
'src/filter/ShadeFilter.js',
|
||||
'src/component/CanvasAnimator.js',
|
||||
'src/component/CropAnimator.js',
|
||||
'src/component/DragState.js',
|
||||
'src/component/EventManager.js',
|
||||
'src/component/ImageLoader.js',
|
||||
'src/component/JcropTouch.js',
|
||||
'src/component/KeyWatcher.js',
|
||||
'src/component/Selection.js',
|
||||
'src/component/StageDrag.js',
|
||||
'src/component/StageManager.js',
|
||||
'src/component/Thumbnailer.js',
|
||||
'src/component/DialDrag.js',
|
||||
'src/defaults.js',
|
||||
'src/api.js',
|
||||
'src/plugin.js',
|
||||
'src/modernizr.js',
|
||||
'src/outro.js'
|
||||
];
|
||||
|
||||
var json = grunt.file.readJSON('package.json');
|
||||
|
||||
// Project configuration
|
||||
grunt.initConfig({
|
||||
pkg: json,
|
||||
watch: {
|
||||
css: {
|
||||
files: [ 'src/**/*.less' ],
|
||||
tasks: [ 'css' ]
|
||||
},
|
||||
js: {
|
||||
files: [ 'src/**/*.js' ],
|
||||
tasks: [ 'js' ]
|
||||
}
|
||||
},
|
||||
concat: {
|
||||
options: {
|
||||
banner: '/*! <%= pkg.name %>.js v<%= pkg.version %> - build: <%= grunt.template.today("yyyymmdd") %>\n'+
|
||||
' * @copyright 2008-2015 Tapmodo Interactive LLC\n' +
|
||||
' * @license Free software under MIT License\n'+
|
||||
' * @website http://jcrop.org/\n'+
|
||||
' **/\n'
|
||||
},
|
||||
dist: {
|
||||
src: jcrop_sources,
|
||||
dest: 'js/<%= pkg.name %>.js'
|
||||
}
|
||||
},
|
||||
less: {
|
||||
dist: {
|
||||
files: {
|
||||
"css/Jcrop.css": "src/css/Jcrop.less"
|
||||
}
|
||||
}
|
||||
},
|
||||
cssmin: {
|
||||
dist: {
|
||||
options: {
|
||||
keepSpecialComments: 0,
|
||||
banner: '/*! <%= pkg.name %>.min.css v<%= pkg.version %> - build: <%= grunt.template.today("yyyymmdd") %>\n'+
|
||||
' * Copyright 2008-2015 Tapmodo Interactive LLC\n' +
|
||||
' * Free software under MIT License\n'+
|
||||
' **/\n'
|
||||
},
|
||||
files: {
|
||||
"css/Jcrop.min.css": "css/Jcrop.css"
|
||||
}
|
||||
}
|
||||
},
|
||||
usebanner: {
|
||||
dist: {
|
||||
options: {
|
||||
banner: '/*! <%= pkg.name %>.css v<%= pkg.version %> - build: <%= grunt.template.today("yyyymmdd") %>\n'+
|
||||
' * Copyright 2008-2015 Tapmodo Interactive LLC\n' +
|
||||
' * Free software under MIT License\n'+
|
||||
' **/\n'
|
||||
},
|
||||
files: {
|
||||
src: [ 'css/Jcrop.css' ]
|
||||
}
|
||||
}
|
||||
},
|
||||
uglify: {
|
||||
options: {
|
||||
banner: '/*! <%= pkg.name %>.min.js v<%= pkg.version %> - build: <%= grunt.template.today("yyyymmdd") %>\n' +
|
||||
' * Copyright 2008-2015 Tapmodo Interactive LLC\n' +
|
||||
' * Free software under MIT License\n'+
|
||||
' **/\n'
|
||||
},
|
||||
dist: {
|
||||
src: 'js/<%= pkg.name %>.js',
|
||||
dest: 'js/<%= pkg.name %>.min.js'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Load grunt plugins
|
||||
grunt.loadNpmTasks('grunt-contrib-concat');
|
||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||
grunt.loadNpmTasks('grunt-contrib-less');
|
||||
grunt.loadNpmTasks('grunt-contrib-cssmin');
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
grunt.loadNpmTasks('grunt-banner');
|
||||
|
||||
// Default tasks
|
||||
grunt.registerTask('default', ['js','css']);
|
||||
grunt.registerTask('js', ['concat','uglify']);
|
||||
grunt.registerTask('css', ['less','cssmin','usebanner']);
|
||||
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
Copyright (c) 2011 Tapmodo Interactive LLC,
|
||||
http://github.com/tapmodo/Jcrop
|
||||
|
||||
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.
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
Jcrop Image Cropping Plugin
|
||||
===========================
|
||||
|
||||
Jcrop is the quick and easy way to add image cropping functionality to
|
||||
your web application. It combines the ease-of-use of a typical jQuery
|
||||
plugin with a powerful cross-platform DHTML cropping engine that is
|
||||
faithful to familiar desktop graphics applications.
|
||||
|
||||
### Feature Overview
|
||||
|
||||
* Attaches unobtrusively to any image or block element
|
||||
* Completely based on true prototypical Javascript objects for extreme flexibility
|
||||
* Supports multiple active selections, per-selection customization
|
||||
* Supports aspect ratio locking, minimum/maximum size, and other features
|
||||
* Acts as in-line form element, can receive focus, tab through
|
||||
* Keyboard support for nuding selections and trapping other keys
|
||||
* Inherently API-driven and stylable with CSS
|
||||
* Mobile touch support for iOS and Android
|
||||
|
||||
### Cross-platform Compatibility
|
||||
|
||||
The current version of Jcrop has been cross-platform tested and core functionality
|
||||
works in all the following browsers:
|
||||
|
||||
* Firefox 3+
|
||||
* Safari 4+
|
||||
* Opera 9.5+
|
||||
* Google Chrome 14+
|
||||
* Internet Explorer 7+
|
||||
|
||||
Older versions of some browsers may also work.
|
||||
|
||||
Always thoroughly test any desired functionality on all target platforms and devices.
|
||||
|
||||
##### Legacy IE Compatibility
|
||||
|
||||
Internet Explorer 6 suffers some visual problems with the new CSS structure
|
||||
and will not be explicitly supported from v2.x and up. Currently Jcrop can still
|
||||
be used in IE6, it just looks ugly. IE7 and newer versions deliver a nearly flawless
|
||||
Jcrop experience.
|
||||
|
||||
-------------
|
||||
## MIT License
|
||||
|
||||
**Jcrop is free software under MIT License.**
|
||||
|
||||
#### Copyright (c) 2008-2015 Tapmodo Interactive LLC,<br />http://github.com/tapmodo/Jcrop
|
||||
|
||||
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.
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "Jcrop",
|
||||
"version": "2.0.4",
|
||||
"homepage": "http://jcrop.org/",
|
||||
"authors": [
|
||||
"Tapmodo <khallman@tapmodo.com>"
|
||||
],
|
||||
"description": "jQuery image cropping plugin",
|
||||
"main": ["js/Jcrop.js", "css/Jcrop.css"],
|
||||
"keywords": [
|
||||
"images",
|
||||
"forms",
|
||||
"cropping",
|
||||
"crop",
|
||||
"select",
|
||||
"image",
|
||||
"form"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,372 @@
|
||||
/*! Jcrop.css v2.0.4 - build: 20151117
|
||||
* Copyright 2008-2015 Tapmodo Interactive LLC
|
||||
* Free software under MIT License
|
||||
**/
|
||||
|
||||
/*
|
||||
The outer-most container in a typical Jcrop instance
|
||||
If you are having difficulty with formatting related to styles
|
||||
on a parent element, place any fixes here or in a like selector
|
||||
|
||||
You can also style this element if you want to add a border, etc
|
||||
A better method for styling can be seen below with .jcrop-light
|
||||
(Add a class to the holder and style elements for that extended class)
|
||||
*/
|
||||
.jcrop-active {
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
box-sizing: border-box;
|
||||
/* IE10 touch compatibility */
|
||||
-ms-touch-action: none;
|
||||
}
|
||||
.jcrop-dragging {
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.jcrop-selection {
|
||||
z-index: 2;
|
||||
}
|
||||
.jcrop-selection.jcrop-current {
|
||||
z-index: 4;
|
||||
}
|
||||
/* Selection Borders */
|
||||
.jcrop-border {
|
||||
background: #ffffff url("Jcrop.gif");
|
||||
line-height: 1px !important;
|
||||
font-size: 0 !important;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
filter: alpha(opacity=50) !important;
|
||||
opacity: 0.5 !important;
|
||||
}
|
||||
.jcrop-border.ord-w,
|
||||
.jcrop-border.ord-e,
|
||||
.jcrop-border.ord-n {
|
||||
top: 0px;
|
||||
}
|
||||
.jcrop-border.ord-n,
|
||||
.jcrop-border.ord-s {
|
||||
width: 100%;
|
||||
height: 1px !important;
|
||||
}
|
||||
.jcrop-border.ord-w,
|
||||
.jcrop-border.ord-e {
|
||||
height: 100%;
|
||||
width: 1px !important;
|
||||
}
|
||||
.jcrop-border.ord-e {
|
||||
right: -1px;
|
||||
}
|
||||
.jcrop-border.ord-n {
|
||||
top: -1px;
|
||||
}
|
||||
.jcrop-border.ord-w {
|
||||
left: -1px;
|
||||
}
|
||||
.jcrop-border.ord-s {
|
||||
bottom: -1px;
|
||||
}
|
||||
.jcrop-selection {
|
||||
position: absolute;
|
||||
}
|
||||
.jcrop-box {
|
||||
z-index: 2;
|
||||
display: block;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-size: 0;
|
||||
}
|
||||
.jcrop-box:hover {
|
||||
background: none;
|
||||
}
|
||||
.jcrop-box:active {
|
||||
background: none;
|
||||
}
|
||||
.jcrop-box:focus {
|
||||
outline: 1px rgba(128, 128, 128, 0.65) dotted;
|
||||
}
|
||||
.jcrop-active,
|
||||
.jcrop-box {
|
||||
position: relative;
|
||||
}
|
||||
.jcrop-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: move;
|
||||
}
|
||||
/* Selection Handles */
|
||||
.jcrop-handle {
|
||||
z-index: 4;
|
||||
background-color: rgba(49, 28, 28, 0.58);
|
||||
border: 1px #eeeeee solid;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
font-size: 0;
|
||||
position: absolute;
|
||||
filter: alpha(opacity=80) !important;
|
||||
opacity: 0.8 !important;
|
||||
}
|
||||
.jcrop-handle.ord-n {
|
||||
left: 50%;
|
||||
margin-left: -5px;
|
||||
margin-top: -5px;
|
||||
top: 0;
|
||||
cursor: n-resize;
|
||||
}
|
||||
.jcrop-handle.ord-s {
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
margin-bottom: -5px;
|
||||
margin-left: -5px;
|
||||
cursor: s-resize;
|
||||
}
|
||||
.jcrop-handle.ord-e {
|
||||
margin-right: -5px;
|
||||
margin-top: -5px;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
cursor: e-resize;
|
||||
}
|
||||
.jcrop-handle.ord-w {
|
||||
left: 0;
|
||||
margin-left: -5px;
|
||||
margin-top: -5px;
|
||||
top: 50%;
|
||||
cursor: w-resize;
|
||||
}
|
||||
.jcrop-handle.ord-nw {
|
||||
left: 0;
|
||||
margin-left: -5px;
|
||||
margin-top: -5px;
|
||||
top: 0;
|
||||
cursor: nw-resize;
|
||||
}
|
||||
.jcrop-handle.ord-ne {
|
||||
margin-right: -5px;
|
||||
margin-top: -5px;
|
||||
right: 0;
|
||||
top: 0;
|
||||
cursor: ne-resize;
|
||||
}
|
||||
.jcrop-handle.ord-se {
|
||||
bottom: 0;
|
||||
margin-bottom: -5px;
|
||||
margin-right: -5px;
|
||||
right: 0;
|
||||
cursor: se-resize;
|
||||
}
|
||||
.jcrop-handle.ord-sw {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
margin-bottom: -5px;
|
||||
margin-left: -5px;
|
||||
cursor: sw-resize;
|
||||
}
|
||||
/* Larger Selection Handles for Touch */
|
||||
.jcrop-touch .jcrop-handle {
|
||||
z-index: 4;
|
||||
background-color: rgba(49, 28, 28, 0.58);
|
||||
border: 1px #eeeeee solid;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
font-size: 0;
|
||||
position: absolute;
|
||||
filter: alpha(opacity=80) !important;
|
||||
opacity: 0.8 !important;
|
||||
}
|
||||
.jcrop-touch .jcrop-handle.ord-n {
|
||||
left: 50%;
|
||||
margin-left: -10px;
|
||||
margin-top: -10px;
|
||||
top: 0;
|
||||
cursor: n-resize;
|
||||
}
|
||||
.jcrop-touch .jcrop-handle.ord-s {
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
margin-bottom: -10px;
|
||||
margin-left: -10px;
|
||||
cursor: s-resize;
|
||||
}
|
||||
.jcrop-touch .jcrop-handle.ord-e {
|
||||
margin-right: -10px;
|
||||
margin-top: -10px;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
cursor: e-resize;
|
||||
}
|
||||
.jcrop-touch .jcrop-handle.ord-w {
|
||||
left: 0;
|
||||
margin-left: -10px;
|
||||
margin-top: -10px;
|
||||
top: 50%;
|
||||
cursor: w-resize;
|
||||
}
|
||||
.jcrop-touch .jcrop-handle.ord-nw {
|
||||
left: 0;
|
||||
margin-left: -10px;
|
||||
margin-top: -10px;
|
||||
top: 0;
|
||||
cursor: nw-resize;
|
||||
}
|
||||
.jcrop-touch .jcrop-handle.ord-ne {
|
||||
margin-right: -10px;
|
||||
margin-top: -10px;
|
||||
right: 0;
|
||||
top: 0;
|
||||
cursor: ne-resize;
|
||||
}
|
||||
.jcrop-touch .jcrop-handle.ord-se {
|
||||
bottom: 0;
|
||||
margin-bottom: -10px;
|
||||
margin-right: -10px;
|
||||
right: 0;
|
||||
cursor: se-resize;
|
||||
}
|
||||
.jcrop-touch .jcrop-handle.ord-sw {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
margin-bottom: -10px;
|
||||
margin-left: -10px;
|
||||
cursor: sw-resize;
|
||||
}
|
||||
/* Selection Dragbars */
|
||||
.jcrop-dragbar {
|
||||
font-size: 0;
|
||||
position: absolute;
|
||||
}
|
||||
.jcrop-dragbar.ord-n,
|
||||
.jcrop-dragbar.ord-s {
|
||||
height: 9px !important;
|
||||
width: 100%;
|
||||
}
|
||||
.jcrop-dragbar.ord-e,
|
||||
.jcrop-dragbar.ord-w {
|
||||
top: 0px;
|
||||
height: 100%;
|
||||
width: 9px !important;
|
||||
}
|
||||
.jcrop-dragbar.ord-n {
|
||||
margin-top: -5px;
|
||||
cursor: n-resize;
|
||||
top: 0px;
|
||||
}
|
||||
.jcrop-dragbar.ord-s {
|
||||
bottom: 0;
|
||||
margin-bottom: -5px;
|
||||
cursor: s-resize;
|
||||
}
|
||||
.jcrop-dragbar.ord-e {
|
||||
margin-right: -5px;
|
||||
right: 0;
|
||||
cursor: e-resize;
|
||||
}
|
||||
.jcrop-dragbar.ord-w {
|
||||
margin-left: -5px;
|
||||
cursor: w-resize;
|
||||
}
|
||||
/* Shading panels */
|
||||
.jcrop-shades {
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.jcrop-shades div {
|
||||
cursor: crosshair;
|
||||
}
|
||||
/* Various special states */
|
||||
.jcrop-noresize .jcrop-dragbar,
|
||||
.jcrop-noresize .jcrop-handle {
|
||||
display: none;
|
||||
}
|
||||
.jcrop-selection.jcrop-nodrag .jcrop-box,
|
||||
.jcrop-nodrag .jcrop-shades div {
|
||||
cursor: default;
|
||||
}
|
||||
/* The "jcrop-light" class/extension */
|
||||
.jcrop-light .jcrop-border {
|
||||
background: #ffffff;
|
||||
filter: alpha(opacity=70) !important;
|
||||
opacity: .70!important;
|
||||
}
|
||||
.jcrop-light .jcrop-handle {
|
||||
background-color: #000000;
|
||||
border-color: #ffffff;
|
||||
}
|
||||
/* The "jcrop-dark" class/extension */
|
||||
.jcrop-dark .jcrop-border {
|
||||
background: #000000;
|
||||
filter: alpha(opacity=70) !important;
|
||||
opacity: 0.7 !important;
|
||||
}
|
||||
.jcrop-dark .jcrop-handle {
|
||||
background-color: #ffffff;
|
||||
border-color: #000000;
|
||||
}
|
||||
/* Simple macro to turn off the antlines */
|
||||
.solid-line .jcrop-border {
|
||||
background: #ffffff;
|
||||
}
|
||||
.jcrop-thumb {
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
z-index: 5;
|
||||
}
|
||||
/* Fix for twitter bootstrap et al. */
|
||||
.jcrop-active img,
|
||||
.jcrop-thumb img,
|
||||
.jcrop-thumb canvas {
|
||||
min-width: none;
|
||||
min-height: none;
|
||||
max-width: none;
|
||||
max-height: none;
|
||||
}
|
||||
/* Improved multiple selection styles - in progress */
|
||||
.jcrop-hl-active .jcrop-border {
|
||||
filter: alpha(opacity=20) !important;
|
||||
opacity: .20!important;
|
||||
}
|
||||
.jcrop-hl-active .jcrop-handle {
|
||||
filter: alpha(opacity=10) !important;
|
||||
opacity: .10!important;
|
||||
}
|
||||
.jcrop-hl-active .jcrop-selection:hover {
|
||||
/*
|
||||
.jcrop-handle {
|
||||
filter:Alpha(opacity=35)!important;
|
||||
opacity:.35!important;
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
.jcrop-hl-active .jcrop-selection:hover .jcrop-border {
|
||||
background-color: #ccc;
|
||||
filter: alpha(opacity=50) !important;
|
||||
opacity: .50!important;
|
||||
}
|
||||
.jcrop-hl-active .jcrop-selection.jcrop-current .jcrop-border {
|
||||
background: #808080 url('Jcrop.gif');
|
||||
opacity: .35!important;
|
||||
filter: alpha(opacity=35) !important;
|
||||
}
|
||||
.jcrop-hl-active .jcrop-selection.jcrop-current .jcrop-handle {
|
||||
filter: alpha(opacity=30) !important;
|
||||
opacity: .30!important;
|
||||
}
|
||||
.jcrop-hl-active .jcrop-selection.jcrop-focus .jcrop-border {
|
||||
background: url('Jcrop.gif');
|
||||
opacity: .65!important;
|
||||
filter: alpha(opacity=65) !important;
|
||||
}
|
||||
.jcrop-hl-active .jcrop-selection.jcrop-focus .jcrop-handle {
|
||||
filter: alpha(opacity=60) !important;
|
||||
opacity: .60!important;
|
||||
}
|
||||
/* Prevent background on button element */
|
||||
button.jcrop-box {
|
||||
background: none;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 329 B |
+6
File diff suppressed because one or more lines are too long
@@ -0,0 +1,100 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Hello World | Jcrop Demos</title>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
|
||||
<script src="../js/Jcrop.js"></script>
|
||||
<script type="text/javascript">
|
||||
jQuery(function($){
|
||||
var d = document, ge = 'getElementById';
|
||||
|
||||
$('#interface').on('cropmove cropend',function(e,s,c){
|
||||
d[ge]('crop-x').value = c.x;
|
||||
d[ge]('crop-y').value = c.y;
|
||||
d[ge]('crop-w').value = c.w;
|
||||
d[ge]('crop-h').value = c.h;
|
||||
});
|
||||
|
||||
// Most basic attachment example
|
||||
$('#target').Jcrop({
|
||||
setSelect: [ 175, 100, 400, 300 ]
|
||||
});
|
||||
|
||||
$('#text-inputs').on('change','input',function(e){
|
||||
$('#target').Jcrop('api').animateTo([
|
||||
parseInt(d[ge]('crop-x').value),
|
||||
parseInt(d[ge]('crop-y').value),
|
||||
parseInt(d[ge]('crop-w').value),
|
||||
parseInt(d[ge]('crop-h').value)
|
||||
]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
<link rel="stylesheet" href="demo_files/main.css">
|
||||
<link rel="stylesheet" href="demo_files/demos.css">
|
||||
<link rel="stylesheet" href="../css/Jcrop.css">
|
||||
<style>
|
||||
#text-inputs { margin: 10px 8px 0; }
|
||||
.input-group { margin-right: 1.5em; }
|
||||
.nav-box { width: 748px; padding: 0 !important; margin: 4px 0; background-color: #f8f8f7; }
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<button type="button" data-toggle="collapse" data-target="nav-collapse" class="btn btn-navbar"><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><a href="../" class="brand">Jcrop</a>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li class="active"><a href="./basic.html">Demos</a>
|
||||
</li>
|
||||
<li><a href="http://beta.jcrop.org/doc/">Docs</a>
|
||||
</li>
|
||||
<li><a href="http://beta.jcrop.org/contact/">Contact</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="span12">
|
||||
<div class="jc-demo-box">
|
||||
<div class="page-header">
|
||||
<h1>Hello World</h1>
|
||||
</div>
|
||||
<div class="demo-nav menu-box">
|
||||
<h3>Jcrop Demos</h3>
|
||||
<ul class="links">
|
||||
<li><b>Hello World</b></li>
|
||||
<li><a href="thumbnail.html">Thumbnail Preview</a></li>
|
||||
<li><a href="panel.html">Feature Panel</a></li>
|
||||
<li><a href="coords.html">Dimensions</a></li>
|
||||
<li><a href="circle.html">Circles</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="interface" class="page-interface"><img src="http://jcrop-cdn.tapmodo.com/assets/images/sierra2-750.jpg" id="target"></div>
|
||||
<div class="nav-box">
|
||||
<form onsubmit="return false;" id="text-inputs"><span class="input-group"><b>X</b>
|
||||
<input type="text" name="cx" id="crop-x" class="span1"></span><span class="input-group"><b>Y</b>
|
||||
<input type="text" name="cy" id="crop-y" class="span1"></span><span class="input-group"><b>W</b>
|
||||
<input type="text" name="cw" id="crop-w" class="span1"></span><span class="input-group"><b>H</b>
|
||||
<input type="text" name="ch" id="crop-h" class="span1"></span>
|
||||
</form>
|
||||
</div>
|
||||
<div class="tapmodo-footer"><a href="http://tapmodo.com" class="tapmodo-logo segment">tapmodo.com</a>
|
||||
<div class="segment"><b>© 2008-2013 Tapmodo Interactive LLC</b>
|
||||
<div>Jcrop is free software released under <a href="../MIT-LICENSE.txt">MIT License</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,101 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Hello World | Jcrop Demos</title>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
|
||||
<script src="../js/Jcrop.js"></script>
|
||||
<script type="text/javascript">
|
||||
jQuery(function($){
|
||||
var d = document, ge = 'getElementById';
|
||||
|
||||
$('#interface').on('cropmove cropend',function(e,s,c){
|
||||
d[ge]('crop-x').value = c.x;
|
||||
d[ge]('crop-y').value = c.y;
|
||||
d[ge]('crop-w').value = c.w;
|
||||
d[ge]('crop-h').value = c.h;
|
||||
});
|
||||
|
||||
// Most basic attachment example
|
||||
$('#target').Jcrop({
|
||||
boxWidth: 750,
|
||||
setSelect: [ 175, 100, 400, 300 ]
|
||||
});
|
||||
|
||||
$('#text-inputs').on('change','input',function(e){
|
||||
$('#target').Jcrop('api').animateTo([
|
||||
parseInt(d[ge]('crop-x').value),
|
||||
parseInt(d[ge]('crop-y').value),
|
||||
parseInt(d[ge]('crop-w').value),
|
||||
parseInt(d[ge]('crop-h').value)
|
||||
]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
<link rel="stylesheet" href="demo_files/main.css">
|
||||
<link rel="stylesheet" href="demo_files/demos.css">
|
||||
<link rel="stylesheet" href="../css/Jcrop.css">
|
||||
<style>
|
||||
#text-inputs { margin: 10px 8px 0; }
|
||||
.input-group { margin-right: 1.5em; }
|
||||
.nav-box { width: 748px; padding: 0 !important; margin: 4px 0; background-color: #f8f8f7; }
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<button type="button" data-toggle="collapse" data-target="nav-collapse" class="btn btn-navbar"><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><a href="../" class="brand">Jcrop</a>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li class="active"><a href="./basic.html">Demos</a>
|
||||
</li>
|
||||
<li><a href="http://beta.jcrop.org/doc/">Docs</a>
|
||||
</li>
|
||||
<li><a href="http://beta.jcrop.org/contact/">Contact</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="span12">
|
||||
<div class="jc-demo-box">
|
||||
<div class="page-header">
|
||||
<h1>Hello World</h1>
|
||||
</div>
|
||||
<div class="demo-nav menu-box">
|
||||
<h3>Jcrop Demos</h3>
|
||||
<ul class="links">
|
||||
<li><b>Hello World</b></li>
|
||||
<li><a href="thumbnail.html">Thumbnail Preview</a></li>
|
||||
<li><a href="panel.html">Feature Panel</a></li>
|
||||
<li><a href="coords.html">Dimensions</a></li>
|
||||
<li><a href="circle.html">Circles</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="interface" class="page-interface"><img src="http://jcrop-cdn.tapmodo.com/assets/images/lake4-1500.jpg" id="target"></div>
|
||||
<div class="nav-box">
|
||||
<form onsubmit="return false;" id="text-inputs"><span class="input-group"><b>X</b>
|
||||
<input type="text" name="cx" id="crop-x" class="span1"></span><span class="input-group"><b>Y</b>
|
||||
<input type="text" name="cy" id="crop-y" class="span1"></span><span class="input-group"><b>W</b>
|
||||
<input type="text" name="cw" id="crop-w" class="span1"></span><span class="input-group"><b>H</b>
|
||||
<input type="text" name="ch" id="crop-h" class="span1"></span>
|
||||
</form>
|
||||
</div>
|
||||
<div class="tapmodo-footer"><a href="http://tapmodo.com" class="tapmodo-logo segment">tapmodo.com</a>
|
||||
<div class="segment"><b>© 2008-2013 Tapmodo Interactive LLC</b>
|
||||
<div>Jcrop is free software released under <a href="../MIT-LICENSE.txt">MIT License</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,232 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Circles | Jcrop Demos</title>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
|
||||
<script src="../js/Jcrop.js"></script>
|
||||
<script type="text/javascript">
|
||||
var cb, filter;
|
||||
|
||||
jQuery(function($){
|
||||
|
||||
// Create a new Selection object extended from Selection
|
||||
var CircleSel = function(){ };
|
||||
|
||||
// Set the custom selection's prototype object to be an instance
|
||||
// of the built-in Selection object
|
||||
CircleSel.prototype = new $.Jcrop.component.Selection();
|
||||
|
||||
// Then we can continue extending it
|
||||
$.extend(CircleSel.prototype,{
|
||||
zoomscale: 1,
|
||||
attach: function(){
|
||||
this.frame.css({
|
||||
background: 'url(' + $('#target')[0].src.replace('750','750') + ')'
|
||||
});
|
||||
},
|
||||
positionBg: function(b){
|
||||
var midx = ( b.x + b.x2 ) / 2;
|
||||
var midy = ( b.y + b.y2 ) / 2;
|
||||
var ox = (-midx*this.zoomscale)+(b.w/2);
|
||||
var oy = (-midy*this.zoomscale)+(b.h/2);
|
||||
//this.frame.css({ backgroundPosition: ox+'px '+oy+'px' });
|
||||
this.frame.css({ backgroundPosition: -(b.x+1)+'px '+(-b.y-1)+'px' });
|
||||
},
|
||||
redraw: function(b){
|
||||
|
||||
// Call original update() method first, with arguments
|
||||
$.Jcrop.component.Selection.prototype.redraw.call(this,b);
|
||||
|
||||
this.positionBg(this.last);
|
||||
return this;
|
||||
},
|
||||
prototype: $.Jcrop.component.Selection.prototype
|
||||
});
|
||||
|
||||
// Jcrop Initialization
|
||||
$('#target').Jcrop({
|
||||
|
||||
// Change default Selection component for new selections
|
||||
selectionComponent: CircleSel,
|
||||
|
||||
// Use a default filter chain that omits shader
|
||||
applyFilters: [ 'constrain', 'extent', 'backoff', 'ratio', 'round' ],
|
||||
|
||||
// Start with circles only
|
||||
aspectRatio: 1,
|
||||
|
||||
// Set an initial selection
|
||||
setSelect: [ 147, 55, 456, 390 ],
|
||||
|
||||
// Only n/s/e/w handles
|
||||
handles: [ 'n','s','e','w' ],
|
||||
|
||||
// No dragbars or borders
|
||||
dragbars: [ ],
|
||||
borders: [ ]
|
||||
|
||||
},function(){
|
||||
this.container.addClass('jcrop-circle-demo');
|
||||
interface_load(this);
|
||||
});
|
||||
|
||||
function interface_load(obj){
|
||||
cb = obj;
|
||||
|
||||
// Add in a custom shading element...
|
||||
cb.container.prepend($('<div />').addClass('custom-shade'));
|
||||
|
||||
function random_coords() {
|
||||
return [
|
||||
Math.random()*300,
|
||||
Math.random()*200,
|
||||
(Math.random()*540)+50,
|
||||
(Math.random()*340)+60
|
||||
];
|
||||
}
|
||||
|
||||
// Settings Buttons
|
||||
$(document.body).on('click','[data-setting]',function(e){
|
||||
var $targ = $(e.target),
|
||||
setting = $targ.data('setting'),
|
||||
value = $targ.data('value'),
|
||||
opt = {};
|
||||
|
||||
opt[setting] = value;
|
||||
cb.setOptions(opt);
|
||||
|
||||
$targ.closest('.btn-group').find('.active').removeClass('active');
|
||||
$targ.addClass('active');
|
||||
|
||||
if ((setting == 'multi') && !value) {
|
||||
var m = cb.ui.multi, s = cb.ui.selection;
|
||||
|
||||
for(var i=0;i<m.length;i++)
|
||||
if (s !== m[i]) m[i].remove();
|
||||
|
||||
cb.ui.multi = [ s ];
|
||||
s.focus();
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
// Animate button event
|
||||
$(document.body).on('click','[data-action]',function(e){
|
||||
var $targ = $(e.target);
|
||||
var action = $targ.data('action');
|
||||
|
||||
switch(action){
|
||||
case 'random-move':
|
||||
cb.ui.selection.animateTo(random_coords());
|
||||
break;
|
||||
}
|
||||
|
||||
cb.ui.selection.refresh();
|
||||
|
||||
}).on('selectstart',function(e){
|
||||
e.preventDefault();
|
||||
}).on('click','a[data-action]',function(e){
|
||||
e.preventDefault();
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
<link rel="stylesheet" href="demo_files/main.css">
|
||||
<link rel="stylesheet" href="demo_files/demos.css">
|
||||
<link rel="stylesheet" href="../css/Jcrop.css"><style type="text/css">.jcrop-circle-demo .jcrop-box {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 1px rgba(255, 255, 255, 0.4) solid;
|
||||
border-radius: 50%;
|
||||
-webkit-box-shadow: 1px 1px 26px #000000;
|
||||
-moz-box-shadow: 1px 1px 26px #000000;
|
||||
box-shadow: 1px 1px 26px #000000;
|
||||
overflow: hidden;
|
||||
}
|
||||
.jcrop-circle-demo .jcrop-box:focus {
|
||||
outline: none;
|
||||
}
|
||||
.custom-shade {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
background-color: black;
|
||||
opacity: 0.4;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<button type="button" data-toggle="collapse" data-target="nav-collapse" class="btn btn-navbar"><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><a href="../" class="brand">Jcrop</a>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li class="active"><a href="./basic.html">Demos</a>
|
||||
</li>
|
||||
<li><a href="http://beta.jcrop.org/doc/">Docs</a>
|
||||
</li>
|
||||
<li><a href="http://beta.jcrop.org/contact/">Contact</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="span12">
|
||||
<div class="jc-demo-box">
|
||||
<div class="page-header">
|
||||
<h1>Circles</h1>
|
||||
</div>
|
||||
<div class="demo-nav menu-box">
|
||||
<h3>Jcrop Demos</h3>
|
||||
<ul class="links">
|
||||
<li><a href="basic.html">Hello World</a></li>
|
||||
<li><a href="thumbnail.html">Thumbnail Preview</a></li>
|
||||
<li><a href="panel.html">Feature Panel</a></li>
|
||||
<li><a href="coords.html">Dimensions</a></li>
|
||||
<li><b>Circles</b></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="page-interface"><img src="http://jcrop-cdn.tapmodo.com/assets/images/sierra2-750.jpg" id="target">
|
||||
<div class="btn-toolbar"><a href="#" data-action="random-move" id="moveselection" class="btn btn-small">Move</a><span class="btn-group"><a href="#" data-setting="aspectRatio" data-value="1" class="btn active btn-small">Circle</a><a href="#" data-setting="aspectRatio" data-value="0" class="btn btn-small">Ellipse</a></span><span class="btn-group"><a href="#" data-setting="multi" data-value="0" class="btn active btn-small">Single </a><a href="#" data-setting="multi" data-value="1" class="btn btn-small">Multi</a></span></div>
|
||||
<h3>About This Demo</h3><p><strong>And you thought Jcrop could only do rectangles!</strong> Well, that's still
|
||||
mostly true. This demo implements a custom <code>Selection</code> object that
|
||||
uses CSS properties to create the appearance of circles and ellipses.</p>
|
||||
|
||||
<h4>Custom CSS and Shading</h4>
|
||||
|
||||
<p>By setting the CSS property <code>border-radius: 50%</code>, we can give the
|
||||
selection an appearance of a circle or an ellipse. The built-in
|
||||
shader filter has been disabled, and a semi-opaque <code><div></code> has been
|
||||
inserted over the image to give the appearance of shading.</p>
|
||||
|
||||
<h4>Cropping Irregular Selections</h4>
|
||||
|
||||
<p>If you actually want to <em>crop</em> a circle or an ellipse, you're on
|
||||
your own. Jcrop will provide the rectangular coordinates for these
|
||||
crops, and further processing can be done to extract the circle
|
||||
or ellipse from the image.</p>
|
||||
</div>
|
||||
<div class="tapmodo-footer"><a href="http://tapmodo.com" class="tapmodo-logo segment">tapmodo.com</a>
|
||||
<div class="segment"><b>© 2008-2013 Tapmodo Interactive LLC</b>
|
||||
<div>Jcrop is free software released under <a href="../MIT-LICENSE.txt">MIT License</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,173 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Dimensions | Jcrop Demos</title>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
|
||||
<script src="../js/Jcrop.js"></script>
|
||||
<script src="/Jcrop/js/jquery.color.js"></script>
|
||||
<script type="text/javascript">
|
||||
var cb, filter;
|
||||
|
||||
jQuery(function($){
|
||||
|
||||
// Create a new Selection object extended from Selection
|
||||
var CoordsSel = function(){ };
|
||||
|
||||
// Set the custom selection's prototype object to be an instance
|
||||
// of the built-in Selection object
|
||||
CoordsSel.prototype = new $.Jcrop.component.Selection;
|
||||
|
||||
// Then we can continue extending it
|
||||
$.extend(CoordsSel.prototype,{
|
||||
attach: function(){
|
||||
// Prepend an element to Selection.element (selection container)
|
||||
this.coords = $('<div> x </div>').addClass('jcrop-coords');
|
||||
this.element.prepend(this.coords);
|
||||
},
|
||||
redraw: function(b){
|
||||
|
||||
// Call original redraw() method first, with arguments
|
||||
$.Jcrop.component.Selection.prototype.redraw.call(this,b);
|
||||
|
||||
// Update coordinates
|
||||
this.coords.html(this.last.w+' × '+this.last.h);
|
||||
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
// Now set it as the component that is used for new selections
|
||||
$('#target').Jcrop({
|
||||
selectionComponent: CoordsSel,
|
||||
bgColor: 'rgb(145,176,241)',
|
||||
bgOpacity: 0.5
|
||||
},function(){
|
||||
this.container.addClass('jcrop-hl-active');
|
||||
interface_load(this);
|
||||
});
|
||||
|
||||
function interface_load(obj){
|
||||
cb = obj;
|
||||
|
||||
cb.newSelection().update($.Jcrop.wrapFromXywh([ 147, 55, 456, 390 ])).refresh();
|
||||
//cb.ui.selection.removeFilter(cb.filter.shader);
|
||||
cb.ui.selection.refresh();
|
||||
|
||||
function random_coords() {
|
||||
return [
|
||||
Math.random()*300,
|
||||
Math.random()*200,
|
||||
(Math.random()*540)+50,
|
||||
(Math.random()*340)+60
|
||||
];
|
||||
}
|
||||
|
||||
// Animate button event
|
||||
$(document.body).on('click','[data-action]',function(e){
|
||||
var $targ = $(e.target);
|
||||
var action = $targ.data('action');
|
||||
|
||||
switch(action){
|
||||
case 'random-move':
|
||||
cb.ui.selection.animateTo(random_coords());
|
||||
break;
|
||||
}
|
||||
|
||||
cb.ui.selection.refresh();
|
||||
|
||||
}).on('selectstart',function(e){
|
||||
e.preventDefault();
|
||||
}).on('click','a[data-action]',function(e){
|
||||
e.preventDefault();
|
||||
});
|
||||
}
|
||||
|
||||
$.Jcrop.component.CoordsSel = CoordsSel;
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
<link rel="stylesheet" href="demo_files/main.css">
|
||||
<link rel="stylesheet" href="demo_files/demos.css">
|
||||
<link rel="stylesheet" href="../css/Jcrop.css">
|
||||
<style type="text/css">
|
||||
.jcrop-border {
|
||||
background: rgba(0,0,0,0.8);
|
||||
}
|
||||
|
||||
.jcrop-handle {
|
||||
border-color: rgba(0,0,0,0.8);
|
||||
}
|
||||
|
||||
.jcrop-coords {
|
||||
display: none;
|
||||
position: absolute;
|
||||
bottom: -24px;
|
||||
right: 7px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
padding: 1px 4px 0;
|
||||
font-size: 10px;
|
||||
white-space: nowrap;
|
||||
font-family: "Lucida Console", Monaco, monospace;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.jcrop-current .jcrop-coords {
|
||||
display: block;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<button type="button" data-toggle="collapse" data-target="nav-collapse" class="btn btn-navbar"><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><a href="../" class="brand">Jcrop</a>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li class="active"><a href="./basic.html">Demos</a>
|
||||
</li>
|
||||
<li><a href="http://beta.jcrop.org/doc/">Docs</a>
|
||||
</li>
|
||||
<li><a href="http://beta.jcrop.org/contact/">Contact</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="span12">
|
||||
<div class="jc-demo-box">
|
||||
<div class="page-header">
|
||||
<h1>Dimensions</h1>
|
||||
</div>
|
||||
<div class="demo-nav menu-box">
|
||||
<h3>Jcrop Demos</h3>
|
||||
<ul class="links">
|
||||
<li><a href="basic.html">Hello World</a></li>
|
||||
<li><a href="thumbnail.html">Thumbnail Preview</a></li>
|
||||
<li><a href="panel.html">Feature Panel</a></li>
|
||||
<li><b>Dimensions</b></li>
|
||||
<li><a href="circle.html">Circles</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="page-interface"><img src="http://jcrop-cdn.tapmodo.com/assets/images/sierra-750.jpg" id="target">
|
||||
<div class="btn-toolbar"><a href="#" data-action="random-move" id="moveselection" class="btn btn-small">Move</a></div>
|
||||
</div>
|
||||
<div class="tapmodo-footer"><a href="http://tapmodo.com" class="tapmodo-logo segment">tapmodo.com</a>
|
||||
<div class="segment"><b>© 2008-2013 Tapmodo Interactive LLC</b>
|
||||
<div>Jcrop is free software released under <a href="../MIT-LICENSE.txt">MIT License</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Jcrop image cropping plugin for jQuery
|
||||
* Example cropping script
|
||||
* @copyright 2008-2009 Kelly Hallman
|
||||
* More info: http://deepliquid.com/content/Jcrop_Implementation_Theory.html
|
||||
*/
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST')
|
||||
{
|
||||
$targ_w = $targ_h = 150;
|
||||
$jpeg_quality = 90;
|
||||
|
||||
$src = 'demo_files/pool.jpg';
|
||||
$img_r = imagecreatefromjpeg($src);
|
||||
$dst_r = ImageCreateTrueColor( $targ_w, $targ_h );
|
||||
|
||||
imagecopyresampled($dst_r,$img_r,0,0,$_POST['x'],$_POST['y'],
|
||||
$targ_w,$targ_h,$_POST['w'],$_POST['h']);
|
||||
|
||||
header('Content-type: image/jpeg');
|
||||
imagejpeg($dst_r,null,$jpeg_quality);
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
// If not a POST request, display page below:
|
||||
|
||||
?><!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Live Cropping Demo</title>
|
||||
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
|
||||
<script src="../js/jquery.min.js"></script>
|
||||
<script src="../js/jquery.Jcrop.js"></script>
|
||||
<link rel="stylesheet" href="demo_files/main.css" type="text/css" />
|
||||
<link rel="stylesheet" href="demo_files/demos.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../css/jquery.Jcrop.css" type="text/css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
$(function(){
|
||||
|
||||
$('#cropbox').Jcrop({
|
||||
aspectRatio: 1,
|
||||
onSelect: updateCoords
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function updateCoords(c)
|
||||
{
|
||||
$('#x').val(c.x);
|
||||
$('#y').val(c.y);
|
||||
$('#w').val(c.w);
|
||||
$('#h').val(c.h);
|
||||
};
|
||||
|
||||
function checkCoords()
|
||||
{
|
||||
if (parseInt($('#w').val())) return true;
|
||||
alert('Please select a crop region then press submit.');
|
||||
return false;
|
||||
};
|
||||
|
||||
</script>
|
||||
<style type="text/css">
|
||||
#target {
|
||||
background-color: #ccc;
|
||||
width: 500px;
|
||||
height: 330px;
|
||||
font-size: 24px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="span12">
|
||||
<div class="jc-demo-box">
|
||||
|
||||
<div class="page-header">
|
||||
<ul class="breadcrumb first">
|
||||
<li><a href="../index.html">Jcrop</a> <span class="divider">/</span></li>
|
||||
<li><a href="../index.html">Demos</a> <span class="divider">/</span></li>
|
||||
<li class="active">Live Demo (Requires PHP)</li>
|
||||
</ul>
|
||||
<h1>Server-based Cropping Behavior</h1>
|
||||
</div>
|
||||
|
||||
<!-- This is the image we're attaching Jcrop to -->
|
||||
<img src="demo_files/pool.jpg" id="cropbox" />
|
||||
|
||||
<!-- This is the form that our event handler fills -->
|
||||
<form action="crop.php" method="post" onsubmit="return checkCoords();">
|
||||
<input type="hidden" id="x" name="x" />
|
||||
<input type="hidden" id="y" name="y" />
|
||||
<input type="hidden" id="w" name="w" />
|
||||
<input type="hidden" id="h" name="h" />
|
||||
<input type="submit" value="Crop Image" class="btn btn-large btn-inverse" />
|
||||
</form>
|
||||
|
||||
<p>
|
||||
<b>An example server-side crop script.</b> Hidden form values
|
||||
are set when a selection is made. If you press the <i>Crop Image</i>
|
||||
button, the form will be submitted and a 150x150 thumbnail will be
|
||||
dumped to the browser. Try it!
|
||||
</p>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,263 @@
|
||||
/* Jcrop Demo Site CSS - 2013 Tapmodo Interactive LLC - MIT License
|
||||
Not required to run Jcrop - contains twitter bootstrap code */
|
||||
/* To build these CSS files you must have LESS and run
|
||||
* $ git submodule init
|
||||
* $ git submodule update
|
||||
* ...to pull in the Twitter bootstrap files
|
||||
*/
|
||||
.clearfix {
|
||||
*zoom: 1;
|
||||
}
|
||||
.clearfix:before,
|
||||
.clearfix:after {
|
||||
display: table;
|
||||
content: "";
|
||||
line-height: 0;
|
||||
}
|
||||
.clearfix:after {
|
||||
clear: both;
|
||||
}
|
||||
.hide-text {
|
||||
font: 0/0 a;
|
||||
color: transparent;
|
||||
text-shadow: none;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
}
|
||||
.input-block-level {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-height: 30px;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
/* JCROP DEMOS CSS */
|
||||
li small {
|
||||
color: #f07878;
|
||||
}
|
||||
.inline-labels label {
|
||||
display: inline;
|
||||
}
|
||||
div#interface.span3 fieldset {
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
div#interface.span3 fieldset legend {
|
||||
margin-bottom: 2px;
|
||||
padding-bottom: 2px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
.article h1 {
|
||||
color: #333;
|
||||
margin-top: .2em;
|
||||
}
|
||||
.jc-demo {
|
||||
text-align: center;
|
||||
}
|
||||
.jcropper-holder {
|
||||
border: 1px #bbb solid;
|
||||
}
|
||||
.jc-demo-box {
|
||||
text-align: left;
|
||||
margin: 3.4em auto 2em;
|
||||
background: white;
|
||||
border: 1px #bbb solid;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.25);
|
||||
-moz-box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.25);
|
||||
box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.25);
|
||||
padding: 1em 2em 2em;
|
||||
}
|
||||
form {
|
||||
margin: 1.5em 0;
|
||||
}
|
||||
form.coords label {
|
||||
margin-right: 1em;
|
||||
font-weight: bold;
|
||||
color: #900;
|
||||
}
|
||||
form.coords input {
|
||||
width: 3em;
|
||||
}
|
||||
.ui-widget-overlay {
|
||||
opacity: 0.80;
|
||||
filter: alpha(opacity=70);
|
||||
}
|
||||
.jc-dialog {
|
||||
padding-top: 1em;
|
||||
}
|
||||
.ui-dialog p tt {
|
||||
color: yellow;
|
||||
}
|
||||
.jcrop-light .jcrop-selection {
|
||||
-moz-box-shadow: 0px 0px 15px #999;
|
||||
/* Firefox */
|
||||
|
||||
-webkit-box-shadow: 0px 0px 15px #999;
|
||||
/* Safari, Chrome */
|
||||
|
||||
box-shadow: 0px 0px 15px #999;
|
||||
/* CSS3 */
|
||||
|
||||
}
|
||||
.jcrop-dark .jcrop-selection {
|
||||
-moz-box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.35);
|
||||
/* Firefox */
|
||||
|
||||
-webkit-box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.35);
|
||||
/* Safari, Chrome */
|
||||
|
||||
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.35);
|
||||
/* CSS3 */
|
||||
|
||||
}
|
||||
.jcrop-dark .jcrop-selection:hover {
|
||||
-moz-box-shadow: 0px 0px 6px #000000;
|
||||
/* Firefox */
|
||||
|
||||
-webkit-box-shadow: 0px 0px 6px #000000;
|
||||
/* Safari, Chrome */
|
||||
|
||||
box-shadow: 0px 0px 6px #000000;
|
||||
/* CSS3 */
|
||||
|
||||
}
|
||||
.jcrop-dark .jcrop-selection.jcrop-current {
|
||||
-moz-box-shadow: 0px 0px 15px #000;
|
||||
/* Firefox */
|
||||
|
||||
-webkit-box-shadow: 0px 0px 15px #000;
|
||||
/* Safari, Chrome */
|
||||
|
||||
box-shadow: 0px 0px 15px #000;
|
||||
/* CSS3 */
|
||||
|
||||
}
|
||||
.jcrop-fancy .jcrop-handle.ord-e {
|
||||
-webkit-border-top-left-radius: 0px;
|
||||
-webkit-border-bottom-left-radius: 0px;
|
||||
}
|
||||
.jcrop-fancy .jcrop-handle.ord-w {
|
||||
-webkit-border-top-right-radius: 0px;
|
||||
-webkit-border-bottom-right-radius: 0px;
|
||||
}
|
||||
.jcrop-fancy .jcrop-handle.ord-nw {
|
||||
-webkit-border-bottom-right-radius: 0px;
|
||||
}
|
||||
.jcrop-fancy .jcrop-handle.ord-ne {
|
||||
-webkit-border-bottom-left-radius: 0px;
|
||||
}
|
||||
.jcrop-fancy .jcrop-handle.ord-sw {
|
||||
-webkit-border-top-right-radius: 0px;
|
||||
}
|
||||
.jcrop-fancy .jcrop-handle.ord-se {
|
||||
-webkit-border-top-left-radius: 0px;
|
||||
}
|
||||
.jcrop-fancy .jcrop-handle.ord-s {
|
||||
-webkit-border-top-left-radius: 0px;
|
||||
-webkit-border-top-right-radius: 0px;
|
||||
}
|
||||
.jcrop-fancy .jcrop-handle.ord-n {
|
||||
-webkit-border-bottom-left-radius: 0px;
|
||||
-webkit-border-bottom-right-radius: 0px;
|
||||
}
|
||||
.description {
|
||||
margin: 16px 0;
|
||||
}
|
||||
.jcrop-droptarget canvas {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
div.nav-box {
|
||||
border: 1px #ccc solid;
|
||||
-webkit-box-shadow: inset 0px 0px 12px #cccccc;
|
||||
-moz-box-shadow: inset 0px 0px 12px #cccccc;
|
||||
box-shadow: inset 0px 0px 12px #cccccc;
|
||||
margin-bottom: 0.5em;
|
||||
padding: 0 0 1em 1em;
|
||||
}
|
||||
div.nav-box h3 {
|
||||
line-height: 1;
|
||||
color: #777;
|
||||
}
|
||||
ul.icons-only {
|
||||
list-style: none outside;
|
||||
margin: 0 0 0 0.5em;
|
||||
}
|
||||
ul.icons-only li i {
|
||||
margin-right: 0.5em;
|
||||
line-height: 22px;
|
||||
}
|
||||
.bolder {
|
||||
font-weight: bolder;
|
||||
}
|
||||
.menu-box {
|
||||
border: 1px #c4c4c4 solid;
|
||||
border-radius: 3px;
|
||||
background: white;
|
||||
margin-right: -40px;
|
||||
margin-left: 15px;
|
||||
font-size: 11.2px;
|
||||
line-height: 1.3;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
.menu-box h3 {
|
||||
background: #307b93;
|
||||
color: white;
|
||||
padding: 4px 4px 4px 12px;
|
||||
line-height: 1;
|
||||
margin-left: -14px;
|
||||
font-size: 16px;
|
||||
position: relative;
|
||||
}
|
||||
.menu-box h3::after {
|
||||
content: '';
|
||||
border-right: #15485c 5px solid;
|
||||
border-bottom: transparent 5px solid;
|
||||
position: absolute;
|
||||
bottom: -5px;
|
||||
left: 0px;
|
||||
}
|
||||
.menu-box ul.links {
|
||||
padding: 0;
|
||||
margin: 0 3px 1em;
|
||||
border-bottom: 1px #ebebeb solid;
|
||||
list-style: none outside;
|
||||
}
|
||||
.menu-box ul.links li {
|
||||
border-top: 1px #ebebeb solid;
|
||||
padding: 0;
|
||||
}
|
||||
.menu-box.demo-nav {
|
||||
float: right;
|
||||
width: 135px;
|
||||
}
|
||||
.menu-box.main-menu {
|
||||
float: right;
|
||||
width: 180px;
|
||||
margin-top: -95px;
|
||||
}
|
||||
pre {
|
||||
margin: 0 0 1.2em;
|
||||
}
|
||||
.alert p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
table.option-list tbody td.col1 {
|
||||
color: #777;
|
||||
font-weight: bolder;
|
||||
}
|
||||
table.option-list td.col1 {
|
||||
width: 19%;
|
||||
}
|
||||
table.option-list td.col2 {
|
||||
width: 31%;
|
||||
}
|
||||
table.option-list td.col3 {
|
||||
width: 50%;
|
||||
}
|
||||
code {
|
||||
border: none;
|
||||
color: #555;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 77 KiB |
@@ -0,0 +1,62 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>All Jcrop Demos | Jcrop Demos</title>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
|
||||
<script src="../js/Jcrop.js"></script>
|
||||
<script type="text/javascript">
|
||||
jQuery(function($){
|
||||
|
||||
// Most basic attachment example
|
||||
$('#target').Jcrop({});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
<link rel="stylesheet" href="demo_files/main.css">
|
||||
<link rel="stylesheet" href="demo_files/demos.css">
|
||||
<link rel="stylesheet" href="../css/Jcrop.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<button type="button" data-toggle="collapse" data-target="nav-collapse" class="btn btn-navbar"><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><a href="../" class="brand">Jcrop</a>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li class="active"><a href="./basic.html">Demos</a>
|
||||
</li>
|
||||
<li><a href="http://beta.jcrop.org/doc/">Docs</a>
|
||||
</li>
|
||||
<li><a href="http://beta.jcrop.org/contact/">Contact</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="span12">
|
||||
<div class="jc-demo-box">
|
||||
<div class="page-header">
|
||||
<h1>All Jcrop Demos</h1>
|
||||
</div>
|
||||
<ul></ul>
|
||||
<li><a href="basic.html">Hello World</a></li>
|
||||
<li><a href="thumbnail.html">Thumbnail Preview</a></li>
|
||||
<li><a href="panel.html">Feature Panel</a></li>
|
||||
<li><a href="coords.html">Dimensions</a></li>
|
||||
<li><a href="circle.html">Circles</a></li>
|
||||
<div class="tapmodo-footer"><a href="http://tapmodo.com" class="tapmodo-logo segment">tapmodo.com</a>
|
||||
<div class="segment"><b>© 2008-2013 Tapmodo Interactive LLC</b>
|
||||
<div>Jcrop is free software released under <a href="../MIT-LICENSE.txt">MIT License</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,91 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Non-image Cropping | Jcrop Demos</title>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
|
||||
<script src="../js/Jcrop.js"></script>
|
||||
<script type="text/javascript">
|
||||
jQuery(function($){
|
||||
// I did JSON.stringify(jcrop_api.ui.selection.get()) on a crop I liked:
|
||||
var c = {"x":186,"y":218,"x2":564,"y2":281,"w":378,"h":63};
|
||||
|
||||
$('#target').Jcrop({
|
||||
setSelect: [c.x,c.y,c.w,c.h]
|
||||
},function(){
|
||||
this.animateTo([ 18, 11, 713, 170 ]);
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
<link rel="stylesheet" href="demo_files/main.css">
|
||||
<link rel="stylesheet" href="demo_files/demos.css">
|
||||
<link rel="stylesheet" href="../css/Jcrop.css">
|
||||
<style>
|
||||
#target {
|
||||
background-color: #ccc;
|
||||
width: 750px;
|
||||
height: 500px;
|
||||
display: block;
|
||||
}
|
||||
#target p {
|
||||
padding: .5em 1em;
|
||||
line-height: 1;
|
||||
font-size: 36px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<button type="button" data-toggle="collapse" data-target="nav-collapse" class="btn btn-navbar"><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><a href="../" class="brand">Jcrop</a>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li class="active"><a href="./basic.html">Demos</a>
|
||||
</li>
|
||||
<li><a href="http://beta.jcrop.org/doc/">Docs</a>
|
||||
</li>
|
||||
<li><a href="http://beta.jcrop.org/contact/">Contact</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="span12">
|
||||
<div class="jc-demo-box">
|
||||
<div class="page-header">
|
||||
<h1>Non-image Cropping</h1>
|
||||
</div>
|
||||
<div class="demo-nav menu-box">
|
||||
<h3>Jcrop Demos</h3>
|
||||
<ul class="links">
|
||||
<li><a href="basic.html">Hello World</a></li>
|
||||
<li><a href="thumbnail.html">Thumbnail Preview</a></li>
|
||||
<li><a href="panel.html">Feature Panel</a></li>
|
||||
<li><a href="coords.html">Dimensions</a></li>
|
||||
<li><a href="circle.html">Circles</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="target" class="jcrop-dark jcrop-hl-active"><p><strong>This is an example of attaching Jcrop to a target that is not an image.</strong>
|
||||
You are now cropping over <div> content.</p>
|
||||
</div>
|
||||
<div class="description"><p><strong>Attaching Jcrop to a non-image element.</strong><br/>This is mostly useful to implement other interfaces, such as
|
||||
<code>canvas</code> or over an arbitrary <code>div</code>.</p>
|
||||
</div>
|
||||
<div class="tapmodo-footer"><a href="http://tapmodo.com" class="tapmodo-logo segment">tapmodo.com</a>
|
||||
<div class="segment"><b>© 2008-2013 Tapmodo Interactive LLC</b>
|
||||
<div>Jcrop is free software released under <a href="../MIT-LICENSE.txt">MIT License</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,373 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Feature Panel | Jcrop Demos</title>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
|
||||
<script src="../js/Jcrop.js"></script>
|
||||
<script src="//code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
|
||||
<script src="http://jcrop-dev.tapmodo.com/Jcrop/js/jquery.color.js"></script>
|
||||
<script type="text/javascript">
|
||||
var cb, filter;
|
||||
|
||||
jQuery(function($){
|
||||
|
||||
var $targ = $('#target');
|
||||
var $easing = $('#easing');
|
||||
|
||||
$('#target').Jcrop({
|
||||
animEasing: 'easeOutQuart',
|
||||
bgOpacity: .35,
|
||||
linked: false,
|
||||
multi: true
|
||||
},function(){
|
||||
this.container.addClass('jcrop-dark jcrop-hl-active');
|
||||
interface_load(this);
|
||||
});
|
||||
|
||||
function interface_load(obj){
|
||||
cb = obj;
|
||||
|
||||
cb.newSelection();
|
||||
cb.setSelect([ 147, 55, 456, 390 ]);
|
||||
cb.refresh();
|
||||
// Hack a "special" selection...
|
||||
var logosel = cb.newSelection().update($.Jcrop.wrapFromXywh([73,268,400,100]));
|
||||
|
||||
$.extend(logosel,{
|
||||
special: true, // custom value used in our local script here
|
||||
bgColor: '#999',
|
||||
bgOpacity: 0.8,
|
||||
canResize: false,
|
||||
canDelete: false
|
||||
});
|
||||
|
||||
logosel.element.prepend('<img src="http://tapmodo.com/img/tapmodo-official.png" style="position:absolute;background-color:white;width:100%;height:100%;" />');
|
||||
logosel.aspectRatio = 400/100;
|
||||
logosel.refresh();
|
||||
cb.ui.multi[1].focus();
|
||||
|
||||
// Select an interesting easing function
|
||||
$easing[0].selectedIndex = 24;
|
||||
|
||||
// Set up the easing function select element event
|
||||
cb.opt.animEasing = $easing.change(function(e){
|
||||
var $targ = $(e.target);
|
||||
cb.opt.animEasing = $targ.val();
|
||||
e.preventDefault();
|
||||
cb.ui.selection.animateTo([Math.random()*300,Math.random()*200,(Math.random()*540)+50,(Math.random()*340)+60]);
|
||||
}).val();
|
||||
|
||||
$('#filter-selections input').attr('checked',false);
|
||||
$('#page-interface').on('startselect',function(e){
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
cb.container.on('cropfocus cropblur cropstart cropend',function(e){
|
||||
var sel = $(e.target).data('selection');
|
||||
switch(e.type){
|
||||
case 'cropfocus':
|
||||
$('#can_size')[0].checked = sel.canResize?true:false;
|
||||
$('#can_delete')[0].checked = sel.canDelete?true:false;
|
||||
$('#can_drag')[0].checked = sel.canDrag?true:false;
|
||||
$('#set_minsize')[0].checked = (sel.minSize[0]>8)?true:false;
|
||||
$('#set_maxsize')[0].checked = (sel.maxSize[0])?true:false;
|
||||
$('#set_bounds')[0].checked = (sel.edge.n)?true:false;
|
||||
$('#is_linked')[0].disabled = sel.special?true:false;
|
||||
$('#is_linked')[0].checked = sel.linked?true:false;
|
||||
$('#shading-tools a')[0].disabled = sel.special?true:false;
|
||||
$('#shading-tools a')[sel.special?'addClass':'removeClass']('disabled');
|
||||
|
||||
$('#ar-links').find('.active').removeClass('active');
|
||||
if (sel.aspectRatio) {
|
||||
if (!$('#ar-links').find('[data-value="'+sel.aspectRatio+'"]').addClass('active').length)
|
||||
$('#ar-lock').addClass('active');
|
||||
} else $('#ar-free').addClass('active');
|
||||
}
|
||||
});
|
||||
|
||||
$('#aspect_ratio').on('change',function(e){
|
||||
var s = cb.ui.selection;
|
||||
var b = s.get();
|
||||
s.aspectRatio = e.target.checked? b.w/b.h : 0;
|
||||
s.refresh();
|
||||
});
|
||||
$('#is_linked').on('change',function(e){
|
||||
cb.ui.selection.linked = e.target.checked;
|
||||
});
|
||||
|
||||
$('#selection-options').on('change','[data-filter-toggle]',function(e){
|
||||
var tog = $(e.target).data('filter-toggle');
|
||||
var o = { };
|
||||
o[tog] = e.target.checked? true: false;
|
||||
cb.setOptions(o);
|
||||
});
|
||||
|
||||
var cycle_colors = [
|
||||
'red',
|
||||
'blue',
|
||||
'gray',
|
||||
'yellow',
|
||||
'orange',
|
||||
'green',
|
||||
'white'
|
||||
];
|
||||
|
||||
function random_coords() {
|
||||
return [
|
||||
Math.random()*300,
|
||||
Math.random()*200,
|
||||
(Math.random()*540)+50,
|
||||
(Math.random()*340)+60
|
||||
];
|
||||
}
|
||||
|
||||
$('#can_drag,#can_size,#can_delete,#enablesel,#multisel,#anim_mode').attr('checked','checked');
|
||||
$('#is_linked,#aspect_ratio').attr('checked',false);
|
||||
|
||||
function anim_mode(){
|
||||
return document.getElementById('anim_mode').checked;
|
||||
}
|
||||
|
||||
// A simple function to cleanup multiple spawned selections
|
||||
function run_cleanup(){
|
||||
var m = cb.ui.multi, s = cb.ui.selection;
|
||||
|
||||
for(var i=0;i<m.length;i++)
|
||||
if (s !== m[i]) m[i].remove();
|
||||
|
||||
cb.ui.multi = [ s ];
|
||||
s.center();
|
||||
s.focus();
|
||||
}
|
||||
|
||||
// Animate button event
|
||||
$(document.body).on('click','[data-action]',function(e){
|
||||
var $targ = $(e.target);
|
||||
var action = $targ.data('action');
|
||||
|
||||
switch(action){
|
||||
case 'set-maxsize':
|
||||
cb.setOptions({ maxSize: e.target.checked? [400,350]: [0,0] });
|
||||
break;
|
||||
case 'set-minsize':
|
||||
cb.setOptions({ minSize: e.target.checked? [60,60]: [8,8] });
|
||||
break;
|
||||
case 'set-bounds':
|
||||
if (e.target.checked){
|
||||
cb.setOptions({ edge: {
|
||||
n: 15,
|
||||
e: -20,
|
||||
s: -40,
|
||||
w: 28
|
||||
}});
|
||||
}
|
||||
else {
|
||||
cb.setOptions({ edge: {
|
||||
n: 0,
|
||||
e: 0,
|
||||
s: 0,
|
||||
w: 0
|
||||
}});
|
||||
}
|
||||
break;
|
||||
case 'set-image':
|
||||
$targ.parent().find('.active').removeClass('active');
|
||||
$targ.addClass('active');
|
||||
$('#target').attr('src','//jcrop-cdn.tapmodo.com/assets/images/'+$targ.data('image')+'-750.jpg');
|
||||
break;
|
||||
case 'set-ar':
|
||||
var value = $targ.data('value');
|
||||
$targ.parent().find('.active').removeClass('active');
|
||||
if (value == 'lock'){
|
||||
var b = cb.ui.selection.get();
|
||||
value = b.w / b.h;
|
||||
}
|
||||
$targ.addClass('active');
|
||||
cb.setOptions({ aspectRatio: value });
|
||||
break;
|
||||
case 'set-selmode':
|
||||
$targ.parent().find('.active').removeClass('active');
|
||||
$targ.addClass('active');
|
||||
switch($targ.data('mode')){
|
||||
case 'none':
|
||||
cb.container.addClass('jcrop-nodrag');
|
||||
cb.setOptions({ allowSelect: false });
|
||||
break;
|
||||
case 'single':
|
||||
cb.container.removeClass('jcrop-nodrag');
|
||||
cb.setOptions({ allowSelect: true, multi: false });
|
||||
break;
|
||||
case 'multi':
|
||||
cb.container.removeClass('jcrop-nodrag');
|
||||
cb.setOptions({ allowSelect: true, multi: true });
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'enable-selections':
|
||||
cb.ui.stage.dragger.active = e.target.checked;
|
||||
break;
|
||||
case 'enable-multi':
|
||||
cb.ui.stage.dragger.multi = e.target.checked;
|
||||
break;
|
||||
case 'color-cycle':
|
||||
var cc = cycle_colors.shift();
|
||||
cb.setOptions({ bgColor: cc });
|
||||
cycle_colors.push(cc);
|
||||
break;
|
||||
case 'set-opacity':
|
||||
$targ.parent().find('.active').removeClass('active');
|
||||
$targ.addClass('active');
|
||||
cb.setOptions({ bgOpacity: $targ.data('opacity'), bgColor: 'black' });
|
||||
break;
|
||||
case 'cleanup-all':
|
||||
run_cleanup();
|
||||
break;
|
||||
case 'random-move':
|
||||
cb[anim_mode()?'animateTo':'setSelect'](random_coords());
|
||||
break;
|
||||
}
|
||||
|
||||
}).on('keydown',function(e){
|
||||
if (e.keyCode == 8) e.preventDefault();
|
||||
}).on('selectstart',function(e){
|
||||
e.preventDefault();
|
||||
}).on('click','a[data-action]',function(e){
|
||||
e.preventDefault();
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
<link rel="stylesheet" href="demo_files/main.css">
|
||||
<link rel="stylesheet" href="demo_files/demos.css">
|
||||
<link rel="stylesheet" href="../css/Jcrop.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<button type="button" data-toggle="collapse" data-target="nav-collapse" class="btn btn-navbar"><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><a href="../" class="brand">Jcrop</a>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li class="active"><a href="./basic.html">Demos</a>
|
||||
</li>
|
||||
<li><a href="http://beta.jcrop.org/doc/">Docs</a>
|
||||
</li>
|
||||
<li><a href="http://beta.jcrop.org/contact/">Contact</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="span12">
|
||||
<div class="jc-demo-box">
|
||||
<div class="page-header">
|
||||
<h1>Feature Panel</h1>
|
||||
</div>
|
||||
<div class="demo-nav menu-box">
|
||||
<h3>Jcrop Demos</h3>
|
||||
<ul class="links">
|
||||
<li><a href="basic.html">Hello World</a></li>
|
||||
<li><a href="thumbnail.html">Thumbnail Preview</a></li>
|
||||
<li><b>Feature Panel</b></li>
|
||||
<li><a href="coords.html">Dimensions</a></li>
|
||||
<li><a href="circle.html">Circles</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="page-interface"><img src="http://jcrop-cdn.tapmodo.com/assets/images/sierra2-750.jpg" id="target">
|
||||
<div class="row-fluid">
|
||||
<div class="span4">
|
||||
<h5>Selection Properties</h5>
|
||||
<div id="selection-options">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" data-filter-toggle="canDrag" id="can_drag">Draggable
|
||||
</label>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" data-filter-toggle="canResize" id="can_size">Resizable
|
||||
</label>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" data-filter-toggle="canDelete" id="can_delete">Deletable
|
||||
</label>
|
||||
</div>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" data-action="set-bounds" id="set_bounds">Enable boundary
|
||||
</label>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" data-action="set-minsize" id="set_minsize">Minimum Size
|
||||
</label>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" data-action="set-maxsize" id="set_maxsize">Maximum Size
|
||||
</label>
|
||||
</div>
|
||||
<div class="span4">
|
||||
<h5>Aspect Ratio</h5>
|
||||
<div class="btn-toolbar"><span id="ar-links" class="btn-group"><a href="#" data-action="set-ar" data-value="0" id="ar-free" class="btn active btn-small">Free</a><a href="#" data-action="set-ar" data-value="lock" id="ar-lock" class="btn btn-small">Lock</a><a href="#" data-action="set-ar" data-value="1.4" class="btn btn-small">Wide</a><a href="#" data-action="set-ar" data-value=".8" class="btn btn-small">Tall</a></span></div>
|
||||
<h5>Shading</h5>
|
||||
<div id="shading-tools" class="btn-toolbar"><a href="#" data-action="color-cycle" class="btn btn-small">Color</a><span class="btn-group"><a href="#" data-action="set-opacity" data-opacity=".35" class="btn active btn-small">Light</a><a href="#" data-action="set-opacity" data-opacity=".55" class="btn btn-small">Medium</a><a href="#" data-action="set-opacity" data-opacity=".75" class="btn btn-small">Dark</a></span></div>
|
||||
<h5>Animation</h5>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" id="anim_mode">Enable Animation
|
||||
</label>
|
||||
<select data-action="update-easing" id="easing" class="select">
|
||||
<option>linear</option>
|
||||
<option>swing</option>
|
||||
<option>easeInOutQuad</option>
|
||||
<option>easeInQuad</option>
|
||||
<option>easeOutQuad</option>
|
||||
<option>easeInOutExpo</option>
|
||||
<option>easeInExpo</option>
|
||||
<option>easeOutExpo</option>
|
||||
<option>easeInOutSine</option>
|
||||
<option>easeInSine</option>
|
||||
<option>easeOutSine</option>
|
||||
<option>easeOutBounce</option>
|
||||
<option>easeInOutCirc</option>
|
||||
<option>easeInCirc</option>
|
||||
<option>easeOutCirc</option>
|
||||
<option>easeInOutCubic</option>
|
||||
<option>easeInCubic</option>
|
||||
<option>easeOutCubic</option>
|
||||
<option>easeOutElastic</option>
|
||||
<option>easeInOutBack</option>
|
||||
<option>easeInBack</option>
|
||||
<option>easeOutBack</option>
|
||||
<option>easeInOutQuart</option>
|
||||
<option>easeInQuart</option>
|
||||
<option>easeOutQuart</option>
|
||||
<option>easeInOutQuint</option>
|
||||
<option>easeInQuint</option>
|
||||
<option>easeOutQuint</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="span4">
|
||||
<h5>Current Selection</h5>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" data-filter-toggle="ratio" id="is_linked">Linked Selection
|
||||
</label>
|
||||
<div class="btn-toolbar"><a href="#" data-action="random-move" id="moveselection" class="btn btn-small">Move</a><a href="#" data-action="cleanup-all" class="btn btn-small">Cleanup</a></div>
|
||||
<h5>New Selections</h5>
|
||||
<div class="btn-toolbar"><span class="btn-group"><a href="#" data-action="set-selmode" data-mode="none" class="btn btn-small">None</a><a href="#" data-action="set-selmode" data-mode="single" class="btn btn-small">Single</a><a href="#" data-action="set-selmode" data-mode="multi" class="btn active btn-small">Multi</a></span></div>
|
||||
<h5>Test Image</h5>
|
||||
<div class="btn-toolbar"><span class="btn-group"><a href="#" data-action="set-image" data-image="sierra" class="btn btn-small">Sierra1</a><a href="#" data-action="set-image" data-image="sierra2" class="btn active btn-small">Sierra2</a><a href="#" data-action="set-image" data-image="market" class="btn btn-small">Market</a></span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tapmodo-footer"><a href="http://tapmodo.com" class="tapmodo-logo segment">tapmodo.com</a>
|
||||
<div class="segment"><b>© 2008-2013 Tapmodo Interactive LLC</b>
|
||||
<div>Jcrop is free software released under <a href="../MIT-LICENSE.txt">MIT License</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,138 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Thumbnail Preview | Jcrop Demos</title>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
|
||||
<script src="../js/Jcrop.js"></script>
|
||||
<script type="text/javascript">
|
||||
jQuery(function($){
|
||||
|
||||
// Create a scope-wide variable to hold the Thumbnailer instance
|
||||
var thumbnail;
|
||||
|
||||
// Instantiate Jcrop
|
||||
$('#target').Jcrop({
|
||||
aspectRatio: 1,
|
||||
setSelect: [ 175, 100, 400, 300 ]
|
||||
},function(){
|
||||
var jcrop_api = this;
|
||||
thumbnail = new $.Jcrop.component.Thumbnailer(jcrop_api,{ width: 130, height: 130 });
|
||||
});
|
||||
|
||||
// Wire up the auto-hide checkbox/toggle
|
||||
$('#autohide').attr('checked',false).on('change',function(e){
|
||||
var chk = this.checked;
|
||||
if (thumbnail) {
|
||||
thumbnail.autoHide = chk? true: false;
|
||||
thumbnail[chk?'hide':'show']();
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
<link rel="stylesheet" href="demo_files/main.css">
|
||||
<link rel="stylesheet" href="demo_files/demos.css">
|
||||
<link rel="stylesheet" href="../css/Jcrop.css">
|
||||
<style>
|
||||
.jcrop-thumb {
|
||||
top: -25px;
|
||||
right: 20px;
|
||||
border: 1px black solid;
|
||||
}
|
||||
|
||||
#text-inputs { margin: 10px 8px 0; }
|
||||
.input-group { margin-right: 1.5em; }
|
||||
.nav-box { width: 748px; padding: 0 !important; margin: 4px 0; background-color: #f8f8f7; }
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<button type="button" data-toggle="collapse" data-target="nav-collapse" class="btn btn-navbar"><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><a href="../" class="brand">Jcrop</a>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li class="active"><a href="./basic.html">Demos</a>
|
||||
</li>
|
||||
<li><a href="http://beta.jcrop.org/doc/">Docs</a>
|
||||
</li>
|
||||
<li><a href="http://beta.jcrop.org/contact/">Contact</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="span12">
|
||||
<div class="jc-demo-box">
|
||||
<div class="page-header">
|
||||
<h1>Thumbnail Preview</h1>
|
||||
</div>
|
||||
<div class="demo-nav menu-box">
|
||||
<h3>Jcrop Demos</h3>
|
||||
<ul class="links">
|
||||
<li><a href="basic.html">Hello World</a></li>
|
||||
<li><b>Thumbnail Preview</b></li>
|
||||
<li><a href="panel.html">Feature Panel</a></li>
|
||||
<li><a href="coords.html">Dimensions</a></li>
|
||||
<li><a href="circle.html">Circles</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="interface" class="page-interface"><img src="http://jcrop-dist.tapmodo.com/assets/images/sierra2-750.jpg" crossOrigin="anonymous" id="target">
|
||||
<div style="margin-top:0.7em">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" id="autohide"><b>Auto-hide Thumbnail Preview</b>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<h3>Built-in Preview Support</h3><p><strong>Thumbnail previews just got much easier!</strong> Used to be, if you wanted to
|
||||
include a dynamic preview with Jcrop, you had to write client code.
|
||||
A number of people had difficulty adapting that code to their needs.
|
||||
No more! Now just attach a Thumbnailer object. Pass in the Jcrop instance,
|
||||
desired width, and height, and you're done.</p>
|
||||
|
||||
<h5>Invocation Code (for this demo)</h5>
|
||||
|
||||
<pre><code>$('#target').Jcrop({
|
||||
aspectRatio: 1,
|
||||
setSelect: [ 175, 100, 400, 300 ]
|
||||
},function(){
|
||||
var jcrop_api = this;
|
||||
new $.Jcrop.component.Thumbnailer(jcrop_api,{ width: 130, height: 130 });
|
||||
});</code></pre>
|
||||
|
||||
<p>The constructor takes a reference to the Jcrop instance, and allows
|
||||
passage of various options such as initial width and height.</p>
|
||||
|
||||
<h5>Customize Position and Styling with CSS</h5>
|
||||
|
||||
<pre><code>.jcrop-thumb {
|
||||
top: -25px;
|
||||
right: 20px;
|
||||
border: 1px black solid;
|
||||
}</code></pre>
|
||||
|
||||
<p>The absolutely-positioned, sized thumbnail is appended to the Jcrop
|
||||
instance container automatically. It can then be positioned relatively
|
||||
to the container by using top/left/bottom/right CSS values. Styling
|
||||
such as a border or a box shadow can be added if desired.</p>
|
||||
|
||||
<h3>Additional Features</h3>
|
||||
|
||||
<ul><li>Can be locked to an individual Selection object.</li><li>Can be resized using <code>resize(w,h)</code> method.</li></ul>
|
||||
<div class="tapmodo-footer"><a href="http://tapmodo.com" class="tapmodo-logo segment">tapmodo.com</a>
|
||||
<div class="segment"><b>© 2008-2013 Tapmodo Interactive LLC</b>
|
||||
<div>Jcrop is free software released under <a href="../MIT-LICENSE.txt">MIT License</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,122 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Jcrop v2.0.0-RC1 | Jcrop Jcrop</title>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
|
||||
<link rel="stylesheet" href="demos/demo_files/main.css">
|
||||
<link rel="stylesheet" href="demos/demo_files/demos.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<button type="button" data-toggle="collapse" data-target="nav-collapse" class="btn btn-navbar"><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><a class="brand">Jcrop</a>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li><a href="demos/">Demos</a>
|
||||
</li>
|
||||
<li><a href="http://beta.jcrop.org/doc/">Docs</a>
|
||||
</li>
|
||||
<li><a href="http://beta.jcrop.org/contact/">Contact</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="span12">
|
||||
<div class="jc-demo-box">
|
||||
<div class="page-header">
|
||||
<ul class="breadcrumb first">
|
||||
<li><a href="http://jcrop.org/">Jcrop.org</a><span class="divider">/</span></li>
|
||||
<li class="active">Jcrop v2.0.0-RC1</li>
|
||||
</ul>
|
||||
<h1>Jcrop v2.0.0-RC1</h1>
|
||||
</div>
|
||||
<div class="main-menu menu-box">
|
||||
<h3>Jcrop Demos</h3>
|
||||
<ul class="links">
|
||||
<li><a href="demos/basic.html">Hello World</a></li>
|
||||
<li><a href="demos/thumbnail.html">Thumbnail Preview</a></li>
|
||||
<li><a href="demos/panel.html">Feature Panel</a></li>
|
||||
<li><a href="demos/coords.html">Dimensions</a></li>
|
||||
<li><a href="demos/circle.html">Circles</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<p><b>Build Date:</b> Sun Sep 08 2013 02:56:09 GMT+0000 (UTC)</p><h3>What's Included</h3>
|
||||
|
||||
<p>The this archive contains the latest version of <strong>Jcrop</strong>,
|
||||
comprised of the following:</p>
|
||||
|
||||
<ul><li>Latest version of <a href="js/Jcrop.js"><strong>Jcrop.js</strong></a> and <a href="css/Jcrop.css"><strong>Jcrop.css</strong></a>, the primary requisite files</li><li>Minimized versions of both of the above (<a href="js/Jcrop.min.js">Jcrop.min.js</a>, <a href="css/Jcrop.min.css">Jcrop.min.css</a>)</li><li>Several demos are also included, see links in menu at right</li></ul>
|
||||
<hr><h1>Jcrop Image Cropping Plugin</h1>
|
||||
|
||||
<p>Jcrop is the quick and easy way to add image cropping functionality to
|
||||
your web application. It combines the ease-of-use of a typical jQuery
|
||||
plugin with a powerful cross-platform DHTML cropping engine that is
|
||||
faithful to familiar desktop graphics applications.</p>
|
||||
|
||||
<h3>Feature Overview</h3>
|
||||
|
||||
<ul><li>Attaches unobtrusively to any image or block element</li><li>Completely based on true prototypical Javascript objects for extreme flexibility</li><li>Supports multiple active selections, per-selection customization</li><li>Supports aspect ratio locking, minimum/maximum size, and other features</li><li>Acts as in-line form element, can receive focus, tab through</li><li>Keyboard support for nuding selections and trapping other keys</li><li>Inherently API-driven and stylable with CSS</li><li>Mobile touch support for iOS and Android</li></ul>
|
||||
|
||||
<h3>Cross-platform Compatibility</h3>
|
||||
|
||||
<p>The current version of Jcrop has been cross-platform tested and core functionality
|
||||
works in all the following browsers:</p>
|
||||
|
||||
<ul><li>Firefox 3+</li><li>Safari 4+</li><li>Opera 9.5+</li><li>Google Chrome 14+</li><li>Internet Explorer 7+</li></ul>
|
||||
|
||||
<p>Older versions of some browsers may also work.</p>
|
||||
|
||||
<p>Always thoroughly test any desired functionality on all target platforms and devices.</p>
|
||||
|
||||
<h5>Legacy IE Compatibility</h5>
|
||||
|
||||
<p>Internet Explorer 6 suffers some visual problems with the new CSS structure
|
||||
and will not be explicitly supported from v2.x and up. Currently Jcrop can still
|
||||
be used in IE6, it just looks ugly. IE7 and newer versions deliver a nearly flawless
|
||||
Jcrop experience.</p>
|
||||
|
||||
<hr/>
|
||||
|
||||
<h2>MIT License</h2>
|
||||
|
||||
<p><strong>Jcrop is free software under MIT License.</strong></p>
|
||||
|
||||
<h4>Copyright (c) 2008-2015 Tapmodo Interactive LLC</h4>
|
||||
|
||||
<h5><a href="http://github.com/tapmodo/Jcrop">http://github.com/tapmodo/Jcrop</a></h5>
|
||||
|
||||
<p>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:</p>
|
||||
|
||||
<p>The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.</p>
|
||||
|
||||
<p>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.</p>
|
||||
<div class="tapmodo-footer"><a href="http://tapmodo.com" class="tapmodo-logo segment">tapmodo.com</a>
|
||||
<div class="segment"><b>© 2008-2015 Tapmodo Interactive LLC</b>
|
||||
<div>Jcrop is free software released under <a href="../MIT-LICENSE.txt">MIT License</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
+6
File diff suppressed because one or more lines are too long
@@ -0,0 +1,661 @@
|
||||
/*!
|
||||
* jQuery Color Animations v2.0pre
|
||||
* http://jquery.org/
|
||||
*
|
||||
* Copyright 2011 John Resig
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*/
|
||||
|
||||
(function( jQuery, undefined ){
|
||||
var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color outlineColor".split(" "),
|
||||
|
||||
// plusequals test for += 100 -= 100
|
||||
rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
|
||||
// a set of RE's that can match strings and generate color tuples.
|
||||
stringParsers = [{
|
||||
re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
|
||||
parse: function( execResult ) {
|
||||
return [
|
||||
execResult[ 1 ],
|
||||
execResult[ 2 ],
|
||||
execResult[ 3 ],
|
||||
execResult[ 4 ]
|
||||
];
|
||||
}
|
||||
}, {
|
||||
re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
|
||||
parse: function( execResult ) {
|
||||
return [
|
||||
2.55 * execResult[1],
|
||||
2.55 * execResult[2],
|
||||
2.55 * execResult[3],
|
||||
execResult[ 4 ]
|
||||
];
|
||||
}
|
||||
}, {
|
||||
re: /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/,
|
||||
parse: function( execResult ) {
|
||||
return [
|
||||
parseInt( execResult[ 1 ], 16 ),
|
||||
parseInt( execResult[ 2 ], 16 ),
|
||||
parseInt( execResult[ 3 ], 16 )
|
||||
];
|
||||
}
|
||||
}, {
|
||||
re: /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/,
|
||||
parse: function( execResult ) {
|
||||
return [
|
||||
parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
|
||||
parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
|
||||
parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
|
||||
];
|
||||
}
|
||||
}, {
|
||||
re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
|
||||
space: "hsla",
|
||||
parse: function( execResult ) {
|
||||
return [
|
||||
execResult[1],
|
||||
execResult[2] / 100,
|
||||
execResult[3] / 100,
|
||||
execResult[4]
|
||||
];
|
||||
}
|
||||
}],
|
||||
|
||||
// jQuery.Color( )
|
||||
color = jQuery.Color = function( color, green, blue, alpha ) {
|
||||
return new jQuery.Color.fn.parse( color, green, blue, alpha );
|
||||
},
|
||||
spaces = {
|
||||
rgba: {
|
||||
cache: "_rgba",
|
||||
props: {
|
||||
red: {
|
||||
idx: 0,
|
||||
type: "byte",
|
||||
empty: true
|
||||
},
|
||||
green: {
|
||||
idx: 1,
|
||||
type: "byte",
|
||||
empty: true
|
||||
},
|
||||
blue: {
|
||||
idx: 2,
|
||||
type: "byte",
|
||||
empty: true
|
||||
},
|
||||
alpha: {
|
||||
idx: 3,
|
||||
type: "percent",
|
||||
def: 1
|
||||
}
|
||||
}
|
||||
},
|
||||
hsla: {
|
||||
cache: "_hsla",
|
||||
props: {
|
||||
hue: {
|
||||
idx: 0,
|
||||
type: "degrees",
|
||||
empty: true
|
||||
},
|
||||
saturation: {
|
||||
idx: 1,
|
||||
type: "percent",
|
||||
empty: true
|
||||
},
|
||||
lightness: {
|
||||
idx: 2,
|
||||
type: "percent",
|
||||
empty: true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
propTypes = {
|
||||
"byte": {
|
||||
floor: true,
|
||||
min: 0,
|
||||
max: 255
|
||||
},
|
||||
"percent": {
|
||||
min: 0,
|
||||
max: 1
|
||||
},
|
||||
"degrees": {
|
||||
mod: 360,
|
||||
floor: true
|
||||
}
|
||||
},
|
||||
rgbaspace = spaces.rgba.props,
|
||||
support = color.support = {},
|
||||
|
||||
// colors = jQuery.Color.names
|
||||
colors,
|
||||
|
||||
// local aliases of functions called often
|
||||
each = jQuery.each;
|
||||
|
||||
spaces.hsla.props.alpha = rgbaspace.alpha;
|
||||
|
||||
function clamp( value, prop, alwaysAllowEmpty ) {
|
||||
var type = propTypes[ prop.type ] || {},
|
||||
allowEmpty = prop.empty || alwaysAllowEmpty;
|
||||
|
||||
if ( allowEmpty && value == null ) {
|
||||
return null;
|
||||
}
|
||||
if ( prop.def && value == null ) {
|
||||
return prop.def;
|
||||
}
|
||||
if ( type.floor ) {
|
||||
value = ~~value;
|
||||
} else {
|
||||
value = parseFloat( value );
|
||||
}
|
||||
if ( value == null || isNaN( value ) ) {
|
||||
return prop.def;
|
||||
}
|
||||
if ( type.mod ) {
|
||||
value = value % type.mod;
|
||||
// -10 -> 350
|
||||
return value < 0 ? type.mod + value : value;
|
||||
}
|
||||
|
||||
// for now all property types without mod have min and max
|
||||
return type.min > value ? type.min : type.max < value ? type.max : value;
|
||||
}
|
||||
|
||||
function stringParse( string ) {
|
||||
var inst = color(),
|
||||
rgba = inst._rgba = [];
|
||||
|
||||
string = string.toLowerCase();
|
||||
|
||||
each( stringParsers, function( i, parser ) {
|
||||
var match = parser.re.exec( string ),
|
||||
values = match && parser.parse( match ),
|
||||
parsed,
|
||||
spaceName = parser.space || "rgba",
|
||||
cache = spaces[ spaceName ].cache;
|
||||
|
||||
|
||||
if ( values ) {
|
||||
parsed = inst[ spaceName ]( values );
|
||||
|
||||
// if this was an rgba parse the assignment might happen twice
|
||||
// oh well....
|
||||
inst[ cache ] = parsed[ cache ];
|
||||
rgba = inst._rgba = parsed._rgba;
|
||||
|
||||
// exit each( stringParsers ) here because we matched
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// Found a stringParser that handled it
|
||||
if ( rgba.length !== 0 ) {
|
||||
|
||||
// if this came from a parsed string, force "transparent" when alpha is 0
|
||||
// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
|
||||
if ( Math.max.apply( Math, rgba ) === 0 ) {
|
||||
jQuery.extend( rgba, colors.transparent );
|
||||
}
|
||||
return inst;
|
||||
}
|
||||
|
||||
// named colors / default - filter back through parse function
|
||||
if ( string = colors[ string ] ) {
|
||||
return string;
|
||||
}
|
||||
}
|
||||
|
||||
color.fn = color.prototype = {
|
||||
constructor: color,
|
||||
parse: function( red, green, blue, alpha ) {
|
||||
if ( red === undefined ) {
|
||||
this._rgba = [ null, null, null, null ];
|
||||
return this;
|
||||
}
|
||||
if ( red instanceof jQuery || red.nodeType ) {
|
||||
red = red instanceof jQuery ? red.css( green ) : jQuery( red ).css( green );
|
||||
green = undefined;
|
||||
}
|
||||
|
||||
var inst = this,
|
||||
type = jQuery.type( red ),
|
||||
rgba = this._rgba = [],
|
||||
source;
|
||||
|
||||
// more than 1 argument specified - assume ( red, green, blue, alpha )
|
||||
if ( green !== undefined ) {
|
||||
red = [ red, green, blue, alpha ];
|
||||
type = "array";
|
||||
}
|
||||
|
||||
if ( type === "string" ) {
|
||||
return this.parse( stringParse( red ) || colors._default );
|
||||
}
|
||||
|
||||
if ( type === "array" ) {
|
||||
each( rgbaspace, function( key, prop ) {
|
||||
rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
if ( type === "object" ) {
|
||||
if ( red instanceof color ) {
|
||||
each( spaces, function( spaceName, space ) {
|
||||
if ( red[ space.cache ] ) {
|
||||
inst[ space.cache ] = red[ space.cache ].slice();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
each( spaces, function( spaceName, space ) {
|
||||
each( space.props, function( key, prop ) {
|
||||
var cache = space.cache;
|
||||
|
||||
// if the cache doesn't exist, and we know how to convert
|
||||
if ( !inst[ cache ] && space.to ) {
|
||||
|
||||
// if the value was null, we don't need to copy it
|
||||
// if the key was alpha, we don't need to copy it either
|
||||
if ( red[ key ] == null || key === "alpha") {
|
||||
return;
|
||||
}
|
||||
inst[ cache ] = space.to( inst._rgba );
|
||||
}
|
||||
|
||||
// this is the only case where we allow nulls for ALL properties.
|
||||
// call clamp with alwaysAllowEmpty
|
||||
inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
|
||||
});
|
||||
});
|
||||
}
|
||||
return this;
|
||||
}
|
||||
},
|
||||
is: function( compare ) {
|
||||
var is = color( compare ),
|
||||
same = true,
|
||||
myself = this;
|
||||
|
||||
each( spaces, function( _, space ) {
|
||||
var isCache = is[ space.cache ],
|
||||
localCache;
|
||||
if (isCache) {
|
||||
localCache = myself[ space.cache ] || space.to && space.to( myself._rgba ) || [];
|
||||
each( space.props, function( _, prop ) {
|
||||
if ( isCache[ prop.idx ] != null ) {
|
||||
same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
|
||||
return same;
|
||||
}
|
||||
});
|
||||
}
|
||||
return same;
|
||||
});
|
||||
return same;
|
||||
},
|
||||
_space: function() {
|
||||
var used = [],
|
||||
inst = this;
|
||||
each( spaces, function( spaceName, space ) {
|
||||
if ( inst[ space.cache ] ) {
|
||||
used.push( spaceName );
|
||||
}
|
||||
});
|
||||
return used.pop();
|
||||
},
|
||||
transition: function( other, distance ) {
|
||||
var end = color( other ),
|
||||
spaceName = end._space(),
|
||||
space = spaces[ spaceName ],
|
||||
start = this[ space.cache ] || space.to( this._rgba ),
|
||||
result = start.slice();
|
||||
|
||||
end = end[ space.cache ];
|
||||
each( space.props, function( key, prop ) {
|
||||
var index = prop.idx,
|
||||
startValue = start[ index ],
|
||||
endValue = end[ index ],
|
||||
type = propTypes[ prop.type ] || {};
|
||||
|
||||
// if null, don't override start value
|
||||
if ( endValue === null ) {
|
||||
return;
|
||||
}
|
||||
// if null - use end
|
||||
if ( startValue === null ) {
|
||||
result[ index ] = endValue;
|
||||
} else {
|
||||
if ( type.mod ) {
|
||||
if ( endValue - startValue > type.mod / 2 ) {
|
||||
startValue += type.mod;
|
||||
} else if ( startValue - endValue > type.mod / 2 ) {
|
||||
startValue -= type.mod;
|
||||
}
|
||||
}
|
||||
result[ prop.idx ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
|
||||
}
|
||||
});
|
||||
return this[ spaceName ]( result );
|
||||
},
|
||||
blend: function( opaque ) {
|
||||
// if we are already opaque - return ourself
|
||||
if ( this._rgba[ 3 ] === 1 ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
var rgb = this._rgba.slice(),
|
||||
a = rgb.pop(),
|
||||
blend = color( opaque )._rgba;
|
||||
|
||||
return color( jQuery.map( rgb, function( v, i ) {
|
||||
return ( 1 - a ) * blend[ i ] + a * v;
|
||||
}));
|
||||
},
|
||||
toRgbaString: function() {
|
||||
var prefix = "rgba(",
|
||||
rgba = jQuery.map( this._rgba, function( v, i ) {
|
||||
return v == null ? ( i > 2 ? 1 : 0 ) : v;
|
||||
});
|
||||
|
||||
if ( rgba[ 3 ] === 1 ) {
|
||||
rgba.pop();
|
||||
prefix = "rgb(";
|
||||
}
|
||||
|
||||
return prefix + rgba.join(",") + ")";
|
||||
},
|
||||
toHslaString: function() {
|
||||
var prefix = "hsla(",
|
||||
hsla = jQuery.map( this.hsla(), function( v, i ) {
|
||||
if ( v == null ) {
|
||||
v = i > 2 ? 1 : 0;
|
||||
}
|
||||
|
||||
// catch 1 and 2
|
||||
if ( i && i < 3 ) {
|
||||
v = Math.round( v * 100 ) + "%";
|
||||
}
|
||||
return v;
|
||||
});
|
||||
|
||||
if ( hsla[ 3 ] === 1 ) {
|
||||
hsla.pop();
|
||||
prefix = "hsl(";
|
||||
}
|
||||
return prefix + hsla.join(",") + ")";
|
||||
},
|
||||
toHexString: function( includeAlpha ) {
|
||||
var rgba = this._rgba.slice(),
|
||||
alpha = rgba.pop();
|
||||
|
||||
if ( includeAlpha ) {
|
||||
rgba.push( ~~( alpha * 255 ) );
|
||||
}
|
||||
|
||||
return "#" + jQuery.map( rgba, function( v, i ) {
|
||||
|
||||
// default to 0 when nulls exist
|
||||
v = ( v || 0 ).toString( 16 );
|
||||
return v.length === 1 ? "0" + v : v;
|
||||
}).join("");
|
||||
},
|
||||
toString: function() {
|
||||
return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
|
||||
}
|
||||
};
|
||||
color.fn.parse.prototype = color.fn;
|
||||
|
||||
// hsla conversions adapted from:
|
||||
// http://www.google.com/codesearch/p#OAMlx_jo-ck/src/third_party/WebKit/Source/WebCore/inspector/front-end/Color.js&d=7&l=193
|
||||
|
||||
function hue2rgb( p, q, h ) {
|
||||
h = ( h + 1 ) % 1;
|
||||
if ( h * 6 < 1 ) {
|
||||
return p + (q - p) * 6 * h;
|
||||
}
|
||||
if ( h * 2 < 1) {
|
||||
return q;
|
||||
}
|
||||
if ( h * 3 < 2 ) {
|
||||
return p + (q - p) * ((2/3) - h) * 6;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
spaces.hsla.to = function ( rgba ) {
|
||||
if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
|
||||
return [ null, null, null, rgba[ 3 ] ];
|
||||
}
|
||||
var r = rgba[ 0 ] / 255,
|
||||
g = rgba[ 1 ] / 255,
|
||||
b = rgba[ 2 ] / 255,
|
||||
a = rgba[ 3 ],
|
||||
max = Math.max( r, g, b ),
|
||||
min = Math.min( r, g, b ),
|
||||
diff = max - min,
|
||||
add = max + min,
|
||||
l = add * 0.5,
|
||||
h, s;
|
||||
|
||||
if ( min === max ) {
|
||||
h = 0;
|
||||
} else if ( r === max ) {
|
||||
h = ( 60 * ( g - b ) / diff ) + 360;
|
||||
} else if ( g === max ) {
|
||||
h = ( 60 * ( b - r ) / diff ) + 120;
|
||||
} else {
|
||||
h = ( 60 * ( r - g ) / diff ) + 240;
|
||||
}
|
||||
|
||||
if ( l === 0 || l === 1 ) {
|
||||
s = l;
|
||||
} else if ( l <= 0.5 ) {
|
||||
s = diff / add;
|
||||
} else {
|
||||
s = diff / ( 2 - add );
|
||||
}
|
||||
return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
|
||||
};
|
||||
|
||||
spaces.hsla.from = function ( hsla ) {
|
||||
if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
|
||||
return [ null, null, null, hsla[ 3 ] ];
|
||||
}
|
||||
var h = hsla[ 0 ] / 360,
|
||||
s = hsla[ 1 ],
|
||||
l = hsla[ 2 ],
|
||||
a = hsla[ 3 ],
|
||||
q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
|
||||
p = 2 * l - q,
|
||||
r, g, b;
|
||||
|
||||
return [
|
||||
Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
|
||||
Math.round( hue2rgb( p, q, h ) * 255 ),
|
||||
Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
|
||||
a
|
||||
];
|
||||
};
|
||||
|
||||
|
||||
each( spaces, function( spaceName, space ) {
|
||||
var props = space.props,
|
||||
cache = space.cache,
|
||||
to = space.to,
|
||||
from = space.from;
|
||||
|
||||
// makes rgba() and hsla()
|
||||
color.fn[ spaceName ] = function( value ) {
|
||||
|
||||
// generate a cache for this space if it doesn't exist
|
||||
if ( to && !this[ cache ] ) {
|
||||
this[ cache ] = to( this._rgba );
|
||||
}
|
||||
if ( value === undefined ) {
|
||||
return this[ cache ].slice();
|
||||
}
|
||||
|
||||
var type = jQuery.type( value ),
|
||||
arr = ( type === "array" || type === "object" ) ? value : arguments,
|
||||
local = this[ cache ].slice(),
|
||||
ret;
|
||||
|
||||
each( props, function( key, prop ) {
|
||||
var val = arr[ type === "object" ? key : prop.idx ];
|
||||
if ( val == null ) {
|
||||
val = local[ prop.idx ];
|
||||
}
|
||||
local[ prop.idx ] = clamp( val, prop );
|
||||
});
|
||||
|
||||
if ( from ) {
|
||||
ret = color( from( local ) );
|
||||
ret[ cache ] = local;
|
||||
return ret;
|
||||
} else {
|
||||
return color( local );
|
||||
}
|
||||
};
|
||||
|
||||
// makes red() green() blue() alpha() hue() saturation() lightness()
|
||||
each( props, function( key, prop ) {
|
||||
// alpha is included in more than one space
|
||||
if ( color.fn[ key ] ) {
|
||||
return;
|
||||
}
|
||||
color.fn[ key ] = function( value ) {
|
||||
var vtype = jQuery.type( value ),
|
||||
fn = ( key === 'alpha' ? ( this._hsla ? 'hsla' : 'rgba' ) : spaceName ),
|
||||
local = this[ fn ](),
|
||||
cur = local[ prop.idx ],
|
||||
match;
|
||||
|
||||
if ( vtype === "undefined" ) {
|
||||
return cur;
|
||||
}
|
||||
|
||||
if ( vtype === "function" ) {
|
||||
value = value.call( this, cur );
|
||||
vtype = jQuery.type( value );
|
||||
}
|
||||
if ( value == null && prop.empty ) {
|
||||
return this;
|
||||
}
|
||||
if ( vtype === "string" ) {
|
||||
match = rplusequals.exec( value );
|
||||
if ( match ) {
|
||||
value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
|
||||
}
|
||||
}
|
||||
local[ prop.idx ] = value;
|
||||
return this[ fn ]( local );
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
// add .fx.step functions
|
||||
each( stepHooks, function( i, hook ) {
|
||||
jQuery.cssHooks[ hook ] = {
|
||||
set: function( elem, value ) {
|
||||
var parsed, backgroundColor, curElem;
|
||||
|
||||
if ( jQuery.type( value ) !== 'string' || ( parsed = stringParse( value ) ) )
|
||||
{
|
||||
value = color( parsed || value );
|
||||
if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
|
||||
curElem = hook === "backgroundColor" ? elem.parentNode : elem;
|
||||
do {
|
||||
backgroundColor = jQuery.curCSS( curElem, "backgroundColor" );
|
||||
} while (
|
||||
( backgroundColor === "" || backgroundColor === "transparent" ) &&
|
||||
( curElem = curElem.parentNode ) &&
|
||||
curElem.style
|
||||
);
|
||||
|
||||
value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
|
||||
backgroundColor :
|
||||
"_default" );
|
||||
}
|
||||
|
||||
value = value.toRgbaString();
|
||||
}
|
||||
elem.style[ hook ] = value;
|
||||
}
|
||||
};
|
||||
jQuery.fx.step[ hook ] = function( fx ) {
|
||||
if ( !fx.colorInit ) {
|
||||
fx.start = color( fx.elem, hook );
|
||||
fx.end = color( fx.end );
|
||||
fx.colorInit = true;
|
||||
}
|
||||
jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
|
||||
};
|
||||
});
|
||||
|
||||
// detect rgba support
|
||||
jQuery(function() {
|
||||
var div = document.createElement( "div" ),
|
||||
div_style = div.style;
|
||||
|
||||
div_style.cssText = "background-color:rgba(1,1,1,.5)";
|
||||
support.rgba = div_style.backgroundColor.indexOf( "rgba" ) > -1;
|
||||
});
|
||||
|
||||
// Some named colors to work with
|
||||
// From Interface by Stefan Petre
|
||||
// http://interface.eyecon.ro/
|
||||
colors = jQuery.Color.names = {
|
||||
aqua: "#00ffff",
|
||||
azure: "#f0ffff",
|
||||
beige: "#f5f5dc",
|
||||
black: "#000000",
|
||||
blue: "#0000ff",
|
||||
brown: "#a52a2a",
|
||||
cyan: "#00ffff",
|
||||
darkblue: "#00008b",
|
||||
darkcyan: "#008b8b",
|
||||
darkgrey: "#a9a9a9",
|
||||
darkgreen: "#006400",
|
||||
darkkhaki: "#bdb76b",
|
||||
darkmagenta: "#8b008b",
|
||||
darkolivegreen: "#556b2f",
|
||||
darkorange: "#ff8c00",
|
||||
darkorchid: "#9932cc",
|
||||
darkred: "#8b0000",
|
||||
darksalmon: "#e9967a",
|
||||
darkviolet: "#9400d3",
|
||||
fuchsia: "#ff00ff",
|
||||
gold: "#ffd700",
|
||||
green: "#008000",
|
||||
indigo: "#4b0082",
|
||||
khaki: "#f0e68c",
|
||||
lightblue: "#add8e6",
|
||||
lightcyan: "#e0ffff",
|
||||
lightgreen: "#90ee90",
|
||||
lightgrey: "#d3d3d3",
|
||||
lightpink: "#ffb6c1",
|
||||
lightyellow: "#ffffe0",
|
||||
lime: "#00ff00",
|
||||
magenta: "#ff00ff",
|
||||
maroon: "#800000",
|
||||
navy: "#000080",
|
||||
olive: "#808000",
|
||||
orange: "#ffa500",
|
||||
pink: "#ffc0cb",
|
||||
purple: "#800080",
|
||||
violet: "#800080",
|
||||
red: "#ff0000",
|
||||
silver: "#c0c0c0",
|
||||
white: "#ffffff",
|
||||
yellow: "#ffff00",
|
||||
transparent: [ null, null, null, 0 ],
|
||||
_default: "#ffffff"
|
||||
};
|
||||
})( jQuery );
|
||||
+4
File diff suppressed because one or more lines are too long
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "Jcrop",
|
||||
"version": "2.0.4",
|
||||
"devDependencies": {
|
||||
"grunt": "^0.4.5",
|
||||
"grunt-banner": "^0.1.4",
|
||||
"grunt-contrib-concat": "^0.3.0",
|
||||
"grunt-contrib-cssmin": "^0.6.2",
|
||||
"grunt-contrib-less": "^0.7.0",
|
||||
"grunt-contrib-uglify": "^0.2.7",
|
||||
"grunt-contrib-watch": "^0.5.3"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
## Javascript source files
|
||||
|
||||
The files in this path are Javascript fragments that are compiled together
|
||||
to create the Jcrop.js source file. Also includes LESS CSS source files.
|
||||
|
||||
##### Building with Grunt
|
||||
|
||||
$ npm install
|
||||
$ grunt
|
||||
|
||||
##### Grunt watch
|
||||
|
||||
The Grunt configuration also includes a watch task using grunt-watch.
|
||||
Using `watch` (in a different terminal) will allow you to modify files
|
||||
and have them automatically recompile when changes are detected.
|
||||
|
||||
$ grunt watch
|
||||
|
||||
Read the [grunt documentation](http://gruntjs.com) for more info.
|
||||
@@ -0,0 +1,352 @@
|
||||
// Jcrop API methods
|
||||
$.extend(Jcrop.prototype,{
|
||||
//init: function(){{{
|
||||
init: function(){
|
||||
this.event = new this.opt.eventManagerComponent(this);
|
||||
this.ui.keyboard = new this.opt.keyboardComponent(this);
|
||||
this.ui.manager = new this.opt.stagemanagerComponent(this);
|
||||
this.applyFilters();
|
||||
|
||||
if ($.Jcrop.supportsTouch)
|
||||
new $.Jcrop.component.Touch(this);
|
||||
|
||||
this.initEvents();
|
||||
},
|
||||
//}}}
|
||||
// applySizeConstraints: function(){{{
|
||||
applySizeConstraints: function(){
|
||||
var o = this.opt,
|
||||
img = this.opt.imgsrc;
|
||||
|
||||
if (img){
|
||||
|
||||
var iw = img.naturalWidth || img.width,
|
||||
ih = img.naturalHeight || img.height,
|
||||
bw = o.boxWidth || iw,
|
||||
bh = o.boxHeight || ih;
|
||||
|
||||
if (img && ((iw > bw) || (ih > bh))){
|
||||
var bx = Jcrop.getLargestBox(iw/ih,bw,bh);
|
||||
$(img).width(bx[0]).height(bx[1]);
|
||||
this.resizeContainer(bx[0],bx[1]);
|
||||
this.opt.xscale = iw / bx[0];
|
||||
this.opt.yscale = ih / bx[1];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (this.opt.trueSize){
|
||||
var dw = this.opt.trueSize[0];
|
||||
var dh = this.opt.trueSize[1];
|
||||
var cs = this.getContainerSize();
|
||||
this.opt.xscale = dw / cs[0];
|
||||
this.opt.yscale = dh / cs[1];
|
||||
}
|
||||
},
|
||||
// }}}
|
||||
initComponent: function(name){
|
||||
if (Jcrop.component[name]) {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var obj = new Jcrop.component[name];
|
||||
args.shift();
|
||||
args.unshift(this);
|
||||
obj.init.apply(obj,args);
|
||||
return obj;
|
||||
}
|
||||
},
|
||||
// setOptions: function(opt){{{
|
||||
setOptions: function(opt,proptype){
|
||||
|
||||
if (!$.isPlainObject(opt)) opt = {};
|
||||
|
||||
$.extend(this.opt,opt);
|
||||
|
||||
// Handle a setSelect value
|
||||
if (this.opt.setSelect) {
|
||||
|
||||
// If there is no current selection
|
||||
// passing setSelect will create one
|
||||
if (!this.ui.multi.length)
|
||||
this.newSelection();
|
||||
|
||||
// Use these values to update the current selection
|
||||
this.setSelect(this.opt.setSelect);
|
||||
|
||||
// Set to null so it doesn't get called again
|
||||
this.opt.setSelect = null;
|
||||
}
|
||||
|
||||
this.event.trigger('configupdate');
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
//destroy: function(){{{
|
||||
destroy: function(){
|
||||
if (this.opt.imgsrc) {
|
||||
this.container.before(this.opt.imgsrc);
|
||||
this.container.remove();
|
||||
$(this.opt.imgsrc).removeData('Jcrop').show();
|
||||
} else {
|
||||
// @todo: more elegant destroy() process for non-image containers
|
||||
this.container.remove();
|
||||
}
|
||||
},
|
||||
// }}}
|
||||
// applyFilters: function(){{{
|
||||
applyFilters: function(){
|
||||
var obj;
|
||||
for(var i=0,f=this.opt.applyFilters,l=f.length; i<l; i++){
|
||||
if ($.Jcrop.filter[f[i]])
|
||||
obj = new $.Jcrop.filter[f[i]];
|
||||
obj.core = this;
|
||||
if (obj.init) obj.init();
|
||||
this.filter[f[i]] = obj;
|
||||
}
|
||||
},
|
||||
// }}}
|
||||
// getDefaultFilters: function(){{{
|
||||
getDefaultFilters: function(){
|
||||
var rv = [];
|
||||
|
||||
for(var i=0,f=this.opt.applyFilters,l=f.length; i<l; i++)
|
||||
if(this.filter.hasOwnProperty(f[i]))
|
||||
rv.push(this.filter[f[i]]);
|
||||
|
||||
rv.sort(function(x,y){ return x.priority - y.priority; });
|
||||
return rv;
|
||||
},
|
||||
// }}}
|
||||
// setSelection: function(sel){{{
|
||||
setSelection: function(sel){
|
||||
var m = this.ui.multi;
|
||||
var n = [];
|
||||
for(var i=0;i<m.length;i++) {
|
||||
if (m[i] !== sel) n.push(m[i]);
|
||||
m[i].toBack();
|
||||
}
|
||||
n.unshift(sel);
|
||||
this.ui.multi = n;
|
||||
this.ui.selection = sel;
|
||||
sel.toFront();
|
||||
return sel;
|
||||
},
|
||||
// }}}
|
||||
// getSelection: function(raw){{{
|
||||
getSelection: function(raw){
|
||||
var b = this.ui.selection.get();
|
||||
return b;
|
||||
},
|
||||
// }}}
|
||||
// newSelection: function(){{{
|
||||
newSelection: function(sel){
|
||||
if (!sel)
|
||||
sel = new this.opt.selectionComponent();
|
||||
|
||||
sel.init(this);
|
||||
this.setSelection(sel);
|
||||
|
||||
return sel;
|
||||
},
|
||||
// }}}
|
||||
// hasSelection: function(sel){{{
|
||||
hasSelection: function(sel){
|
||||
for(var i=0;i<this.ui.multi;i++)
|
||||
if (sel === this.ui.multi[i]) return true;
|
||||
},
|
||||
// }}}
|
||||
// removeSelection: function(sel){{{
|
||||
removeSelection: function(sel){
|
||||
var i, n = [], m = this.ui.multi;
|
||||
for(var i=0;i<m.length;i++){
|
||||
if (sel !== m[i])
|
||||
n.push(m[i]);
|
||||
else m[i].remove();
|
||||
}
|
||||
return this.ui.multi = n;
|
||||
},
|
||||
// }}}
|
||||
//addFilter: function(filter){{{
|
||||
addFilter: function(filter){
|
||||
for(var i=0,m=this.ui.multi,l=m.length; i<l; i++)
|
||||
m[i].addFilter(filter);
|
||||
|
||||
return this;
|
||||
},
|
||||
//}}}
|
||||
// removeFiltersByTag: function(tag){{{
|
||||
removeFilter: function(filter){
|
||||
for(var i=0,m=this.ui.multi,l=m.length; i<l; i++)
|
||||
m[i].removeFilter(filter);
|
||||
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
// blur: function(){{{
|
||||
blur: function(){
|
||||
this.ui.selection.blur();
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
// focus: function(){{{
|
||||
focus: function(){
|
||||
this.ui.selection.focus();
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
//initEvents: function(){{{
|
||||
initEvents: function(){
|
||||
var t = this;
|
||||
t.container.on('selectstart',function(e){ return false; })
|
||||
.on('mousedown','.'+t.opt.css_drag,t.startDrag());
|
||||
},
|
||||
//}}}
|
||||
// maxSelect: function(){{{
|
||||
maxSelect: function(){
|
||||
this.setSelect([0,0,this.elw,this.elh]);
|
||||
},
|
||||
// }}}
|
||||
// nudge: function(x,y){{{
|
||||
nudge: function(x,y){
|
||||
var s = this.ui.selection, b = s.get();
|
||||
|
||||
b.x += x;
|
||||
b.x2 += x;
|
||||
b.y += y;
|
||||
b.y2 += y;
|
||||
|
||||
if (b.x < 0) { b.x2 = b.w; b.x = 0; }
|
||||
else if (b.x2 > this.elw) { b.x2 = this.elw; b.x = b.x2 - b.w; }
|
||||
|
||||
if (b.y < 0) { b.y2 = b.h; b.y = 0; }
|
||||
else if (b.y2 > this.elh) { b.y2 = this.elh; b.y = b.y2 - b.h; }
|
||||
|
||||
s.element.trigger('cropstart',[s,this.unscale(b)]);
|
||||
s.updateRaw(b,'move');
|
||||
s.element.trigger('cropend',[s,this.unscale(b)]);
|
||||
},
|
||||
// }}}
|
||||
// refresh: function(){{{
|
||||
refresh: function(){
|
||||
for(var i=0,s=this.ui.multi,l=s.length;i<l;i++)
|
||||
s[i].refresh();
|
||||
},
|
||||
// }}}
|
||||
// blurAll: function(){{{
|
||||
blurAll: function(){
|
||||
var m = this.ui.multi;
|
||||
for(var i=0;i<m.length;i++) {
|
||||
if (m[i] !== sel) n.push(m[i]);
|
||||
m[i].toBack();
|
||||
}
|
||||
},
|
||||
// }}}
|
||||
// scale: function(b){{{
|
||||
scale: function(b){
|
||||
var xs = this.opt.xscale,
|
||||
ys = this.opt.yscale;
|
||||
|
||||
return {
|
||||
x: b.x / xs,
|
||||
y: b.y / ys,
|
||||
x2: b.x2 / xs,
|
||||
y2: b.y2 / ys,
|
||||
w: b.w / xs,
|
||||
h: b.h / ys
|
||||
};
|
||||
},
|
||||
// }}}
|
||||
// unscale: function(b){{{
|
||||
unscale: function(b){
|
||||
var xs = this.opt.xscale,
|
||||
ys = this.opt.yscale;
|
||||
|
||||
return {
|
||||
x: b.x * xs,
|
||||
y: b.y * ys,
|
||||
x2: b.x2 * xs,
|
||||
y2: b.y2 * ys,
|
||||
w: b.w * xs,
|
||||
h: b.h * ys
|
||||
};
|
||||
},
|
||||
// }}}
|
||||
// requestDelete: function(){{{
|
||||
requestDelete: function(){
|
||||
if ((this.ui.multi.length > 1) && (this.ui.selection.canDelete))
|
||||
return this.deleteSelection();
|
||||
},
|
||||
// }}}
|
||||
// deleteSelection: function(){{{
|
||||
deleteSelection: function(){
|
||||
if (this.ui.selection) {
|
||||
this.removeSelection(this.ui.selection);
|
||||
if (this.ui.multi.length) this.ui.multi[0].focus();
|
||||
this.ui.selection.refresh();
|
||||
}
|
||||
},
|
||||
// }}}
|
||||
// animateTo: function(box){{{
|
||||
animateTo: function(box){
|
||||
if (this.ui.selection)
|
||||
this.ui.selection.animateTo(box);
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
// setselect: function(box){{{
|
||||
setSelect: function(box){
|
||||
if (this.ui.selection)
|
||||
this.ui.selection.update(Jcrop.wrapFromXywh(box));
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
//startDrag: function(){{{
|
||||
startDrag: function(){
|
||||
var t = this;
|
||||
return function(e){
|
||||
var $targ = $(e.target);
|
||||
var selection = $targ.closest('.'+t.opt.css_selection).data('selection');
|
||||
var ord = $targ.data('ord');
|
||||
t.container.trigger('cropstart',[selection,t.unscale(selection.get())]);
|
||||
selection.startDrag(e,ord);
|
||||
return false;
|
||||
};
|
||||
},
|
||||
//}}}
|
||||
// getContainerSize: function(){{{
|
||||
getContainerSize: function(){
|
||||
return [ this.container.width(), this.container.height() ];
|
||||
},
|
||||
// }}}
|
||||
// resizeContainer: function(w,h){{{
|
||||
resizeContainer: function(w,h){
|
||||
this.container.width(w).height(h);
|
||||
this.refresh();
|
||||
},
|
||||
// }}}
|
||||
// setImage: function(src,cb){{{
|
||||
setImage: function(src,cb){
|
||||
var t = this, targ = t.opt.imgsrc;
|
||||
|
||||
if (!targ) return false;
|
||||
|
||||
new $.Jcrop.component.ImageLoader(src,null,function(w,h){
|
||||
t.resizeContainer(w,h);
|
||||
|
||||
targ.src = src;
|
||||
$(targ).width(w).height(h);
|
||||
t.applySizeConstraints();
|
||||
t.refresh();
|
||||
t.container.trigger('cropimage',[t,targ]);
|
||||
|
||||
if (typeof cb == 'function')
|
||||
cb.call(t,w,h);
|
||||
});
|
||||
},
|
||||
// }}}
|
||||
// update: function(b){{{
|
||||
update: function(b){
|
||||
if (this.ui.selection)
|
||||
this.ui.selection.update(b);
|
||||
}
|
||||
// }}}
|
||||
});
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* CanvasAnimator
|
||||
* manages smooth cropping animation
|
||||
*
|
||||
* This object is called internally to manage animation.
|
||||
* An in-memory div is animated and a progress callback
|
||||
* is used to update the selection coordinates of the
|
||||
* visible selection in realtime.
|
||||
*/
|
||||
var CanvasAnimator = function(stage){
|
||||
this.stage = stage;
|
||||
this.core = stage.core;
|
||||
this.cloneStagePosition();
|
||||
};
|
||||
|
||||
CanvasAnimator.prototype = {
|
||||
|
||||
cloneStagePosition: function(){
|
||||
var s = this.stage;
|
||||
this.angle = s.angle;
|
||||
this.scale = s.scale;
|
||||
this.offset = s.offset;
|
||||
},
|
||||
|
||||
getElement: function(){
|
||||
var s = this.stage;
|
||||
|
||||
return $('<div />')
|
||||
.css({
|
||||
position: 'absolute',
|
||||
top: s.offset[0]+'px',
|
||||
left: s.offset[1]+'px',
|
||||
width: s.angle+'px',
|
||||
height: s.scale+'px'
|
||||
});
|
||||
},
|
||||
|
||||
animate: function(cb){
|
||||
var t = this;
|
||||
|
||||
this.scale = this.stage.boundScale(this.scale);
|
||||
t.stage.triggerEvent('croprotstart');
|
||||
|
||||
t.getElement().animate({
|
||||
top: t.offset[0]+'px',
|
||||
left: t.offset[1]+'px',
|
||||
width: t.angle+'px',
|
||||
height: t.scale+'px'
|
||||
},{
|
||||
easing: t.core.opt.animEasing,
|
||||
duration: t.core.opt.animDuration,
|
||||
complete: function(){
|
||||
t.stage.triggerEvent('croprotend');
|
||||
(typeof cb == 'function') && cb.call(this);
|
||||
},
|
||||
progress: function(anim){
|
||||
var props = {}, i, tw = anim.tweens;
|
||||
|
||||
for(i=0;i<tw.length;i++){
|
||||
props[tw[i].prop] = tw[i].now; }
|
||||
|
||||
t.stage.setAngle(props.width)
|
||||
.setScale(props.height)
|
||||
.setOffset(props.top,props.left)
|
||||
.redraw();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
Jcrop.stage.Canvas.prototype.getAnimator = function(){
|
||||
return new CanvasAnimator(this);
|
||||
};
|
||||
Jcrop.registerComponent('CanvasAnimator',CanvasAnimator);
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* CropAnimator
|
||||
* manages smooth cropping animation
|
||||
*
|
||||
* This object is called internally to manage animation.
|
||||
* An in-memory div is animated and a progress callback
|
||||
* is used to update the selection coordinates of the
|
||||
* visible selection in realtime.
|
||||
*/
|
||||
// var CropAnimator = function(selection){{{
|
||||
var CropAnimator = function(selection){
|
||||
this.selection = selection;
|
||||
this.core = selection.core;
|
||||
};
|
||||
// }}}
|
||||
|
||||
CropAnimator.prototype = {
|
||||
|
||||
getElement: function(){
|
||||
var b = this.selection.get();
|
||||
|
||||
return $('<div />')
|
||||
.css({
|
||||
position: 'absolute',
|
||||
top: b.y+'px',
|
||||
left: b.x+'px',
|
||||
width: b.w+'px',
|
||||
height: b.h+'px'
|
||||
});
|
||||
},
|
||||
|
||||
animate: function(x,y,w,h,cb){
|
||||
var t = this;
|
||||
|
||||
t.selection.allowResize(false);
|
||||
|
||||
t.getElement().animate({
|
||||
top: y+'px',
|
||||
left: x+'px',
|
||||
width: w+'px',
|
||||
height: h+'px'
|
||||
},{
|
||||
easing: t.core.opt.animEasing,
|
||||
duration: t.core.opt.animDuration,
|
||||
complete: function(){
|
||||
t.selection.allowResize(true);
|
||||
cb && cb.call(this);
|
||||
},
|
||||
progress: function(anim){
|
||||
var props = {}, i, tw = anim.tweens;
|
||||
|
||||
for(i=0;i<tw.length;i++){
|
||||
props[tw[i].prop] = tw[i].now; }
|
||||
|
||||
var b = {
|
||||
x: parseInt(props.left),
|
||||
y: parseInt(props.top),
|
||||
w: parseInt(props.width),
|
||||
h: parseInt(props.height)
|
||||
};
|
||||
|
||||
b.x2 = b.x + b.w;
|
||||
b.y2 = b.y + b.h;
|
||||
|
||||
t.selection.updateRaw(b,'se');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
Jcrop.registerComponent('Animator',CropAnimator);
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* DialDrag component
|
||||
* This is a little hacky, it was adapted from some previous/old code
|
||||
* Plan to update this API in the future
|
||||
*/
|
||||
var DialDrag = function() { };
|
||||
|
||||
DialDrag.prototype = {
|
||||
|
||||
init: function(core,actuator,callback){
|
||||
var that = this;
|
||||
|
||||
if (!actuator) actuator = core.container;
|
||||
this.$btn = $(actuator);
|
||||
this.$targ = $(actuator);
|
||||
this.core = core;
|
||||
|
||||
this.$btn
|
||||
.addClass('dialdrag')
|
||||
.on('mousedown.dialdrag',this.mousedown())
|
||||
.data('dialdrag',this);
|
||||
|
||||
if (!$.isFunction(callback)) callback = function(){ };
|
||||
this.callback = callback;
|
||||
this.ondone = callback;
|
||||
},
|
||||
|
||||
remove: function(){
|
||||
this.$btn
|
||||
.removeClass('dialdrag')
|
||||
.off('.dialdrag')
|
||||
.data('dialdrag',null);
|
||||
return this;
|
||||
},
|
||||
|
||||
setTarget: function(obj){
|
||||
this.$targ = $(obj);
|
||||
return this;
|
||||
},
|
||||
|
||||
getOffset: function(){
|
||||
var targ = this.$targ, pos = targ.offset();
|
||||
return [
|
||||
pos.left + (targ.width()/2),
|
||||
pos.top + (targ.height()/2)
|
||||
];
|
||||
},
|
||||
|
||||
relMouse: function(e){
|
||||
var x = e.pageX - this.offset[0],
|
||||
y = e.pageY - this.offset[1],
|
||||
ang = Math.atan2(y,x) * (180 / Math.PI),
|
||||
vec = Math.sqrt(Math.pow(x,2)+Math.pow(y,2));
|
||||
return [ x, y, ang, vec ];
|
||||
},
|
||||
|
||||
mousedown: function(){
|
||||
var that = this;
|
||||
|
||||
function mouseUp(e){
|
||||
$(window).off('.dialdrag');
|
||||
that.ondone.call(that,that.relMouse(e));
|
||||
that.core.container.trigger('croprotend');
|
||||
}
|
||||
|
||||
function mouseMove(e){
|
||||
that.callback.call(that,that.relMouse(e));
|
||||
}
|
||||
|
||||
return function(e) {
|
||||
that.offset = that.getOffset();
|
||||
var rel = that.relMouse(e);
|
||||
that.angleOffset = -that.core.ui.stage.angle+rel[2];
|
||||
that.distOffset = rel[3];
|
||||
that.dragOffset = [rel[0],rel[1]];
|
||||
that.core.container.trigger('croprotstart');
|
||||
|
||||
$(window)
|
||||
.on('mousemove.dialdrag',mouseMove)
|
||||
.on('mouseup.dialdrag',mouseUp);
|
||||
|
||||
that.callback.call(that,that.relMouse(e));
|
||||
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
Jcrop.registerComponent('DialDrag',DialDrag);
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
/**
|
||||
* DragState
|
||||
* an object that handles dragging events
|
||||
*
|
||||
* This object is used by the built-in selection object to
|
||||
* track a dragging operation on a selection
|
||||
*/
|
||||
// var DragState = function(e,selection,ord){{{
|
||||
var DragState = function(e,selection,ord){
|
||||
var t = this;
|
||||
|
||||
t.x = e.pageX;
|
||||
t.y = e.pageY;
|
||||
|
||||
t.selection = selection;
|
||||
t.eventTarget = selection.core.opt.dragEventTarget;
|
||||
t.orig = selection.get();
|
||||
|
||||
selection.callFilterFunction('refresh');
|
||||
|
||||
var p = selection.core.container.position();
|
||||
t.elx = p.left;
|
||||
t.ely = p.top;
|
||||
|
||||
t.offsetx = 0;
|
||||
t.offsety = 0;
|
||||
t.ord = ord;
|
||||
t.opposite = t.getOppositeCornerOffset();
|
||||
|
||||
t.initEvents(e);
|
||||
|
||||
};
|
||||
// }}}
|
||||
|
||||
DragState.prototype = {
|
||||
// getOppositeCornerOffset: function(){{{
|
||||
// Calculate relative offset of locked corner
|
||||
getOppositeCornerOffset: function(){
|
||||
|
||||
var o = this.orig;
|
||||
var relx = this.x - this.elx - o.x;
|
||||
var rely = this.y - this.ely - o.y;
|
||||
|
||||
switch(this.ord){
|
||||
case 'nw':
|
||||
case 'w':
|
||||
return [ o.w - relx, o.h - rely ];
|
||||
return [ o.x + o.w, o.y + o.h ];
|
||||
|
||||
case 'sw':
|
||||
return [ o.w - relx, -rely ];
|
||||
return [ o.x + o.w, o.y ];
|
||||
|
||||
case 'se':
|
||||
case 's':
|
||||
case 'e':
|
||||
return [ -relx, -rely ];
|
||||
return [ o.x, o.y ];
|
||||
|
||||
case 'ne':
|
||||
case 'n':
|
||||
return [ -relx, o.h - rely ];
|
||||
return [ o.w, o.y + o.h ];
|
||||
}
|
||||
|
||||
return [ null, null ];
|
||||
},
|
||||
// }}}
|
||||
// initEvents: function(e){{{
|
||||
initEvents: function(e){
|
||||
$(this.eventTarget)
|
||||
.on('mousemove.jcrop',this.createDragHandler())
|
||||
.on('mouseup.jcrop',this.createStopHandler());
|
||||
},
|
||||
// }}}
|
||||
// dragEvent: function(e){{{
|
||||
dragEvent: function(e){
|
||||
this.offsetx = e.pageX - this.x;
|
||||
this.offsety = e.pageY - this.y;
|
||||
this.selection.updateRaw(this.getBox(),this.ord);
|
||||
},
|
||||
// }}}
|
||||
// endDragEvent: function(e){{{
|
||||
endDragEvent: function(e){
|
||||
var sel = this.selection;
|
||||
sel.core.container.removeClass('jcrop-dragging');
|
||||
sel.element.trigger('cropend',[sel,sel.core.unscale(sel.get())]);
|
||||
sel.focus();
|
||||
},
|
||||
// }}}
|
||||
// createStopHandler: function(){{{
|
||||
createStopHandler: function(){
|
||||
var t = this;
|
||||
return function(e){
|
||||
$(t.eventTarget).off('.jcrop');
|
||||
t.endDragEvent(e);
|
||||
return false;
|
||||
};
|
||||
},
|
||||
// }}}
|
||||
// createDragHandler: function(){{{
|
||||
createDragHandler: function(){
|
||||
var t = this;
|
||||
return function(e){
|
||||
t.dragEvent(e);
|
||||
return false;
|
||||
};
|
||||
},
|
||||
// }}}
|
||||
//update: function(x,y){{{
|
||||
update: function(x,y){
|
||||
var t = this;
|
||||
t.offsetx = x - t.x;
|
||||
t.offsety = y - t.y;
|
||||
},
|
||||
//}}}
|
||||
//resultWrap: function(d){{{
|
||||
resultWrap: function(d){
|
||||
var b = {
|
||||
x: Math.min(d[0],d[2]),
|
||||
y: Math.min(d[1],d[3]),
|
||||
x2: Math.max(d[0],d[2]),
|
||||
y2: Math.max(d[1],d[3])
|
||||
};
|
||||
|
||||
b.w = b.x2 - b.x;
|
||||
b.h = b.y2 - b.y;
|
||||
|
||||
return b;
|
||||
},
|
||||
//}}}
|
||||
//getBox: function(){{{
|
||||
getBox: function(){
|
||||
var t = this;
|
||||
var o = t.orig;
|
||||
var _c = { x2: o.x + o.w, y2: o.y + o.h };
|
||||
switch(t.ord){
|
||||
case 'n': return t.resultWrap([ o.x, t.offsety + o.y, _c.x2, _c.y2 ]);
|
||||
case 's': return t.resultWrap([ o.x, o.y, _c.x2, t.offsety + _c.y2 ]);
|
||||
case 'e': return t.resultWrap([ o.x, o.y, t.offsetx + _c.x2, _c.y2 ]);
|
||||
case 'w': return t.resultWrap([ o.x + t.offsetx, o.y, _c.x2, _c.y2 ]);
|
||||
case 'sw': return t.resultWrap([ t.offsetx + o.x, o.y, _c.x2, t.offsety + _c.y2 ]);
|
||||
case 'se': return t.resultWrap([ o.x, o.y, t.offsetx + _c.x2, t.offsety + _c.y2 ]);
|
||||
case 'ne': return t.resultWrap([ o.x, t.offsety + o.y, t.offsetx + _c.x2, _c.y2 ]);
|
||||
case 'nw': return t.resultWrap([ t.offsetx + o.x, t.offsety + o.y, _c.x2, _c.y2 ]);
|
||||
case 'move':
|
||||
_c.nx = o.x + t.offsetx;
|
||||
_c.ny = o.y + t.offsety;
|
||||
return t.resultWrap([ _c.nx, _c.ny, _c.nx + o.w, _c.ny + o.h ]);
|
||||
}
|
||||
}
|
||||
//}}}
|
||||
};
|
||||
Jcrop.registerComponent('DragState',DragState);
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* EventManager
|
||||
* provides internal event support
|
||||
*/
|
||||
var EventManager = function(core){
|
||||
this.core = core;
|
||||
};
|
||||
EventManager.prototype = {
|
||||
on: function(n,cb){ $(this).on(n,cb); },
|
||||
off: function(n){ $(this).off(n); },
|
||||
trigger: function(n){ $(this).trigger(n); }
|
||||
};
|
||||
Jcrop.registerComponent('EventManager',EventManager);
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Image Loader
|
||||
* Reliably pre-loads images
|
||||
*/
|
||||
// var ImageLoader = function(src,element,cb){{{
|
||||
var ImageLoader = function(src,element,cb){
|
||||
this.src = src;
|
||||
if (!element) element = new Image;
|
||||
this.element = element;
|
||||
this.callback = cb;
|
||||
this.load();
|
||||
};
|
||||
// }}}
|
||||
|
||||
$.extend(ImageLoader,{
|
||||
// attach: function(el,cb){{{
|
||||
attach: function(el,cb){
|
||||
return new ImageLoader(el.src,el,cb);
|
||||
},
|
||||
// }}}
|
||||
// prototype: {{{
|
||||
prototype: {
|
||||
getDimensions: function(){
|
||||
var el = this.element;
|
||||
|
||||
if (el.naturalWidth)
|
||||
return [ el.naturalWidth, el. naturalHeight ];
|
||||
|
||||
if (el.width)
|
||||
return [ el.width, el.height ];
|
||||
|
||||
return null;
|
||||
},
|
||||
fireCallback: function(){
|
||||
this.element.onload = null;
|
||||
if (typeof this.callback == 'function')
|
||||
this.callback.apply(this,this.getDimensions());
|
||||
},
|
||||
isLoaded: function(){
|
||||
return this.element.complete;
|
||||
},
|
||||
load: function(){
|
||||
var t = this;
|
||||
var el = t.element;
|
||||
|
||||
el.src = t.src;
|
||||
|
||||
if (t.isLoaded()) t.fireCallback();
|
||||
else t.element.onload = function(e){
|
||||
t.fireCallback();
|
||||
};
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
});
|
||||
Jcrop.registerComponent('ImageLoader',ImageLoader);
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* JcropTouch
|
||||
* Detects and enables mobile touch support
|
||||
*/
|
||||
// var JcropTouch = function(core){{{
|
||||
var JcropTouch = function(core){
|
||||
this.core = core;
|
||||
this.init();
|
||||
};
|
||||
// }}}
|
||||
|
||||
$.extend(JcropTouch,{
|
||||
// support: function(){{{
|
||||
support: function(){
|
||||
if(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch)
|
||||
return true;
|
||||
},
|
||||
// }}}
|
||||
prototype: {
|
||||
// init: function(){{{
|
||||
init: function(){
|
||||
var t = this,
|
||||
p = $.Jcrop.component.DragState.prototype;
|
||||
|
||||
// A bit of an ugly hack to make sure we modify prototype
|
||||
// only once, store a key on the prototype
|
||||
if (!p.touch) {
|
||||
t.initEvents();
|
||||
t.shimDragState();
|
||||
t.shimStageDrag();
|
||||
p.touch = true;
|
||||
}
|
||||
},
|
||||
// }}}
|
||||
// shimDragState: function(){{{
|
||||
shimDragState: function(){
|
||||
var t = this;
|
||||
$.Jcrop.component.DragState.prototype.initEvents = function(e){
|
||||
|
||||
// Attach subsequent drag event handlers based on initial
|
||||
// event type - avoids collecting "pseudo-mouse" events
|
||||
// generated by some mobile browsers in some circumstances
|
||||
if (e.type.substr(0,5) == 'touch') {
|
||||
|
||||
$(this.eventTarget)
|
||||
.on('touchmove.jcrop.jcrop-touch',t.dragWrap(this.createDragHandler()))
|
||||
.on('touchend.jcrop.jcrop-touch',this.createStopHandler());
|
||||
|
||||
}
|
||||
|
||||
// For other events, use the mouse handlers that
|
||||
// the default DragState.initEvents() method sets...
|
||||
else {
|
||||
|
||||
$(this.eventTarget)
|
||||
.on('mousemove.jcrop',this.createDragHandler())
|
||||
.on('mouseup.jcrop',this.createStopHandler());
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
},
|
||||
// }}}
|
||||
// shimStageDrag: function(){{{
|
||||
shimStageDrag: function(){
|
||||
this.core.container
|
||||
.addClass('jcrop-touch')
|
||||
.on('touchstart.jcrop.jcrop-stage',this.dragWrap(this.core.ui.manager.startDragHandler()));
|
||||
},
|
||||
// }}}
|
||||
// dragWrap: function(cb){{{
|
||||
dragWrap: function(cb){
|
||||
return function(e){
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (e.type.substr(0,5) == 'touch') {
|
||||
e.pageX = e.originalEvent.changedTouches[0].pageX;
|
||||
e.pageY = e.originalEvent.changedTouches[0].pageY;
|
||||
return cb(e);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
},
|
||||
// }}}
|
||||
// initEvents: function(){{{
|
||||
initEvents: function(){
|
||||
var t = this, c = t.core;
|
||||
|
||||
c.container.on(
|
||||
'touchstart.jcrop.jcrop-touch',
|
||||
'.'+c.opt.css_drag,
|
||||
t.dragWrap(c.startDrag())
|
||||
);
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
});
|
||||
Jcrop.registerComponent('Touch',JcropTouch);
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* KeyWatcher
|
||||
* provides keyboard support
|
||||
*/
|
||||
// var KeyWatcher = function(core){{{
|
||||
var KeyWatcher = function(core){
|
||||
this.core = core;
|
||||
this.init();
|
||||
};
|
||||
// }}}
|
||||
$.extend(KeyWatcher,{
|
||||
// defaults: {{{
|
||||
defaults: {
|
||||
eventName: 'keydown.jcrop',
|
||||
passthru: [ 9 ],
|
||||
debug: false
|
||||
},
|
||||
// }}}
|
||||
prototype: {
|
||||
// init: function(){{{
|
||||
init: function(){
|
||||
$.extend(this,KeyWatcher.defaults);
|
||||
this.enable();
|
||||
},
|
||||
// }}}
|
||||
// disable: function(){{{
|
||||
disable: function(){
|
||||
this.core.container.off(this.eventName);
|
||||
},
|
||||
// }}}
|
||||
// enable: function(){{{
|
||||
enable: function(){
|
||||
var t = this, m = t.core;
|
||||
m.container.on(t.eventName,function(e){
|
||||
var nudge = e.shiftKey? 16: 2;
|
||||
|
||||
if ($.inArray(e.keyCode,t.passthru) >= 0)
|
||||
return true;
|
||||
|
||||
switch(e.keyCode){
|
||||
case 37: m.nudge(-nudge,0); break;
|
||||
case 38: m.nudge(0,-nudge); break;
|
||||
case 39: m.nudge(nudge,0); break;
|
||||
case 40: m.nudge(0,nudge); break;
|
||||
|
||||
case 46:
|
||||
case 8:
|
||||
m.requestDelete();
|
||||
return false;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (t.debug) console.log('keycode: ' + e.keyCode);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!e.metaKey && !e.ctrlKey)
|
||||
e.preventDefault();
|
||||
});
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
});
|
||||
Jcrop.registerComponent('Keyboard',KeyWatcher);
|
||||
|
||||
@@ -0,0 +1,336 @@
|
||||
/**
|
||||
* Selection
|
||||
* Built-in selection object
|
||||
*/
|
||||
var Selection = function(){};
|
||||
|
||||
$.extend(Selection,{
|
||||
// defaults: {{{
|
||||
defaults: {
|
||||
minSize: [ 8, 8 ],
|
||||
maxSize: [ 0, 0 ],
|
||||
aspectRatio: 0,
|
||||
edge: { n: 0, s: 0, e: 0, w: 0 },
|
||||
bgColor: null,
|
||||
bgOpacity: null,
|
||||
last: null,
|
||||
|
||||
state: null,
|
||||
active: true,
|
||||
linked: true,
|
||||
canDelete: true,
|
||||
canDrag: true,
|
||||
canResize: true,
|
||||
canSelect: true
|
||||
},
|
||||
// }}}
|
||||
prototype: {
|
||||
// init: function(core){{{
|
||||
init: function(core){
|
||||
this.core = core;
|
||||
this.startup();
|
||||
this.linked = this.core.opt.linked;
|
||||
this.attach();
|
||||
this.setOptions(this.core.opt);
|
||||
core.container.trigger('cropcreate',[this]);
|
||||
},
|
||||
// }}}
|
||||
// attach: function(){{{
|
||||
attach: function(){
|
||||
// For extending init() sequence
|
||||
},
|
||||
// }}}
|
||||
// startup: function(){{{
|
||||
startup: function(){
|
||||
var t = this, o = t.core.opt;
|
||||
$.extend(t,Selection.defaults);
|
||||
t.filter = t.core.getDefaultFilters();
|
||||
|
||||
t.element = $('<div />').addClass(o.css_selection).data({ selection: t });
|
||||
t.frame = $('<button />').addClass(o.css_button).data('ord','move').attr('type','button');
|
||||
t.element.append(t.frame).appendTo(t.core.container);
|
||||
|
||||
// IE background/draggable hack
|
||||
if (t.core.opt.is_msie) t.frame.css({
|
||||
opacity: 0,
|
||||
backgroundColor: 'white'
|
||||
});
|
||||
|
||||
t.insertElements();
|
||||
|
||||
// Bind focus and blur events for this selection
|
||||
t.frame.on('focus.jcrop',function(e){
|
||||
t.core.setSelection(t);
|
||||
t.element.trigger('cropfocus',t);
|
||||
t.element.addClass('jcrop-focus');
|
||||
}).on('blur.jcrop',function(e){
|
||||
t.element.removeClass('jcrop-focus');
|
||||
t.element.trigger('cropblur',t);
|
||||
});
|
||||
},
|
||||
// }}}
|
||||
// propagate: [{{{
|
||||
propagate: [
|
||||
'canDelete', 'canDrag', 'canResize', 'canSelect',
|
||||
'minSize', 'maxSize', 'aspectRatio', 'edge'
|
||||
],
|
||||
// }}}
|
||||
// setOptions: function(opt){{{
|
||||
setOptions: function(opt){
|
||||
Jcrop.propagate(this.propagate,opt,this);
|
||||
this.refresh();
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
// refresh: function(){{{
|
||||
refresh: function(){
|
||||
this.allowResize();
|
||||
this.allowDrag();
|
||||
this.allowSelect();
|
||||
this.callFilterFunction('refresh');
|
||||
this.updateRaw(this.get(),'se');
|
||||
},
|
||||
// }}}
|
||||
// callFilterFunction: function(f,args){{{
|
||||
callFilterFunction: function(f,args){
|
||||
for(var i=0;i<this.filter.length;i++)
|
||||
if (this.filter[i][f]) this.filter[i][f](this);
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
//addFilter: function(filter){{{
|
||||
addFilter: function(filter){
|
||||
filter.core = this.core;
|
||||
if (!this.hasFilter(filter)) {
|
||||
this.filter.push(filter);
|
||||
this.sortFilters();
|
||||
if (filter.init) filter.init();
|
||||
this.refresh();
|
||||
}
|
||||
},
|
||||
//}}}
|
||||
// hasFilter: function(filter){{{
|
||||
hasFilter: function(filter){
|
||||
var i, f = this.filter, n = [];
|
||||
for(i=0;i<f.length;i++) if (f[i] === filter) return true;
|
||||
},
|
||||
// }}}
|
||||
// sortFilters: function(){{{
|
||||
sortFilters: function(){
|
||||
this.filter.sort(
|
||||
function(x,y){ return x.priority - y.priority; }
|
||||
);
|
||||
},
|
||||
// }}}
|
||||
//clearFilters: function(){{{
|
||||
clearFilters: function(){
|
||||
var i, f = this.filter;
|
||||
|
||||
for(var i=0;i<f.length;i++)
|
||||
if (f[i].destroy) f[i].destroy();
|
||||
|
||||
this.filter = [];
|
||||
},
|
||||
//}}}
|
||||
// removeFiltersByTag: function(tag){{{
|
||||
removeFilter: function(tag){
|
||||
var i, f = this.filter, n = [];
|
||||
|
||||
for(var i=0;i<f.length;i++)
|
||||
if ((f[i].tag && (f[i].tag == tag)) || (tag === f[i])){
|
||||
if (f[i].destroy) f[i].destroy();
|
||||
}
|
||||
else n.push(f[i]);
|
||||
|
||||
this.filter = n;
|
||||
},
|
||||
// }}}
|
||||
// runFilters: function(b,ord){{{
|
||||
runFilters: function(b,ord){
|
||||
for(var i=0;i<this.filter.length;i++)
|
||||
b = this.filter[i].filter(b,ord,this);
|
||||
return b;
|
||||
},
|
||||
// }}}
|
||||
//endDrag: function(){{{
|
||||
endDrag: function(){
|
||||
if (this.state) {
|
||||
$(document.body).off('.jcrop');
|
||||
this.focus();
|
||||
this.state = null;
|
||||
}
|
||||
},
|
||||
//}}}
|
||||
// startDrag: function(e,ord){{{
|
||||
startDrag: function(e,ord){
|
||||
var t = this;
|
||||
var m = t.core;
|
||||
|
||||
ord = ord || $(e.target).data('ord');
|
||||
|
||||
this.focus();
|
||||
|
||||
if ((ord == 'move') && t.element.hasClass(t.core.opt.css_nodrag))
|
||||
return false;
|
||||
|
||||
this.state = new Jcrop.component.DragState(e,this,ord);
|
||||
return false;
|
||||
},
|
||||
// }}}
|
||||
// allowSelect: function(v){{{
|
||||
allowSelect: function(v){
|
||||
if (v === undefined) v = this.canSelect;
|
||||
|
||||
if (v && this.canSelect) this.frame.attr('disabled',false);
|
||||
else this.frame.attr('disabled','disabled');
|
||||
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
// allowDrag: function(v){{{
|
||||
allowDrag: function(v){
|
||||
var t = this, o = t.core.opt;
|
||||
if (v == undefined) v = t.canDrag;
|
||||
|
||||
if (v && t.canDrag) t.element.removeClass(o.css_nodrag);
|
||||
else t.element.addClass(o.css_nodrag);
|
||||
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
// allowResize: function(v){{{
|
||||
allowResize: function(v){
|
||||
var t = this, o = t.core.opt;
|
||||
if (v == undefined) v = t.canResize;
|
||||
|
||||
if (v && t.canResize) t.element.removeClass(o.css_noresize);
|
||||
else t.element.addClass(o.css_noresize);
|
||||
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
// remove: function(){{{
|
||||
remove: function(){
|
||||
this.element.trigger('cropremove',this);
|
||||
this.element.remove();
|
||||
},
|
||||
// }}}
|
||||
// toBack: function(){{{
|
||||
toBack: function(){
|
||||
this.active = false;
|
||||
this.element.removeClass('jcrop-current jcrop-focus');
|
||||
},
|
||||
// }}}
|
||||
// toFront: function(){{{
|
||||
toFront: function(){
|
||||
this.active = true;
|
||||
this.element.addClass('jcrop-current');
|
||||
this.callFilterFunction('refresh');
|
||||
this.refresh();
|
||||
},
|
||||
// }}}
|
||||
// redraw: function(b){{{
|
||||
redraw: function(b){
|
||||
this.moveTo(b.x,b.y);
|
||||
this.resize(b.w,b.h);
|
||||
this.last = b;
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
// update: function(b,ord){{{
|
||||
update: function(b,ord){
|
||||
return this.updateRaw(this.core.scale(b),ord);
|
||||
},
|
||||
// }}}
|
||||
// update: function(b,ord){{{
|
||||
updateRaw: function(b,ord){
|
||||
b = this.runFilters(b,ord);
|
||||
this.redraw(b);
|
||||
this.element.trigger('cropmove',[this,this.core.unscale(b)]);
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
// animateTo: function(box,cb){{{
|
||||
animateTo: function(box,cb){
|
||||
var ca = new Jcrop.component.Animator(this),
|
||||
b = this.core.scale(Jcrop.wrapFromXywh(box));
|
||||
|
||||
ca.animate(b.x,b.y,b.w,b.h,cb);
|
||||
},
|
||||
// }}}
|
||||
// center: function(instant){{{
|
||||
center: function(instant){
|
||||
var b = this.get(), m = this.core;
|
||||
var elw = m.container.width(), elh = m.container.height();
|
||||
var box = [ (elw-b.w)/2, (elh-b.h)/2, b.w, b.h ];
|
||||
return this[instant?'setSelect':'animateTo'](box);
|
||||
},
|
||||
// }}}
|
||||
//createElement: function(type,ord){{{
|
||||
createElement: function(type,ord){
|
||||
return $('<div />').addClass(type+' ord-'+ord).data('ord',ord);
|
||||
},
|
||||
//}}}
|
||||
//moveTo: function(x,y){{{
|
||||
moveTo: function(x,y){
|
||||
this.element.css({top: y+'px', left: x+'px'});
|
||||
},
|
||||
//}}}
|
||||
// blur: function(){{{
|
||||
blur: function(){
|
||||
this.element.blur();
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
// focus: function(){{{
|
||||
focus: function(){
|
||||
this.core.setSelection(this);
|
||||
this.frame.focus();
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
//resize: function(w,h){{{
|
||||
resize: function(w,h){
|
||||
this.element.css({width: w+'px', height: h+'px'});
|
||||
},
|
||||
//}}}
|
||||
//get: function(){{{
|
||||
get: function(){
|
||||
var b = this.element,
|
||||
o = b.position(),
|
||||
w = b.width(),
|
||||
h = b.height(),
|
||||
rv = { x: o.left, y: o.top };
|
||||
|
||||
rv.x2 = rv.x + w;
|
||||
rv.y2 = rv.y + h;
|
||||
rv.w = w;
|
||||
rv.h = h;
|
||||
|
||||
return rv;
|
||||
},
|
||||
//}}}
|
||||
//insertElements: function(){{{
|
||||
insertElements: function(){
|
||||
var t = this, i,
|
||||
m = t.core,
|
||||
fr = t.element,
|
||||
o = t.core.opt,
|
||||
b = o.borders,
|
||||
h = o.handles,
|
||||
d = o.dragbars;
|
||||
|
||||
for(i=0; i<d.length; i++)
|
||||
fr.append(t.createElement(o.css_dragbars,d[i]));
|
||||
|
||||
for(i=0; i<h.length; i++)
|
||||
fr.append(t.createElement(o.css_handles,h[i]));
|
||||
|
||||
for(i=0; i<b.length; i++)
|
||||
fr.append(t.createElement(o.css_borders,b[i]));
|
||||
}
|
||||
//}}}
|
||||
}
|
||||
});
|
||||
Jcrop.registerComponent('Selection',Selection);
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* StageDrag
|
||||
* Facilitates dragging
|
||||
*/
|
||||
// var StageDrag = function(manager,opt){{{
|
||||
var StageDrag = function(manager,opt){
|
||||
$.extend(this,StageDrag.defaults,opt || {});
|
||||
this.manager = manager;
|
||||
this.core = manager.core;
|
||||
};
|
||||
// }}}
|
||||
// StageDrag.defaults = {{{
|
||||
StageDrag.defaults = {
|
||||
offset: [ -8, -8 ],
|
||||
active: true,
|
||||
minsize: [ 20, 20 ]
|
||||
};
|
||||
// }}}
|
||||
|
||||
$.extend(StageDrag.prototype,{
|
||||
// start: function(e){{{
|
||||
start: function(e){
|
||||
var c = this.core;
|
||||
|
||||
// Do nothing if allowSelect is off
|
||||
if (!c.opt.allowSelect) return;
|
||||
|
||||
// Also do nothing if we can't draw any more selections
|
||||
if (c.opt.multi && c.opt.multiMax && (c.ui.multi.length >= c.opt.multiMax)) return false;
|
||||
|
||||
// calculate a few variables for this drag operation
|
||||
var o = $(e.currentTarget).offset();
|
||||
var origx = e.pageX - o.left + this.offset[0];
|
||||
var origy = e.pageY - o.top + this.offset[1];
|
||||
var m = c.ui.multi;
|
||||
|
||||
// Determine newly dragged crop behavior if multi disabled
|
||||
if (!c.opt.multi) {
|
||||
// For multiCleaanup true, remove all existing selections
|
||||
if (c.opt.multiCleanup){
|
||||
for(var i=0;i<m.length;i++) m[i].remove();
|
||||
c.ui.multi = [];
|
||||
}
|
||||
// If not, only remove the currently active selection
|
||||
else {
|
||||
c.removeSelection(c.ui.selection);
|
||||
}
|
||||
}
|
||||
|
||||
c.container.addClass('jcrop-dragging');
|
||||
|
||||
// Create the new selection
|
||||
var sel = c.newSelection()
|
||||
// and position it
|
||||
.updateRaw(Jcrop.wrapFromXywh([origx,origy,1,1]));
|
||||
|
||||
sel.element.trigger('cropstart',[sel,this.core.unscale(sel.get())]);
|
||||
|
||||
return sel.startDrag(e,'se');
|
||||
},
|
||||
// }}}
|
||||
// end: function(x,y){{{
|
||||
end: function(x,y){
|
||||
this.drag(x,y);
|
||||
var b = this.sel.get();
|
||||
|
||||
this.core.container.removeClass('jcrop-dragging');
|
||||
|
||||
if ((b.w < this.minsize[0]) || (b.h < this.minsize[1]))
|
||||
this.core.requestDelete();
|
||||
|
||||
else this.sel.focus();
|
||||
}
|
||||
// }}}
|
||||
});
|
||||
Jcrop.registerComponent('StageDrag',StageDrag);
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* StageManager
|
||||
* Provides basic stage-specific functionality
|
||||
*/
|
||||
// var StageManager = function(core){{{
|
||||
var StageManager = function(core){
|
||||
this.core = core;
|
||||
this.ui = core.ui;
|
||||
this.init();
|
||||
};
|
||||
// }}}
|
||||
|
||||
$.extend(StageManager.prototype,{
|
||||
// init: function(){{{
|
||||
init: function(){
|
||||
this.setupEvents();
|
||||
this.dragger = new StageDrag(this);
|
||||
},
|
||||
// }}}
|
||||
// tellConfigUpdate: function(options){{{
|
||||
tellConfigUpdate: function(options){
|
||||
for(var i=0,m=this.ui.multi,l=m.length;i<l;i++)
|
||||
if (m[i].setOptions && (m[i].linked || (this.core.opt.linkCurrent && m[i] == this.ui.selection)))
|
||||
m[i].setOptions(options);
|
||||
},
|
||||
// }}}
|
||||
// startDragHandler: function(){{{
|
||||
startDragHandler: function(){
|
||||
var t = this;
|
||||
return function(e){
|
||||
if (!e.button || t.core.opt.is_ie_lt9) return t.dragger.start(e);
|
||||
};
|
||||
},
|
||||
// }}}
|
||||
// removeEvents: function(){{{
|
||||
removeEvents: function(){
|
||||
this.core.event.off('.jcrop-stage');
|
||||
this.core.container.off('.jcrop-stage');
|
||||
},
|
||||
// }}}
|
||||
// shimLegacyHandlers: function(options){{{
|
||||
// This method uses the legacyHandlers configuration object to
|
||||
// gracefully wrap old-style Jcrop events with new ones
|
||||
shimLegacyHandlers: function(options){
|
||||
var _x = {}, core = this.core, tmp;
|
||||
|
||||
$.each(core.opt.legacyHandlers,function(k,i){
|
||||
if (k in options) {
|
||||
tmp = options[k];
|
||||
core.container.off('.jcrop-'+k)
|
||||
.on(i+'.jcrop.jcrop-'+k,function(e,s,c){
|
||||
tmp.call(core,c);
|
||||
});
|
||||
delete options[k];
|
||||
}
|
||||
});
|
||||
},
|
||||
// }}}
|
||||
// setupEvents: function(){{{
|
||||
setupEvents: function(){
|
||||
var t = this, c = t.core;
|
||||
|
||||
c.event.on('configupdate.jcrop-stage',function(e){
|
||||
t.shimLegacyHandlers(c.opt);
|
||||
t.tellConfigUpdate(c.opt)
|
||||
c.container.trigger('cropconfig',[c,c.opt]);
|
||||
});
|
||||
|
||||
this.core.container
|
||||
.on('mousedown.jcrop.jcrop-stage',this.startDragHandler());
|
||||
}
|
||||
// }}}
|
||||
});
|
||||
Jcrop.registerComponent('StageManager',StageManager);
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
var Thumbnailer = function(){
|
||||
};
|
||||
|
||||
$.extend(Thumbnailer,{
|
||||
defaults: {
|
||||
// Set to a specific Selection object
|
||||
// If this value is set, the preview will only track that Selection
|
||||
selection: null,
|
||||
|
||||
fading: true,
|
||||
fadeDelay: 1000,
|
||||
fadeDuration: 1000,
|
||||
autoHide: false,
|
||||
width: 80,
|
||||
height: 80,
|
||||
_hiding: null
|
||||
},
|
||||
|
||||
prototype: {
|
||||
recopyCanvas: function(){
|
||||
var s = this.core.ui.stage, cxt = s.context;
|
||||
this.context.putImageData(cxt.getImageData(0,0,s.canvas.width,s.canvas.height),0,0);
|
||||
},
|
||||
init: function(core,options){
|
||||
var t = this;
|
||||
this.core = core;
|
||||
$.extend(this,Thumbnailer.defaults,options);
|
||||
t.initEvents();
|
||||
t.refresh();
|
||||
t.insertElements();
|
||||
if (t.selection) {
|
||||
t.renderSelection(t.selection);
|
||||
t.selectionTarget = t.selection.element[0];
|
||||
} else if (t.core.ui.selection) {
|
||||
t.renderSelection(t.core.ui.selection);
|
||||
}
|
||||
|
||||
if (t.core.ui.stage.canvas) {
|
||||
t.context = t.preview[0].getContext('2d');
|
||||
t.core.container.on('cropredraw',function(e){
|
||||
t.recopyCanvas();
|
||||
t.refresh();
|
||||
});
|
||||
}
|
||||
},
|
||||
updateImage: function(imgel){
|
||||
this.preview.remove();
|
||||
this.preview = $($.Jcrop.imageClone(imgel));
|
||||
this.element.append(this.preview);
|
||||
this.refresh();
|
||||
return this;
|
||||
},
|
||||
insertElements: function(){
|
||||
this.preview = $($.Jcrop.imageClone(this.core.ui.stage.imgsrc));
|
||||
|
||||
this.element = $('<div />').addClass('jcrop-thumb')
|
||||
.width(this.width).height(this.height)
|
||||
.append(this.preview)
|
||||
.appendTo(this.core.container);
|
||||
},
|
||||
resize: function(w,h){
|
||||
this.width = w;
|
||||
this.height = h;
|
||||
this.element.width(w).height(h);
|
||||
this.renderCoords(this.last);
|
||||
},
|
||||
refresh: function(){
|
||||
this.cw = (this.core.opt.xscale * this.core.container.width());
|
||||
this.ch = (this.core.opt.yscale * this.core.container.height());
|
||||
if (this.last) {
|
||||
this.renderCoords(this.last);
|
||||
}
|
||||
},
|
||||
renderCoords: function(c){
|
||||
var rx = this.width / c.w;
|
||||
var ry = this.height / c.h;
|
||||
|
||||
this.preview.css({
|
||||
width: Math.round(rx * this.cw) + 'px',
|
||||
height: Math.round(ry * this.ch) + 'px',
|
||||
marginLeft: '-' + Math.round(rx * c.x) + 'px',
|
||||
marginTop: '-' + Math.round(ry * c.y) + 'px'
|
||||
});
|
||||
|
||||
this.last = c;
|
||||
return this;
|
||||
},
|
||||
renderSelection: function(s){
|
||||
return this.renderCoords(s.core.unscale(s.get()));
|
||||
},
|
||||
selectionStart: function(s){
|
||||
this.renderSelection(s);
|
||||
},
|
||||
show: function(){
|
||||
if (this._hiding) clearTimeout(this._hiding);
|
||||
|
||||
if (!this.fading) this.element.stop().css({ opacity: 1 });
|
||||
else this.element.stop().animate({ opacity: 1 },{ duration: 80, queue: false });
|
||||
},
|
||||
hide: function(){
|
||||
var t = this;
|
||||
if (!t.fading) t.element.hide();
|
||||
else t._hiding = setTimeout(function(){
|
||||
t._hiding = null;
|
||||
t.element.stop().animate({ opacity: 0 },{ duration: t.fadeDuration, queue: false });
|
||||
},t.fadeDelay);
|
||||
},
|
||||
initEvents: function(){
|
||||
var t = this;
|
||||
t.core.container.on('croprotstart croprotend cropimage cropstart cropmove cropend',function(e,s,c){
|
||||
if (t.selectionTarget && (t.selectionTarget !== e.target)) return false;
|
||||
|
||||
switch(e.type){
|
||||
|
||||
case 'cropimage':
|
||||
t.updateImage(c);
|
||||
break;
|
||||
|
||||
case 'cropstart':
|
||||
t.selectionStart(s);
|
||||
case 'croprotstart':
|
||||
t.show();
|
||||
break;
|
||||
|
||||
case 'cropend':
|
||||
t.renderCoords(c);
|
||||
case 'croprotend':
|
||||
if (t.autoHide) t.hide();
|
||||
break;
|
||||
|
||||
case 'cropmove':
|
||||
t.renderCoords(c);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
Jcrop.registerComponent('Thumbnailer',Thumbnailer);
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// Jcrop constructor
|
||||
var Jcrop = function(element,opt){
|
||||
var _ua = navigator.userAgent.toLowerCase();
|
||||
|
||||
this.opt = $.extend({},Jcrop.defaults,opt || {});
|
||||
|
||||
this.container = $(element);
|
||||
|
||||
this.opt.is_msie = /msie/.test(_ua);
|
||||
this.opt.is_ie_lt9 = /msie [1-8]\./.test(_ua);
|
||||
|
||||
this.container.addClass(this.opt.css_container);
|
||||
|
||||
this.ui = {};
|
||||
this.state = null;
|
||||
this.ui.multi = [];
|
||||
this.ui.selection = null;
|
||||
this.filter = {};
|
||||
|
||||
this.init();
|
||||
this.setOptions(opt);
|
||||
this.applySizeConstraints();
|
||||
this.container.trigger('cropinit',this);
|
||||
|
||||
// IE<9 doesn't work if mouse events are attached to window
|
||||
if (this.opt.is_ie_lt9)
|
||||
this.opt.dragEventTarget = document.body;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,278 @@
|
||||
|
||||
@white: white;
|
||||
@black: black;
|
||||
|
||||
@selectionBorderWidth: 1px;
|
||||
@selectionBackgroundImage: "Jcrop.gif";
|
||||
@selectionBackgroundColor: @white;
|
||||
@selectionBackground: @selectionBackgroundColor url(@selectionBackgroundImage);
|
||||
|
||||
// Setting some variables to
|
||||
// Used to set handle and dragbar size/width
|
||||
// To center on a 1px selection line, use an odd number
|
||||
@grabSize: 9px;
|
||||
|
||||
// Used to offset handles and dragbar
|
||||
// Default value will center on 1px selection line
|
||||
@grabOffset: (floor(@grabSize/2)+1) * -1;
|
||||
|
||||
@handleSize: @grabSize;
|
||||
@handleOffset: @grabOffset;
|
||||
@handleBorderWidth: 1px;
|
||||
@handleBorderColor: #eee;
|
||||
@handleBorderStyle: solid;
|
||||
@handleBackgroundColor: rgba(49,28,28,0.58);
|
||||
@handleOpacity: 0.8;
|
||||
|
||||
@dragbarWidth: @grabSize;
|
||||
@dragbarOffset: @grabOffset;
|
||||
|
||||
/*
|
||||
The outer-most container in a typical Jcrop instance
|
||||
If you are having difficulty with formatting related to styles
|
||||
on a parent element, place any fixes here or in a like selector
|
||||
|
||||
You can also style this element if you want to add a border, etc
|
||||
A better method for styling can be seen below with .jcrop-light
|
||||
(Add a class to the holder and style elements for that extended class)
|
||||
*/
|
||||
.jcrop-active {
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
box-sizing: border-box;
|
||||
|
||||
/* IE10 touch compatibility */ -ms-touch-action: none;
|
||||
}
|
||||
|
||||
.jcrop-dragging {
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.jcrop-selection {
|
||||
z-index: 2;
|
||||
&.jcrop-current { z-index: 4; }
|
||||
}
|
||||
|
||||
/* Selection Borders */
|
||||
.jcrop-border {
|
||||
background: @selectionBackground;
|
||||
line-height: 1px !important;
|
||||
font-size: 0 !important;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
filter: Alpha(opacity=50) !important;
|
||||
opacity: 0.5 !important;
|
||||
&.ord-w, &.ord-e, &.ord-n { top: 0px; }
|
||||
&.ord-n, &.ord-s { width: 100%; height: @selectionBorderWidth !important; }
|
||||
&.ord-w, &.ord-e { height: 100%; width: @selectionBorderWidth !important; }
|
||||
&.ord-e { right: -@selectionBorderWidth; }
|
||||
&.ord-n { top: -@selectionBorderWidth; }
|
||||
&.ord-w { left: -@selectionBorderWidth; }
|
||||
&.ord-s { bottom: -@selectionBorderWidth; }
|
||||
}
|
||||
|
||||
.jcrop-selection {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.jcrop-box {
|
||||
z-index: 2;
|
||||
display: block;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-size: 0;
|
||||
&:hover { background: none; }
|
||||
&:active { background: none; }
|
||||
&:focus { outline: 1px rgba(128,128,128,.65) dotted; }
|
||||
}
|
||||
|
||||
.jcrop-active, .jcrop-box { position: relative; }
|
||||
.jcrop-box { width: 100%; height: 100%; cursor: move; }
|
||||
|
||||
.handles (@handleSize;@handleOffset;@bgColor;@bgOpacity;@borderWidth;@borderColor;@borderStyle) {
|
||||
|
||||
z-index: 4;
|
||||
@ieopacity: @bgOpacity * 100;
|
||||
font-size: 0;
|
||||
background-color: @bgColor;
|
||||
border: @borderWidth @borderColor @borderStyle;
|
||||
width: @handleSize;
|
||||
height: @handleSize;
|
||||
font-size: 0;
|
||||
position: absolute;
|
||||
filter: Alpha(opacity=@ieopacity) !important;
|
||||
opacity: @bgOpacity !important;
|
||||
|
||||
&.ord-n {left:50%;margin-left:@handleOffset;margin-top:@handleOffset;top:0;cursor:n-resize;}
|
||||
&.ord-s {bottom:0;left:50%;margin-bottom:@handleOffset;margin-left:@handleOffset;cursor:s-resize;}
|
||||
&.ord-e {margin-right:@handleOffset;margin-top:@handleOffset;right:0;top:50%;cursor:e-resize;}
|
||||
&.ord-w {left:0;margin-left:@handleOffset;margin-top:@handleOffset;top:50%;cursor:w-resize;}
|
||||
&.ord-nw {left:0;margin-left:@handleOffset;margin-top:@handleOffset;top:0;cursor:nw-resize;}
|
||||
&.ord-ne {margin-right:@handleOffset;margin-top:@handleOffset;right:0;top:0;cursor:ne-resize;}
|
||||
&.ord-se {bottom:0;margin-bottom:@handleOffset;margin-right:@handleOffset;right:0;cursor:se-resize;}
|
||||
&.ord-sw {bottom:0;left:0;margin-bottom:@handleOffset;margin-left:@handleOffset;cursor:sw-resize;}
|
||||
|
||||
}
|
||||
|
||||
.standard-handles (@handleSize;@bgColor;@bgOpacity;@borderColor) {
|
||||
@handleOffset: (floor(@handleSize/2)+1) * -1;
|
||||
.handles(@handleSize;@handleOffset;@bgColor;@bgOpacity;@handleBorderWidth;@borderColor;@handleBorderStyle);
|
||||
}
|
||||
|
||||
/* Selection Handles */
|
||||
|
||||
.jcrop-handle {
|
||||
.standard-handles(@handleSize;@handleBackgroundColor;@handleOpacity;@handleBorderColor);
|
||||
}
|
||||
|
||||
/* Larger Selection Handles for Touch */
|
||||
|
||||
.jcrop-touch .jcrop-handle {
|
||||
.standard-handles(@handleSize * 2;@handleBackgroundColor;@handleOpacity;@handleBorderColor);
|
||||
}
|
||||
|
||||
/* Selection Dragbars */
|
||||
|
||||
.jcrop-dragbar {
|
||||
|
||||
font-size: 0;
|
||||
position: absolute;
|
||||
|
||||
&.ord-n, &.ord-s {height:@dragbarWidth !important;width:100%;}
|
||||
&.ord-e, &.ord-w { top:0px; height:100%;width:@dragbarWidth !important;}
|
||||
&.ord-n {margin-top:@dragbarOffset;cursor:n-resize; top:0px; }
|
||||
&.ord-s {bottom:0;margin-bottom:@dragbarOffset;cursor:s-resize;}
|
||||
&.ord-e {margin-right:@dragbarOffset;right:0;cursor:e-resize;}
|
||||
&.ord-w {margin-left:@dragbarOffset;cursor:w-resize;}
|
||||
|
||||
}
|
||||
|
||||
/* Shading panels */
|
||||
|
||||
.jcrop-shades {
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
div { cursor: crosshair; }
|
||||
}
|
||||
|
||||
/* Various special states */
|
||||
|
||||
.jcrop-noresize {
|
||||
.jcrop-dragbar,
|
||||
.jcrop-handle
|
||||
{ display: none; }
|
||||
}
|
||||
|
||||
.jcrop-selection.jcrop-nodrag .jcrop-box,
|
||||
.jcrop-nodrag .jcrop-shades div
|
||||
{ cursor: default; }
|
||||
|
||||
/* The "jcrop-light" class/extension */
|
||||
|
||||
.jcrop-light {
|
||||
.jcrop-border {
|
||||
background: @white;
|
||||
filter:Alpha(opacity=70)!important;
|
||||
opacity:.70!important;
|
||||
}
|
||||
.jcrop-handle {
|
||||
background-color: @black;
|
||||
border-color: @white;
|
||||
}
|
||||
}
|
||||
|
||||
/* The "jcrop-dark" class/extension */
|
||||
|
||||
.jcrop-dark {
|
||||
.jcrop-border {
|
||||
background: @black;
|
||||
filter: Alpha(opacity=70) !important;
|
||||
opacity: 0.7 !important;
|
||||
}
|
||||
.jcrop-handle {
|
||||
background-color: @white;
|
||||
border-color: @black;
|
||||
}
|
||||
}
|
||||
|
||||
/* Simple macro to turn off the antlines */
|
||||
|
||||
.solid-line {
|
||||
.jcrop-border {
|
||||
background: @selectionBackgroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
.jcrop-thumb {
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
/* Fix for twitter bootstrap et al. */
|
||||
|
||||
.jcrop-active img,
|
||||
.jcrop-thumb img,
|
||||
.jcrop-thumb canvas {
|
||||
min-width: none;
|
||||
min-height: none;
|
||||
max-width: none;
|
||||
max-height: none;
|
||||
}
|
||||
|
||||
/* Improved multiple selection styles - in progress */
|
||||
|
||||
.jcrop-hl-active {
|
||||
.jcrop-border {
|
||||
filter:Alpha(opacity=20)!important;
|
||||
opacity:.20!important;
|
||||
}
|
||||
.jcrop-handle {
|
||||
filter:Alpha(opacity=10)!important;
|
||||
opacity:.10!important;
|
||||
}
|
||||
.jcrop-selection:hover {
|
||||
.jcrop-border {
|
||||
background-color: #ccc;
|
||||
filter:Alpha(opacity=50)!important;
|
||||
opacity:.50!important;
|
||||
}
|
||||
/*
|
||||
.jcrop-handle {
|
||||
filter:Alpha(opacity=35)!important;
|
||||
opacity:.35!important;
|
||||
}
|
||||
*/
|
||||
}
|
||||
.jcrop-selection.jcrop-current {
|
||||
.jcrop-border {
|
||||
background: gray url('Jcrop.gif');
|
||||
opacity:.35!important;
|
||||
filter:Alpha(opacity=35)!important;
|
||||
}
|
||||
.jcrop-handle {
|
||||
filter:Alpha(opacity=30)!important;
|
||||
opacity:.30!important;
|
||||
}
|
||||
}
|
||||
.jcrop-selection.jcrop-focus {
|
||||
.jcrop-border {
|
||||
background: url('Jcrop.gif');
|
||||
opacity:.65!important;
|
||||
filter:Alpha(opacity=65)!important;
|
||||
}
|
||||
.jcrop-handle {
|
||||
filter:Alpha(opacity=60)!important;
|
||||
opacity:.60!important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Prevent background on button element */
|
||||
button.jcrop-box { background: none; }
|
||||
@@ -0,0 +1,8 @@
|
||||
## LESScss source files
|
||||
|
||||
Files in this folder are used to compile the Jcrop.css file from .less definitions.
|
||||
|
||||
##### Compiling with Grunt
|
||||
|
||||
$ npm install
|
||||
$ grunt css
|
||||
@@ -0,0 +1,64 @@
|
||||
/*!
|
||||
* Bootstrap v2.2.1
|
||||
*
|
||||
* Copyright 2012 Twitter, Inc
|
||||
* Licensed under the Apache License v2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Designed and built with all the love in the world @twitter by @mdo and @fat.
|
||||
*/
|
||||
|
||||
// CSS Reset
|
||||
@import "_reset.less";
|
||||
|
||||
// Core variables and mixins
|
||||
@import "_variables.less"; // Modify this for custom colors, font-sizes, etc
|
||||
@import "bs/less/mixins.less";
|
||||
|
||||
// Grid system and page structure
|
||||
@import "bs/less/scaffolding.less";
|
||||
@import "bs/less/grid.less";
|
||||
@import "bs/less/layouts.less";
|
||||
|
||||
// Base CSS
|
||||
@import "bs/less/type.less";
|
||||
@import "bs/less/code.less";
|
||||
@import "bs/less/forms.less";
|
||||
@import "bs/less/tables.less";
|
||||
|
||||
// Components: common
|
||||
@import "bs/less/sprites.less";
|
||||
@import "bs/less/dropdowns.less";
|
||||
@import "bs/less/wells.less";
|
||||
@import "bs/less/component-animations.less";
|
||||
@import "bs/less/close.less";
|
||||
|
||||
// Components: Buttons & Alerts
|
||||
@import "bs/less/buttons.less";
|
||||
@import "bs/less/button-groups.less";
|
||||
@import "bs/less/alerts.less"; // Note: alerts share common CSS with buttons and thus have styles in buttons.less
|
||||
|
||||
// Components: Nav
|
||||
@import "bs/less/navs.less";
|
||||
@import "bs/less/navbar.less";
|
||||
@import "bs/less/breadcrumbs.less";
|
||||
@import "bs/less/pagination.less";
|
||||
@import "bs/less/pager.less";
|
||||
|
||||
// Components: Popovers
|
||||
@import "bs/less/modals.less";
|
||||
@import "bs/less/tooltip.less";
|
||||
@import "bs/less/popovers.less";
|
||||
|
||||
// Components: Misc
|
||||
//@import "bs/less/thumbnails.less";
|
||||
@import "bs/less/media.less";
|
||||
@import "bs/less/labels-badges.less";
|
||||
@import "bs/less/progress-bars.less";
|
||||
@import "bs/less/accordion.less";
|
||||
@import "bs/less/carousel.less";
|
||||
@import "bs/less/hero-unit.less";
|
||||
|
||||
// Utility classes
|
||||
@import "bs/less/utilities.less"; // Has to be last to override when necessary
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
//
|
||||
// Modals
|
||||
// Adapted from http://github.com/necolas/normalize.css
|
||||
// --------------------------------------------------
|
||||
|
||||
|
||||
// Display in IE6-9 and FF3
|
||||
// -------------------------
|
||||
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
nav,
|
||||
section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
// Display block in IE6-9 and FF3
|
||||
// -------------------------
|
||||
|
||||
audio,
|
||||
canvas,
|
||||
video {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
// Prevents modern browsers from displaying 'audio' without controls
|
||||
// -------------------------
|
||||
|
||||
audio:not([controls]) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// Base settings
|
||||
// -------------------------
|
||||
|
||||
html {
|
||||
font-size: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
}
|
||||
// Focus states
|
||||
a:focus {
|
||||
.tab-focus();
|
||||
}
|
||||
// Hover & Active
|
||||
a:hover,
|
||||
a:active {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
// Prevents sub and sup affecting line-height in all browsers
|
||||
// -------------------------
|
||||
|
||||
sub,
|
||||
sup {
|
||||
position: relative;
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
// Forms
|
||||
// -------------------------
|
||||
|
||||
// Font size in all browsers, margin changes, misc consistency
|
||||
button,
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
margin: 0;
|
||||
font-size: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
button,
|
||||
input {
|
||||
*overflow: visible; // Inner spacing ie IE6/7
|
||||
line-height: normal; // FF3/4 have !important on line-height in UA stylesheet
|
||||
}
|
||||
button::-moz-focus-inner,
|
||||
input::-moz-focus-inner { // Inner padding and border oddities in FF3/4
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
button,
|
||||
html input[type="button"], // Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` and `video` controls.
|
||||
input[type="reset"],
|
||||
input[type="submit"] {
|
||||
-webkit-appearance: button; // Corrects inability to style clickable `input` types in iOS.
|
||||
cursor: pointer; // Improves usability and consistency of cursor style between image-type `input` and others.
|
||||
}
|
||||
input[type="search"] { // Appearance in Safari/Chrome
|
||||
-webkit-box-sizing: content-box;
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
-webkit-appearance: textfield;
|
||||
}
|
||||
input[type="search"]::-webkit-search-decoration,
|
||||
input[type="search"]::-webkit-search-cancel-button {
|
||||
-webkit-appearance: none; // Inner-padding issues in Chrome OSX, Safari 5
|
||||
}
|
||||
textarea {
|
||||
overflow: auto; // Remove vertical scrollbar in IE6-9
|
||||
vertical-align: top; // Readability and alignment cross-browser
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
.tapmodo-logo
|
||||
{
|
||||
display: block;
|
||||
width: 103px;
|
||||
height: 21px;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGcAAAAVCAYAAABbq/AzAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABUNJREFUeNrsWX9oU1cUvn0pkUDlSaDSEcgoRAqFN1IqhY79IRuFDUFRFEHp6LBYMhRBURREQSYbW5UOpaIoSkVpURDEYZlMWhiWDQNloigWgsFCoFCQBQphj3nu+C4cD/e+NCOTsnjgI+/d3nvfuef3uW0aHh5WjLJAHO8zhMdq+dRGCAhJwoR6T+OEDJ5vEb6rZXEzfjsIo4RPLXMWCPcJhwnzEXvlsIem1++V8w/1EtJ4fl7rYg+a/cOhGE2thJ2YE0Ts5bPnsIEV0kKI1WMjD5udg7VHURJKsjFzgbCFjcUxNmph9HPCdcIjhm9gBFLZ5u85zHlJ+BuGkrPw0o/vXkA02Eu4hz3GEHa1Ed7E2G+Y4zrvt4QpzL1LOERIRHjJE8KfhL8Iv2CPKOoknAUfj8BXv/ljE+Uc/bElCGcMwrOFtTOEvOUDaQjNRWuY4i8RdjvmFQhdbG61fTVdJAyx9+sOA1Is3PqW8a8J59l7N4TrO/j8DL9cMVMsV9voBmEXe9/jMF4FeX/hQdvaChf1ABjVRcBRCGstNtXMjBA2WQ6cF/mogrEZKF6JuKvnXiXcYX9rj1Cc+c5lwu/igN1VFFixhN6KmLNJeP2YUExZ8Dkq1h9higkRia5ZvmMoA1nGxPkM9REOeHD1UbhVAAv6CJXFLDxJh4lXhP2W8KM3XQ+GDJUw9rFgUM/5inASBy4B/OAuOkYYhNUuijBpI20UHxA2i/EfCKtEFZoSXtDJlKjPsFp4aJ9QHs/XWm77CF+Ks8nwm2Ce+CF45TLsb2aTslDQSXwghFd1RiT+WimHOO5y/6hEGjIrniP0sJzn8piSsHrFwpErx6bE3Bk8X4ORGj5T2CMmeMgvs+UwNE0osnLb5MC0J5iMI/H2Whg1tPgvFaOVfJopZh4HWVjm+iQzjgwbn69ztfVaCLGFhSJlCXWhMIC2Gr/R4XgueyKxmY/Ngimbl/xaxbKNUrUFXGHekBXzdyHElJfpOdpoXhCeMUVp77hdZ+XMMJ70+R/CY+6J3Flk75Ps+TjOPs56HEmTIoz+DFmN8DkeXElWZ2WLpSg0lnOODxaFkHWJOMAsLy8UOIUDtIsEH5V3Mswyl5CD6u05OjKcYO8B+EoxIxwSa06x3NqGs++I+MYDUQz1QVYJpoNTHqx3VihHWbQ+bWGK00+Ep5akXGHWNijCYgmCmINBbLV4sqEfkQsv4raiC3nAFXIX2W/oGFeO/HMGletji1DXQxactPw2iPPrCLMdZbGyhO+tKBxklXsVBVmhCXdr2rq/RxWhD7IOVdAY3PwyFlXr/GNI1AEEnnck3jSEUxbNbDmif5K9yLukTETEsN2UVEQLUY0SCNVvRYEmcfG5kighYrDscf731LyCeVuqEkZrpawI30pUqXFL2V0PSrIQGqgabvm9BjLEoujTOkTFtEO9fbGbEq2Ebynpux0hMMWKgxzmJcBDzNKb+eLqKN5oyjE3CVoJGyEs16XnNibk3Wz9TlZR9eF3AD1cDIrw8W6rOj9hPPDeJoAiB5DX9XVST7NqPGpFxWe8w0eFGCLkpDCnAAWZCkwXOgdFExrDmk6su2EpgAri1iBEldqG314UW3tRfCWByUZUTrWYz3PPhCiXFbP8aXZ3llHufyW42o4BKOMpK6MVqsIHjRbWbDcZvN/qgPUXWF7IsKusUPSCxltMKJpECAzgZWnWXqQtyishvJoK9D7WhRhvWcml9H9VNfks9PjwkhDPrayfCSDYWUvVZd7bEbJaWJjLQnlFppwA+/gi7LWK5tTcG2rFzb8RYADOuFkIlIcpJwAAAABJRU5ErkJggg==);
|
||||
overflow: hidden;
|
||||
text-indent: -99em;
|
||||
}
|
||||
|
||||
.tapmodo-footer {
|
||||
font-size: 10px;
|
||||
color: #aaa;
|
||||
line-height: 1.1;
|
||||
border-top: 1px #eee solid;
|
||||
padding: 22px 0 16px;
|
||||
margin-top: 3.5em;
|
||||
.segment {
|
||||
float: left;
|
||||
margin-right: 1.5em;
|
||||
|
||||
a {
|
||||
color: #999;
|
||||
text-decoration: underline;
|
||||
&:hover { color: #888; text-decoration: none; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/////////////////////////////////
|
||||
// DEFAULT SETTINGS
|
||||
|
||||
Jcrop.defaults = {
|
||||
|
||||
// Selection Behavior
|
||||
edge: { n: 0, s: 0, e: 0, w: 0 },
|
||||
setSelect: null,
|
||||
linked: true,
|
||||
linkCurrent: true,
|
||||
canDelete: true,
|
||||
canSelect: true,
|
||||
canDrag: true,
|
||||
canResize: true,
|
||||
|
||||
// Component constructors
|
||||
eventManagerComponent: Jcrop.component.EventManager,
|
||||
keyboardComponent: Jcrop.component.Keyboard,
|
||||
dragstateComponent: Jcrop.component.DragState,
|
||||
stagemanagerComponent: Jcrop.component.StageManager,
|
||||
animatorComponent: Jcrop.component.Animator,
|
||||
selectionComponent: Jcrop.component.Selection,
|
||||
|
||||
// This is a function that is called, which returns a stage object
|
||||
stageConstructor: Jcrop.stageConstructor,
|
||||
|
||||
// Stage Behavior
|
||||
allowSelect: true,
|
||||
multi: false,
|
||||
multiMax: false,
|
||||
multiCleanup: true,
|
||||
animation: true,
|
||||
animEasing: 'swing',
|
||||
animDuration: 400,
|
||||
fading: true,
|
||||
fadeDuration: 300,
|
||||
fadeEasing: 'swing',
|
||||
bgColor: 'black',
|
||||
bgOpacity: .5,
|
||||
|
||||
// Startup options
|
||||
applyFilters: [ 'constrain', 'extent', 'backoff', 'ratio', 'shader', 'round' ],
|
||||
borders: [ 'e', 'w', 's', 'n' ],
|
||||
handles: [ 'n', 's', 'e', 'w', 'sw', 'ne', 'nw', 'se' ],
|
||||
dragbars: [ 'n', 'e', 'w', 's' ],
|
||||
|
||||
dragEventTarget: window,
|
||||
|
||||
xscale: 1,
|
||||
yscale: 1,
|
||||
|
||||
boxWidth: null,
|
||||
boxHeight: null,
|
||||
|
||||
// CSS Classes
|
||||
// @todo: These need to be moved to top-level object keys
|
||||
// for better customization. Currently if you try to extend one
|
||||
// via an options object to Jcrop, it will wipe out all
|
||||
// the others you don't specify. Be careful for now!
|
||||
css_nodrag: 'jcrop-nodrag',
|
||||
css_drag: 'jcrop-drag',
|
||||
css_container: 'jcrop-active',
|
||||
css_shades: 'jcrop-shades',
|
||||
css_selection: 'jcrop-selection',
|
||||
css_borders: 'jcrop-border',
|
||||
css_handles: 'jcrop-handle jcrop-drag',
|
||||
css_button: 'jcrop-box jcrop-drag',
|
||||
css_noresize: 'jcrop-noresize',
|
||||
css_dragbars: 'jcrop-dragbar jcrop-drag',
|
||||
|
||||
legacyHandlers: {
|
||||
onChange: 'cropmove',
|
||||
onSelect: 'cropend'
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* BackoffFilter
|
||||
* move out-of-bounds selection into allowed position at same size
|
||||
*/
|
||||
var BackoffFilter = function(){
|
||||
this.minw = 40;
|
||||
this.minh = 40;
|
||||
this.maxw = 0;
|
||||
this.maxh = 0;
|
||||
this.core = null;
|
||||
};
|
||||
$.extend(BackoffFilter.prototype,{
|
||||
tag: 'backoff',
|
||||
priority: 22,
|
||||
filter: function(b){
|
||||
var r = this.bound;
|
||||
|
||||
if (b.x < r.minx) { b.x = r.minx; b.x2 = b.w + b.x; }
|
||||
if (b.y < r.miny) { b.y = r.miny; b.y2 = b.h + b.y; }
|
||||
if (b.x2 > r.maxx) { b.x2 = r.maxx; b.x = b.x2 - b.w; }
|
||||
if (b.y2 > r.maxy) { b.y2 = r.maxy; b.y = b.y2 - b.h; }
|
||||
|
||||
return b;
|
||||
},
|
||||
refresh: function(sel){
|
||||
this.elw = sel.core.container.width();
|
||||
this.elh = sel.core.container.height();
|
||||
this.bound = {
|
||||
minx: 0 + sel.edge.w,
|
||||
miny: 0 + sel.edge.n,
|
||||
maxx: this.elw + sel.edge.e,
|
||||
maxy: this.elh + sel.edge.s
|
||||
};
|
||||
}
|
||||
});
|
||||
Jcrop.registerFilter('backoff',BackoffFilter);
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* ConstrainFilter
|
||||
* a filter to constrain crop selection to bounding element
|
||||
*/
|
||||
var ConstrainFilter = function(){
|
||||
this.core = null;
|
||||
};
|
||||
$.extend(ConstrainFilter.prototype,{
|
||||
tag: 'constrain',
|
||||
priority: 5,
|
||||
filter: function(b,ord){
|
||||
if (ord == 'move') {
|
||||
if (b.x < this.minx) { b.x = this.minx; b.x2 = b.w + b.x; }
|
||||
if (b.y < this.miny) { b.y = this.miny; b.y2 = b.h + b.y; }
|
||||
if (b.x2 > this.maxx) { b.x2 = this.maxx; b.x = b.x2 - b.w; }
|
||||
if (b.y2 > this.maxy) { b.y2 = this.maxy; b.y = b.y2 - b.h; }
|
||||
} else {
|
||||
if (b.x < this.minx) { b.x = this.minx; }
|
||||
if (b.y < this.miny) { b.y = this.miny; }
|
||||
if (b.x2 > this.maxx) { b.x2 = this.maxx; }
|
||||
if (b.y2 > this.maxy) { b.y2 = this.maxy; }
|
||||
}
|
||||
b.w = b.x2 - b.x;
|
||||
b.h = b.y2 - b.y;
|
||||
return b;
|
||||
},
|
||||
refresh: function(sel){
|
||||
this.elw = sel.core.container.width();
|
||||
this.elh = sel.core.container.height();
|
||||
this.minx = 0 + sel.edge.w;
|
||||
this.miny = 0 + sel.edge.n;
|
||||
this.maxx = this.elw + sel.edge.e;
|
||||
this.maxy = this.elh + sel.edge.s;
|
||||
}
|
||||
});
|
||||
Jcrop.registerFilter('constrain',ConstrainFilter);
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* ExtentFilter
|
||||
* a filter to implement minimum or maximum size
|
||||
*/
|
||||
var ExtentFilter = function(){
|
||||
this.core = null;
|
||||
};
|
||||
$.extend(ExtentFilter.prototype,{
|
||||
tag: 'extent',
|
||||
priority: 12,
|
||||
offsetFromCorner: function(corner,box,b){
|
||||
var w = box[0], h = box[1];
|
||||
switch(corner){
|
||||
case 'bl': return [ b.x2 - w, b.y, w, h ];
|
||||
case 'tl': return [ b.x2 - w , b.y2 - h, w, h ];
|
||||
case 'br': return [ b.x, b.y, w, h ];
|
||||
case 'tr': return [ b.x, b.y2 - h, w, h ];
|
||||
}
|
||||
},
|
||||
getQuadrant: function(s){
|
||||
var relx = s.opposite[0]-s.offsetx
|
||||
var rely = s.opposite[1]-s.offsety;
|
||||
|
||||
if ((relx < 0) && (rely < 0)) return 'br';
|
||||
else if ((relx >= 0) && (rely >= 0)) return 'tl';
|
||||
else if ((relx < 0) && (rely >= 0)) return 'tr';
|
||||
return 'bl';
|
||||
},
|
||||
filter: function(b,ord,sel){
|
||||
|
||||
if (ord == 'move') return b;
|
||||
|
||||
var w = b.w, h = b.h, st = sel.state, r = this.limits;
|
||||
var quad = st? this.getQuadrant(st): 'br';
|
||||
|
||||
if (r.minw && (w < r.minw)) w = r.minw;
|
||||
if (r.minh && (h < r.minh)) h = r.minh;
|
||||
if (r.maxw && (w > r.maxw)) w = r.maxw;
|
||||
if (r.maxh && (h > r.maxh)) h = r.maxh;
|
||||
|
||||
if ((w == b.w) && (h == b.h)) return b;
|
||||
|
||||
return Jcrop.wrapFromXywh(this.offsetFromCorner(quad,[w,h],b));
|
||||
},
|
||||
refresh: function(sel){
|
||||
this.elw = sel.core.container.width();
|
||||
this.elh = sel.core.container.height();
|
||||
|
||||
this.limits = {
|
||||
minw: sel.minSize[0],
|
||||
minh: sel.minSize[1],
|
||||
maxw: sel.maxSize[0],
|
||||
maxh: sel.maxSize[1]
|
||||
};
|
||||
}
|
||||
});
|
||||
Jcrop.registerFilter('extent',ExtentFilter);
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* GridFilter
|
||||
* a rudimentary grid effect
|
||||
*/
|
||||
var GridFilter = function(){
|
||||
this.stepx = 1;
|
||||
this.stepy = 1;
|
||||
this.core = null;
|
||||
};
|
||||
$.extend(GridFilter.prototype,{
|
||||
tag: 'grid',
|
||||
priority: 19,
|
||||
filter: function(b){
|
||||
|
||||
var n = {
|
||||
x: Math.round(b.x / this.stepx) * this.stepx,
|
||||
y: Math.round(b.y / this.stepy) * this.stepy,
|
||||
x2: Math.round(b.x2 / this.stepx) * this.stepx,
|
||||
y2: Math.round(b.y2 / this.stepy) * this.stepy
|
||||
};
|
||||
|
||||
n.w = n.x2 - n.x;
|
||||
n.h = n.y2 - n.y;
|
||||
|
||||
return n;
|
||||
}
|
||||
});
|
||||
Jcrop.registerFilter('grid',GridFilter);
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* RatioFilter
|
||||
* implements aspectRatio locking
|
||||
*/
|
||||
var RatioFilter = function(){
|
||||
this.ratio = 0;
|
||||
this.core = null;
|
||||
};
|
||||
$.extend(RatioFilter.prototype,{
|
||||
tag: 'ratio',
|
||||
priority: 15,
|
||||
offsetFromCorner: function(corner,box,b){
|
||||
var w = box[0], h = box[1];
|
||||
switch(corner){
|
||||
case 'bl': return [ b.x2 - w, b.y, w, h ];
|
||||
case 'tl': return [ b.x2 - w , b.y2 - h, w, h ];
|
||||
case 'br': return [ b.x, b.y, w, h ];
|
||||
case 'tr': return [ b.x, b.y2 - h, w, h ];
|
||||
}
|
||||
},
|
||||
getBoundRatio: function(b,quad){
|
||||
var box = Jcrop.getLargestBox(this.ratio,b.w,b.h);
|
||||
return Jcrop.wrapFromXywh(this.offsetFromCorner(quad,box,b));
|
||||
},
|
||||
getQuadrant: function(s){
|
||||
var relx = s.opposite[0]-s.offsetx
|
||||
var rely = s.opposite[1]-s.offsety;
|
||||
|
||||
if ((relx < 0) && (rely < 0)) return 'br';
|
||||
else if ((relx >= 0) && (rely >= 0)) return 'tl';
|
||||
else if ((relx < 0) && (rely >= 0)) return 'tr';
|
||||
return 'bl';
|
||||
},
|
||||
filter: function(b,ord,sel){
|
||||
|
||||
if (!this.ratio) return b;
|
||||
|
||||
var rt = b.w / b.h;
|
||||
var st = sel.state;
|
||||
|
||||
var quad = st? this.getQuadrant(st): 'br';
|
||||
ord = ord || 'se';
|
||||
|
||||
if (ord == 'move') return b;
|
||||
|
||||
switch(ord) {
|
||||
case 'n':
|
||||
b.x2 = this.elw;
|
||||
b.w = b.x2 - b.x;
|
||||
quad = 'tr';
|
||||
break;
|
||||
case 's':
|
||||
b.x2 = this.elw;
|
||||
b.w = b.x2 - b.x;
|
||||
quad = 'br';
|
||||
break;
|
||||
case 'e':
|
||||
b.y2 = this.elh;
|
||||
b.h = b.y2 - b.y;
|
||||
quad = 'br';
|
||||
break;
|
||||
case 'w':
|
||||
b.y2 = this.elh;
|
||||
b.h = b.y2 - b.y;
|
||||
quad = 'bl';
|
||||
break;
|
||||
}
|
||||
|
||||
return this.getBoundRatio(b,quad);
|
||||
},
|
||||
refresh: function(sel){
|
||||
this.ratio = sel.aspectRatio;
|
||||
this.elw = sel.core.container.width();
|
||||
this.elh = sel.core.container.height();
|
||||
}
|
||||
});
|
||||
Jcrop.registerFilter('ratio',RatioFilter);
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* RoundFilter
|
||||
* rounds coordinate values to integers
|
||||
*/
|
||||
var RoundFilter = function(){
|
||||
this.core = null;
|
||||
};
|
||||
$.extend(RoundFilter.prototype,{
|
||||
tag: 'round',
|
||||
priority: 90,
|
||||
filter: function(b){
|
||||
|
||||
var n = {
|
||||
x: Math.round(b.x),
|
||||
y: Math.round(b.y),
|
||||
x2: Math.round(b.x2),
|
||||
y2: Math.round(b.y2)
|
||||
};
|
||||
|
||||
n.w = n.x2 - n.x;
|
||||
n.h = n.y2 - n.y;
|
||||
|
||||
return n;
|
||||
}
|
||||
});
|
||||
Jcrop.registerFilter('round',RoundFilter);
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* ShadeFilter
|
||||
* A filter that implements div-based shading on any element
|
||||
*
|
||||
* The shading you see is actually four semi-opaque divs
|
||||
* positioned inside the container, around the selection
|
||||
*/
|
||||
var ShadeFilter = function(opacity,color){
|
||||
this.color = color || 'black';
|
||||
this.opacity = opacity || 0.5;
|
||||
this.core = null;
|
||||
this.shades = {};
|
||||
};
|
||||
$.extend(ShadeFilter.prototype,{
|
||||
tag: 'shader',
|
||||
fade: true,
|
||||
fadeEasing: 'swing',
|
||||
fadeSpeed: 320,
|
||||
priority: 95,
|
||||
init: function(){
|
||||
var t = this;
|
||||
|
||||
if (!t.attached) {
|
||||
t.visible = false;
|
||||
|
||||
t.container = $('<div />').addClass(t.core.opt.css_shades)
|
||||
.prependTo(this.core.container).hide();
|
||||
|
||||
t.elh = this.core.container.height();
|
||||
t.elw = this.core.container.width();
|
||||
|
||||
t.shades = {
|
||||
top: t.createShade(),
|
||||
right: t.createShade(),
|
||||
left: t.createShade(),
|
||||
bottom: t.createShade()
|
||||
};
|
||||
|
||||
t.attached = true;
|
||||
}
|
||||
},
|
||||
destroy: function(){
|
||||
this.container.remove();
|
||||
},
|
||||
setColor: function(color,instant){
|
||||
var t = this;
|
||||
|
||||
if (color == t.color) return t;
|
||||
|
||||
this.color = color;
|
||||
var colorfade = Jcrop.supportsColorFade();
|
||||
$.each(t.shades,function(u,i){
|
||||
if (!t.fade || instant || !colorfade) i.css('backgroundColor',color);
|
||||
else i.animate({backgroundColor:color},{queue:false,duration:t.fadeSpeed,easing:t.fadeEasing});
|
||||
});
|
||||
return t;
|
||||
},
|
||||
setOpacity: function(opacity,instant){
|
||||
var t = this;
|
||||
|
||||
if (opacity == t.opacity) return t;
|
||||
|
||||
t.opacity = opacity;
|
||||
$.each(t.shades,function(u,i){
|
||||
if (!t.fade || instant) i.css({opacity:opacity});
|
||||
else i.animate({opacity:opacity},{queue:false,duration:t.fadeSpeed,easing:t.fadeEasing});
|
||||
});
|
||||
return t;
|
||||
},
|
||||
createShade: function(){
|
||||
return $('<div />').css({
|
||||
position: 'absolute',
|
||||
backgroundColor: this.color,
|
||||
opacity: this.opacity
|
||||
}).appendTo(this.container);
|
||||
},
|
||||
refresh: function(sel){
|
||||
var m = this.core, s = this.shades;
|
||||
|
||||
this.setColor(sel.bgColor?sel.bgColor:this.core.opt.bgColor);
|
||||
this.setOpacity(sel.bgOpacity?sel.bgOpacity:this.core.opt.bgOpacity);
|
||||
|
||||
this.elh = m.container.height();
|
||||
this.elw = m.container.width();
|
||||
s.right.css('height',this.elh+'px');
|
||||
s.left.css('height',this.elh+'px');
|
||||
},
|
||||
filter: function(b,ord,sel){
|
||||
|
||||
if (!sel.active) return b;
|
||||
|
||||
var t = this,
|
||||
s = t.shades;
|
||||
|
||||
s.top.css({
|
||||
left: Math.round(b.x)+'px',
|
||||
width: Math.round(b.w)+'px',
|
||||
height: Math.round(b.y)+'px'
|
||||
});
|
||||
s.bottom.css({
|
||||
top: Math.round(b.y2)+'px',
|
||||
left: Math.round(b.x)+'px',
|
||||
width: Math.round(b.w)+'px',
|
||||
height: (t.elh-Math.round(b.y2))+'px'
|
||||
});
|
||||
s.right.css({
|
||||
left: Math.round(b.x2)+'px',
|
||||
width: (t.elw-Math.round(b.x2))+'px'
|
||||
});
|
||||
s.left.css({
|
||||
width: Math.round(b.x)+'px'
|
||||
});
|
||||
|
||||
if (!t.visible) {
|
||||
t.container.show();
|
||||
t.visible = true;
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
});
|
||||
Jcrop.registerFilter('shader',ShadeFilter);
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
(function($){
|
||||
'use strict';
|
||||
@@ -0,0 +1,378 @@
|
||||
/* Modernizr 2.7.1 (Custom Build) | MIT & BSD
|
||||
* Build: http://modernizr.com/download/#-csstransforms-canvas-canvastext-draganddrop-inlinesvg-svg-svgclippaths-touch-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-url_data_uri
|
||||
*/
|
||||
;
|
||||
|
||||
var Modernizr = (function( window, document, undefined ) {
|
||||
|
||||
var version = '2.7.1',
|
||||
|
||||
Modernizr = {},
|
||||
|
||||
|
||||
docElement = document.documentElement,
|
||||
|
||||
mod = 'modernizr',
|
||||
modElem = document.createElement(mod),
|
||||
mStyle = modElem.style,
|
||||
|
||||
inputElem ,
|
||||
|
||||
|
||||
toString = {}.toString,
|
||||
|
||||
prefixes = ' -webkit- -moz- -o- -ms- '.split(' '),
|
||||
|
||||
|
||||
|
||||
omPrefixes = 'Webkit Moz O ms',
|
||||
|
||||
cssomPrefixes = omPrefixes.split(' '),
|
||||
|
||||
domPrefixes = omPrefixes.toLowerCase().split(' '),
|
||||
|
||||
ns = {'svg': 'http://www.w3.org/2000/svg'},
|
||||
|
||||
tests = {},
|
||||
inputs = {},
|
||||
attrs = {},
|
||||
|
||||
classes = [],
|
||||
|
||||
slice = classes.slice,
|
||||
|
||||
featureName,
|
||||
|
||||
|
||||
injectElementWithStyles = function( rule, callback, nodes, testnames ) {
|
||||
|
||||
var style, ret, node, docOverflow,
|
||||
div = document.createElement('div'),
|
||||
body = document.body,
|
||||
fakeBody = body || document.createElement('body');
|
||||
|
||||
if ( parseInt(nodes, 10) ) {
|
||||
while ( nodes-- ) {
|
||||
node = document.createElement('div');
|
||||
node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
|
||||
div.appendChild(node);
|
||||
}
|
||||
}
|
||||
|
||||
style = ['­','<style id="s', mod, '">', rule, '</style>'].join('');
|
||||
div.id = mod;
|
||||
(body ? div : fakeBody).innerHTML += style;
|
||||
fakeBody.appendChild(div);
|
||||
if ( !body ) {
|
||||
fakeBody.style.background = '';
|
||||
fakeBody.style.overflow = 'hidden';
|
||||
docOverflow = docElement.style.overflow;
|
||||
docElement.style.overflow = 'hidden';
|
||||
docElement.appendChild(fakeBody);
|
||||
}
|
||||
|
||||
ret = callback(div, rule);
|
||||
if ( !body ) {
|
||||
fakeBody.parentNode.removeChild(fakeBody);
|
||||
docElement.style.overflow = docOverflow;
|
||||
} else {
|
||||
div.parentNode.removeChild(div);
|
||||
}
|
||||
|
||||
return !!ret;
|
||||
|
||||
},
|
||||
|
||||
|
||||
|
||||
isEventSupported = (function() {
|
||||
|
||||
var TAGNAMES = {
|
||||
'select': 'input', 'change': 'input',
|
||||
'submit': 'form', 'reset': 'form',
|
||||
'error': 'img', 'load': 'img', 'abort': 'img'
|
||||
};
|
||||
|
||||
function isEventSupported( eventName, element ) {
|
||||
|
||||
element = element || document.createElement(TAGNAMES[eventName] || 'div');
|
||||
eventName = 'on' + eventName;
|
||||
|
||||
var isSupported = eventName in element;
|
||||
|
||||
if ( !isSupported ) {
|
||||
if ( !element.setAttribute ) {
|
||||
element = document.createElement('div');
|
||||
}
|
||||
if ( element.setAttribute && element.removeAttribute ) {
|
||||
element.setAttribute(eventName, '');
|
||||
isSupported = is(element[eventName], 'function');
|
||||
|
||||
if ( !is(element[eventName], 'undefined') ) {
|
||||
element[eventName] = undefined;
|
||||
}
|
||||
element.removeAttribute(eventName);
|
||||
}
|
||||
}
|
||||
|
||||
element = null;
|
||||
return isSupported;
|
||||
}
|
||||
return isEventSupported;
|
||||
})(),
|
||||
|
||||
|
||||
_hasOwnProperty = ({}).hasOwnProperty, hasOwnProp;
|
||||
|
||||
if ( !is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined') ) {
|
||||
hasOwnProp = function (object, property) {
|
||||
return _hasOwnProperty.call(object, property);
|
||||
};
|
||||
}
|
||||
else {
|
||||
hasOwnProp = function (object, property) {
|
||||
return ((property in object) && is(object.constructor.prototype[property], 'undefined'));
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
if (!Function.prototype.bind) {
|
||||
Function.prototype.bind = function bind(that) {
|
||||
|
||||
var target = this;
|
||||
|
||||
if (typeof target != "function") {
|
||||
throw new TypeError();
|
||||
}
|
||||
|
||||
var args = slice.call(arguments, 1),
|
||||
bound = function () {
|
||||
|
||||
if (this instanceof bound) {
|
||||
|
||||
var F = function(){};
|
||||
F.prototype = target.prototype;
|
||||
var self = new F();
|
||||
|
||||
var result = target.apply(
|
||||
self,
|
||||
args.concat(slice.call(arguments))
|
||||
);
|
||||
if (Object(result) === result) {
|
||||
return result;
|
||||
}
|
||||
return self;
|
||||
|
||||
} else {
|
||||
|
||||
return target.apply(
|
||||
that,
|
||||
args.concat(slice.call(arguments))
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return bound;
|
||||
};
|
||||
}
|
||||
|
||||
function setCss( str ) {
|
||||
mStyle.cssText = str;
|
||||
}
|
||||
|
||||
function setCssAll( str1, str2 ) {
|
||||
return setCss(prefixes.join(str1 + ';') + ( str2 || '' ));
|
||||
}
|
||||
|
||||
function is( obj, type ) {
|
||||
return typeof obj === type;
|
||||
}
|
||||
|
||||
function contains( str, substr ) {
|
||||
return !!~('' + str).indexOf(substr);
|
||||
}
|
||||
|
||||
function testProps( props, prefixed ) {
|
||||
for ( var i in props ) {
|
||||
var prop = props[i];
|
||||
if ( !contains(prop, "-") && mStyle[prop] !== undefined ) {
|
||||
return prefixed == 'pfx' ? prop : true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function testDOMProps( props, obj, elem ) {
|
||||
for ( var i in props ) {
|
||||
var item = obj[props[i]];
|
||||
if ( item !== undefined) {
|
||||
|
||||
if (elem === false) return props[i];
|
||||
|
||||
if (is(item, 'function')){
|
||||
return item.bind(elem || obj);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function testPropsAll( prop, prefixed, elem ) {
|
||||
|
||||
var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
|
||||
props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
|
||||
|
||||
if(is(prefixed, "string") || is(prefixed, "undefined")) {
|
||||
return testProps(props, prefixed);
|
||||
|
||||
} else {
|
||||
props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
|
||||
return testDOMProps(props, prefixed, elem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
tests['canvas'] = function() {
|
||||
var elem = document.createElement('canvas');
|
||||
return !!(elem.getContext && elem.getContext('2d'));
|
||||
};
|
||||
|
||||
tests['canvastext'] = function() {
|
||||
return !!(Modernizr['canvas'] && is(document.createElement('canvas').getContext('2d').fillText, 'function'));
|
||||
};
|
||||
tests['touch'] = function() {
|
||||
var bool;
|
||||
|
||||
if(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
|
||||
bool = true;
|
||||
} else {
|
||||
injectElementWithStyles(['@media (',prefixes.join('touch-enabled),('),mod,')','{#modernizr{top:9px;position:absolute}}'].join(''), function( node ) {
|
||||
bool = node.offsetTop === 9;
|
||||
});
|
||||
}
|
||||
|
||||
return bool;
|
||||
};
|
||||
|
||||
tests['draganddrop'] = function() {
|
||||
var div = document.createElement('div');
|
||||
return ('draggable' in div) || ('ondragstart' in div && 'ondrop' in div);
|
||||
};
|
||||
|
||||
|
||||
tests['csstransforms'] = function() {
|
||||
return !!testPropsAll('transform');
|
||||
};
|
||||
|
||||
|
||||
tests['svg'] = function() {
|
||||
return !!document.createElementNS && !!document.createElementNS(ns.svg, 'svg').createSVGRect;
|
||||
};
|
||||
|
||||
tests['inlinesvg'] = function() {
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = '<svg/>';
|
||||
return (div.firstChild && div.firstChild.namespaceURI) == ns.svg;
|
||||
};
|
||||
|
||||
|
||||
|
||||
tests['svgclippaths'] = function() {
|
||||
return !!document.createElementNS && /SVGClipPath/.test(toString.call(document.createElementNS(ns.svg, 'clipPath')));
|
||||
};
|
||||
|
||||
for ( var feature in tests ) {
|
||||
if ( hasOwnProp(tests, feature) ) {
|
||||
featureName = feature.toLowerCase();
|
||||
Modernizr[featureName] = tests[feature]();
|
||||
|
||||
classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Modernizr.addTest = function ( feature, test ) {
|
||||
if ( typeof feature == 'object' ) {
|
||||
for ( var key in feature ) {
|
||||
if ( hasOwnProp( feature, key ) ) {
|
||||
Modernizr.addTest( key, feature[ key ] );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
feature = feature.toLowerCase();
|
||||
|
||||
if ( Modernizr[feature] !== undefined ) {
|
||||
return Modernizr;
|
||||
}
|
||||
|
||||
test = typeof test == 'function' ? test() : test;
|
||||
|
||||
if (typeof enableClasses !== "undefined" && enableClasses) {
|
||||
docElement.className += ' ' + (test ? '' : 'no-') + feature;
|
||||
}
|
||||
Modernizr[feature] = test;
|
||||
|
||||
}
|
||||
|
||||
return Modernizr;
|
||||
};
|
||||
|
||||
|
||||
setCss('');
|
||||
modElem = inputElem = null;
|
||||
|
||||
|
||||
Modernizr._version = version;
|
||||
|
||||
Modernizr._prefixes = prefixes;
|
||||
Modernizr._domPrefixes = domPrefixes;
|
||||
Modernizr._cssomPrefixes = cssomPrefixes;
|
||||
|
||||
|
||||
Modernizr.hasEvent = isEventSupported;
|
||||
|
||||
Modernizr.testProp = function(prop){
|
||||
return testProps([prop]);
|
||||
};
|
||||
|
||||
Modernizr.testAllProps = testPropsAll;
|
||||
|
||||
|
||||
Modernizr.testStyles = injectElementWithStyles;
|
||||
return Modernizr;
|
||||
|
||||
})(window, window.document);
|
||||
// data uri test.
|
||||
// https://github.com/Modernizr/Modernizr/issues/14
|
||||
|
||||
// This test is asynchronous. Watch out.
|
||||
|
||||
|
||||
// in IE7 in HTTPS this can cause a Mixed Content security popup.
|
||||
// github.com/Modernizr/Modernizr/issues/362
|
||||
// To avoid that you can create a new iframe and inject this.. perhaps..
|
||||
|
||||
|
||||
(function(){
|
||||
|
||||
var datauri = new Image();
|
||||
|
||||
|
||||
datauri.onerror = function() {
|
||||
Modernizr.addTest('datauri', function () { return false; });
|
||||
};
|
||||
datauri.onload = function() {
|
||||
Modernizr.addTest('datauri', function () { return (datauri.width == 1 && datauri.height == 1); });
|
||||
};
|
||||
|
||||
datauri.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
|
||||
|
||||
})();
|
||||
;
|
||||
@@ -0,0 +1,14 @@
|
||||
// Attach to jQuery object
|
||||
$.Jcrop = Jcrop;
|
||||
|
||||
$.Jcrop.supportsCanvas = Modernizr.canvas;
|
||||
$.Jcrop.supportsCanvasText = Modernizr.canvastext;
|
||||
$.Jcrop.supportsDragAndDrop = Modernizr.draganddrop;
|
||||
$.Jcrop.supportsDataURI = Modernizr.datauri;
|
||||
$.Jcrop.supportsSVG = Modernizr.svg;
|
||||
$.Jcrop.supportsInlineSVG = Modernizr.inlinesvg;
|
||||
$.Jcrop.supportsSVGClipPaths = Modernizr.svgclippaths;
|
||||
$.Jcrop.supportsCSSTransforms = Modernizr.csstransforms;
|
||||
$.Jcrop.supportsTouch = Modernizr.touch;
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,63 @@
|
||||
// Jcrop jQuery plugin function
|
||||
$.fn.Jcrop = function(options,callback){
|
||||
options = options || {};
|
||||
|
||||
var first = this.eq(0).data('Jcrop');
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
|
||||
// Return API if requested
|
||||
if (options == 'api') { return first; }
|
||||
|
||||
// Allow calling API methods (with arguments)
|
||||
else if (first && (typeof options == 'string')) {
|
||||
|
||||
// Call method if it exists
|
||||
if (first[options]) {
|
||||
args.shift();
|
||||
first[options].apply(first,args);
|
||||
return first;
|
||||
}
|
||||
|
||||
// Unknown input/method does not exist
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, loop over selected elements
|
||||
this.each(function(){
|
||||
var t = this, $t = $(this);
|
||||
var exists = $t.data('Jcrop');
|
||||
var obj;
|
||||
|
||||
// If Jcrop already exists on this element only setOptions()
|
||||
if (exists)
|
||||
exists.setOptions(options);
|
||||
|
||||
else {
|
||||
|
||||
if (!options.stageConstructor)
|
||||
options.stageConstructor = $.Jcrop.stageConstructor;
|
||||
|
||||
options.stageConstructor(this,options,function(stage,options){
|
||||
var selection = options.setSelect;
|
||||
if (selection) delete(options.setSelect);
|
||||
|
||||
var obj = $.Jcrop.attach(stage.element,options);
|
||||
|
||||
if (typeof stage.attach == 'function')
|
||||
stage.attach(obj);
|
||||
|
||||
$t.data('Jcrop',obj);
|
||||
|
||||
if (selection) {
|
||||
obj.newSelection();
|
||||
obj.setSelect(selection);
|
||||
}
|
||||
|
||||
if (typeof callback == 'function')
|
||||
callback.call(obj);
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
var AbstractStage = function(){
|
||||
};
|
||||
|
||||
$.extend(AbstractStage,{
|
||||
isSupported: function(el,o){
|
||||
// @todo: should actually check if it's an HTML element
|
||||
return true;
|
||||
},
|
||||
// A higher priority means less desirable
|
||||
// AbstractStage is the last one we want to use
|
||||
priority: 100,
|
||||
create: function(el,options,callback){
|
||||
var obj = new AbstractStage;
|
||||
obj.element = el;
|
||||
callback.call(this,obj,options);
|
||||
},
|
||||
prototype: {
|
||||
attach: function(core){
|
||||
this.init(core);
|
||||
core.ui.stage = this;
|
||||
},
|
||||
triggerEvent: function(ev){
|
||||
$(this.element).trigger(ev);
|
||||
return this;
|
||||
},
|
||||
getElement: function(){
|
||||
return this.element;
|
||||
}
|
||||
}
|
||||
});
|
||||
Jcrop.registerStageType('Block',AbstractStage);
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
var CanvasStage = function(){
|
||||
this.angle = 0;
|
||||
this.scale = 1;
|
||||
this.scaleMin = 0.2;
|
||||
this.scaleMax = 1.25;
|
||||
this.offset = [0,0];
|
||||
};
|
||||
|
||||
CanvasStage.prototype = new ImageStage();
|
||||
|
||||
$.extend(CanvasStage,{
|
||||
isSupported: function(el,o){
|
||||
if ($.Jcrop.supportsCanvas && (el.tagName == 'IMG')) return true;
|
||||
},
|
||||
priority: 60,
|
||||
create: function(el,options,callback){
|
||||
var $el = $(el);
|
||||
var opt = $.extend({},options);
|
||||
$.Jcrop.component.ImageLoader.attach(el,function(w,h){
|
||||
var obj = new CanvasStage;
|
||||
$el.hide();
|
||||
obj.createCanvas(el,w,h);
|
||||
$el.before(obj.element);
|
||||
obj.imgsrc = el;
|
||||
opt.imgsrc = el;
|
||||
|
||||
if (typeof callback == 'function'){
|
||||
callback(obj,opt);
|
||||
obj.redraw();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$.extend(CanvasStage.prototype,{
|
||||
init: function(core){
|
||||
this.core = core;
|
||||
},
|
||||
// setOffset: function(x,y) {{{
|
||||
setOffset: function(x,y) {
|
||||
this.offset = [x,y];
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
// setAngle: function(v) {{{
|
||||
setAngle: function(v) {
|
||||
this.angle = v;
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
// setScale: function(v) {{{
|
||||
setScale: function(v) {
|
||||
this.scale = this.boundScale(v);
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
boundScale: function(v){
|
||||
if (v<this.scaleMin) v = this.scaleMin;
|
||||
else if (v>this.scaleMax) v = this.scaleMax;
|
||||
return v;
|
||||
},
|
||||
createCanvas: function(img,w,h){
|
||||
this.width = w;
|
||||
this.height = h;
|
||||
this.canvas = document.createElement('canvas');
|
||||
this.canvas.width = w;
|
||||
this.canvas.height = h;
|
||||
this.$canvas = $(this.canvas).width('100%').height('100%');
|
||||
this.context = this.canvas.getContext('2d');
|
||||
this.fillstyle = "rgb(0,0,0)";
|
||||
this.element = this.$canvas.wrap('<div />').parent().width(w).height(h);
|
||||
},
|
||||
triggerEvent: function(ev){
|
||||
this.$canvas.trigger(ev);
|
||||
return this;
|
||||
},
|
||||
// clear: function() {{{
|
||||
clear: function() {
|
||||
this.context.fillStyle = this.fillstyle;
|
||||
this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
// redraw: function() {{{
|
||||
redraw: function() {
|
||||
// Save the current context
|
||||
this.context.save();
|
||||
this.clear();
|
||||
|
||||
// Translate to the center point of our image
|
||||
this.context.translate(parseInt(this.width * 0.5), parseInt(this.height * 0.5));
|
||||
// Perform the rotation and scaling
|
||||
this.context.translate(this.offset[0]/this.core.opt.xscale,this.offset[1]/this.core.opt.yscale);
|
||||
this.context.rotate(this.angle * (Math.PI/180));
|
||||
this.context.scale(this.scale,this.scale);
|
||||
// Translate back to the top left of our image
|
||||
this.context.translate(-parseInt(this.width * 0.5), -parseInt(this.height * 0.5));
|
||||
// Finally we draw the image
|
||||
this.context.drawImage(this.imgsrc,0,0,this.width,this.height);
|
||||
|
||||
// And restore the updated context
|
||||
this.context.restore();
|
||||
this.$canvas.trigger('cropredraw');
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
// setFillStyle: function(v) {{{
|
||||
setFillStyle: function(v) {
|
||||
this.fillstyle = v;
|
||||
return this;
|
||||
}
|
||||
// }}}
|
||||
});
|
||||
|
||||
Jcrop.registerStageType('Canvas',CanvasStage);
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
var TransformStage = function(){
|
||||
this.angle = 0;
|
||||
this.scale = 1;
|
||||
this.scaleMin = 0.2;
|
||||
this.scaleMax = 1.25;
|
||||
this.offset = [0,0];
|
||||
};
|
||||
|
||||
TransformStage.prototype = new ImageStage();
|
||||
|
||||
$.extend(TransformStage,{
|
||||
isSupported: function(el,o){
|
||||
if ($.Jcrop.supportsCSSTransforms && (el.tagName == 'IMG')) return true;
|
||||
},
|
||||
priority: 101,
|
||||
create: function(el,options,callback){
|
||||
$.Jcrop.component.ImageLoader.attach(el,function(w,h){
|
||||
var obj = new TransformStage;
|
||||
obj.$img = $(el);
|
||||
obj.element = obj.$img.wrap('<div />').parent();
|
||||
obj.element.width(w).height(h);
|
||||
obj.imgsrc = el;
|
||||
|
||||
if (typeof callback == 'function')
|
||||
callback.call(this,obj,options);
|
||||
});
|
||||
}
|
||||
});
|
||||
$.extend(TransformStage.prototype,{
|
||||
init: function(core){
|
||||
this.core = core;
|
||||
},
|
||||
boundScale: function(v){
|
||||
if (v<this.scaleMin) v = this.scaleMin;
|
||||
else if (v>this.scaleMax) v = this.scaleMax;
|
||||
return v;
|
||||
},
|
||||
// setOffset: function(x,y) {{{
|
||||
setOffset: function(x,y) {
|
||||
this.offset = [x,y];
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
// setAngle: function(v) {{{
|
||||
setAngle: function(v) {
|
||||
this.angle = v;
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
// setScale: function(v) {{{
|
||||
setScale: function(v) {
|
||||
this.scale = this.boundScale(v);
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
// clear: function() {{{
|
||||
clear: function() {
|
||||
},
|
||||
// }}}
|
||||
triggerEvent: function(ev){
|
||||
this.$img.trigger(ev);
|
||||
return this;
|
||||
},
|
||||
// redraw: function() {{{
|
||||
redraw: function() {
|
||||
|
||||
this.$img.css({
|
||||
transform:
|
||||
'translate('+(-this.offset[0])+'px,'+(-this.offset[1])+'px) '+
|
||||
'rotate('+this.angle+'deg) '+
|
||||
'scale('+this.scale+','+this.scale+')'
|
||||
});
|
||||
|
||||
this.$img.trigger('cropredraw');
|
||||
return this;
|
||||
},
|
||||
// }}}
|
||||
});
|
||||
Jcrop.registerStageType('Transform',TransformStage);
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
var ImageStage = function(){
|
||||
};
|
||||
|
||||
ImageStage.prototype = new AbstractStage();
|
||||
|
||||
$.extend(ImageStage,{
|
||||
isSupported: function(el,o){
|
||||
if (el.tagName == 'IMG') return true;
|
||||
},
|
||||
priority: 90,
|
||||
create: function(el,options,callback){
|
||||
$.Jcrop.component.ImageLoader.attach(el,function(w,h){
|
||||
var obj = new ImageStage;
|
||||
obj.element = $(el).wrap('<div />').parent();
|
||||
|
||||
obj.element.width(w).height(h);
|
||||
obj.imgsrc = el;
|
||||
|
||||
if (typeof callback == 'function')
|
||||
callback.call(this,obj,options);
|
||||
});
|
||||
}
|
||||
});
|
||||
Jcrop.registerStageType('Image',ImageStage);
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
// Jcrop static functions
|
||||
$.extend(Jcrop,{
|
||||
component: { },
|
||||
filter: { },
|
||||
stage: { },
|
||||
registerComponent: function(name,component){
|
||||
Jcrop.component[name] = component;
|
||||
},
|
||||
registerFilter: function(name,filter){
|
||||
Jcrop.filter[name] = filter;
|
||||
},
|
||||
registerStageType: function(name,stage){
|
||||
Jcrop.stage[name] = stage;
|
||||
},
|
||||
// attach: function(element,opt){{{
|
||||
attach: function(element,opt){
|
||||
var obj = new $.Jcrop(element,opt);
|
||||
return obj;
|
||||
},
|
||||
// }}}
|
||||
// imgCopy: function(imgel){{{
|
||||
imgCopy: function(imgel){
|
||||
var img = new Image;
|
||||
img.src = imgel.src;
|
||||
return img;
|
||||
},
|
||||
// }}}
|
||||
// imageClone: function(imgel){{{
|
||||
imageClone: function(imgel){
|
||||
return $.Jcrop.supportsCanvas?
|
||||
Jcrop.canvasClone(imgel):
|
||||
Jcrop.imgCopy(imgel);
|
||||
},
|
||||
// }}}
|
||||
// canvasClone: function(imgel){{{
|
||||
canvasClone: function(imgel){
|
||||
var canvas = document.createElement('canvas'),
|
||||
ctx = canvas.getContext('2d');
|
||||
|
||||
$(canvas).width(imgel.width).height(imgel.height),
|
||||
canvas.width = imgel.naturalWidth;
|
||||
canvas.height = imgel.naturalHeight;
|
||||
ctx.drawImage(imgel,0,0,imgel.naturalWidth,imgel.naturalHeight);
|
||||
return canvas;
|
||||
},
|
||||
// }}}
|
||||
// propagate: function(plist,config,obj){{{
|
||||
propagate: function(plist,config,obj){
|
||||
for(var i=0,l=plist.length;i<l;i++)
|
||||
if (config.hasOwnProperty(plist[i]))
|
||||
obj[plist[i]] = config[plist[i]];
|
||||
},
|
||||
// }}}
|
||||
// getLargestBox: function(ratio,w,h){{{
|
||||
getLargestBox: function(ratio,w,h){
|
||||
if ((w/h) > ratio)
|
||||
return [ h * ratio, h ];
|
||||
else return [ w, w / ratio ];
|
||||
},
|
||||
// }}}
|
||||
// stageConstructor: function(el,options,callback){{{
|
||||
stageConstructor: function(el,options,callback){
|
||||
|
||||
// Get a priority-ordered list of available stages
|
||||
var stages = [];
|
||||
$.each(Jcrop.stage,function(i,e){
|
||||
stages.push(e);
|
||||
});
|
||||
stages.sort(function(a,b){ return a.priority - b.priority; });
|
||||
|
||||
// Find the first one that supports this element
|
||||
for(var i=0,l=stages.length;i<l;i++){
|
||||
if (stages[i].isSupported(el,options)){
|
||||
stages[i].create(el,options,function(obj,opt){
|
||||
if (typeof callback == 'function') callback(obj,opt);
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
// }}}
|
||||
// supportsColorFade: function(){{{
|
||||
supportsColorFade: function(){
|
||||
return $.fx.step.hasOwnProperty('backgroundColor');
|
||||
},
|
||||
// }}}
|
||||
// wrapFromXywh: function(xywh){{{
|
||||
wrapFromXywh: function(xywh){
|
||||
var b = { x: xywh[0], y: xywh[1], w: xywh[2], h: xywh[3] };
|
||||
b.x2 = b.x + b.w;
|
||||
b.y2 = b.y + b.h;
|
||||
return b;
|
||||
}
|
||||
// }}}
|
||||
});
|
||||
Reference in New Issue
Block a user