diff --git a/application/common.php b/application/common.php index cdaeca6a..647fdfbc 100644 --- a/application/common.php +++ b/application/common.php @@ -791,9 +791,9 @@ function execute_action($rules = false, $action_id = null, $user_id = null) { function avatar($uid, $size = 'middle') { $size = in_array($size, array('big', 'middle', 'small', 'real')) ? $size : 'middle'; $dir = setavatardir($uid); - $file = BASE_PATH . '/uploads/avatar/' . $dir . 'avatar_' . $size . '.png'; + $file = BASE_PATH . '/static/avatar/' . $dir . 'avatar_' . $size . '.png'; if (!file_exists('.' . $file)) { - $file = BASE_PATH . '/public/images/default_avatar_' . $size . '.jpg'; + $file = BASE_PATH . '/static/images/default_avatar_' . $size . '.jpg'; } return $file; } diff --git a/application/common/model/Member.php b/application/common/model/Member.php index 396a0543..d3cc7f46 100644 --- a/application/common/model/Member.php +++ b/application/common/model/Member.php @@ -13,6 +13,46 @@ class Member extends Base { 'reg_time' => 'integer' ); + public $editfield = array( + array('name'=>'uid','type'=>'hidden'), + array('name'=>'username','title'=>'用户名','type'=>'readonly','help'=>''), + array('name'=>'nickname','title'=>'昵称','type'=>'text','help'=>''), + array('name'=>'password','title'=>'密码','type'=>'password','help'=>'为空时则不修改'), + array('name'=>'sex','title'=>'性别','type'=>'select','option'=>array('0'=>'保密','1'=>'男','2'=>'女'),'help'=>''), + array('name'=>'email','title'=>'邮箱','type'=>'text','help'=>'用户邮箱,用于找回密码等安全操作'), + array('name'=>'qq','title'=>'QQ','type'=>'text','help'=>''), + array('name'=>'score','title'=>'用户积分','type'=>'text','help'=>''), + array('name'=>'signature','title'=>'用户签名','type'=>'textarea','help'=>''), + array('name'=>'status','title'=>'状态','type'=>'select','option'=>array('0'=>'禁用','1'=>'启用'),'help'=>''), + ); + + public $addfield = array( + array('name'=>'username','title'=>'用户名','type'=>'text','help'=>'用户名会作为默认的昵称'), + array('name'=>'password','title'=>'密码','type'=>'password','help'=>'用户密码不能少于6位'), + array('name'=>'repassword','title'=>'确认密码','type'=>'password','help'=>'确认密码'), + array('name'=>'email','title'=>'邮箱','type'=>'text','help'=>'用户邮箱,用于找回密码等安全操作'), + ); + + public $useredit = array( + array('name'=>'uid','type'=>'hidden'), + array('name'=>'nickname','title'=>'昵称','type'=>'text','help'=>''), + array('name'=>'sex','title'=>'性别','type'=>'select','option'=>array('0'=>'保密','1'=>'男','2'=>'女'),'help'=>''), + array('name'=>'email','title'=>'邮箱','type'=>'text','help'=>'用户邮箱,用于找回密码等安全操作'), + array('name'=>'mobile','title'=>'联系电话','type'=>'text','help'=>''), + array('name'=>'qq','title'=>'QQ','type'=>'text','help'=>''), + array('name'=>'signature','title'=>'用户签名','type'=>'textarea','help'=>''), + ); + + public $userextend = array( + array('name'=>'company','title'=>'单位名称','type'=>'text','help'=>''), + array('name'=>'company_addr','title'=>'单位地址','type'=>'text','help'=>''), + array('name'=>'company_contact','title'=>'单位联系人','type'=>'text','help'=>''), + array('name'=>'company_zip','title'=>'单位邮编','type'=>'text','help'=>''), + array('name'=>'company_depart','title'=>'所属部门','type'=>'text','help'=>''), + array('name'=>'company_post','title'=>'所属职务','type'=>'text','help'=>''), + array('name'=>'company_type','title'=>'单位类型','type'=>'select', 'option'=>'', 'help'=>''), + ); + protected function getGroupListAttr($value, $data){ $sql = db('AuthGroupAccess')->where('uid', $data['uid'])->fetchSql(true)->column('group_id'); return db('AuthGroup')->where('id in ('.$sql.')')->column('title', 'id'); diff --git a/web/static/plugs/avatar/css/style.css b/web/static/plugs/avatar/css/style.css new file mode 100644 index 00000000..df76ef75 --- /dev/null +++ b/web/static/plugs/avatar/css/style.css @@ -0,0 +1,823 @@ +@charset "utf-8"; + +/*缓冲效果开始 2.3加入的*/ + +#shearphoto_main { + visibility: hidden; + margin: 0 auto; +} + +#shearphoto_loading { + width: 100px; + text-align: center; + line-height: 130px; + color: #999; + margin: 0 auto; + background: url(../images/loading.gif) no-repeat +} + + +/*缓冲效果结束*/ + +/*预览开始*/ + +#shearphoto_main #preview { + float: left; + position: relative; +} + +#shearphoto_main #preview a { + display: inline; + float: left; + -moz-border-radius: 5px; + border-radius: 5px; + -moz-box-shadow: 1px 1px 3px 1px #999; + box-shadow: 1px 1px 3px 1px #999; + overflow: hidden; + position: relative; +} + +#shearphoto_main #preview a img { + position: relative; +} + + +/*预览结束*/ + +.bottom a:hover { + color: #39F; + text-decoration: underline; +} + + +/*旋转开始*/ + +#Shearbar #LeftRotate { + margin: 0 10px; +} + +#Shearbar #LeftRotate em, +#Shearbar #RightRotate em { + display: inline-block; + height: 21px; + vertical-align: middle; + width: 15px; + margin: 1px 3px 0 0; + background: url(../images/bch.jpg) no-repeat; +} + +#Shearbar #LeftRotate, +#Shearbar #RightRotate { + -moz-border-radius: 5px; + border: 1px solid #CCC; + border-radius: 5px; + color: #666; + cursor: pointer; + float: left; + font-size: 12px; + margin-top: -5px; + text-align: center; + width: 80px; + padding: 5px 0; +} + +#Shearbar #LeftRotate:hover, +#Shearbar #RightRotate:hover { + border: 1px solid #919191; + color: #414141 +} + +#Shearbar #RightRotate { + margin-left: 10px +} + +#Shearbar #RightRotate em { + background-position: -91px 0; + margin: 1px 0 0 3px; +} + +#Shearbar .hint { + color: #333; + display: block; + float: left; + font-size: 12px; + font-style: normal; + height: 19px; + line-height: 15px; + width: 19px +} + +#Shearbar .hint.L, +#Shearbar .hint.R { + background: url(../images/zoom.png) no-repeat -2px -1px +} + +#Shearbar .hint.R { + background-position: -43px -1px +} + + +/*旋转结束*/ + + +/*选择图片方式开始*/ + +#shearphoto_main #SelectBox { + background: url(../images/bg.png); + position: absolute; + z-index: 180 +} + +#SelectBox #selectImage input { + height: 74px; + width: 224px; + background-color: #FFF; + filter: alpha(opacity=0); + opacity: 0; + position: absolute; + float: left; + cursor: pointer; + display: block; +} + +.displayNone { + display: none; +} + +#SelectBox #selectImage, +#SelectBox #PhotoLoading, +#SelectBox #camerasImage { + -moz-border-radius: 10px; + border-radius: 10px; + -moz-box-shadow: 2px 2px 7px 1px #3e4044; + box-shadow: 2px 2px 7px 1px #3e4044; + display: block; + height: 74px; + outline: 0 none; + position: absolute; + width: 223px; + overflow: hidden; + margin: -37px 0 0 -112px; + background: url(../images/Select.jpg) no-repeat; +} + +#SelectBox #PhotoLoading { + background-position: 0 -148px; + left: 50%; + top: 52% +} + +#SelectBox #selectImage { + left: 50%; + top: 25% +} + +#SelectBox #camerasImage { + background-position: 0 -74px; + left: 50%; + top: 79% +} + +#SelectBox #selectImage:hover, +#SelectBox #PhotoLoading:hover, +#SelectBox #camerasImage:hover { + border: 3px solid #666; + margin: -40px 0 0 -115px; +} + + +/*选择图片方式结束*/ + + +/*工具条开始*/ + +#shearphoto_main #Shearbar { + padding-top: 10px; + width: 442px; + margin: 0 auto; +} + +#Shearbar .Psava { + clear: both; + height: 40px; + padding: 20px 0 0 110px +} + +#Shearbar .Psava #againIMG, +#Shearbar .Psava #saveShear { + background: url(../images/btn5.jpg) no-repeat; + color: #666; + float: left; + line-height: 31px; + margin-right: 20px; + text-align: center; + width: 79px; + height: 31px; +} + +#Shearbar .Psava #againIMG:hover { + background-position: 0px -31px; +} + +#Shearbar .Psava #saveShear { + background-position: -79px 0px; + color: #FFF; +} + +#Shearbar .Psava #saveShear:hover { + background-position: -79px -31px +} + +#Shearbar #ZoomDist { + float: left; + height: 20px; + position: relative; + width: 200px +} + +#Shearbar #ZoomDist #ZoomBar { + background: url(../images/ZoomBar.gif) no-repeat; + filter: alpha(opacity=80); + opacity: 0.8; + height: 20px; + left: 0; + position: absolute; + width: 15px +} + +#ZoomDist #Zoomcentre { + filter: alpha(opacity=100); + height: 9px; + left: 50%; + top: 25px; + position: absolute; + width: 10px; + margin-left: -4px; + background: url(../images/Zoomcentre.jpg) no-repeat +} + +#ZoomDist .progress { + -moz-border-radius: 15px; + border-radius: 15px; + background: #999; + display: block; + float: left; + height: 8px; + margin-top: 4px; + overflow: hidden; + width: 100% +} + + +/*工具条结束*/ + + +/*主功能界面开始*/ + +#shearphoto_main #black { + position: absolute; + z-index: 99 +} + +#shearphoto_main .primary { + float: left; +} + +#shearphoto_main #main { + -moz-user-select: none; + -ms-user-select: none; + -webkit-user-select: none; + background: url(../images/bg.png); + overflow: hidden; + position: relative; + z-index: 50; + border: 1px solid #CCC; + float: left; +} + +#main .BigImg { + float: left; + position: relative; + z-index: 51 +} + +#main .MoveImg { + position: relative; + z-index: 98 +} + +#main #imgID { + display: block; + z-index: 51 +} + +#main #movebox { + position: absolute; + z-index: 100; + float: left; +} + + +/*动态边框开始*/ + +#movebox #borderTop, +#movebox #borderLeft, +#movebox #borderRight, +#movebox #borderBottom { + background: url(../images/border.gif) #FFF; + display: inline-block; + filter: alpha(opacity=50); + opacity: 0.5; + overflow: hidden; + position: absolute; + z-index: 104; +} + +#movebox #borderTop { + height: 1px; + left: 0; + top: 0; + width: 100%; +} + +#movebox #borderLeft { + height: 100%; + left: 0; + top: 0; + width: 1px; +} + +#movebox #borderRight { + height: 100%; + right: 0; + top: 0; + width: 1px; +} + +#movebox #borderBottom { + bottom: 0; + height: 1px; + left: 0; + width: 100%; +} + + +/*动态边框结束*/ + + +/*拉伸截框的八个点开始*/ + +#main #movebox #BottomRight, +#main #movebox #TopRight, +#main #movebox #Topleft, +#main #movebox #Bottomleft, +#main #movebox #Topmiddle, +#main #movebox #leftmiddle, +#main #movebox #Rightmiddle, +#main #movebox #Bottommiddle { + background: #000; + border: 1px solid #FFF; + bottom: -5px; + cursor: nw-resize; + display: block; + filter: alpha(opacity=50); + height: 8px; + opacity: 0.5; + overflow: hidden; + position: absolute; + right: -5px; + width: 8px; + z-index: 105; +} + +#main #movebox #Bottomleft { + bottom: -5px; + cursor: ne-resize; + left: -5px +} + +#main #movebox #Bottommiddle { + bottom: -5px; + cursor: n-resize; + left: 50%; + margin-left: -5px +} + +#main #movebox #Rightmiddle { + cursor: e-resize; + margin-top: -5px; + right: -5px; + top: 50% +} + +#main #movebox #TopRight { + cursor: ne-resize; + right: -5px; + top: -5px +} + +#main #movebox #Topleft { + cursor: nw-resize; + left: -5px; + top: -5px +} + +#main #movebox #Topmiddle { + cursor: n-resize; + left: 50%; + margin-left: -5px; + top: -5px +} + +#main #movebox #leftmiddle { + cursor: e-resize; + left: -5px; + margin-top: -5px; + top: 50% +} + + +/*拉伸截框的八个点结束*/ + +#main #relat { + position: relative; + z-index: 60 +} + +#main #smallbox { + background: url(); + overflow: hidden; + position: relative; + z-index: 100 +} + + +/*主功能界面结束*/ + + +/*上滚下滚提示的CSS*/ + +#main .point { + width: 100%; + line-height: 35px; + font-size: 12px; + position: absolute; + z-index: 200; + filter: alpha(opacity=70); + opacity: 0.7; +} + +.point i { + display: inline-block; + height: 16px; + width: 15px; + float: left; + margin: 10px 10px 0 20px; + background: url(../images/bg_repno.png) no-repeat; +} + + +/*上滚下滚提示的CSS结束*/ + + +/*截图完成后的CSS开始*/ + +#shearphoto_main .complete { + float: left; + overflow: hidden; + position: absolute; + width: 100%; + z-index: 250; + padding: 10px 0 0 5px; + background: url(../images/bg.jpg) #CCC; +} + +.complete .completeTxt { + -moz-border-radius: 10px; + -moz-box-shadow: 0 0 15px 0 #666; + border-radius: 10px; + bottom: 30px; + box-shadow: 0 0 15px 0 #666; + position: absolute; + right: 30px; + text-align: center; + width: 280px; + padding: 30px 0; + background: #FBFDFF; +} + +.complete .completeTxt a { + color: #FFF; + display: block; + font-size: 14px; + line-height: 40px; + width: 128px; + margin: 0 auto; + background: url(../images/bg_index.gif) no-repeat 0 -2px; +} + +.complete .completeTxt a:hover { + background-position: -137px -2px +} + +.complete .completeTxt p { + color: #666; + font-size: 12px; + font-weight: 700; + margin: 10px 0; +} + +.complete .completeTxt strong { + font-size: 14px +} + +.complete img { + border: 1px solid #CCC; + display: inline-block; + float: left; + margin: 5px 5px; + padding: 2px; +} + +.complete .completeTxt strong i { + display: inline-block; + height: 16px; + width: 15px; + vertical-align: middle; + margin: -3px 5px 0 0; + background: url(../images/bg_repno.png) no-repeat; +} + + +/*截图完成后的CSS结束*/ + + +/*弹出相册开始*/ + +#photoalbum { + -moz-border-radius: 10px; + -moz-box-shadow: 3px 3px 10px 0 #000; + border: 8px solid #999; + border-radius: 10px; + box-shadow: 3px 3px 10px 0 #000; + display: none; + height: 340px; + left: 50%; + position: absolute; + top: 50%; + width: 465px; + z-index: 210; + margin: -178px 0 0 -240.5px; + background: #DFEFFF; +} + +#photoalbum h1 { + background: #999; + color: #FFF; + font-size: 15px; + height: 40px; + line-height: 30px; + padding-left: 10px; + width: 455px +} + +#photoalbum i { + background: url(../images/fancybox_sprite.png) no-repeat; + display: block; + float: left; + height: 37px; + left: 429px; + position: absolute; + top: 0; + cursor: pointer; + width: 36px +} + +#photoalbum ul { + height: auto; + width: 100% +} + +#photoalbum ul li { + border: 1px solid #CCC; + cursor: pointer; + display: inline; + float: left; + height: 133px; + margin: 5px; + padding: 2px; + width: 100px; + overflow: hidden; +} + +#photoalbum ul li img { + width: 100% +} + +#photoalbum ul li:hover { + border: 1px solid #09F +} + + +/*弹出相册结束*/ + + +/*弹出拍照开始*/ + +#CamBox { + -moz-border-radius: 10px; + border-radius: 10px; + left: 50%; + position: absolute; + -moz-box-shadow: 5px 5px 10px 0 #3b3b3f; + box-shadow: 5px 5px 10px 0 #3b3b3f; + width: 550px; + z-index: 250; + display: none; + top: 50%; + margin: -285px 0 0 -276px; + background: url(../images/cam_bg.jpg) #d5d5d5; +} + +#CamBox #CamFlash { + height: 450px; + width: 450px; + margin: 0 auto; + background: #fff; +} + +#CamBox #timing { + color: #F60; + display: none; + font-size: 36px; + font-weight: 700; + height: 200px; + left: 50%; + line-height: 200px; + position: absolute; + text-align: center; + top: 50%; + width: 200px; + margin: -100px 0 0 -100px; +} + +#CamBox .cambar { + height: 50px; + padding-top: 20px; + width: 300px; + margin: 0 auto; +} + +#CamBox .cambar a { + background: url(../images/btn5.jpg) no-repeat; + float: left; + height: 31px; + line-height: 31px; + text-align: center; + width: 79px +} + +#CamBox .lens { + background: url(../images/cam.png) no-repeat 50%; + height: 50px; + width: 100% +} + +#CamBox .cambar #camClose, +#CamBox .cambar #setCam { + color: #333; +} + +#CamBox .cambar #setCam { + margin-right: 30px; +} + +#CamBox .cambar #camClose:hover, +#CamBox .cambar #setCam:hover { + background-position: 0 -31px; +} + +#CamBox .cambar #CamOk { + background-position: -79px 0; + color: #fff; + margin-right: 30px; +} + +#CamBox .cambar #CamOk:hover { + background-position: -79px -31px; +} + + +/*弹出拍照结束*/ + + +/*图片特效*/ + +#shearphoto_main .Effects { + color: #FFF; + overflow-x: hidden; + width: 155px; + display: none; + float: left; + border-color: #CCC; + border-style: solid none; + border-width: 1px; + background: url(../images/Effects/cardboard.png); +} + +#shearphoto_main .Effects .EffectsStrong { + border-bottom: solid 1px #676767; + display: block; + font-size: 14px; + height: 30px; + line-height: 30px; + text-align: center; + width: 100% +} + +#shearphoto_main .Effects a { + border-bottom: solid 1px #676767; + color: #FFF; + display: block; + vertical-align: middle; + text-shadow: #000 0 2px 0; + width: 100%; + padding: 5px 0 7px; +} + +#shearphoto_main .Effects a:hover, +#shearphoto_main .Effects .Aclick { + background-color: #A7A7A7; +} + +#shearphoto_main .Effects a img { + -moz-border-radius: 3px; + border-radius: 3px; + display: inline-block; + height: 42px; + vertical-align: middle; + -moz-box-shadow: 0 0 5px 0 #000; + box-shadow: 0 0 5px 0 #000; + width: 70px; + margin: 2px 7px 0; +} + +::-webkit-scrollbar { + height: 13px; + width: 13px +} + +::-webkit-scrollbar-thumb { + background: padding-box #c2c2c2; + border: 1px solid #979797; + min-height: 28px +} + +::-webkit-scrollbar-thumb:hover { + background: #929292; + border: 1px solid #636363 +} + +::-webkit-scrollbar-track-piece { + background: #f5f5f5; + border-left: 1px solid #d2d2d2 +} + + +/*图片特效结束*/ + + +/*底部开始*/ + +.bottom { + width: 1000px; + left: 2px; + color: #666; + clear: both; + text-align: center; + margin: 0 auto; + padding: 0 0 10px 5px +} + +.bottom span { + vertical-align: middle; + display: inline-block; + margin: 0 5px 0 2px +} + +.bottom a { + color: #666; +} + +.header h1 a { + font-size: 14px; + color: #fff; +} + +.bottom span img { + border-radius: 30px; + -moz-border-radius: 30px; +} + + +/*底部结束*/ \ No newline at end of file diff --git a/web/static/plugs/avatar/images/Author.png b/web/static/plugs/avatar/images/Author.png new file mode 100644 index 00000000..8ce2196c Binary files /dev/null and b/web/static/plugs/avatar/images/Author.png differ diff --git a/web/static/plugs/avatar/images/Effects/cardboard.png b/web/static/plugs/avatar/images/Effects/cardboard.png new file mode 100644 index 00000000..ff27dd8e Binary files /dev/null and b/web/static/plugs/avatar/images/Effects/cardboard.png differ diff --git a/web/static/plugs/avatar/images/Effects/e0.jpg b/web/static/plugs/avatar/images/Effects/e0.jpg new file mode 100644 index 00000000..f1574968 Binary files /dev/null and b/web/static/plugs/avatar/images/Effects/e0.jpg differ diff --git a/web/static/plugs/avatar/images/Effects/e1.jpg b/web/static/plugs/avatar/images/Effects/e1.jpg new file mode 100644 index 00000000..30dcb2e2 Binary files /dev/null and b/web/static/plugs/avatar/images/Effects/e1.jpg differ diff --git a/web/static/plugs/avatar/images/Effects/e10.jpg b/web/static/plugs/avatar/images/Effects/e10.jpg new file mode 100644 index 00000000..4a49ee8e Binary files /dev/null and b/web/static/plugs/avatar/images/Effects/e10.jpg differ diff --git a/web/static/plugs/avatar/images/Effects/e11.jpg b/web/static/plugs/avatar/images/Effects/e11.jpg new file mode 100644 index 00000000..d66729a8 Binary files /dev/null and b/web/static/plugs/avatar/images/Effects/e11.jpg differ diff --git a/web/static/plugs/avatar/images/Effects/e12.jpg b/web/static/plugs/avatar/images/Effects/e12.jpg new file mode 100644 index 00000000..40294805 Binary files /dev/null and b/web/static/plugs/avatar/images/Effects/e12.jpg differ diff --git a/web/static/plugs/avatar/images/Effects/e13.jpg b/web/static/plugs/avatar/images/Effects/e13.jpg new file mode 100644 index 00000000..d81fea9e Binary files /dev/null and b/web/static/plugs/avatar/images/Effects/e13.jpg differ diff --git a/web/static/plugs/avatar/images/Effects/e14.jpg b/web/static/plugs/avatar/images/Effects/e14.jpg new file mode 100644 index 00000000..688b907f Binary files /dev/null and b/web/static/plugs/avatar/images/Effects/e14.jpg differ diff --git a/web/static/plugs/avatar/images/Effects/e2.jpg b/web/static/plugs/avatar/images/Effects/e2.jpg new file mode 100644 index 00000000..224f6075 Binary files /dev/null and b/web/static/plugs/avatar/images/Effects/e2.jpg differ diff --git a/web/static/plugs/avatar/images/Effects/e3.jpg b/web/static/plugs/avatar/images/Effects/e3.jpg new file mode 100644 index 00000000..352cba89 Binary files /dev/null and b/web/static/plugs/avatar/images/Effects/e3.jpg differ diff --git a/web/static/plugs/avatar/images/Effects/e4.jpg b/web/static/plugs/avatar/images/Effects/e4.jpg new file mode 100644 index 00000000..421657ad Binary files /dev/null and b/web/static/plugs/avatar/images/Effects/e4.jpg differ diff --git a/web/static/plugs/avatar/images/Effects/e5.jpg b/web/static/plugs/avatar/images/Effects/e5.jpg new file mode 100644 index 00000000..d5fbde4b Binary files /dev/null and b/web/static/plugs/avatar/images/Effects/e5.jpg differ diff --git a/web/static/plugs/avatar/images/Effects/e6.jpg b/web/static/plugs/avatar/images/Effects/e6.jpg new file mode 100644 index 00000000..af3df0f6 Binary files /dev/null and b/web/static/plugs/avatar/images/Effects/e6.jpg differ diff --git a/web/static/plugs/avatar/images/Effects/e7.jpg b/web/static/plugs/avatar/images/Effects/e7.jpg new file mode 100644 index 00000000..6a0d794d Binary files /dev/null and b/web/static/plugs/avatar/images/Effects/e7.jpg differ diff --git a/web/static/plugs/avatar/images/Effects/e8.jpg b/web/static/plugs/avatar/images/Effects/e8.jpg new file mode 100644 index 00000000..6aaa798d Binary files /dev/null and b/web/static/plugs/avatar/images/Effects/e8.jpg differ diff --git a/web/static/plugs/avatar/images/Effects/e9.jpg b/web/static/plugs/avatar/images/Effects/e9.jpg new file mode 100644 index 00000000..bfb415f6 Binary files /dev/null and b/web/static/plugs/avatar/images/Effects/e9.jpg differ diff --git a/web/static/plugs/avatar/images/Select.jpg b/web/static/plugs/avatar/images/Select.jpg new file mode 100644 index 00000000..4284a88c Binary files /dev/null and b/web/static/plugs/avatar/images/Select.jpg differ diff --git a/web/static/plugs/avatar/images/ZoomBar.gif b/web/static/plugs/avatar/images/ZoomBar.gif new file mode 100644 index 00000000..bf50e3c9 Binary files /dev/null and b/web/static/plugs/avatar/images/ZoomBar.gif differ diff --git a/web/static/plugs/avatar/images/Zoomcentre.jpg b/web/static/plugs/avatar/images/Zoomcentre.jpg new file mode 100644 index 00000000..0a3d6f09 Binary files /dev/null and b/web/static/plugs/avatar/images/Zoomcentre.jpg differ diff --git a/web/static/plugs/avatar/images/bch.jpg b/web/static/plugs/avatar/images/bch.jpg new file mode 100644 index 00000000..ef77ba98 Binary files /dev/null and b/web/static/plugs/avatar/images/bch.jpg differ diff --git a/web/static/plugs/avatar/images/bg.jpg b/web/static/plugs/avatar/images/bg.jpg new file mode 100644 index 00000000..a464e659 Binary files /dev/null and b/web/static/plugs/avatar/images/bg.jpg differ diff --git a/web/static/plugs/avatar/images/bg.png b/web/static/plugs/avatar/images/bg.png new file mode 100644 index 00000000..d4f4f660 Binary files /dev/null and b/web/static/plugs/avatar/images/bg.png differ diff --git a/web/static/plugs/avatar/images/bg_headLine1.png b/web/static/plugs/avatar/images/bg_headLine1.png new file mode 100644 index 00000000..a386fc91 Binary files /dev/null and b/web/static/plugs/avatar/images/bg_headLine1.png differ diff --git a/web/static/plugs/avatar/images/bg_index.gif b/web/static/plugs/avatar/images/bg_index.gif new file mode 100644 index 00000000..8b72e563 Binary files /dev/null and b/web/static/plugs/avatar/images/bg_index.gif differ diff --git a/web/static/plugs/avatar/images/bg_repno.png b/web/static/plugs/avatar/images/bg_repno.png new file mode 100644 index 00000000..829a44ff Binary files /dev/null and b/web/static/plugs/avatar/images/bg_repno.png differ diff --git a/web/static/plugs/avatar/images/border.gif b/web/static/plugs/avatar/images/border.gif new file mode 100644 index 00000000..72ea7ccb Binary files /dev/null and b/web/static/plugs/avatar/images/border.gif differ diff --git a/web/static/plugs/avatar/images/btn5.jpg b/web/static/plugs/avatar/images/btn5.jpg new file mode 100644 index 00000000..6743bd52 Binary files /dev/null and b/web/static/plugs/avatar/images/btn5.jpg differ diff --git a/web/static/plugs/avatar/images/cam.png b/web/static/plugs/avatar/images/cam.png new file mode 100644 index 00000000..79b86aa4 Binary files /dev/null and b/web/static/plugs/avatar/images/cam.png differ diff --git a/web/static/plugs/avatar/images/cam_bg.jpg b/web/static/plugs/avatar/images/cam_bg.jpg new file mode 100644 index 00000000..b0b4df31 Binary files /dev/null and b/web/static/plugs/avatar/images/cam_bg.jpg differ diff --git a/web/static/plugs/avatar/images/default.gif b/web/static/plugs/avatar/images/default.gif new file mode 100644 index 00000000..71971206 Binary files /dev/null and b/web/static/plugs/avatar/images/default.gif differ diff --git a/web/static/plugs/avatar/images/fancybox_sprite.png b/web/static/plugs/avatar/images/fancybox_sprite.png new file mode 100644 index 00000000..fd8d5ca5 Binary files /dev/null and b/web/static/plugs/avatar/images/fancybox_sprite.png differ diff --git a/web/static/plugs/avatar/images/loading.gif b/web/static/plugs/avatar/images/loading.gif new file mode 100644 index 00000000..52c59954 Binary files /dev/null and b/web/static/plugs/avatar/images/loading.gif differ diff --git a/web/static/plugs/avatar/images/logo.png b/web/static/plugs/avatar/images/logo.png new file mode 100644 index 00000000..5252791d Binary files /dev/null and b/web/static/plugs/avatar/images/logo.png differ diff --git a/web/static/plugs/avatar/images/logo2.png b/web/static/plugs/avatar/images/logo2.png new file mode 100644 index 00000000..b10b2854 Binary files /dev/null and b/web/static/plugs/avatar/images/logo2.png differ diff --git a/web/static/plugs/avatar/images/photo/1.jpg b/web/static/plugs/avatar/images/photo/1.jpg new file mode 100644 index 00000000..ac503c66 Binary files /dev/null and b/web/static/plugs/avatar/images/photo/1.jpg differ diff --git a/web/static/plugs/avatar/images/photo/2.jpg b/web/static/plugs/avatar/images/photo/2.jpg new file mode 100644 index 00000000..07035788 Binary files /dev/null and b/web/static/plugs/avatar/images/photo/2.jpg differ diff --git a/web/static/plugs/avatar/images/photo/3.jpg b/web/static/plugs/avatar/images/photo/3.jpg new file mode 100644 index 00000000..8efc2e5b Binary files /dev/null and b/web/static/plugs/avatar/images/photo/3.jpg differ diff --git a/web/static/plugs/avatar/images/photo/4.jpg b/web/static/plugs/avatar/images/photo/4.jpg new file mode 100644 index 00000000..248004ae Binary files /dev/null and b/web/static/plugs/avatar/images/photo/4.jpg differ diff --git a/web/static/plugs/avatar/images/photo/5.jpg b/web/static/plugs/avatar/images/photo/5.jpg new file mode 100644 index 00000000..387696d3 Binary files /dev/null and b/web/static/plugs/avatar/images/photo/5.jpg differ diff --git a/web/static/plugs/avatar/images/photo/6.jpg b/web/static/plugs/avatar/images/photo/6.jpg new file mode 100644 index 00000000..a9f79dbc Binary files /dev/null and b/web/static/plugs/avatar/images/photo/6.jpg differ diff --git a/web/static/plugs/avatar/images/photo/7.jpg b/web/static/plugs/avatar/images/photo/7.jpg new file mode 100644 index 00000000..16d62c1f Binary files /dev/null and b/web/static/plugs/avatar/images/photo/7.jpg differ diff --git a/web/static/plugs/avatar/images/photo/8.jpg b/web/static/plugs/avatar/images/photo/8.jpg new file mode 100644 index 00000000..b7213f62 Binary files /dev/null and b/web/static/plugs/avatar/images/photo/8.jpg differ diff --git a/web/static/plugs/avatar/images/photo/ShearPhoto作者.txt b/web/static/plugs/avatar/images/photo/ShearPhoto作者.txt new file mode 100644 index 00000000..0ad06e1b --- /dev/null +++ b/web/static/plugs/avatar/images/photo/ShearPhoto作者.txt @@ -0,0 +1 @@ +ShearPhotoФ8ţֻ \ No newline at end of file diff --git a/web/static/plugs/avatar/images/shutter.mp3 b/web/static/plugs/avatar/images/shutter.mp3 new file mode 100644 index 00000000..16df2b3b Binary files /dev/null and b/web/static/plugs/avatar/images/shutter.mp3 differ diff --git a/web/static/plugs/avatar/images/waterimg.png b/web/static/plugs/avatar/images/waterimg.png new file mode 100644 index 00000000..d6715c83 Binary files /dev/null and b/web/static/plugs/avatar/images/waterimg.png differ diff --git a/web/static/plugs/avatar/images/waterimg2.png b/web/static/plugs/avatar/images/waterimg2.png new file mode 100644 index 00000000..bae42a72 Binary files /dev/null and b/web/static/plugs/avatar/images/waterimg2.png differ diff --git a/web/static/plugs/avatar/images/webcam.swf b/web/static/plugs/avatar/images/webcam.swf new file mode 100644 index 00000000..3300f1eb Binary files /dev/null and b/web/static/plugs/avatar/images/webcam.swf differ diff --git a/web/static/plugs/avatar/images/zoom.png b/web/static/plugs/avatar/images/zoom.png new file mode 100644 index 00000000..1158648b Binary files /dev/null and b/web/static/plugs/avatar/images/zoom.png differ diff --git a/web/static/plugs/avatar/js/ShearPhoto.js b/web/static/plugs/avatar/js/ShearPhoto.js new file mode 100644 index 00000000..b56497e4 --- /dev/null +++ b/web/static/plugs/avatar/js/ShearPhoto.js @@ -0,0 +1,2139 @@ +/*--------------------------拉伸,截图.HTML5的压缩,剪图的处理核心部份-----------------------------------------------------------------------------*/ +window.ShearPhoto = function() { + this.transform = this.DomMoveEve = this.DomUpEve = this.MoveDivEve = this.zoomEve = this.eveMold = false; + this.DivDownEVe = {}; + this.transformFun(); + !this.addevent && window.addEventListener ? (this.addevent = "add", this.selectionempty = function() { + window.getSelection().removeAllRanges(); + }) : (this.addevent = "att", this.selectionempty = function() { + document.selection.empty(); + }); + this.MyAjax = new window.ShearPhoto.MyAjax(); +}; + +window.ShearPhoto.prototype = { + transformFun: function() { + var Imgstyle = document.body.style, + arr = new Array("MsTransform", "MozTransform", "WebkitTransform", "WebkitTransform", "OTransform", "transform"); + for (var i = 0; i < arr.length; i++) { + if (arr[i] in Imgstyle) { + this.transform = arr[i]; + break; + } + } + }, + HTML5: { + Reg: new RegExp("translate3d\\((.*?)\\)", "i"), + HTML5LT: function(Transform) { + if (Transform) { + this.getLT = function(dom) { + domstyleTransform = this.Reg.exec(dom.style[Transform]); + if (domstyleTransform) { + return domstyleTransform[1].split(",", 2); + } else { + return [0, 0]; + } + }; + this.setLT = function(dom, L, T) { + var domstyle = dom.style, + RegTrue = true, + domstyleTransform = domstyle[Transform], + txt = "translate3d(" + L + "," + T + ",0)", + str = domstyleTransform.replace(this.Reg, function(a) { + RegTrue = false; + return txt; + }); + domstyle[Transform] = RegTrue ? domstyleTransform + " " + txt : str; + }; + this.setL = function(dom, L) { + var domstyle = dom.style, + RegTrue = true, + domstyleTransform = domstyle[Transform], + str = domstyleTransform.replace(this.Reg, function(a, b) { + RegTrue = false; + var T = b.split(",", 2)[1]; + return "translate3d(" + L + "," + T + ",0)"; + }); + domstyle[Transform] = RegTrue ? domstyleTransform + " " + "translate3d(" + L + ",0,0)" : str; + }; + this.setT = function(dom, T) { + var domstyle = dom.style, + RegTrue = true, + domstyleTransform = domstyle[Transform], + str = domstyleTransform.replace(this.Reg, function(a, b) { + RegTrue = false; + var L = b.split(",", 2)[0]; + return "translate3d(" + L + "," + T + ",0)"; + }); + domstyle[Transform] = RegTrue ? domstyleTransform + " " + "translate3d(0," + T + ",0)" : str; + }; + } else { + this.getLT = function(dom) { + var domstyle = dom.style; + return [domstyle.left || 0, domstyle.top || 0]; + }; + this.setLT = function(dom, L, T) { + var domstyle = dom.style; + domstyle.left = L, domstyle.top = T; + }; + this.setL = function(dom, L) { + dom.style.left = L; + }; + this.setT = function(dom, T) { + dom.style.top = T; + }; + } + }, + URL: window.URL || window.webkitURL || window.mozURL || window.msURL || false, + canvas: false, + Images: false, + ImagesType: "image/jpeg", + HTML5PHP: false, + HTML5MAX: false, + HandleRotation: function(this_, MyR, SendArry, newcanvas, ctx, p, W, H) { + var ImgH = this_.ImgOHeight, + ImgW = this_.ImgOWidth, + ImgRW, ImgRH, ImgslateX, ImgslateY, MyRR, imgData, arrIMGWH = [Math.ceil(ImgW * p), Math.ceil(ImgH * p)]; + switch (MyR) { + case 90: + ImgRW = arrIMGWH[1]; + ImgRH = arrIMGWH[0]; + ImgslateX = 0; + ImgslateY = ImgRH; + break; + + case 180: + ImgRW = arrIMGWH[0]; + ImgRH = arrIMGWH[1]; + ImgslateX = ImgRW; + ImgslateY = ImgRH; + break; + + case 270: + ImgRW = arrIMGWH[1]; + ImgRH = arrIMGWH[0]; + ImgslateX = ImgRW; + ImgslateY = 0; + break; + } + newcanvas.width = ImgRW; + newcanvas.height = ImgRH; + ctx.translate(ImgslateX, ImgslateY); + ctx.rotate((360 - MyR) * Math.PI / 180); + ctx.drawImage(this_.arg.ImgMain, 0, 0, ImgW, ImgH, 0, 0, arrIMGWH[0], arrIMGWH[1]); + imgData = ctx.getImageData(0, 0, ImgRW, ImgRH); + ctx.clearRect(0, 0, arrIMGWH[0], arrIMGWH[1]); + ctx.fillStyle = "#FFFFFF"; + ctx.fillRect(0, 0, arrIMGWH[0], arrIMGWH[1]); + newcanvas.width = SendArry.IW = W; + newcanvas.height = SendArry.IH = H; + ctx.putImageData(imgData, -SendArry.X * p, -SendArry.Y * p); + delete imgData; + }, + zipImg: function(DataUrl, maxs, type, functions) { + var Image64 = new Image(), + this_ = this; + Image64.onload = function() { + var newcanvas = document.createElement("canvas"); + newcanvas.style.display = "none"; + var bodys = document.body; + bodys.appendChild(newcanvas); + var ctx = newcanvas.getContext("2d"), + width = this.width, + height = this.height; + if (maxs) { + var P = width / height; + if (width > maxs[0]) { + width = maxs[0]; + height = Math.round(maxs[0] / P); + } + if (height > maxs[0]) { + height = maxs[0]; + width = Math.round(maxs[0] * P); + if (width > maxs[0]) { + width = maxs[0]; + height = Math.round(maxs[0] / P); + } + } + } + newcanvas.width = width; + newcanvas.height = height; + ctx.fillStyle = "#FFFFFF"; + ctx.fillRect(0, 0, width, height); + ctx.drawImage(Image64, 0, 0, this.width, this.height, 0, 0, width, height); + var DATA64 = newcanvas.toDataURL(type, maxs ? maxs[1] : .85); + if (this_.URL) { + this_.BOLBID && this_.URL.revokeObjectURL(this_.BOLBID); + this_.BOLBID = this_.URL.createObjectURL(this_.FormBlob(DATA64)); + typeof functions === "function" && functions(this_.BOLBID); + } else { + typeof functions === "function" && functions(DATA64); + } + ctx.clearRect(0, 0, width, height); + bodys.removeChild(newcanvas); + delete DATA64; + delete Image64; + }; + Image64.src = DataUrl; + delete DataUrl; + }, + CtxDrawImage: function(ctx, SendArry, newcanvas, this_) { + var MyR = SendArry.R, + arg = this_.arg; + if (this.HTML5MAX) { + var W = SendArry.IW, + WW = W, + H = SendArry.IH, + p = W / H; + W > this.HTML5MAX ? (W = this.HTML5MAX, H = Math.round(W / p), H > this.HTML5MAX && (H = this.HTML5MAX, + W = Math.round(H * p))) : H > this.HTML5MAX && (H = this.HTML5MAX, W = Math.round(H * p), + W > this.HTML5MAX && (W = this.HTML5MAX, H = Math.round(W / p))); + p = W / WW; + if (MyR === 0) { + var twx = this_.ImgOWidth - SendArry.X, + twy = this_.ImgOHeight - SendArry.Y, + IMGWx = twx * p, + IMGHy = twy * p; + newcanvas.width = SendArry.IW = W; + newcanvas.height = SendArry.IH = H; + ctx.fillStyle = "#FFFFFF"; + ctx.fillRect(0, 0, IMGWx, IMGHy); + ctx.drawImage(arg.ImgMain, SendArry.X, SendArry.Y, twx, twy, 0, 0, IMGWx, IMGHy); + } else { + this.HandleRotation(this_, MyR, SendArry, newcanvas, ctx, p, W, H); + } + } else { + if (MyR === 0) { + newcanvas.width = SendArry.IW; + newcanvas.height = SendArry.IH; + ctx.fillStyle = "#FFFFFF"; + ctx.fillRect(0, 0, SendArry.IW, SendArry.IH); + ctx.drawImage(arg.ImgMain, -SendArry.X, -SendArry.Y); + } else { + this.HandleRotation(this_, MyR, SendArry, newcanvas, ctx, 1, SendArry.IW, SendArry.IH); + } + } + }, + lock: false, + PhotoHTML5True: false, + SetSrc: function(newsrc, ImgMain, ImgDom, domimg) { + ImgMain.src = ImgDom.src = newsrc; + for (var i = 0; i < domimg[1]; i++) { + domimg[0][i].src = newsrc; + } + delete newsrc; + }, + BOLBID: false, + Aclick: false, + artwork: false, + EffectsReturn: function() { + this.Aclick && (this.Aclick.className = ""); + this.Aclick = this.artwork; + this.artwork && (this.artwork.className = "Aclick"); + }, + Effects: function(StrEvent, HTML5) { + var ImgMain = this.arg.ImgMain, + ImgDom = this.arg.ImgDom, + AP; + var preview = this.preview; + var this_ = this; + return function() { + if (HTML5.lock) return; + if (HTML5.Aclick === this) { + this_.pointhandle(1500, 1, "亲!现在已经是" + StrEvent + "效果了,吃饱饭没事干吗?", 2, "#307ff6", "#fff"); + return; + } + HTML5.lock = true; + AP = window.ShearPhoto.psLib(HTML5.Images); + HTML5.Aclick && (HTML5.Aclick.className = ""); + HTML5.Aclick = this; + this.className = "Aclick"; + this_.pointhandle(0, 1, "正在加载" + StrEvent + "效果!稍等....,不要动鼠标,可能有点卡", 2, "#fbeb61", "#3a414c", function() { + setTimeout(function() { + var domimg = preview.domimg, + DATA64; + if (StrEvent === "原图") { + DATA64 = AP.save(false, HTML5.ImagesType); + } else { + DATA64 = AP.ps(StrEvent).save(false, HTML5.ImagesType); + } + if (HTML5.URL) { + HTML5.BOLBID && HTML5.URL.revokeObjectURL(HTML5.BOLBID); + HTML5.BOLBID = HTML5.URL.createObjectURL(HTML5.FormBlob(DATA64)); + HTML5.SetSrc(HTML5.BOLBID, ImgMain, ImgDom, domimg); + this_.runImgUrl = [HTML5.BOLBID, true, true]; + } else { + HTML5.SetSrc(DATA64, ImgMain, ImgDom, domimg); + this_.runImgUrl = [DATA64, true, true]; + } + delete DATA64; + this_.pointhandle(1500, 1, StrEvent + "效果加载成功!提示:如果机器配置差,效果加载时间会更长哦", 1, "#307ff6", "#fff"); + HTML5.lock = false; + HTML5.PhotoHTML5True = true; + }, 1); + }); + }; + }, + BlobRegExp: new RegExp("^data:.*base64,"), + FormBlob: function(dataURI) { + var byteString, splits = false, + splits1 = dataURI.replace(this.BlobRegExp, function() { + splits = true; + return ""; + }); + if (splits) byteString = atob(splits1); + else byteString = unescape(splits1); + var byteStringlength = byteString.length, + ia = new Uint8Array(byteStringlength); + for (var i = 0; i < byteStringlength; i++) { + ia[i] = byteString.charCodeAt(i); + } + return new Blob([ia], { + type: this.ImagesType + }); + }, + IfHTML5: function(transform, H5True, HTML5MAX) { + try { + new Blob(["1"], { + type: "text/plain" + }); + } catch (e) { + H5True = false; + } + transform && H5True && (this.canvas = true, this.HTML5MAX = HTML5MAX); + }, + CanvasImg: function(SendArry, postArgs, this_) { + var newcanvas = document.createElement("canvas"), + bodys = document.body; + newcanvas.style.display = "none"; + bodys.appendChild(newcanvas); + var ctx = newcanvas.getContext("2d"); + this.CtxDrawImage(ctx, SendArry, newcanvas, this_); + var blob = this.FormBlob(newcanvas.toDataURL(this.ImagesType, this_.arg.HTML5Quality)); + ctx.clearRect(0, 0, SendArry.IW, SendArry.IH); + bodys.removeChild(newcanvas); + var readerForm = new FormData(); + readerForm.append("ShearPhotoIW", SendArry.IW); + readerForm.append("ShearPhotoIH", SendArry.IH); + readerForm.append("ShearPhotoFW", SendArry.FW); + readerForm.append("ShearPhotoFH", SendArry.FH); + readerForm.append("ShearPhotoP", this_.arg.proportional[0]); + if (Object.prototype.toString.call(postArgs) === "[object Object]") { + for (var key in postArgs) { + readerForm.append(key, postArgs[key]); + } + } + readerForm.append("UpFile", blob); + return readerForm; + } + }, + _ieexchange_: function() { + var this_ = this; + + function e(a, b) { + var exchange = new Array(this_[a], this_[b]); + this_[a] = exchange[1]; + this_[b] = exchange[0]; + } + e("ImgWidth", "ImgHeight"); + }, + SetRote: { + ROReg: new RegExp("rotate\\((.*?)\\)", "i"), + SLReg: new RegExp("translate\\((.*?)\\)", "i"), + run: function(DOM, Transform, RO, SL) { + var domstyle = DOM.style, + RegTrue = true, + domstyleTransform = domstyle[Transform], + ROstr = domstyleTransform.replace(this.ROReg, function() { + RegTrue = false; + return RO; + }), + txt = RegTrue ? domstyleTransform + " " + RO : ROstr, + RegTrue = true, + SLstr = txt.replace(this.SLReg, function() { + RegTrue = false; + return SL; + }), + txt = RegTrue ? txt + " " + SL : SLstr; + return txt; + }, + runSL: function(DOM, Transform, SL) { + var domstyle = DOM.style, + RegTrue = true, + domstyleTransform = domstyle[Transform], + SLstr = domstyleTransform.replace(this.SLReg, function() { + RegTrue = false; + return SL; + }); + return RegTrue ? domstyleTransform + " " + SL : SLstr; + } + }, + _exchange_: function() { + var this_ = this; + this._ieexchange_(); + var IfRotate = this.rotate; + if (IfRotate === 90 || IfRotate === 270) { + var consts = { + 90: -1, + 270: 1 + }[IfRotate]; + this.ImgRotateFun = function(W, H) { + var ImgRotateLT = consts * Math.round((H - W) * .5) + "px", + arg = this.arg, + str = "translate(" + ImgRotateLT + "," + ImgRotateLT + ")"; + arg.ImgMain.style[this_.transform] = this_.SetRote.runSL(arg.ImgMain, this_.transform, str); + arg.ImgDom.style[this_.transform] = this_.SetRote.runSL(arg.ImgDom, this_.transform, str); + return [H, W]; + }; + return function(ImgMain, ImgDom, rotate) { + var slate = consts * Math.round((this_.ImgWidth - this_.ImgHeight) * .5), + str = "translate(" + slate + "px," + slate + "px)"; + ImgMain.style[this_.transform] = this_.SetRote.run(ImgMain, this_.transform, rotate, str); + ImgDom.style[this_.transform] = this_.SetRote.run(ImgDom, this_.transform, rotate, str); + return slate; + }; + this.preview.WH = [this_.ImgHeight, this_.ImgWidth]; + } else { + this.preview.WH = [this_.ImgWidth, this_.ImgHeight]; + this.ImgRotateFun = function(W, H) { + return [W, H]; + }; + return function(ImgMain, ImgDom, rotate) { + ImgMain.style[this_.transform] = this_.SetRote.run(ImgMain, this_.transform, rotate, "translate(0,0)"); + ImgDom.style[this_.transform] = this_.SetRote.run(ImgDom, this_.transform, rotate, "translate(0,0)"); + return 0; + }; + } + }, + preview: { + isW: new Array(), + isH: new Array(), + run: function(arg, thisMain) { + var _this = this; + if (Object.prototype.toString.call(arg.preview) === "[object Array]") { + var leng = arg.preview.length, + EmptyFun = function() {}, + srcDefault = arg.relativeUrl + "images/default.gif"; + if (leng > 0) { + arg.scope.parentNode.insertAdjacentHTML("afterEnd", ''); + var HTML = "", + proportionFun = EmptyFun, + p = false; + arg.proportional[0] ? p = arg.proportional[0] : proportionFun = function(d, w, i, pro) { + d[1][i].style.height = Math.round(w[i] / pro[0] * pro[1]) + "px"; + }; + var margin_right = 10, + borderW = 5, + MBall = margin_right + borderW * 2; + for (var i = 0; i < leng; i++) { + this.domWidth += arg.preview[i] + MBall; + HTML += ''; + } + this.dom = document.getElementById("preview"); + this.dom.innerHTML = HTML; + this.dom.parentNode.style.width = arg.scopeWidth + 2 + "px"; + var domimg = [this.dom.getElementsByTagName("img"), this.dom.getElementsByTagName("a")], + imgUrlFun = function(d, u) { + d.src = u; + }, + imgWHFun = function(d, WH, pro, i) { + var W = Math.round(WH[0] * pro), + H = Math.round(WH[1] * pro), + True = false; + _this.isW[i] === W || (d.style.width = W + "px", _this.isW[i] = W, True = true); + _this.isH[i] === H || (d.style.height = H + "px", _this.isH[i] = H, True = true); + if (True && thisMain.rotate > 10 && thisMain.rotate !== 180) { + var mylt = (_this.isW[i] - _this.isH[i]) / (thisMain.rotate === 270 ? -2 : 2) + "px"; + d.style[thisMain.transform] = thisMain.SetRote.runSL(d, thisMain.transform, "translate(" + mylt + "," + mylt + ")"); + } + }, + RFun = function(d, styleR, R, pro) { + if (thisMain.transform) { + var SL = R[1] * pro + "px"; + d.style[styleR] = thisMain.SetRote.run(d, styleR, R[0], "translate(" + SL + "," + SL + ")"); + } else { + d.style[styleR] = R; + } + }, + funone, funtwo, funthree, domimgA = domimg[0], + pro, leftBorder, topBorder, domimgi; + this.domimg = [domimg[0], leng], this.close_ = function() { + for (var i = 0; i < leng; i++) { + domimgi = domimgA[i]; + domimgi.src = srcDefault; + if ("cssText" in domimgi.style) domimgi.style.cssText = ""; + else domimgi.setAttribute("style", ""); + } + this.dom.style.display = "none"; + arg.Effects && (arg.Effects.style.display = "none"); + this.dom.parentNode.style.width = arg.scopeWidth + 2 + "px"; + }; + this.SetPreview = function(p) { + if (p) { + for (var i = 0; i < leng; i++) domimg[1][i].style.height = Math.round(arg.preview[i] / p) + "px"; + proportionFun = EmptyFun; + } else proportionFun = function(d, w, i, pro) { + d[1][i].style.height = Math.round(w[i] / pro[0] * pro[1]) + "px"; + }; + }; + this.handle = function(argarr, True, TrueHTML5, args) { + True && this.open_(args || arg, TrueHTML5); + var left = argarr.left, + top = argarr.top, + formAllW = argarr.formAllW, + imgUrl = argarr.imgUrl, + TF = argarr.TF, + styleR = argarr.styleR, + R = argarr.R, + formAllH = argarr.formAllH, + HTML3D = argarr.HTML3D; + typeof imgUrl === "boolean" ? funone = EmptyFun : funone = imgUrlFun; + TF ? funtwo = imgWHFun : funtwo = EmptyFun; + typeof R === "boolean" ? funthree = EmptyFun : funthree = RFun; + typeof left === "boolean" ? left = EmptyFun : (leftBorder = left + arg.Border, topBorder = top + arg.Border, + left = function(pro) { + HTML3D.setLT(domimgi, Math.round(leftBorder * pro) + "px", Math.round(topBorder * pro) + "px"); + }); + for (var i = 0; i < leng; i++) { + domimgi = domimgA[i]; + pro = arg.preview[i] / formAllW; + left(pro); + proportionFun(domimg, arg.preview, i, [formAllW, formAllH]); + funone(domimgi, imgUrl); + funtwo(domimgi, this.WH, pro, i); + funthree(domimgi, styleR, R, pro); + } + }; + } + } + }, + dom: false, + domWidth: 0, + domimg: false, + WH: new Array(2), + parentNodes: false, + SetPreview: function() {}, + EffTrue: false, + handle: function(argarr, True, arg) { + True && this.open_(arg); + }, + close_: function() { + this.arg.Effects && (this.arg.Effects.style.display = "none"); + this.parentNodes && (this.parentNodes.style.width = this.arg.scopeWidth + 2 + "px"); + }, + open_: function(arg) { + var efffwidth = 0; + this.arg = arg; + if (this.EffTrue) { + arg.Effects.style.display = "block"; + arg.Effects.scrollTop = 0; + arg.Effects.style.height = arg.scopeHeight + "px"; + this.parentNodes = arg.Effects.parentNode; + efffwidth = arg.Effects.offsetWidth; + } else { + arg.Effects && (arg.Effects.parentNode.removeChild(arg.Effects), arg.Effects = false); + } + if (this.dom) { + var this_ = this; + this.dom.style.display = "block"; + this.dom.parentNode.style.width = arg.scopeWidth + this.domWidth + efffwidth + 10 + "px"; + } else { + arg.Effects && (arg.Effects.parentNode.style.width = arg.scopeWidth + this.domWidth + efffwidth + 2 + "px"); + } + } + }, + Rotate: function(arg) { + var rotate; + this.saveL = this.formLeft + this.relatL; + this.saveT = this.formTop + this.relatT; + if (this.transform) { + arg === "left" ? this.rotate -= 90 : this.rotate += 90; + this.rotate = { + "-90": 270, + 0: 0, + "-270": 90, + 360: 0, + 180: 180, + 90: 90, + 270: 270, + "-360": 0, + "-180": 180 + }[this.rotate] || 0; + rotate = "rotate(" + this.rotate + "deg)"; + var fun = this._exchange_(); + this.setinitial(this.arg, true); + var SL = fun(this.arg.ImgMain, this.arg.ImgDom, rotate); + this.preview.handle({ + left: this.ImgDomL, + top: this.ImgDomT, + formAllW: this.formAllW, + formAllH: this.formAllH, + imgUrl: false, + styleR: this.transform, + R: [rotate, SL], + HTML3D: this.HTML5 + }); + } else { + arg === "left" ? this.rotate -= 1 : this.rotate += 1; + this.rotate = this.rotate > 3 ? 0 : this.rotate < 0 ? 3 : this.rotate; + if (this.rotate === 1 || this.rotate === 3) { + this.ImgRotateFun = function(W, H) { + return [H, W]; + }; + } else { + this.ImgRotateFun = function(W, H) { + return [W, H]; + }; + } + this.arg.ImgMain.style.filter = this.arg.ImgDom.style.filter = rotate = "progid:DXImageTransform.Microsoft.BasicImage(rotation=" + this.rotate + ")"; + this._ieexchange_(); + this.preview.handle({ + left: false, + top: false, + formAllW: this.formAllW, + formAllH: this.formAllH, + imgUrl: false, + styleR: "filter", + R: rotate, + HTML3D: this.HTML5 + }); + this.setinitial(this.arg, true); + } + }, + pointhandle: function(residencetime, speed, txt, Position, backgroundColor, color, functions) { + var point = this.arg.scope.children[0]; + point.className === "point" && this.arg.scope.removeChild(point); + if (residencetime === -1) return; + point = document.createElement("div"); + point.className = "point"; + this.arg.scope.insertBefore(point, this.arg.scope.childNodes[0]); + var this_ = this, + num = -35, + HTML53D = this.HTML5; + + function show(begin, end, speed, cmd) { + begin += cmd; + if (begin > end && 0 < cmd) { + HTML53D.setT(point, end + "px"); + if (residencetime) { + setTimeout(function() { + show(end, num, speed, -1); + }, residencetime); + } else { + typeof functions === "function" && functions(); + } + return; + } else { + if (end > begin && 0 > cmd) { + try { + this_.arg.scope.removeChild(point); + } catch (e) {} + return; + } + } + HTML53D.setT(point, begin + "px"); + setTimeout(function() { + show(begin, end, speed, cmd); + }, speed); + } + point.style.color = color; + point.style.backgroundColor = backgroundColor; + point.innerHTML = "" + txt; + var pointI = point.getElementsByTagName("i")[0]; + switch (Position) { + case 0: + pointI.style.backgroundPosition = "-16px 0"; + break; + + case 1: + pointI.style.backgroundPosition = "0 0"; + break; + + case 2: + pointI.style.backgroundPosition = "-31px 0"; + break; + } + show(num, 0, speed, 1); + }, + setinitial: function(arg, TF) { + var cl = 0, + ct = 0, + TrueTraverse = !arg.traverse, + HTML53D = this.HTML5, + RL, BL, RT, BT; + if (this.BoxW > this.ImgWidth) { + this.relatW = this.ImgWidth; + arg.relat.style.width = this.ImgWidth + "px"; + var BiW = Math.round((this.BoxW - this.ImgWidth) * .5); + RL = (this.relatL = BiW) + "px"; + BL = -BiW + "px"; + } else { + arg.relat.style.width = this.BoxW + "px"; + this.relatW = this.BoxW; + RL = BL = this.relatL = 0; + TrueTraverse && (cl = (this.BoxW - this.ImgWidth) * .5); + } + if (this.BoxH > this.ImgHeight) { + this.relatH = this.ImgHeight; + arg.relat.style.height = this.ImgHeight + "px"; + var BiH = Math.round((this.BoxH - this.ImgHeight) * .5); + this.relatT = BiH; + RT = BiH + "px"; + BT = -BiH + "px"; + } else { + this.relatH = this.BoxH; + arg.relat.style.height = this.BoxH + "px"; + RT = BT = this.relatT = 0; + TrueTraverse && (ct = (this.BoxH - this.ImgHeight) * .5); + } + HTML53D.setLT(arg.relat, RL, RT); + HTML53D.setLT(arg.black, BL, BT); + this.AmendOffset(); + this.MovePhoto(TF, cl, ct, TrueTraverse); + }, + MovePhoto: function(TF, cl, ct, True) { + var arg = this.arg, + ImgDom = arg.ImgDom, + ImgMain = arg.ImgMain, + also, scale, ImgMainL, ImgMainT, ImgDomL, ImgDomT, HTML3D = this.HTML5; + if (arg.traverse && this.BoxW < this.ImgWidth) { + var MinusImgWBoxW = this.ImgWidth - this.BoxW; + also = this.BoxW - this.formAllW; + scale = also && MinusImgWBoxW / also; + var L = Math.round(-this.formLeft * scale); + ImgMainL = L; + ImgDomL = L - this.formLeft - this.Border; + } else { + ImgMainL = cl = arg.traverse ? 0 : True ? cl : this.ImgMainL; + ImgDomL = cl - this.formLeft - this.Border; + } + if (arg.traverse && this.BoxH < this.ImgHeight) { + var MinusImgHBoxH = this.ImgHeight - this.BoxH; + also = this.BoxH - this.formAllH; + scale = also && MinusImgHBoxH / also; + var T = Math.round(-this.formTop * scale); + ImgMainT = T; + ImgDomT = T - this.formTop - this.Border; + } else { + ImgMainT = ct = arg.traverse ? 0 : True ? ct : this.ImgMainT; + ImgDomT = ct - this.formTop - this.Border; + } + this.ImgMainT = ImgMainT, this.ImgMainL = ImgMainL; + this.ImgDomL = ImgDomL, this.ImgDomT = ImgDomT; + HTML3D.setLT(ImgMain, ImgMainL + "px", ImgMainT + "px"); + HTML3D.setLT(ImgDom, ImgDomL + "px", ImgDomT + "px"); + this.preview.handle({ + left: ImgDomL, + top: ImgDomT, + formAllW: this.formAllW, + formAllH: this.formAllH, + imgUrl: false, + TF: TF, + styleR: false, + R: false, + HTML3D: HTML3D + }); + }, + AmendOffset: function() { + var HTML53D = this.HTML5, + LT3D; + if (this.saveL) { + this.formLeft = this.saveL - this.relatL; + this.formTop = this.saveT - this.relatT; + } else { + LT3D = HTML53D.getLT(this.formParent); + typeof this.formLeft === "boolean" && (this.formLeft = parseFloat(LT3D[0])); + typeof this.formTop === "boolean" && (this.formTop = parseFloat(LT3D[1])); + this.formLeft -= this.relatL; + this.formTop -= this.relatT; + } + this.formLeft < 0 && (this.formLeft = 0, this.saveL = this.relatL); + this.formTop < 0 && (this.formTop = 0, this.saveT = this.relatT); + var formWL = this.formLeft + this.formAllW, + formHT = this.formTop + this.formAllH; + if (formWL > this.relatW) { + var FrL = formWL - this.relatW; + if (FrL > this.formLeft) { + this.formW = this.formW - (FrL - this.formLeft); + this.formLeft = 0; + this.saveL = this.relatL; + this.formAllW = this.formW + this.Mdouble; + } else { + this.formLeft -= FrL; + this.saveL = this.formLeft + this.relatL; + } + } + if (formHT > this.relatH) { + var FrT = formHT - this.relatH; + if (FrT > this.formTop) { + this.formH = this.formH - (FrT - this.formTop); + this.formTop = 0; + this.saveT = this.relatT; + this.formAllH = this.formH + this.Mdouble; + } else { + this.formTop -= FrT; + this.saveT = this.formTop + this.relatT; + } + } + HTML53D.setLT(this.formParent, this.formLeft + "px", this.formTop + "px"); + if (this.arg.proportional[0]) { + var H = Math.round(this.formAllW / this.arg.proportional[0]); + if (H > this.formAllH) { + this.formAllW = Math.round(this.formAllH * this.arg.proportional[0]); + this.formW = this.formAllW - this.Mdouble; + } else { + this.formAllH = H; + this.formH = H - this.Mdouble; + } + } + this.arg.form.style.width = this.formW + "px", this.arg.form.style.height = this.formH + "px"; + this.ie6(this.formParent, this.formAllW, this.formAllH); + }, + MaxMinLimit: function(this_) { + this_.ImgWidth = this_.ImgOWidth = this.width; + this_.ImgHeight = this_.ImgOHeight = this.height; + if (typeof this_.arg.Max === "number") { + this_.ImgWidth > this_.arg.Max && (this_.ImgWidth = this_.arg.Max, this_.ImgHeight = Math.round(this_.ImgWidth / this_.ImgScales)); + this_.ImgHeight > this_.arg.Max && (this_.ImgHeight = this_.arg.Max, this_.ImgWidth = Math.round(this_.ImgHeight * this_.ImgScales)); + } + var MH, MW; + if (this_.arg.proportional[0]) { + MH = this_.Min; + MW = Math.round(MH * this_.arg.proportional[0]); + if (MW < this_.Min) { + MW = this_.Min; + MH = Math.round(MW / this_.arg.proportional[0]); + } + } else { + MW = MH = this_.Min; + } + this_.ImgWidth < MW && (this_.ImgWidth = MW, this_.ImgHeight = Math.round(this_.ImgWidth / this_.ImgScales)); + this_.ImgHeight < MH && (this_.ImgHeight = MH, this_.ImgWidth = Math.round(this_.ImgHeight * this_.ImgScales)); + this_.artworkW = this_.ImgWidth, this_.artworkH = this_.ImgHeight; + }, + SetProportional: function(pro) { + if (pro != this.arg.proportional[0]) { + this.arg.proportional[0] = pro; + if (!this.runImgUrl) { + return; + } + var Type = this.HTML5.ImagesType, + this_ = this, + runImgUrl = this.runImgUrl; + this.preview.close_(); + this.pointhandle(0, 1, "正在更换截框比例......", 2, "#fbeb61", "#3a414c", function() { + this_.again(); + this_.run.apply(this_, runImgUrl); + this_.HTML5.ImagesType = Type; + this_.preview.SetPreview(pro); + }); + } + }, + run: function(ImgUrl, Trues, SetPro) { + this.runImgUrl = [ImgUrl, Trues, true]; + this.HTML5.HTML5PHP = Trues; + var this_ = this, + arg = this.arg, + relatImgUrl = this.HTML5.canvas && Trues ? ImgUrl : arg.relativeUrl + ImgUrl, + image = new Image(); + SetPro || (this.HTML5.Images = image); + this.defaultShear(); + this.arg = arg; + this.HTML5.canvas && Trues || (this.ImgUrl = ImgUrl); + image.onload = function() { + if (!(this.width = Math.round(this.width)) > 0 || !(this.height = Math.round(this.height)) > 0) { + this_.pointhandle(3e3, 10, "请选择正确图片", 0, "#f82373", "#fff"); + return; + } + arg.ImgMain.src = arg.ImgDom.src = relatImgUrl; + arg.black.style.zIndex = 99; + this_.ImgScales = this.width / this.height; + this_.Min = arg.Min; + this_.MaxMinLimit.call(this, this_); + arg.ImgMain.style.width = arg.ImgDom.style.width = this_.artworkW + "px", arg.ImgMain.style.height = arg.ImgDom.style.height = this_.artworkH + "px"; + this_.BoxW = arg.scope.offsetWidth - 2; + this_.BoxH = arg.scope.offsetHeight - 2; + this_.Border = arg.Border; + this_.Mdouble = arg.Border * 2; + var W, H; + if (arg.proportional[0]) { + W = arg.proportional[1] - this_.Mdouble; + H = arg.proportional[1] / arg.proportional[0] - this_.Mdouble; + } else { + W = arg.proportional[1] - this_.Mdouble; + H = arg.proportional[2] - this_.Mdouble; + } + this_.formW = W = Math.round(W); + this_.formH = H = Math.round(H); + this_.formAllW = W + this_.Mdouble; + this_.formAllH = H + this_.Mdouble; + this_.preview.WH = [this_.artworkW, this_.artworkH]; + this_.formParent = arg.form.offsetParent; + this_.et(); + this_.setinitial(arg); + this_.preview.handle({ + left: false, + top: false, + formAllW: this_.formAllW, + formAllH: this_.formAllH, + TF: true, + imgUrl: relatImgUrl, + styleR: false, + R: false, + HTML3D: this_.HTML5 + }, true, arg); + var str = this_.MoveDiv = new window.ShearPhoto.MoveDiv(); + str.reckon(arg.relat, false); + str.selectionempty = this_.selectionempty; + str.addevent = this_.addevent; + str.HTML5 = this_.HTML5; + str.run({ + to: new Array(arg.form), + form: this_.formParent, + MoveWidth: this_.relatW, + MoveHeight: this_.relatH, + shifting: new Array(), + center: 1, + centerFront: function() { + return [this_.relatW, this_.relatH]; + }, + DivDownFun: function(t) { + t.arg.MoveWidth = this_.relatW; + t.arg.MoveHeight = this_.relatH; + t.DivW = this_.formW + this_.Mdouble; + t.DivH = this_.formH + this_.Mdouble; + }, + centerfun: function(l, t, tt) { + this_.formLeft = l; + this_.formTop = t; + this_.MovePhoto(false, 0, 0); + tt.arg.MoveWidth = this_.relatW; + tt.arg.MoveHeight = this_.relatH; + tt.DivW = this_.formW + this_.Mdouble; + tt.DivH = this_.formH + this_.Mdouble; + }, + zIndex: 100, + MoveFun: function(iL, iT, MoveScale) { + this_.formLeft = iL; + this_.formTop = iT; + this_.MovePhoto(true, 0, 0); + } + }); + this_.MoveDivEve = function() { + str.delDownEve(); + }; + arg.Shearbar.style.display = "block"; + arg.SelectBox.style.visibility = "hidden"; + this_.zoom(); + this_.pointhandle(2e3, 10, "可以拖动或拉伸蓝边框进行截图", 1, "#fbeb61", "#3a414c"); + delete relatImgUrl; + delete ImgUrl; + }; + image.onerror = function() { + this_.pointhandle(0, 10, "无法读取图片。图片类型或路径不正确 或 relativeUrl参数是否存在问题", 0, "#f82373", "#fff"); + }; + this.pointhandle(0, 1, "图片已加载,正在创建截图环境,请稍等........", 2, "#fbeb61", "#3a414c", function() { + image.src = relatImgUrl; + }); + }, + config: function(arg) { + this.arg = arg; + arg.Shearbar.style.display = "none"; + arg.scope.style.width = arg.black.style.width = arg.SelectBox.style.width = arg.scopeWidth + "px"; + arg.scope.style.height = arg.black.style.height = arg.SelectBox.style.height = arg.scopeHeight + "px"; + var scopeparentNode = arg.scope.parentNode; + scopeparentNode.style.width = scopeparentNode.parentNode.style.width = arg.scopeWidth + 2 + "px"; + var opacityFun; + this.HTML5.IfHTML5(this.transform, arg.HTML5, arg.HTML5MAX); + this.HTML5.HTML5LT(arg.translate3d && this.transform); + if (this.transform) opacityFun = function(t, n) { + t.style.opacity = n; + }; + else opacityFun = function(t, n) { + t.style.filter = "alpha(opacity=" + n * 100 + ")"; + }; + if (arg.Border > 0) { + arg.DynamicBorder[0].style.display = arg.DynamicBorder[1].style.display = arg.DynamicBorder[2].style.display = arg.DynamicBorder[3].style.display = "none"; + arg.DynamicBorder[0].style.background = arg.DynamicBorder[1].style.background = arg.DynamicBorder[2].style.background = arg.DynamicBorder[3].style.background = "#FFF"; + for (var a in arg.to) { + arg.to[a].style.border = "1px solid" + " " + arg.BorderColor; + arg.to[a].style.background = arg.BorderColor; + opacityFun(arg.to[a], 1); + } + arg.form.style.border = arg.Border + "px" + " " + arg.BorderStyle + " " + arg.BorderColor; + } + arg.black.style.background = arg.backgroundColor; + opacityFun(arg.black, arg.backgroundOpacity); + this.preview.run(arg, this); + arg.scope.ondragstart = function() { + return false; + }; + if (navigator.userAgent.indexOf("MSIE 6.0") > 0 && arg.Border === 0) this.ie6 = function(a, b, c) { + a.style.height = arg.DynamicBorder[1].style.height = arg.DynamicBorder[2].style.height = c + "px"; + a.style.width = b + "px"; + }; + else this.ie6 = function() {}; + if (this.preview.EffTrue = arg.HTML5Effects && this.HTML5.canvas && arg.Effects) { + var EffectsA = arg.Effects.getElementsByTagName("a"), + EffectsAi, EffectsAiclick = this.HTML5.Effects; + this.HTML5.artwork = this.HTML5.Aclick = EffectsA[0]; + for (var i = 0; i < EffectsA.length; i++) { + EffectsAi = EffectsA[i]; + EffectsAi.onclick = EffectsAiclick.call(this, EffectsAi.getAttribute("StrEvent"), this.HTML5); + } + } + this.pointhandle(3e3, 10, "请选择本地照片进行截取头像", 2, "#307ff6", "#fff"); + }, + zoom: function() { + var this_ = this, + zoom = new window.ShearPhoto.MoveDiv(); + zoom.reckon(this_.arg.ZoomDist, false); + zoom.selectionempty = this_.selectionempty; + zoom.addevent = this_.addevent; + zoom.HTML5 = this.HTML5; + var Draggable = this_.arg.ZoomBar, + MH, MW, thePro; + + function SetMHW(PRO) { + if (PRO) { + MH = this_.Min; + MW = Math.round(MH * PRO); + if (MW < this_.Min) { + MW = this_.Min; + MH = Math.round(MW / PRO); + } + } else { + MW = MH = this_.Min; + } + } + SetMHW(this_.arg.proportional[0]); + zoom.run({ + to: [Draggable], + form: Draggable, + MoveWidth: zoom.ReckonWH.W, + MoveHeight: zoom.ReckonWH.H, + shifting: new Array(), + center: 1, + zIndex: 100, + DivDownFun: function() { + this_.saveL = this_.formLeft + this_.relatL; + this_.saveT = this_.formTop + this_.relatT; + }, + cursor: "pointer", + MoveFun: function(L) { + var schedule; + if (L < bisect) schedule = Math.round(Zoomout * L + 10) / 100; + else schedule = Math.round(L * magnify - 100) / 100; + var W = Math.round(this_.artworkW * schedule), + H = Math.round(this_.artworkH * schedule); + W < MW && (W = MW, H = Math.round(W / this_.ImgScales)); + H < MH && (H = MH, W = Math.round(H * this_.ImgScales)); + var IMGWH = this_.ImgRotateFun(W, H); + this_.ImgWidth = IMGWH[0]; + this_.ImgHeight = IMGWH[1]; + this_.arg.ImgMain.style.width = this_.arg.ImgDom.style.width = W + "px"; + this_.arg.ImgMain.style.height = this_.arg.ImgDom.style.height = H + "px"; + this_.preview.WH = [W, H]; + this_.setinitial(this_.arg, true); + } + }); + this_.zoomEve = function() { + zoom.delDownEve(); + }; + var zoomMAx = zoom.ReckonWH.W - zoom.DivW, + bisect = zoomMAx * .5, + magnify = 200 / bisect, + Zoomout = 90 / bisect; + }, + PointerShape: function(Shape) { + this.arg.scope.style.cursor = this.arg.form.style.cursor = Shape; + }, + DelPointerShape: function() { + this.arg.scope.style.cursor = ""; + this.arg.form.style.cursor = "move"; + }, + ShearPhotoDown: function(obj, fun) { + this.addEvent(obj, "mousedown", fun); + this.addEvent(obj, "touchstart", fun); + }, + delShearPhotoDown: function(obj, fun) { + this.delEvent(obj, "mousedown", fun); + this.delEvent(obj, "touchstart", fun); + }, + et: function() { + for (var a in this.arg.to) { + if (this.addevent === "add") { + if (typeof this.DivDownEVe[a] !== "function") { + this.DivDownEVe[a] = this.DivDown(a); + } else { + this.delShearPhotoDown(this.arg.to[a], this.DivDownEVe[a]); + } + this.ShearPhotoDown(this.arg.to[a], this.DivDownEVe[a]); + } else { + this.arg.to[a].onmousedown = this.DivDown(a); + } + } + }, + addEvent: function(obj, evetype, fun) { + var addevent = { + add: function() { + obj.addEventListener(evetype, fun, false); + }, + att: function() { + obj.attachEvent("on" + evetype, fun); + } + }; + addevent[this.addevent] && addevent[this.addevent](); + }, + delEvent: function(obj, evetype, fun) { + var delevent = { + add: function() { + obj.removeEventListener(evetype, fun, false); + }, + att: function() { + obj.detachEvent("on" + evetype, fun); + } + }; + delevent[this.addevent] && delevent[this.addevent](); + }, + DomUp: function(dom) { + var this_ = this; + return function() { + typeof this_.arg.UpFun === "function" && this_.arg.UpFun(); + dom.releaseCapture && dom.releaseCapture(); + this_.DelPointerShape(); + typeof this_.DomMoveEve === "function" && this_.delEvent(document, this_.eveMold[1], this_.DomMoveEve); + if (typeof this_.DomUpEve === "function") { + this_.delEvent(document, this_.eveMold[2], this_.DomUpEve); + this_.delEvent(window, this_.eveMold[2], this_.DomUpEve); + this_.delEvent(window, "blur", this_.DomUpEve); + this_.delEvent(dom, "losecapture", this_.DomUpEve); + } + return false; + }; + }, + setWHfalse: function(argform, iW, iH, proportional, MaxW, MaxH) { + iW > MaxW && (iW = MaxW); + iH > MaxH && (iH = MaxH); + iW < this.Min && (iW = this.Min); + iH < this.Min && (iH = this.Min); + return [iW, iH]; + }, + setWfalse: function(argform, iW, iH, proportional, MaxW, MaxH) { + iW > MaxW && (iW = MaxW); + iW < this.Min && (iW = this.Min); + return [iW, this.formAllH]; + }, + setHfalse: function(argform, iW, iH, proportional, MaxW, MaxH) { + iH > MaxH && (iH = MaxH); + iH < this.Min && (iH = this.Min); + return [this.formAllW, iH]; + }, + CycleCalculation: function(iW, iH, proportional, MaxW, MaxH) { + if (iH > MaxH) { + iH = MaxH; + iW = Math.round(iH * proportional); + return this.CycleCalculation.apply(this, arguments); + } + if (iW > MaxW) { + iW = MaxW; + iH = Math.round(iW / proportional); + return this.CycleCalculation.apply(this, arguments); + } + if (iH < this.Min) { + iH = this.Min; + iW = Math.round(iH * proportional); + return this.CycleCalculation.apply(this, arguments); + } + if (iW < this.Min) { + iW = this.Min; + iH = Math.round(iW / proportional); + return this.CycleCalculation.apply(this, arguments); + } + return [iW, iH]; + }, + setHtrue: function(argform, iW, iH, proportional, MaxW, MaxH) { + iW = Math.round(iH * proportional); + return this.CycleCalculation(iW, iH, proportional, MaxW, MaxH); + }, + setWtrue: function(argform, iW, iH, proportional, MaxW, MaxH) { + iH = Math.round(iW / proportional); + return this.CycleCalculation(iW, iH, proportional, MaxW, MaxH); + }, + amend: function(iW, iH, formParent, strLL, strTT) { + var L = iW - this.formAllW, + T = iH - this.formAllH, + Left, Top, ImgLeft, ImgTop, this_ = this, + HTML5 = this.HTML5, + fun = { + LL: function() { + Left = Math.round(this_.formLeft - L); + this_.formLeft = Left; + HTML5.setL(formParent, Left + "px"); + }, + TT: function() { + Top = Math.round(this_.formTop - T); + this_.formTop = Top; + HTML5.setT(formParent, Top + "px"); + }, + ML: function() { + L *= .5; + Left = this_.formLeft - L; + this_.formLeft = Left; + HTML5.setL(formParent, Left + "px"); + }, + MT: function() { + T *= .5; + Top = this_.formTop - T; + this_.formTop = Top; + HTML5.setT(formParent, Top + "px"); + }, + NO: function() {} + }; + fun[strLL](), fun[strTT](); + }, + DomMove: function(this_, dom, disX, disY, PNW, PNH, formParent, MaxW, MaxH, strLL, strTT) { + var eveclientX, eveclientY, drawWH, iW, iH, argform, iHH, iWW, ImgMain = this_.arg.ImgMain, + ImgDom = this_.arg.ImgDom; + if (typeof this_.DomUpEve === "function") { + this_.delEvent(document, this_.eveMold[2], this_.DomUpEve); + this_.delEvent(window, this_.eveMold[2], this_.DomUpEve); + this_.delEvent(window, "blur", this_.DomUpEve); + this_.delEvent(dom, "losecapture", this_.DomUpEve); + } + this_.DomUpEve = this_.DomUp(dom); + this_.addEvent(document, this_.eveMold[2], this_.DomUpEve); + this_.addEvent(window, this_.eveMold[2], this_.DomUpEve); + this_.addEvent(window, "blur", this_.DomUpEve); + this_.addEvent(dom, "losecapture", this_.DomUpEve); + return function(eve) { + eve = eve || window.event; + if (eve.button > 1) { + this_.DomUp(this)(); + return false; + } + eveclientX = this_.eveMold[3](eve, "clientX"), eveclientY = this_.eveMold[3](eve, "clientY"), + argform = this_.arg.form; + setTimeout(function() { + iW = PNW * (eveclientX - disX); + iH = PNH * (eveclientY - disY); + this_.selectionempty(); + drawWH = this_.drawfun(argform, iW, iH, this_.arg.proportional[0], MaxW, MaxH); + iW = drawWH[0]; + iH = drawWH[1]; + this_.amend(iW, iH, formParent, strLL, strTT); + this_.formAllW = iW; + this_.formAllH = iH; + iW = this_.formW = iW - this_.Mdouble; + iH = this_.formH = iH - this_.Mdouble; + argform.style.width = iW + "px", argform.style.height = iH + "px"; + this_.ie6(formParent, iW, iH); + this_.MovePhoto(true, 0, 0); + }, 1); + return false; + }; + }, + defaultShear: function() { + this.arg.Shearbar.style.display = "none"; + typeof this.MoveDivEve === "function" && this.MoveDivEve(); + typeof this.zoomEve === "function" && this.zoomEve(); + if ("cssText" in this.arg.ImgMain.style) this.arg.ImgMain.style.cssText = this.arg.ImgDom.style.cssText = ""; + else { + this.arg.ImgMain.setAttribute("style", ""); + this.arg.ImgDom.setAttribute("style", ""); + } + this.arg = this.ImgUrl = this.formW = this.formH = this.formAllW = this.formAllH = this.drawfun = this.formParent = this.ImgWidth = this.ImgHeight = this.artworkW = this.artworkH = this.BoxW = this.BoxH = this.Border = this.Mdouble = this.ImgScales = this.Min = this.formLeft = this.formTop = this.relatL = this.relatT = this.relatW = this.relatH = this.saveL = this.ImgOWidth = this.ImgOHeight = this.saveT = this.HTML5.lock = this.HTML5.PhotoHTML5True = false; + this.rotate = this.ImgMainT = this.ImgDomT = this.ImgMainL = this.ImgDomL = 0; + this.preview.isW = []; + this.preview.isH = []; + this.ImgRotateFun = function(W, H) { + return [W, H]; + }; + }, + SendUserMsg: function(msg, n, p, b, c, i, k, f) { + this.arg.black.style.zIndex = i ? 199 : 99; + this.pointhandle(n, 5, msg, p, b, c, f); + k ? this.arg.Shearbar.style.display = "none" : this.arg.Shearbar.style.display = "block"; + }, + again: function() { + this.arg.SelectBox.style.visibility = "visible"; + this.arg.Shearbar.style.display = "none"; + this.runImgUrl = false; + this.arg.ImgDom.src = this.arg.ImgMain.src = this.arg.relativeUrl + "images/default.gif"; + }, + CoordinateData: function(True) { + var SendPHPSmaller = function(W, H, P) { + if (W < 1) { + W = 1; + H = Math.round(1 / P); + } + if (H < 1) { + H = 1; + W = Math.round(P); + } + return [W, H]; + }, + SendArry = {}; + True || (SendArry.url = "../" + this.ImgUrl); + var R = { + 1: 270, + 2: 180, + 3: 90, + "90": 270, + "180": 180, + "270": 90 + }[this.rotate] || (R = this.rotate), + LT = this.ImgWidth, + TL = this.ImgHeight, + XYWH = { + 0: LT, + 90: TL, + 180: LT, + 270: TL + }, + XYWHP = this.ImgOWidth / XYWH[R]; + SendArry.R = R; + SendArry.X = Math.round((Math.abs(this.ImgDomL) - this.Border) * XYWHP); + SendArry.Y = Math.round((Math.abs(this.ImgDomT) - this.Border) * XYWHP); + SendArry.P = this.arg.proportional[0]; + var P = this.formAllW / this.formAllH, + Smaller = SendPHPSmaller(Math.round(this.formAllW * XYWHP), Math.round(this.formAllH * XYWHP), P); + SendArry.IW = Smaller[0]; + SendArry.IH = Smaller[1]; + Smaller = SendPHPSmaller(this.formAllW, this.formAllH, P); + SendArry.FW = Smaller[0]; + SendArry.FH = Smaller[1]; + return SendArry; + }, + SendPHP: function(postArgs) { + var this_ = this, + SendArry, HTML5 = this.HTML5, + ResultData; + this.SendUserMsg("正在为你处理截图,稍等...", 0, 2, "#fbeb61", "#3a414c", true, true, function() { + if ((HTML5.HTML5PHP || HTML5.PhotoHTML5True) && HTML5.canvas) { + try { + HTML5.BOLBID && HTML5.URL.revokeObjectURL(HTML5.BOLBID); + SendArry = this_.CoordinateData(true); + ResultData = HTML5.CanvasImg(SendArry, postArgs, this_); + } catch (e) { + this_.SendUserMsg("错误:切割图片时严重报错,请更换浏览器试试,或者换张图片", 5e3, 0, "#f4102b", "#fff", false); + return; + } + } else { + var POSTHTML = ""; + if (Object.prototype.toString.call(postArgs) === "[object Object]") { + for (var key in postArgs) { + POSTHTML += "&" + key + "=" + postArgs[key]; + } + } + SendArry = this_.CoordinateData(); + ResultData = "JSdate=" + window.ShearPhoto.JsonString.JsonToString(SendArry) + POSTHTML; + } + this_.MyAjax.carry({ + url: this_.arg.url, + data: ResultData, + type: "POST", + timeout: 9e4, + async: true, + lock: true, + complete: false, + success: function(serverdata) { + serverdata = window.ShearPhoto.JsonString.StringToJson(serverdata); + if (serverdata === false) { + this_.SendUserMsg("错误:请保证后端环境运行正常", 5e3, 0, "#f4102b", "#fff", false); + return; + } + if (serverdata["erro"]) { + this_.SendUserMsg("错误:" + serverdata["erro"], 5e3, 0, "#f4102b", "#fff", false); + return; + } + this_.runImgUrl = false; + typeof this_.complete === "function" && this_.complete(serverdata); + delete this_.HTML5.Images; + }, + error: function(ErroMsg) { + this_.SendUserMsg("错误:连接后端失败,可能原因,超时!或者后端环境无法运行", 5e3, 0, "#f4102b", "#fff", false); + }, + cache: false + }); + }); + }, + DivDown: function(a) { + var this_ = this, + PNW = 1, + PNH = 1, + strLL = "NO", + strTT = "NO", + MaxW, MaxH, W, H, formParentoffsetLeft, formParent, formParentoffsetTop; + return function(event) { + var event = event || window.event, + eventbutton = event.button, + typebutton = typeof eventbutton, + clientX, clientY; + event.preventDefault && event.preventDefault(); + if (typebutton !== "number") { + this_.eveMold = ["touchstart", "touchmove", "touchend", function(events, clientXY) { + return events.touches[0][clientXY]; + }]; + clientX = event.touches[0].clientX; + clientY = event.touches[0].clientY; + } else { + this_.eveMold = ["mousedown", "mousemove", "mouseup", function(events, clientXY) { + return events[clientXY]; + }]; + clientX = event.clientX; + clientY = event.clientY; + } + if (eventbutton < 2 || typebutton !== "number") { + W = this_.formAllW, H = this_.formAllH, formParent = this_.formParent, formParentoffsetLeft = this_.formLeft, + formParentoffsetTop = this_.formTop; + switch (a) { + case "BottomRight": + MaxW = this_.relatW - formParentoffsetLeft, MaxH = this_.relatH - formParentoffsetTop; + this_.arg.proportional[0] ? this_.drawfun = this_.setHtrue : this_.drawfun = this_.setWHfalse; + this_.PointerShape("nw-resize"); + break; + + case "TopRight": + PNH = -1; + strTT = "TT"; + MaxW = this_.relatW - formParentoffsetLeft, MaxH = formParentoffsetTop + this_.formAllH; + this_.arg.proportional[0] ? this_.drawfun = this_.setHtrue : this_.drawfun = this_.setWHfalse; + this_.PointerShape("ne-resize"); + break; + + case "Bottomleft": + PNW = -1; + strLL = "LL"; + MaxW = formParentoffsetLeft + this_.formAllW; + MaxH = this_.relatH - formParentoffsetTop; + this_.arg.proportional[0] ? this_.drawfun = this_.setHtrue : this_.drawfun = this_.setWHfalse; + this_.PointerShape("ne-resize"); + break; + + case "Topleft": + PNH = PNW = -1; + strLL = "LL"; + strTT = "TT"; + MaxW = formParentoffsetLeft + this_.formAllW; + MaxH = formParentoffsetTop + this_.formAllH; + this_.arg.proportional[0] ? this_.drawfun = this_.setHtrue : this_.drawfun = this_.setWHfalse; + this_.PointerShape("nw-resize"); + break; + + case "Topmiddle": + strLL = "ML"; + var MaxWA = formParentoffsetLeft, + MaxWB = this_.relatW - MaxWA - this_.formAllW; + MaxW = Math.min(MaxWA, MaxWB) * 2 + this_.formAllW; + strTT = "TT"; + MaxH = formParentoffsetTop + this_.formAllH; + PNH = -1; + this_.arg.proportional[0] ? this_.drawfun = this_.setHtrue : this_.drawfun = this_.setHfalse; + this_.PointerShape("n-resize"); + break; + + case "leftmiddle": + PNH = PNW = -1; + MaxW = formParentoffsetLeft + this_.formAllW; + var MaxHA = formParentoffsetTop, + MaxHB = this_.relatH - MaxHA - this_.formAllH; + MaxH = Math.min(MaxHA, MaxHB) * 2 + this_.formAllH; + strTT = "MT"; + strLL = "LL"; + this_.arg.proportional[0] ? this_.drawfun = this_.setWtrue : this_.drawfun = this_.setWfalse; + this_.PointerShape("e-resize"); + break; + + case "Rightmiddle": + MaxW = this_.relatW - formParentoffsetLeft; + var MaxHA = formParentoffsetTop, + MaxHB = this_.relatH - MaxHA - this_.formAllH; + MaxH = Math.min(MaxHA, MaxHB) * 2 + this_.formAllH; + strTT = "MT"; + this_.arg.proportional[0] ? this_.drawfun = this_.setWtrue : this_.drawfun = this_.setWfalse; + this_.PointerShape("e-resize"); + break; + + case "Bottommiddle": + var MaxWA = formParentoffsetLeft, + MaxWB = this_.relatW - MaxWA - this_.formAllW; + MaxW = Math.min(MaxWA, MaxWB) * 2 + this_.formAllW; + MaxH = this_.relatH - formParentoffsetTop; + this_.arg.proportional[0] ? this_.drawfun = this_.setHtrue : this_.drawfun = this_.setHfalse; + strLL = "ML"; + this_.PointerShape("n-resize"); + break; + + default: + break; + } + var disX = clientX - PNW * W, + disY = clientY - PNH * H; + this.setCapture && this.setCapture(); + typeof this_.DomMoveEve === "function" && this_.delEvent(document, this_.eveMold[1], this_.DomMoveEve); + this_.DomMoveEve = this_.DomMove(this_, this, disX, disY, PNW, PNH, formParent, MaxW, MaxH, strLL, strTT); + this_.addEvent(document, this_.eveMold[1], this_.DomMoveEve); + } else { + this_.DomUp(this)(); + } + return false; + }; + } +}; + +window.ShearPhoto.MINGGE = function(a) { + function b() { + try { + var c = function() { + "complete" === document.readyState && (document.detachEvent("onreadystatechange", c), + a()); + }, + d = window.frameElement; + } catch (e) { + return document.attachEvent("onreadystatechange", c), void 0; + } + if (null != d) return document.attachEvent("onreadystatechange", c), void 0; + try { + document.documentElement.doScroll("left"); + } catch (c) { + return setTimeout(b, 13), void 0; + } + a(); + } + var c; + "function" == typeof a && (document.addEventListener ? (c = function() { + document.removeEventListener("DOMContentLoaded", c, !1), a(); + }, document.addEventListener("DOMContentLoaded", c, !1)) : b()); +}; +/*--------------------------拉伸,截图.HTML5的压缩,剪图的处理核心部份结束-----------------------------------------------------------------------------*/ + + +/*--------------------------拖拽移动处理开始-----------------------------------------------------------------------------*/ + +window.ShearPhoto.MoveDiv = function() { + this.arg = new Array(), this.ReckonWH = this.DivW = this.DivH = this.selectionempty = this.addevent = this.DivDownEVe = this.DomMoveEve = this.DomUpEve = this.eveMold = false; +}; + +window.ShearPhoto.MoveDiv.prototype = { + ZeroSetting: function() { + var getLT = this.HTML5.getLT(this.arg.form), + left = parseFloat(getLT[0]), + top = parseFloat(getLT[1]), + size = this._size_(window, true), + leftfun = function() {}, + topfun = function() {}, + tf = false; + if (!isNaN(left)) { + tf = true; + this.HTML5.setL(this.arg.form, 0); + leftfun = function(a, b) { + a < 0 && (a = 0); + this_.HTML5.setL(b, left - a + "px"); + }; + } + if (!isNaN(top)) { + tf = true; + this.HTML5.setT(this.arg.form, 0); + topfun = function(a, b) { + a < 0 && (a = 0); + this_.HTML5.setT(b, top - a + "px"); + }; + } + if (tf === true) { + var size2 = this._size_(window, true); + leftfun(size.W - size2.W, this.arg.form); + topfun(size.H - size2.H, this.arg.form); + } + }, + reckon: function(obj, se) { + this._size_(obj); + var this_ = this; + if (se === true) { + var addfun = function() { + this_.ZeroSetting(); + this_._size_(obj); + this_.arg.MoveWidth = this_.ReckonWH.W; + this_.arg.MoveHeight = this_.ReckonWH.H; + this_.SetCenter(this_.arg); + }; + this.addEvent(window, "resize", addfun); + } + }, + _size_: function(obj, t) { + var w, h, ReckonWH; + if (obj === window) { + var DE = { + add: document.documentElement, + att: document.body + }[this.addevent]; + w = DE.clientWidth; + h = DE.clientHeight; + ReckonWH = { + W: Math.max(DE.scrollWidth, w), + H: Math.max(DE.scrollHeight, h), + CW: w, + CH: h + }; + } else { + w = obj.offsetWidth; + h = obj.offsetHeight; + ReckonWH = { + W: w, + H: h, + CW: w, + CH: h + }; + } + if (t === true) return ReckonWH; + this.ReckonWH = ReckonWH; + }, + DomUp: function(dom) { + var this_ = this; + return function() { + dom.releaseCapture && dom.releaseCapture(); + typeof this_.DomMoveEve === "function" && this_.delEvent(document, this_.eveMold[1], this_.DomMoveEve); + if (typeof this_.DomUpEve === "function") { + this_.delEvent(document, this_.eveMold[2], this_.DomUpEve); + this_.delEvent(window, this_.eveMold[2], this_.DomUpEve); + this_.delEvent(window, "blur", this_.DomUpEve); + this_.delEvent(dom, "losecapture", this_.DomUpEve); + } + return false; + }; + }, + DivWHFun: function() { + this.DivW = this.arg.form.offsetWidth; + this.DivH = this.arg.form.offsetHeight; + }, + DomMove: function(this_, dom, disX, disY, formLeft, formTop) { + var argform = this_.arg.form, + DivW = this_.DivW, + DivH = this_.DivH, + MoveScale, MoveFun = function() {}, + shifting = this_.arg.shifting = Object.prototype.toString.call(this_.arg.shifting) === "[object Array]" && this_.arg.shifting.length > 1 ? this_.arg.shifting : new Array(0, 0), + argMoveWidth = this_.arg.MoveWidth - shifting[0], + argMoveHeight = this_.arg.MoveHeight - shifting[1]; + if (typeof this_.DomUpEve === "function") { + this_.delEvent(document, this_.eveMold[2], this_.DomUpEve); + this_.delEvent(window, this_.eveMold[2], this_.DomUpEve); + this_.delEvent(window, "blur", this_.DomUpEve); + this_.delEvent(dom, "losecapture", this_.DomUpEve); + } + this_.DomUpEve = this_.DomUp(dom); + this_.addEvent(document, this_.eveMold[2], this_.DomUpEve); + this_.addEvent(window, this_.eveMold[2], this_.DomUpEve); + this_.addEvent(window, "blur", this_.DomUpEve); + this_.addEvent(dom, "losecapture", this_.DomUpEve); + var maxL = argMoveWidth - DivW, + maxT = argMoveHeight - DivH, + iL, iT, eveclientX, eveclientY; + typeof this_.arg.MoveFun === "function" && (MoveFun = this_.arg.MoveFun); + MoveScale = [maxL, maxT]; + return function(eve) { + eve = eve || window.event; + if (eve.button > 1) { + this_.DomUp(this)(); + return false; + } + eveclientX = this_.eveMold[3](eve, "clientX"), eveclientY = this_.eveMold[3](eve, "clientY"); + setTimeout(function() { + iL = eveclientX - disX; + iT = eveclientY - disY; + this_.selectionempty(); + iL = iL < -shifting[0] ? -shifting[0] : iL; + iL = iL > maxL ? maxL : iL; + iT = iT < -shifting[1] ? -shifting[1] : iT; + iT = iT > maxT ? maxT : iT; + this_.HTML5.setLT(argform, iL + "px", iT + "px"); + MoveFun(iL, iT, MoveScale); + }, 1); + return false; + }; + }, + DivDown: function() { + var this_ = this; + return function(event) { + var event = event || window.event, + eventbutton = event.button, + typebutton = typeof eventbutton, + clientX, clientY; + event.preventDefault && event.preventDefault(); + if (typebutton !== "number") { + this_.eveMold = ["touchstart", "touchmove", "touchend", function(events, clientXY) { + return events.touches[0][clientXY]; + }]; + clientX = event.touches[0].clientX; + clientY = event.touches[0].clientY; + } else { + this_.eveMold = ["mousedown", "mousemove", "mouseup", function(events, clientXY) { + return events[clientXY]; + }]; + clientX = event.clientX; + clientY = event.clientY; + } + if (eventbutton < 2 || typebutton !== "number") { + var getLT = this_.HTML5.getLT(this_.arg.form), + formLeft = parseFloat(getLT[0]), + formTop = parseFloat(getLT[1]), + disX = clientX - formLeft, + disY = clientY - formTop; + this.setCapture && this.setCapture(); + typeof this_.arg.DivDownFun === "function" && this_.arg.DivDownFun(this_); + typeof this_.DomMoveEve === "function" && this_.delEvent(document, this_.eveMold[1], this_.DomMoveEve); + this_.DomMoveEve = this_.DomMove(this_, this, disX, disY, formLeft, formTop); + this_.addEvent(document, this_.eveMold[1], this_.DomMoveEve); + } else { + this_.DomUp(this)(); + } + return false; + }; + }, + ShearPhotoDown: function(obj, fun) { + this.addEvent(obj, "mousedown", fun); + this.addEvent(obj, "touchstart", fun); + }, + delShearPhotoDown: function(obj, fun) { + this.delEvent(obj, "mousedown", fun); + this.delEvent(obj, "touchstart", fun); + }, + et: function() { + var this_ = this; + var cursor = this.arg.cursor || "move"; + this_ = this; + for (var i = 0; i < this.arg.to.length; i++) { + if (this.addevent === "add") { + if (typeof this.DivDownEVe !== "function") { + this.DivDownEVe = this.DivDown(); + } else { + this.delShearPhotoDown(this.arg.to[i], this.DivDownEVe); + } + this.ShearPhotoDown(this.arg.to[i], this.DivDownEVe); + } else { + this.arg.to[i].onmousedown = this.DivDown(); + } + this.arg.to[i].style["cursor"] = cursor; + } + }, + delDownEve: function() { + for (var i = 0; i < this.arg.to.length; i++) { + if (this.addevent === "add") { + if (typeof this.DivDownEVe === "function") { + this.delShearPhotoDown(this.arg.to[i], this.DivDownEVe); + } + } + } + }, + setdiv: function(argform, CW, CH, arg) { + if (typeof arg.centerFront === "function") { + var CWCH = arg.centerFront(); + CW = CWCH[0]; + CH = CWCH[1]; + } + var DivT = Math.round((CH - this.DivH) * .5); + DivT = DivT < 0 ? 0 : DivT; + var DivL = Math.round((CW - this.DivW) * .5); + DivL = DivL < 0 ? 0 : DivL; + this.HTML5.setLT(argform, DivL + "px", DivT + "px"); + typeof arg.centerfun === "function" && arg.centerfun(DivL, DivT, this); + }, + addEvent: function(obj, evetype, fun) { + var addevent = { + add: function() { + obj.addEventListener(evetype, fun, false); + }, + att: function() { + obj.attachEvent("on" + evetype, fun); + } + }; + addevent[this.addevent] && addevent[this.addevent](); + }, + delEvent: function(obj, evetype, fun) { + var delevent = { + add: function() { + obj.removeEventListener(evetype, fun, false); + }, + att: function() { + obj.detachEvent("on" + evetype, fun); + } + }; + delevent[this.addevent] && delevent[this.addevent](); + }, + SetCenter: function(arg) { + if (arg.center) { + if (arg.center === 1) { + var CW = this.ReckonWH.CW, + CH = this.ReckonWH.CH; + } else { + var ReckonWH = this._size_(arg.center, true); + var CW = ReckonWH.CW, + CH = ReckonWH.CH; + } + this.setdiv(arg.form, CW, CH, arg); + } + }, + run: function(arg) { + this.arg = arg; + this.DivW = arg.form.offsetWidth; + this.DivH = arg.form.offsetHeight; + this.SetCenter(arg); + typeof arg.zIndex === "number" && (arg.form.style.zIndex = arg.zIndex); + this.et(); + } +}; + +/*--------------------------拖拽移动处理结束--------------------------------------------------------------------------------------*/ + +/*--------------------------与服务器交互数据JS部份开始-------------------------------------------------------------------------------*/ + +window.ShearPhoto.JsonString = { + _json_: null, + JsonToString: function(arr) { + try { + this._json_ = new Array(); + this._read_(arr, true); + var JsonJoin = this._json_.join(""); + JsonJoin = JsonJoin.replace(/,([\}\]])/g, function(a, b) { + return b; + }); + this._json_ = null; + return JsonJoin; + } catch (e) { + alert("发生错误,错误代码--" + e); + return ""; + } + }, + StringToJson: function(arrtxt) { + if (typeof arrtxt !== "string") { + alert("请传入JSON字串符,看清楚demo.html是怎么操作的"); + return; + } + try { + var array = new Function("return " + "(" + arrtxt + ")")(); + var type = this._type_(array); + if (type !== "[object Object]" && type !== "[object Array]") { + alert("严重报错:后端没返回到JSON,而是一串无效字符串。\n\n你是在调试吗?\n\n那么按确定,查看那串无效字符串吧"); + alert(arrtxt); + return false; + } + return array; + } catch (e) { + alert("严重报错:后端没返回到JSON,而是一串无效字符串。\n\n你是在调试吗?\n\n那么按确定,查看那串无效字符串吧"); + alert(arrtxt); + return false; + } + }, + _type_: function(arr) { + if (typeof arr.nodeType === "number") return "[object document]"; + var Types = Object.prototype.toString.call(arr); + return Types; + }, + _addjson_: function(types, txt, txt2, TrueFalse) { + var run = { + "[object Object]": txt, + "[object Array]": txt2 + }; + this._json_.push(run[types]); + }, + _addstring_: function(parameter) { + var of = typeof parameter; + if (of === "string") return '"' + parameter + '"'; + else if (of === "number") return parameter; + var types = this._type_(parameter); + if (types === "[object Object]" || types === "[object Array]") { + return false; + } else return '""'; + }, + _read_: function(arr, TrueFalse) { + var types = this._type_(arr); + if (TrueFalse && types !== "[object Object]" && types !== "[object Array]") { + alert("你传入不是数组或JSON,看清楚demo.html是怎么操作的"); + this._json_ = null; + return false; + } + this._addjson_(types, "{", "[", TrueFalse); + for (var a in arr) { + if (typeof arr.constructor.prototype[a] === "undefined") { + var ArrA = this._addstring_(arr[a]); + if (typeof ArrA !== "boolean") { + this._addjson_(types, '"' + a + '":' + ArrA + ",", ArrA + ","); + } else { + this._addjson_(types, '"' + a + '":', ""); + this._read_(arr[a], false); + } + } + } + TrueFalse = TrueFalse ? "" : ","; + this._addjson_(types, "}" + TrueFalse, "]" + TrueFalse); + + } +}; + +window.ShearPhoto.MyAjax = function() { + this.serverdata = this.erromsg = this.timeout = this.stop = this.xmlhttp = false; + this.transit = true; +}; + +window.ShearPhoto.MyAjax.prototype.handle = function(xmlhttp, arg) { + if (4 == xmlhttp.readyState) { + if (this.stop === true) return; + this.transit = true; + if (arg.timeout && arg.async) { + clearTimeout(this.timeout); + this.timeout = false; + } + if (200 == xmlhttp.status) { + var responseText = this.serverdata = xmlhttp.responseText.replace(/(^\s*)|(\s*$)/g, ""); + typeof arg.success === "function" && arg.success(responseText); + } else { + this.erromsg = xmlhttp.status; + typeof arg.error === "function" && arg.error(xmlhttp.status); + } + } else { + if (0 == xmlhttp.readyState) { + if (this.stop === true) return; + if (arg.timeout && arg.async) { + clearTimeout(this.timeout); + this.timeout = false; + } + this.erromsg = xmlhttp.readyState; + this.transit = true; + typeof arg.error === "function" && arg.error(xmlhttp.readyState); + } + } +}; + +window.ShearPhoto.MyAjax.prototype.out = function(arg) { + this.transit = true; + this.erromsg = 504; + this.stop = true; + typeof arg.error === "function" && arg.error(504); +}; + +window.ShearPhoto.MyAjax.prototype.carry = function(arg) { + if (arg.lock && !this.transit) return false; + this.transit = false; + this.stop = this.erromsg = false; + var xmlhttp; + if (window.XMLHttpRequest) { + xmlhttp = new XMLHttpRequest(); + } else { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } + arg.type = arg.type.toUpperCase(); + var ContentType = function() {}; + if (typeof arg.data === "string") { + arg.data = arg.data.replace(/(^\s*)|(\s*$)/g, ""); + ContentType = function() { + xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + }; + } else { + if (Object.prototype.toString.call(arg.data) !== "[object FormData]") { + arg.data = ""; + ContentType = function() { + xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + }; + } else { + typeof arg.progress === "function" && xmlhttp.upload.addEventListener("progress", arg.progress, false); + arg.type = "POST"; + } + } + var SendArg = arg.data == "" ? [null, ""] : [arg.data, "?" + arg.data]; + var self = this; + typeof arg.complete === "function" && arg.complete(); + arg.timeout && arg.async && (this.timeout = setTimeout(function() { + self.out(arg); + }, arg.timeout)); + if (arg.async === true) { + xmlhttp.onreadystatechange = function() { + self.handle(xmlhttp, arg); + }; + } + try { + switch (arg.type) { + case "POST": + xmlhttp.open("POST", arg.url, arg.async); + ContentType(); + break; + + default: + xmlhttp.open("GET", arg.url + SendArg[1], arg.async); + arg.cache === true || xmlhttp.setRequestHeader("If-Modified-Since", "0"); + break; + } + } catch (e2) { + this.erromsg = 505; + if (arg.timeout && arg.async) { + clearTimeout(this.timeout); + this.timeout = false; + } + this.transit = true; + typeof arg.error === "function" && arg.error(505); + return; + } + xmlhttp.send(SendArg[0]); + if (arg.async === false) { + self.handle(xmlhttp, arg); + } +}; + +/*--------------------------与服务器交互数据JS部份结束-------------------------------------------------------------------------------*/ + + + + + +/*--------------------------选择上传截图的JS部份开始-------------------------------------------------------------------------------*/ +window.ShearPhoto.frameUpImg = function(config) { + this.BodyDom = document.body; + this.FORM = config.FORM; + this.upfile = this.FORM.UpFile; + this.config = config; + this.upfileclick = false; + typeof config.erro !== "function" && (config.erro = function() {}); + this.FORM.action = config["url"]; + var this_ = this; + this.parentNodes = this.upfile.parentNode; + if (window.attachEvent) { + this.parentNodes.onmousemove = function() { + var offsetX = window.event.offsetX + 5; + offsetX < 0 && (offsetX = 0); + offsetX > 224 && (offsetX = 224); + this_.upfile.style.width = offsetX + "px"; + }; + } +}; + +window.ShearPhoto.frameUpImg.prototype = { + createframe: function() { + this.BodyDom.insertAdjacentHTML("afterBegin", ''); + this.iframe = document.getElementsByName("POSTiframe")[0]; + this.createEve(this.iframe, window.frames["POSTiframe"]); + }, + createEve: function(iframe, windowframes) { + var this_ = this; + if (this.upfile.files) { + iframe.onload = function() { + iframe.onload = null; + var windowframesbody = windowframes.document.getElementsByTagName("BODY")[0]; + var html = windowframesbody.innerHTML; + this_.Evebubbling(html); + }; + } else { + iframe.onreadystatechange = function() { + if (iframe.readyState === "complete") { + iframe.onreadystatechange = null; + var windowframesbody = windowframes.document.getElementsByTagName("BODY")[0]; + var html = windowframesbody.innerHTML; + this_.Evebubbling(html); + } + }; + } + }, + delframe: function() { + this.BodyDom.removeChild(this.iframe); + this.DelCreateUpfile(); + }, + Evebubbling: function(html) { + if (html != "") { + this.upfile.onclick = this.upfileclick; + typeof this.fun === "function" && this.fun(html); + this.delframe(); + } + }, + inArray: function(elem, array) { + if (array.indexOf) { + return array.indexOf(elem); + } + for (var i = 0, length = array.length; i < length; i++) { + if (array[i] === elem) { + return i; + } + } + return -1; + }, + DelCreateUpfile: function() { + var change = this.upfile.onchange; + this.upfile.onchange = this.upfile.onclick = null; + this.parentNodes.removeChild(this.upfile); + var inputfile = document.createElement("input"); + inputfile.setAttribute("type", "file"); + inputfile.setAttribute("name", "UpFile"); + this.parentNodes.appendChild(inputfile); + this.upfile = inputfile; + this.upfile.onchange = change; + this.upfile.onclick = this.upfileclick; + }, + Upsubmit: function(upfile) { + try { + var filestype = upfile.value.split("."); + filestype = Object.prototype.toString.call(filestype) === "[object Array]" ? filestype[filestype.length - 1] : ""; + if (this.inArray(filestype.toLowerCase(), this.config.UpType) == -1) { + this.DelCreateUpfile(); + this.config.erro("请选择正确图片类型"); + return; + } + var files = upfile.files, + type; + if (files) { + files = files[0]; + files.type && (type = files.type === "image/gif" ? "image/jpeg" : files.type, this.config.HTML5.ImagesType = type); + if (files.size <= 0) { + this.DelCreateUpfile(); + this.config.erro("错误:不能选择空字节文件"); + return; + } + if (this.config.HTML5.canvas) { + if (files.size > this.config.HTML5FilesSize * 1024 * 1024) { + this.DelCreateUpfile(); + this.config.erro("错误:HTML5上传不能大于" + this.config.HTML5FilesSize + "M"); + return; + } + } else if (files.size > this.config.FilesSize * 1024 * 1024) { + this.DelCreateUpfile(); + this.config.erro("错误:文件不能大于" + this.config.FilesSize + "M"); + return; + } + } + var this_ = this; + typeof this.config.preced === "function" && this.config.preced(function() { + if (this_.config.HTML5.canvas) { + var reader = new FileReader(); + reader.onload = function() { + this_.DelCreateUpfile(); + this_.config.HTML5.zipImg(this.result, this_.config.HTML5ZIP, type, function(DataUrl) { + typeof this_.fun === "function" && this_.fun({ + success: DataUrl + }, true); + delete(reader); + }); + }; + reader.readAsDataURL(files); + return; + } + this_.createframe(); + this_.FORM.submit(); + }); + + } catch (e) { + this.DelCreateUpfile(); + this.config.erro("你选择了非图片类型,或 图片路径有误"); + return; + } + }, + run: function(fun) { + var this_ = this; + this.fun = fun; + this.upfile.onclick = this.upfileclick = function() { + typeof this_.config.fileClick === "function" && this_.config.fileClick(); + }; + this.upfile.onchange = function() { + if (this.value == "") return false; + this.onclick = function() { + return false; + }; + this_.Upsubmit(this); + }; + } +}; +/*--------------------------选择上传截图的JS部份结束-------------------------------------------------------------------------------*/ \ No newline at end of file diff --git a/web/static/plugs/avatar/js/alloyimage.js b/web/static/plugs/avatar/js/alloyimage.js new file mode 100644 index 00000000..d7680d9d --- /dev/null +++ b/web/static/plugs/avatar/js/alloyimage.js @@ -0,0 +1,811 @@ +try { + Array.prototype.del = function(a) { + a.sort(); + for (var b = this.concat([]), c = a.length - 1; c >= 0; c--) b = b.slice(0, a[c]).concat(b.slice(a[c] + 1)); + return b; + }, + + HTMLImageElement.prototype.loadOnce = function(a) { + var b = 0; + this.onload = function() { + b || a.call(this, null), b++; + }; + }, + function(a) { + var b = { + lib: [], + init: function() { + this.require("config"); + }, + module: function(a, b) { + this.lib[a] = b.call(null, this); + }, + require: function(a) { + var b = this, + c = document.createElement("script"); + document.body.appendChild(c), c.src = "./js/module/" + a + ".js", c.onload = c.onerror = function(a) { + b.handlerror(a); + }; + }, + handlerror: function() {}, + destroySelf: function(b) { + throw delete ShearPhoto[a], Error(b); + }, + reflect: function(a, b, c) { + return a = this.lib.config.getModuleName(a), this.lib[a].process(b, c); + }, + reflectEasy: function(a) { + return a = this.lib.config.getEasyFun(a), this.lib.easy.getFun(a); + }, + add: function(a, b, c, d, e, f, g, h) { + return this.lib.addLayer.add(a, b, c, d, e, f, g, h); + }, + applyMatrix: function() {} + }; + ShearPhoto[a] = function(b, c, d) { + if (!(this instanceof ShearPhoto[a])) return new ShearPhoto[a](b, c, d); + this.startTime = +new Date(); + var e = document.createElement("canvas"), + f = e.getContext("2d"), + imgWidth, imgHeight; + isNaN(b) ? (e.width = parseInt(b.width), e.height = parseInt(b.height), c = getComputedStyle(b), + imgWidth = parseInt(c.getPropertyValue("width")), imgHeight = parseInt(c.getPropertyValue("height")), + isNaN(imgWidth) ? f.drawImage(b, 0, 0) : f.drawImage(b, 0, 0, imgWidth, imgHeight)) : (e.width = b, + e.height = c, f.fillStyle = d || "#fff", f.fillRect(0, 0, b, c)), this.canvas = e, + this.context = f, this.imgData = f.getImageData(0, 0, e.width, e.height), this.name = a + "_" + Math.random(), + this.canvas.id = this.name, this.layers = [], b = document.createElement("canvas"), + b.width = e.width, b.height = e.height; + }, ShearPhoto[a].module = function(a, c) { + b.module(a, c); + }, ShearPhoto[a].dorsyMath = function() { + return b.lib.dorsyMath; + }, ShearPhoto[a].prototype = { + act: function(a) { + var c = [], + c = Array.prototype.slice.call(arguments, 1); + return b.reflect(a, this.imgData, c), this; + }, + view: function(a, b, c, d, e) { + var f = this.clone(); + return f.type = 1, this.addLayer(f, "正常", 0, 0), f.act(a, b, c, d, e), this; + }, + excute: function() { + var a = this.layers, + b = a.length; + a[b - 1] && 1 == a[b - 1][0].type && (this.imgData = a[b - 1][0].imgData, delete a[b - 1]); + }, + cancel: function() { + var a = this.layers, + b = a.length; + a[b - 1] && 1 == a[b - 1][0].type && delete a[b - 1]; + }, + show: function(b, c) { + var d, e, f, g, h = new ShearPhoto[a](this.canvas.width, this.canvas.height); + for (h.add(this, "正常", 0, 0, c), this.tempPsLib = h, d = 0; d < this.layers.length; d++) e = this.layers[d], + f = e[0].layers, g = e[0], f[f.length - 1] && 1 == f[f.length - 1][0].type && (g = f[f.length - 1][0]), + h.add(g, e[1], e[2], e[3], c); + return this.context.clearRect(0, 0, this.canvas.width, this.canvas.height), this.context.putImageData(h.imgData, 0, 0), + b ? document.querySelector(b).appendChild(this.canvas) : document.body.appendChild(this.canvas), + this; + }, + replace: function(a) { + return a && (a.onload = function() {}, a.src = this.save()), this; + }, + add: function() { + var a, c, d, e, f, g = []; + for (d = 0; d < arguments.length; d++) + if (d) switch (typeof arguments[d]) { + case "string": + /\d+%/.test(arguments[d]) ? c = arguments[d].replace("%", "") : /[RGB]+/.test(arguments[d]) ? f = arguments[d] : a = arguments[d]; + break; + + case "number": + g.push(arguments[d]); + break; + + case "boolean": + e = arguments[d]; + } + return d = g[0] || 0, g = g[1] || 0, this.imgData = b.add(this.imgData, arguments[0].imgData, a || "正常", c / 100 || 1, d, g, e || !1, f || "RGB"), + this; + }, + addLayer: function(a, b, c, d) { + return this.layers.push([a, b, c, d]), this; + }, + clone: function() { + var b = new ShearPhoto[a](this.canvas.width, this.canvas.height); + return b.context.putImageData(this.imgData, 0, 0), b.imgData = b.context.getImageData(0, 0, this.canvas.width, this.canvas.height), + b; + }, + swap: function(a, b) { + var c = this.layers[a]; + return this.layers[a] = this.layers[b], this.layers[b] = c, this; + }, + deleteLayers: function(a) { + this.layers = this.layers.del(a); + }, + save: function(b, c) { + var d, e, f, g, h; + if (!this.layers.length) return c ? (this.context.putImageData(this.imgData, 0, 0), + this.canvas.toDataURL(c, .9)) : (this.context.putImageData(this.imgData, 0, 0), this.canvas.toDataURL()); + for (d = new ShearPhoto[a](this.canvas.width, this.canvas.height), d.add(this, "正常", 0, 0, b), + this.tempPsLib = d, e = 0; e < this.layers.length; e++) f = this.layers[e], g = f[0].layers, + h = f[0], g[g.length - 1] && 1 == g[g.length - 1][0].type && (h = g[g.length - 1][0]), + d.add(h, f[1], f[2], f[3], b); + return this.context.clearRect(0, 0, this.canvas.width, this.canvas.height), this.context.putImageData(d.imgData, 0, 0), + c ? this.canvas.toDataURL(c, .9) : this.canvas.toDataURL(); + }, + drawRect: function() { + var a, b, c, d, e, f; + for ((a = document.getElementById("imgRect")) || (a = document.createElement("canvas"), + a.id = "imgRect", document.body.appendChild(a), a.width = parseInt(this.canvas.width), + a.height = parseInt(this.canvas.height)), b = a.getContext("2d"), b.clearRect(0, 0, a.width, a.height), + c = [], d = this.tempPsLib.imgData.data, e = 0, f = d.length; f > e; e++) c[d[e]] ? c[d[e]]++ : c[d[e]] = 1; + for (b.beginPath(), b.moveTo(0, a.height), e = d = 0; 255 > e; e++) c[e] > d && (d = c[e]); + for (e = 0; 255 > e; e++) f = c[e] || 0, f = a.height - .8 * (f / d) * a.height, + b.lineTo(e / 256 * a.width, f, 1, 1); + b.lineTo(a.width + 10, a.height), b.fill(); + }, + ps: function(a) { + var c; + return c = b.reflectEasy(a).call(this), this.logTime("组合效果" + a), c; + }, + logTime: function(a) { + console.log(a + ": " + (+new Date() - this.startTime) / 1e3 + "s"); + }, + ctx: function(a) { + var b = this.ctxContext; + return b.putImageData(this.imgData, 0, 0), a.call(b), this.imgData = b.getImageData(0, 0, this.canvas.width, this.canvas.height), + this; + } + }; + }("psLib"), + function(a) { + ShearPhoto[a].module("ImageEnhance", function() { + return { + process: function(a) { + for (var b = a.data, c = 0, d = b.length; d > c; c += 4); + return a.data = b, a; + } + }; + }); + }("psLib"), + function(a) { + ShearPhoto[a].module("addLayer", function() { + return { + add: function(a, b, c, d, e, f, g, h) { + var i, j, k, l, m, n, o, p; + for (g = a.data, i = b.data, e = e || 0, f = f || 0, d = d || 1, h = h || "RGB", + /[RGB]+/.test(h) || (h = "RGB"), k = h.replace("R", "0").replace("G", "1").replace("B", "2"), + h = a.width, l = i.length, b = b.width, k = [-1 < k.indexOf("0"), -1 < k.indexOf("1"), -1 < k.indexOf("2")], + o = 0, p = g.length; p > o; o += 4) + if (m = o / 4, n = parseInt(m / h), m %= h, + n -= f, m -= e, n = n * b + m, n *= 4, n >= 0 && l - 4 > n && b > m && m >= 0) + for (m = 0; 3 > m && 0 != i[n + 3]; m++) switch (g[o + 3] = i[n + 3], + c) { + case "颜色减淡": + k[m] && (j = g[o + m] + g[o + m] * i[n + m] / (255 - i[n + m]), g[o + m] = (1 - d) * g[o + m] + d * j); + break; + + case "变暗": + k[m] && (j = g[o + m] < i[n + m] ? g[o + m] : i[n + m], g[o + m] = (1 - d) * g[o + m] + d * j); + break; + + case "变亮": + k[m] && (j = g[o + m] > i[n + m] ? g[o + m] : i[n + m], g[o + m] = (1 - d) * g[o + m] + d * j); + break; + + case "正片叠底": + k[m] && (j = parseInt(g[o + m] * i[n + m] / 255), g[o + m] = (1 - d) * g[o + m] + d * j); + break; + + case "滤色": + k[m] && (j = parseInt(255 - (255 - g[o + m]) * (255 - i[n + m]) / 255), g[o + m] = (1 - d) * g[o + m] + d * j); + break; + + case "叠加": + k[m] && (j = 127.5 >= g[o + m] ? g[o + m] * i[n + m] / 127.5 : 255 - (255 - g[o + m]) * (255 - i[n + m]) / 127.5, + g[o + m] = (1 - d) * g[o + m] + d * j); + break; + + case "强光": + k[m] && (j = 127.5 >= i[n + m] ? g[o + m] * i[n + m] / 127.5 : g[o + m] + (255 - g[o + m]) * (i[n + m] - 127.5) / 127.5, + g[o + m] = (1 - d) * g[o + m] + d * j); + break; + + case "差值": + k[m] && (j = g[o + m] > i[n + m] ? g[o + m] - i[n + m] : i[n + m] - g[o + m], g[o + m] = (1 - d) * g[o + m] + d * j); + break; + + case "排除": + k[m] && (j = g[o + m] + i[n + m] - g[o + m] * i[n + m] / 127.5, g[o + m] = (1 - d) * g[o + m] + d * j); + break; + + case "点光": + k[m] && (j = g[o + m] < 2 * i[n + m] - 255 ? 2 * i[n + m] - 255 : g[o + m] < 2 * i[n + m] ? g[o + m] : 2 * i[n + m], + g[o + m] = (1 - d) * g[o + m] + d * j); + break; + + case "颜色加深": + k[m] && (j = 255 - 255 * (255 - g[o + m]) / i[n + m], g[o + m] = (1 - d) * g[o + m] + d * j); + break; + + case "线性加深": + k[m] && (j = g[o + m] + i[n + m], j = j > 255 ? j - 255 : 0, g[o + m] = (1 - d) * g[o + m] + d * j); + break; + + case "线性减淡": + k[m] && (j = g[o + m] + i[n + m], j = j > 255 ? 255 : j, g[o + m] = (1 - d) * g[o + m] + d * j); + break; + + case "柔光": + k[m] && (j = 127.5 > i[n + m] ? ((2 * i[n + m] - 255) * (255 - g[o + m]) / 65025 + 1) * g[o + m] : (2 * i[n + m] - 255) * (Math.sqrt(g[o + m] / 255) - g[o + m] / 255) + g[o + m], + g[o + m] = (1 - d) * g[o + m] + d * j); + break; + + case "亮光": + k[m] && (j = 127.5 > i[n + m] ? 255 * (1 - (255 - g[o + m]) / (2 * i[n + m])) : g[o + m] / (2 * (1 - i[n + m] / 255)), + g[o + m] = (1 - d) * g[o + m] + d * j); + break; + + case "线性光": + k[m] && (j = g[o + m] + 2 * i[n + m] - 255, j = j > 255 ? 255 : j, g[o + m] = (1 - d) * g[o + m] + d * j); + break; + + case "实色混合": + k[m] && (j = i[n + m] < 255 - g[o + m] ? 0 : 255, g[o + m] = (1 - d) * g[o + m] + d * j); + break; + + default: + k[m] && (j = i[n + m], g[o + m] = (1 - d) * g[o + m] + d * j); + } + return a; + } + }; + }); + }("psLib"), + function(a) { + ShearPhoto[a].module("brightness", function() { + return { + process: function(a, b) { + var c, d, e, f, g, h; + for (c = a.data, d = b[0] / 50, e = Math.tan((45 + 44 * ((b[1] || 0) / 50)) * Math.PI / 180), + f = 0, g = c.length; g > f; f += 4) + for (h = 0; 3 > h; h++) c[f + h] = (c[f + h] - 127.5 * (1 - d)) * e + 127.5 * (1 + d); + return a; + } + }; + }); + }("psLib"), + function(a) { + ShearPhoto[a].module("applyMatrix", function(a) { + return { + process: function(b) { + var c, d, e, f, g, h, i, j, k, l, m, n, o, p; + for (c = b.data, d = b.width, e = new a.lib.dorsyMath.Matrix([-2, -4, -4, -4, -2, -4, 0, 8, 0, -4, -4, 8, 24, 8, -4, -4, 0, 8, 0, -4, -2, -4, -4, -4, -2], 25, 1), + f = [], g = 0, h = c.length; h > g; g += 4) + if (i = g / 4, j = parseInt(i / d), + k = i % d, 0 != j && 0 != k) { + for (l = [ + [], + [], + [] + ], m = -2; 3 > m; m++) + for (n = j + m, o = -2; 3 > o; o++) + for (p = 4 * (n * d + (k + o)), + i = 0; 3 > i; i++) l[i].push(c[p + i]); + for (j = new a.lib.dorsyMath.Matrix(l, 3, matrixSize).mutiply(e), i = 0; 3 > i; i++) f[g + i] = j.data[i]; + f[g + 4] = c[g + 4]; + } + for (g = 0, h = c.length; h > g; g++) c[g] = f[g] || c[g]; + return b; + } + }; + }); + }("psLib"), + function(a) { + ShearPhoto[a].module("config", function() { + var a = { + "灰度处理": "toGray", + "反色": "toReverse", + "灰度阈值": "toThresh", + "高斯模糊": "gaussBlur", + "亮度": "brightness", + "浮雕效果": "embossment", + "查找边缘": "borderline", + "色相/饱和度调节": "setHSI", + "马赛克": "mosaic", + "油画": "oilPainting", + "腐蚀": "corrode", + "锐化": "sharp", + "添加杂色": "noise", + "曲线": "curve", + "暗角": "darkCorner", + "喷点": "dotted" + }, + b = { + "美肤": "softenFace", + "素描": "sketch", + "自然增强": "softEnhancement", + "紫调": "purpleStyle", + "柔焦": "soften", + "复古": "vintage", + "黑白": "gray", + "仿lomo": "lomo", + "亮白增强": "strongEnhancement", + "灰白": "strongGray", + "灰色": "lightGray", + "暖秋": "warmAutumn", + "木雕": "carveStyle", + "粗糙": "rough" + }; + return { + getModuleName: function(b) { + return a[b] || b; + }, + getEasyFun: function(a) { + return b[a] || a; + } + }; + }); + }("psLib"), + function(a) { + ShearPhoto[a].module("corrode", function() { + return { + process: function(a, b) { + var c, d, e, f, g, h, i, j, k; + for (c = parseInt(b[0]) || 3, d = a.data, e = a.width, f = a.height, g = 0; e > g; g++) + for (h = 0; f > h; h++) + for (i = parseInt(2 * Math.random() * c) - c, + j = parseInt(2 * Math.random() * c) - c, k = h * e + g, i = (h + i) * e + g + j, + j = 0; 3 > j; j++) d[4 * k + j] = d[4 * i + j]; + return a; + } + }; + }); + }("psLib"), + function(a) { + ShearPhoto[a].module("curve", function(a) { + return { + process: function(b, c) { + var d, e, f, g, h, i, j, k; + for (d = a.lib.dorsyMath.lagrange(c[0], c[1]), e = b.data, f = b.width, g = b.height, + h = 0; f > h; h++) + for (i = 0; g > i; i++) + for (j = i * f + h, k = 0; 3 > k; k++) e[4 * j + k] = d(e[4 * j + k]); + return b; + } + }; + }); + }("psLib"), + function(a) { + ShearPhoto[a].module("darkCorner", function(a) { + return { + process: function(b, c) { + var d, e, f, g, h, i, j, k, l, m, n, o, p, q; + for (d = parseInt(c[0]) || 3, e = c[1] || 30, f = b.data, g = b.width, h = b.height, + i = 2 * g / 3, j = 1 * h / 2, k = a.lib.dorsyMath.distance([i, j]), d = k * (1 - d / 10), + l = 0; g > l; l++) + for (m = 0; h > m; m++) + for (n = m * g + l, o = 0; 3 > o; o++) p = f[4 * n + o], + q = (a.lib.dorsyMath.distance([l, m], [i, j]) - d) / (k - d), 0 > q && (q = 0), + p = (0 * Math.pow(1 - q, 3) + .06 * q * Math.pow(1 - q, 2) + 3 * .3 * q * q * (1 - q) + 1 * Math.pow(q, 3)) * p * e / 255, + f[4 * n + o] -= p; + return b; + } + }; + }); + }("psLib"), + function(a) { + ShearPhoto[a].module("dorsyMath", function(a) { + var b = { + FFT1: function(a) { + function c() { + var g, h, i, j, k, l, m, n, o, p, q; + for (e++, g = d / Math.pow(2, e), h = d / g, i = 0; g > i; i++) + for (j = i * h, + k = (i + 1) * h - 1, l = e, m = Math.pow(2, l - 1), n = 0; k - m >= j; j++) o = j + m, + p = n * d / Math.pow(2, l), q = p + d / 4, a[j] instanceof b.C || (a[j] = new b.C(a[j])), + a[o] instanceof b.C || (a[o] = new b.C(a[o])), p = a[j].plus(a[o].mutiply(f[p])), + q = a[j].plus(a[o].mutiply(f[q])), a[j] = p, a[o] = q, n++; + g > 1 && c(); + } + for (var d = a.length, e = 0, f = [], g = 0; d > g; g++) f[g] = this.exp(-2 * Math.PI * g / d); + return c(), a; + }, + DFT: function() {}, + Matrix: function(a, b, c) { + var d, e, f = []; + if (b) { + if (isNaN(b) ? (d = /(\d+)\*/.exec(b)[1], b = /\*(\d+)/.exec(b)[1]) : (d = b, b = c), + a[0] && a[0][0]) + for (c = 0; d > c; c++) + for (f[c] = [], e = 0; b > e; e++) f[c][e] = a[c][e] || 0; + else + for (c = 0; d > c; c++) + for (f[c] = [], + e = 0; b > e; e++) f[c][e] = a[c * b + e] || 0; + this.m = d, this.n = b; + } else this.m = a.length, this.n = a[0].length; + this.data = f; + }, + C: function(a, b) { + this.r = a || 0, this.i = b || 0; + }, + exp: function(a, c) { + a = a || 0, c = c || 1; + var d = new b.C(); + return d.r = c * Math.cos(a), d.i = c * Math.sin(a), d; + }, + lagrange: function(a, b) { + var c = a.length; + return function(d) { + var e, f, g, h, i; + for (e = 0, f = 0; c > f; f++) { + for (g = 1, h = 1, i = 0; c > i; i++) i != f && (g *= a[f] - a[i], h *= d - a[i]); + e += b[f] * (h / g); + } + return e; + }; + }, + applyMatrix: function(c, d, e) { + var f, g, h, i, j, k, l, m, n, o, p, q, r, s, t; + for (e = e || 0, f = c.data, g = c.width, h = d.length, d = new b.Matrix(d, h, 1), + i = [], j = -(Math.sqrt(h) - 1) / 2, k = 0, l = f.length; l > k; k += 4) + if (m = k / 4, + n = parseInt(m / g), o = m % g, 0 != n && 0 != o) { + for (p = [ + [], + [], + [] + ], q = j; - j >= q; q++) + for (r = n + q, s = j; - j >= s; s++) + for (t = 4 * (r * g + (o + s)), + m = 0; 3 > m; m++) p[m].push(f[t + m]); + for (n = new a.lib.dorsyMath.Matrix(p, 3, h).mutiply(d), m = 0; 3 > m; m++) i[k + m] = n.data[m]; + i[k + 4] = f[k + 4]; + } + for (k = 0, l = f.length; l > k; k++) i[k] && (f[k] = i[k] < e ? i[k] : f[k]); + return c; + }, + RGBToHSI: function(a, b, c) { + var d = (a - b + a - c) / 2 / Math.sqrt((a - b) * (a - b) + (a - c) * (b - c)) || 0, + d = Math.acos(d), + d = c > b ? 2 * Math.PI - d : d, + e = 1 - 3 * Math.min(a, b, c) / (a + b + c); + return d > 2 * Math.PI && (d = 2 * Math.PI), 0 > d && (d = 0), { + H: d, + S: e, + I: (a + b + c) / 3 + }; + }, + HSIToRGB: function(a, b, c) { + if (0 > a ? (a %= 2 * Math.PI, a += 2 * Math.PI) : a %= 2 * Math.PI, a <= 2 * Math.PI / 3) var d = c * (1 - b), + e = c * (1 + b * Math.cos(a) / Math.cos(Math.PI / 3 - a)), + f = 3 * c - (e + d); + else a <= 4 * Math.PI / 3 ? (a -= 2 * Math.PI / 3, + e = c * (1 - b), f = c * (1 + b * Math.cos(a) / Math.cos(Math.PI / 3 - a)), d = 3 * c - (f + e)) : (a -= 4 * Math.PI / 3, + f = c * (1 - b), d = c * (1 + b * Math.cos(a) / Math.cos(Math.PI / 3 - a)), e = 3 * c - (f + d)); + return { + R: e, + G: f, + B: d + }; + }, + applyInHSI: function(a, b) { + var c, d, e, f; + for (c = a.data, d = 0, e = c.length; e > d; d += 4) f = this.RGBToHSI(c[d], c[d + 1], c[d + 2]), + b(f), 1 < f.S && (f.S = 1), 0 > f.S && (f.S = 0), f = this.HSIToRGB(f.H, f.S, f.I), + c[d] = f.R, c[d + 1] = f.G, c[d + 2] = f.B; + }, + applyInCoordinate: function() {}, + distance: function(a, c) { + return c = c || [0, 0], a = new b.C(a[0], a[1]), c = new b.C(c[0], c[1]), a.minus(c).distance(); + }, + xyToIFun: function(a) { + return function(b, c, d) { + return 4 * (c * a + b) + (d || 0); + }; + }, + xyCal: function(a, b, c, d, e) { + var f, g, h; + for (f = this.xyToIFun(a.width), g = 0; 3 > g; g++) h = f(b, c, g), a[h] = d(a[h]); + e && (a[h + 1] = e(a[h + 1])); + } + }; + return b.Matrix.prototype = { + plus: function(a) { + var c, d, e; + if (this.m != a.m || this.n != a.n) throw Error("矩阵加法行列不匹配"); + for (c = new b.Matrix([], this.m, this.n), d = 0; d < this.m; d++) + for (e = 0; e < this.n; e++) c.data[d][e] = this.data[d][e] + a.data[d][e]; + return c; + }, + minus: function(a) { + var c, d, e; + if (this.m != a.m || this.n != a.n) throw Error("矩阵减法法行列不匹配"); + for (c = new b.Matrix([], this.m, this.n), d = 0; d < this.m; d++) + for (e = 0; e < this.n; e++) c.data[d][e] = this.data[d][e] - a.data[d][e]; + return c; + }, + mutiply: function(a) { + var c, d, e, f, g; + if (this.n != a.m) throw Error("矩阵乘法行列不匹配"); + for (c = new b.Matrix([], this.m, a.n), d = 0; d < this.m; d++) + for (e = 0; e < a.n; e++) { + for (f = 0, g = 0; g < this.n; g++) f += this.data[d][g] * a.data[g][e]; + c.data[d][e] = f; + } + return c; + } + }, b.C.prototype = { + plus: function(a) { + var c = new b.C(); + return c.r = this.r + a.r, c.i = this.i + a.i, c; + }, + minus: function(a) { + var c = new b.C(); + return c.r = this.r - a.r, c.i = this.i - a.i, c; + }, + mutiply: function(a) { + var c = new b.C(); + return c.r = this.r * a.r - this.i * a.i, c.i = this.r * a.i + this.i * a.r, c; + }, + divide: function(a) { + var c = new b.C(), + d = a.mutiply(a.conjugated()); + return a = this.mutiply(a.conjugated()), c.r = a.r / d.r, c.i = a.i / d.r, c; + }, + conjugated: function() { + return new b.C(this.r, -this.i); + }, + distance: function() { + return Math.sqrt(this.r * this.r + this.i * this.i); + } + }, b; + }); + }("psLib"), + function(a) { + ShearPhoto[a].module("dotted", function(a) { + return { + process: function(b, c) { + var d, e, f, g, h, i, j, k, l, m, n, o, p, q; + for (d = parseInt(c[0]) || 1, e = parseInt(c[1]) || 1, f = b.data, g = b.width, + h = b.height, i = 2 * d + 1, j = [], k = e * e, e = -d; d > e; e++) + for (l = -d; d > l; l++) e * e + l * l > k && j.push([e, l]); + for (d = a.lib.dorsyMath.xyToIFun(g), e = 0, g = parseInt(g / i); g > e; e++) + for (l = 0, + k = parseInt(h / i); k > l; l++) + for (m = parseInt((e + .5) * i), n = parseInt((l + .5) * i), + o = 0; o < j.length; o++) p = m + j[o][0], q = n + j[o][1], f[d(p, q, 3)] = 225, + f[d(p, q, 2)] = 225, f[d(p, q, 0)] = 225, f[d(p, q, 1)] = 225; + return b; + } + }; + }); + }("psLib"), + function(a) { + ShearPhoto[a].module("easy", function() { + return { + getFun: function(b) { + return { + softenFace: function() { + return this.clone().add(this.act("高斯模糊", 10), "滤色").act("亮度", -10, 5); + }, + sketch: function() { + var a = this.act("灰度处理").clone(); + return this.add(a.act("反色").act("高斯模糊", 8), "颜色减淡").act("锐化", 1); + }, + softEnhancement: function() { + return this.act("曲线", [0, 190, 255], [0, 229, 255]); + }, + purpleStyle: function() { + var a = this.clone(); + return this.add(a.act("高斯模糊", 3), "正片叠底", "RG"); + }, + soften: function() { + var a = this.clone(); + return this.add(a.act("高斯模糊", 6), "变暗"); + }, + vintage: function() { + return this.clone(), this.act("灰度处理").add(ShearPhoto[a](this.canvas.width, this.canvas.height, "#808080").act("添加杂色").act("高斯模糊", 4).act("色相/饱和度调节", 32, 19, 0, !0), "叠加"); + }, + gray: function() { + return this.act("灰度处理"); + }, + lomo: function() { + return this.clone().add(this.clone(), "滤色").add(this.clone(), "柔光").add(this.clone().act("反色"), "正常", "20%", "B").act("暗角", 6, 200); + }, + strongEnhancement: function() { + return this.clone().add(this.clone().act("曲线", [0, 50, 255], [0, 234, 255]), "柔光"); + }, + strongGray: function() { + return this.act("灰度处理").act("曲线", [0, 61, 69, 212, 255], [0, 111, 176, 237, 255]); + }, + lightGray: function() { + return this.act("灰度处理").act("曲线", [0, 60, 142, 194, 255], [0, 194, 240, 247, 255]); + }, + warmAutumn: function() { + var a = this.clone().act("色相/饱和度调节", 36, 47, 8, !0).act("暗角", 6, 150); + return this.add(a, "叠加"); + }, + carveStyle: function() { + var a = this.clone().act("马赛克").act("查找边缘").act("浮雕效果"); + return this.add(a, "线性光"); + }, + rough: function() { + return this.add(ShearPhoto[a](this.canvas.width, this.canvas.height, "#000").act("喷点").act("反色").act("浮雕效果"), "叠加"); + } + }[b]; + } + }; + }); + }("psLib"), + function(a) { + ShearPhoto[a].module("embossment", function() { + return { + process: function(a) { + var b, c, d, e, f, g, h, i, j; + for (b = a.data, c = a.width, d = [], e = 0, f = b.length; f > e; e += 4) + if (g = e / 4, + h = parseInt(g / c), i = g % c, g = 4 * ((h - 1) * c + (i - 1)), j = 4 * (h + 1) * c + 4 * (i + 1), + 0 != h && 0 != i) { + for (h = 0; 3 > h; h++) d[e + h] = b[g + h] - b[j + h] + 127.5; + d[e + 4] = b[e + 4]; + } + for (e = 0, f = b.length; f > e; e++) b[e] = d[e] || b[e]; + return a; + } + }; + }); + }("psLib"), + function(a) { + ShearPhoto[a].module("gaussBlur", function() { + return { + process: function(a, b, c) { + var d, e, f, g, h, i, j = a.data, + k = a.width, + l = a.height, + m = [], + n = 0; + for (b = Math.floor(b) || 3, c = c || b / 3, d = 1 / (Math.sqrt(2 * Math.PI) * c), + g = -1 / (2 * c * c), h = 0, c = -b; b >= c; c++, h++) f = d * Math.exp(g * c * c), + m[h] = f, n += f; + for (h = 0, c = m.length; c > h; h++) m[h] /= n; + for (d = 0; l > d; d++) + for (c = 0; k > c; c++) { + for (n = e = f = g = 0, i = -b; b >= i; i++) h = c + i, h >= 0 && k > h && (h = 4 * (d * k + h), + e += j[h] * m[i + b], f += j[h + 1] * m[i + b], g += j[h + 2] * m[i + b], n += m[i + b]); + h = 4 * (d * k + c), j[h] = e / n, j[h + 1] = f / n, j[h + 2] = g / n; + } + for (c = 0; k > c; c++) + for (d = 0; l > d; d++) { + for (n = e = f = g = 0, i = -b; b >= i; i++) h = d + i, h >= 0 && l > h && (h = 4 * (h * k + c), + e += j[h] * m[i + b], f += j[h + 1] * m[i + b], g += j[h + 2] * m[i + b], n += m[i + b]); + h = 4 * (d * k + c), j[h] = e / n, j[h + 1] = f / n, j[h + 2] = g / n; + } + return a.data = j, a; + } + }; + }); + }("psLib"), + function(a) { + ShearPhoto[a].module("borderline", function(a) { + return { + process: function(b) { + return a.lib.dorsyMath.applyMatrix(b, [0, 1, 0, 1, -4, 1, 0, 1, 0], 250); + } + }; + }); + }("psLib"), + function(a) { + ShearPhoto[a].module("mosaic", function() { + return { + process: function(a, b) { + var c, d, e, f, g, h, i, j, k, l, m, n, o; + for (c = parseInt(b[0]) || 3, d = a.data, e = a.width, f = a.height, c = 2 * c + 1, + g = 0, h = parseInt(e / c); h > g; g++) + for (i = 0, j = parseInt(f / c); j > i; i++) { + for (k = [], l = [0, 0, 0], m = 0; c > m; m++) + for (n = 0; c > n; n++) o = (i * c + m) * e + g * c + n, + l[0] += d[4 * o], l[1] += d[4 * o + 1], l[2] += d[4 * o + 2]; + for (k[0] = l[0] / (c * c), k[1] = l[1] / (c * c), k[2] = l[2] / (c * c), m = 0; c > m; m++) + for (n = 0; c > n; n++) o = (i * c + m) * e + g * c + n, + d[4 * o] = k[0], d[4 * o + 1] = k[1], d[4 * o + 2] = k[2]; + } + return a; + } + }; + }); + }("psLib"), + function(a) { + ShearPhoto[a].module("noise", function() { + return { + process: function(a, b) { + var c, d, e, f, g, h, i, j, k; + for (c = parseInt(b[0]) || 100, d = a.data, e = a.width, f = a.height, g = 0; e > g; g++) + for (h = 0; f > h; h++) + for (i = h * e + g, + j = 0; 3 > j; j++) k = parseInt(2 * Math.random() * c) - c, d[4 * i + j] += k; + return a; + } + }; + }); + }("psLib"), + function(a) { + ShearPhoto[a].module("oilPainting", function() { + return { + process: function(a, b) { + var c, d, e, f, g, h, i, j, k; + for (c = parseInt(b[0]) || 16, d = a.data, e = a.width, f = a.height, g = 0; e > g; g++) + for (h = 0; f > h; h++) { + for (i = h * e + g, j = 0, k = 0; 3 > k; k++) j += d[4 * i + k]; + for (j /= 3, j = parseInt(j / c) * c, k = 0; 3 > k; k++) d[4 * i + k] = j; + } + return a; + } + }; + }); + }("psLib"), + function(a) { + ShearPhoto[a].module("setHSI", function(a) { + return { + process: function(b, c) { + return c[0] = c[0] / 180 * Math.PI, c[1] = c[1] / 100 || 0, c[2] = 255 * (c[2] / 100) || 0, + c[3] = c[3] || !1, a.lib.dorsyMath.applyInHSI(b, function(a) { + c[3] ? (a.H = c[0], a.S = c[1]) : (a.H += c[0], a.S += c[1]), a.I += c[2]; + }), b; + } + }; + }); + }("psLib"), + function(a) { + ShearPhoto[a].module("sharp", function() { + return { + process: function(a, b) { + var c, d, e, f, g, h, i, j, k; + for (c = b[0] || .6, d = a.data, e = a.width, f = 0, g = d.length; g > f; f += 4) + if (h = f / 4, + i = parseInt(h / e), j = h % e, 0 != i && 0 != j) + for (k = 4 * ((i - 1) * e + (j - 1)), + i = 4 * ((i - 1) * e + j), h = 4 * (h - 1), j = 0; 3 > j; j++) d[f + j] += (d[f + j] - (d[i + j] + d[h + j] + d[k + j]) / 3) * c; + return a; + } + }; + }); + }("psLib"), + function(a) { + ShearPhoto[a].module("toGray", function() { + return { + process: function(a) { + var b, c, d, e; + for (b = a.data, c = 0, d = b.length; d > c; c += 4) e = parseInt((b[c] + b[c + 1] + b[c + 2]) / 3), + b[c + 2] = b[c + 1] = b[c] = e; + return a.data = b, a; + } + }; + }); + }("psLib"), + function(a) { + ShearPhoto[a].module("toReverse", function() { + return { + process: function(a) { + for (var b = a.data, c = 0, d = b.length; d > c; c += 4) b[c] = 255 - b[c], b[c + 1] = 255 - b[c + 1], + b[c + 2] = 255 - b[c + 2]; + return a.data = b, a; + } + }; + }); + }("psLib"), + function(a) { + ShearPhoto[a].module("toThresh", function(a) { + return { + process: function(b, c) { + var d, e, f; + for (b = a.lib.toGray.process(b), d = b.data, c = c[0] || 128, e = 0, f = d.length; f > e; e++)(e + 1) % 4 && (d[e] = d[e] > c ? 255 : 0); + return b.data = d, b; + } + }; + }); + }("psLib"); +} catch (e) {} \ No newline at end of file diff --git a/web/static/plugs/avatar/js/handle.js b/web/static/plugs/avatar/js/handle.js new file mode 100644 index 00000000..b20d0b57 --- /dev/null +++ b/web/static/plugs/avatar/js/handle.js @@ -0,0 +1,222 @@ +/*----------------------------注释结束--程序开始-----------------------------------------------------------*/ +window.ShearPhoto.MINGGE(function() { + //██████████重要设置████████████████ + var relativeUrl = "/public/plugs/avatar"; //你不要在后面加斜杠,系统会自动给你加上斜杠,不信看下面! index.html的JS引用路径自己改,很简单的说 + + //█████████重要设置█████████████████ + relativeUrl = relativeUrl.replace(/(^\s*)|(\s*$)/g, ""); //去掉相对路径的所有空格 + relativeUrl === "" || (relativeUrl += "/"); //在相对地址后面加斜框,不需要用户自己加 + var publicRelat = document.getElementById("relat"); //"relat"对像 + var publicRelatImg = publicRelat.getElementsByTagName("img"); //"relat"下的两张图片对像 + var Shear = new ShearPhoto; + Shear.config({ + /*---------------用户设置部份开始-----------------------------------------------------------------------*/ + relativeUrl: relativeUrl, //取回相对路径,不懂原理的话,你不要改动哦,否则你又鸡巴痛了 + + traverse: true, //可选 true,false 。 是否在拖动或拉伸时允许历遍全图(是否让大图动呢), + + /*HTML5重点功能*/ + translate3d: false, //是否开启3D移动,CPU加速。可选true false。默认关闭的,作者认为PC端没必要!在PC端开启后,有部份浏览器页面走位的问题。主要是各大浏览器不统一所致,手机端效果会明显!PC端没什么感觉。 原来是采用left top进行定位的,那么3D移动就是CSS3的translate3d属性。去百度一下translate3D吧 + + /*HTML5重点功能*/ + HTML5: true, //可选 true,false 是否使用HTML5进行切图 ,支持HTML5浏览器会使用HTML5进行切图,没有HTML5浏览器则采用原始的方式(先上传大图再截取),SHEARPHOTO这个方案无可挑剔了吧! + + /*HTML5重点功能*/ + HTML5MAX: 500, //默认请设0 (最大尺寸做事), HTML上传截图最大宽度, 宽度越大,HTML5截出来的图片容量越大,服务器压力就大,截图就更清淅! 设得越小 HTML5截出来的图片容量越小.但是造成一定程序的不清淅,请适量设置 当然开启HTML5切图,该设置才有效 + + /*HTML5重点功能*/ + HTML5Quality: 0.9, //截好的截图 0至1范围可选(可填小数) HTML5切图的质量 为1时 最高 ,当然开启HTML5切图,该设置才有效,设得越高,越清淅,但文件体积越大,同上! + + /*HTML5重点功能*/ + HTML5FilesSize: 50, //如果是HTML5切图时,选择的图片不能超过多少,单位M,,你设大点都不怕, ------因为HTML5ZIP会对原图进行压缩处理 + + /*HTML5重点功能*/ + HTML5Effects: true, //是否开启图片特效功能给用户 可选true false, 提示:有HTML5浏览器才会开启的!当然开启HTML5切图,该设置才有效 + + /*HTML5重点功能*/ + HTML5ZIP: [900, 0.9], //HTML5截图前载入的大图 是否压缩图片(数组成员 是数字) ,如果不压缩的话填false,在处理特效时或者拉伸时会明显出卡顿,不流畅!官方强烈建意你进行设置 ,默认填写的是[900,0.9] ,代表宽和高都不能大于900,质量是0.9(最大是1) + + /*记住 preview (预览图片功能) 尽量设false*/ + + preview: [150], // 开启动态预览图片 (数组成员整数型,禁止含小数点 可选false 和数组) 数组内是宽度设置,没有高度设!因为高度会按比例做事 ,此设置代表预览150 大小的预览图(你可以增加多个预览图,如[100,70,50]),设置越多预览图,shearphoto性能越差!官方不建意你开启这个功能,尽可能请设为preview:false + + /*记住 preview 尽量设false*/ + + url: "/user/upload/avatar", //后端处理地址,保证正确哦,这是常识,连这个地址都能写错,你就是菜B,已经在本版本中帮你加入相对路径,你基本不用改这里了 + + scopeWidth: 500, //可拖动范围宽 也就是"main"对象的初始大小(整数型,禁止含小数点) 宽和高的值最好能一致 + + scopeHeight: 500, //可拖动范围高 也就是"main"对象的初始大小(整数型,禁止含小数点) 宽和高的值最好能一致 + + proportional: [1 / 1, + /* + 2.3版本加了一个新API ,动态修改比例!接口示例:Shear.SetProportional(3/4); 意思就是:动态修改比例为3/4; + */ + 100, //必须整数!启动后的截框初始宽度(整数型,禁止含小数点) + + 133 //比例设置后,这个高度无效,由宽和比例来决定(整数型,禁止含小数点) + ], + + Min: 50, //截框拉伸或拖拽不能少于多少PX(整数型,禁止含小数点) + + Max: 500, //一开始启动时,图片的宽和高,有时候图片会很大的,必须要设置一下(整数型,禁止含小数点),尽可能和scopeWidth值 一致 + + backgroundColor: "#000", //遮层色 + + backgroundOpacity: 0.6, //遮层透明度-数字0-1 可选 + + Border: 0, //截框的边框大小 0代表动态边框。大于0表示静态边框,大于0时也代表静态边框的粗细值 + + BorderStyle: "solid", //只作用于静态边框,截框的边框类型,其实是引入CSS的border属性,和CSS2的border属性是一样的 + + BorderColor: "#09F", //只作用于静态边框,截框的边框色彩 + /*---------------用户设置截图功能部份..还没结束----------------------页面下面还有一些细节设置,去看一下-------------------------------------------------*/ + relat: publicRelat, //请查看 id:"relat"对象 + scope: document.getElementById("main"), //main范围对象 + ImgDom: publicRelatImg[0], //截图图片对象(小) + ImgMain: publicRelatImg[1], //截图图片对象(大) + black: document.getElementById("black"), //黑色遮层对象 + form: document.getElementById("smallbox"), //截框对象 + ZoomDist: document.getElementById("ZoomDist"), //放大工具条,可从HTML查看此对象,不作详细解释了 + ZoomBar: document.getElementById("ZoomBar"), //放大工具条,可从HTML查看此对象 + to: { + BottomRight: document.getElementById("BottomRight"), //拉伸点中右 + TopRight: document.getElementById("TopRight"), //拉伸点上右,下面如此类推,一共8点进行拉伸,下面不再作解释 + Bottomleft: document.getElementById("Bottomleft"), + Topleft: document.getElementById("Topleft"), + Topmiddle: document.getElementById("Topmiddle"), + leftmiddle: document.getElementById("leftmiddle"), + Rightmiddle: document.getElementById("Rightmiddle"), + Bottommiddle: document.getElementById("Bottommiddle") + }, + Effects: document.getElementById("shearphoto_Effects") || false, + DynamicBorder: [document.getElementById("borderTop"), document.getElementById("borderLeft"), document.getElementById("borderRight"), document.getElementById("borderBottom")], + SelectBox: document.getElementById("SelectBox"), //选择图片方式的对象 + Shearbar: document.getElementById("Shearbar"), //截图工具条对象 + UpFun: function() { //鼠标健松开时执行函数 + Shear.MoveDiv.DivWHFun(); //把截框现时的宽高告诉JS + } + + }); + /*--------------------------------------------------------------截图成功后,返回来的callback-------------------------*/ + Shear.complete = function(serverdata) { //截图成功完成时,由shearphoto.php返回数据过来的成功包 + // alert(serverdata);//你可以调试一下这个返回包 + var point = this.arg.scope.childNodes[0]; + point.className === "point" && this.arg.scope.removeChild(point); + var complete = document.createElement("div"); + complete.className = "complete"; + complete.style.height = this.arg.scopeHeight + "px"; + this.arg.scope.insertBefore(complete, this.arg.scope.childNodes[0]); + var length = serverdata.length, + creatImg; + for (var i = 0; i < length; i++) { + creatImg = document.createElement("img"); + complete.appendChild(creatImg); + creatImg.src = serverdata[i]["ImgUrl"]; + } + this.HTML5.EffectsReturn(); + this.HTML5.BOLBID && this.HTML5.URL.revokeObjectURL(this.HTML5.BOLBID); + creatImg = document.createElement("DIV"); + creatImg.className = "completeTxt"; + creatImg.innerHTML = '恭喜你!截图成功

以上是你图片的' + length + '种尺寸

完成'; + complete.appendChild(creatImg); + var completeA = document.getElementById("completeA"); + var this_ = this; + this_.preview.close_(); + completeA.onclick || (completeA.onclick = function() { + completeA.onclick = null; + this_.arg.scope.removeChild(complete); + this_.again(); + this_.pointhandle(3e3, 10, "截图完成!已返回!", 2, "#fbeb61", "#3a414c"); + }); + } + /*--------------------------------------------------------------截图成功后,返回来的callback-------------------------*/ + + /*.................................................选择图片上传的设置...............................................................*/ + + var ShearPhotoForm = document.getElementById("ShearPhotoForm"); //FORM对象 + ShearPhotoForm.UpFile.onclick = function() { + return false + } //一开始时先不让用户点免得事件阻塞 + var up = new ShearPhoto.frameUpImg({ + + url: "/user/upload/avatar", //HTML5切图时,不会用到该文件,后端处理地址,保证正确哦,这是常识,连这个地址都能写错,你就是菜B,已经在本版本中帮你加入相对路径,你基本不用改这里了 + + FORM: ShearPhotoForm, //FORM对象传到设置 + + UpType: new Array("jpg", "jpeg", "png", "gif"), //图片类限制,上传的一定是图片,你就不要更改了 + + FilesSize: 2, //选择的图片不能超过 单位M(注意:是非HTML5时哦) + + HTML5: Shear.HTML5, //切匆改动这句,不然你他妈又问为什么出错 + + HTML5FilesSize: Shear.arg.HTML5FilesSize, //切匆改动这句 如果是HTML5切图时,选择的图片不能超过 单位M,设太大话,如果客户端HTML5加截超大图片时,会卡爆的 + + HTML5ZIP: Shear.arg.HTML5ZIP, //切匆改动这句, 把压缩设置转移到这里 + + erro: function(msg) { + Shear.pointhandle(3e3, 10, msg, 0, "#f82373", "#fff"); + }, + fileClick: function() { //先择图片被点击时,触发的事件 + Shear.pointhandle(-1); //关闭提示,防止线程阻塞事件冒泡 + }, + preced: function(fun) { //点击选择图,载入图片时的事件 + // try { + // photoalbum.style.display = "none"; //什么情况下都关了相册 + // camClose.onclick(); //什么情况下都关了视频 + // } catch (e) { + // console.log("在加载图片时,发现相册或拍照的对象检测不到,错误代码:" + e); + // } + Shear.pointhandle(0, 10, "正在为你加载图片,请你稍等哦......", 2, "#307ff6", "#fff", fun); + } + }); + + up.run(function(data, True) { //upload.php成功返回数据后 + //alert(data);你可以调试一下这个返回包 + True || (data = ShearPhoto.JsonString.StringToJson(data)); + if (data === false) { + Shear.SendUserMsg("错误:请保证后端环境运行正常", 5e3, 0, "#f4102b", "#fff", true, true); + return; + } + if (data["erro"]) { + Shear.SendUserMsg("错误:" + data["erro"], 5e3, 0, "#f4102b", "#fff", true, true); + return; + } + Shear.run(data["success"], true); + }); + /*.................................................选择图片上传的设置结束...............................................................*/ + + /*............................截图,左旋,右旋,重新选择..................开始.........看好怎么调用截图,左旋,右旋,重新选择..........................................*/ + Shear.addEvent(document.getElementById("saveShear"), "click", function() { //按下截图事件,提交到后端的shearphoto.php接收 + Shear.SendPHP({ + shearphoto: "我要传参数到服端", + mingge: "我要传第二个参数到服务器" + }); //我们示例截图并且传参数,后端文件shearphoto.php用 示例:$_POST["shearphoto"] 接收参数,不需要传参数请清空Shear.SendPHP里面的参数示例 Shear.SendPHP(); + + }); + + Shear.addEvent(document.getElementById("LeftRotate"), "click", function() { //向左旋转事件 + Shear.Rotate("left"); + }); + + Shear.addEvent(document.getElementById("RightRotate"), "click", function() { //向右旋转事件 + Shear.Rotate("right"); + }); + + Shear.addEvent(document.getElementById("againIMG"), "click", function() { //重新选择事件 + Shear.preview.close_(); + Shear.again(); + Shear.HTML5.EffectsReturn(); + Shear.HTML5.BOLBID && Shear.HTML5.URL.revokeObjectURL(Shear.HTML5.BOLBID); + Shear.pointhandle(3e3, 10, "已取消!重新选择", 2, "#fbeb61", "#3a414c"); + }); + + /*............................截图,左旋,右旋,重新选择.................................................结束....................*/ + + /*...........2.2加入的缓冲效果............................*/ + var shearphoto_loading = document.getElementById("shearphoto_loading"); + var shearphoto_main = document.getElementById("shearphoto_main"); + shearphoto_loading && shearphoto_loading.parentNode.removeChild(shearphoto_loading); + shearphoto_main.style.visibility = "visible"; + /*................2.2加入的缓冲效果结束..................*/ +}); \ No newline at end of file diff --git a/web/static/plugs/board/board.min.css b/web/static/plugs/board/board.min.css new file mode 100644 index 00000000..86bc088c --- /dev/null +++ b/web/static/plugs/board/board.min.css @@ -0,0 +1,6 @@ +/*! + * ZUI - v1.3.1 - 2015-05-19 + * http://zui.sexy + * GitHub: https://github.com/easysoft/zui.git + * Copyright (c) 2015 cnezsoft.com; Licensed MIT + */.board-item{padding:6px 10px;margin-bottom:5px;background:#fff;border:1px solid #ddd;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.05);box-shadow:0 1px 0 rgba(0,0,0,.05);-webkit-transition:all .5s cubic-bezier(.175,.885,.32,1);-o-transition:all .5s cubic-bezier(.175,.885,.32,1);transition:all .5s cubic-bezier(.175,.885,.32,1)}.board-item:hover{-webkit-box-shadow:0 1px 1 rgba(0,0,0,.1);box-shadow:0 1px 1 rgba(0,0,0,.1)}.board-item.board-item-empty{display:none;color:gray;border-style:dashed}.board-item.board-item-shadow{display:none;padding:0;background:#ddd;border:none;border-color:#ddd;-webkit-box-shadow:inset 0 0 4px rgba(0,0,0,.1);box-shadow:inset 0 0 4px rgba(0,0,0,.1);-webkit-transition:all .5s cubic-bezier(.175,.885,.32,1);-o-transition:all .5s cubic-bezier(.175,.885,.32,1);transition:all .5s cubic-bezier(.175,.885,.32,1)}.board-item.drag-shadow{width:250px;cursor:move;background-color:#fff;border-color:#c4c4c4;-webkit-box-shadow:1px 1px 15px rgba(0,0,0,.25);box-shadow:1px 1px 15px rgba(0,0,0,.25);opacity:.9}.board-item.drag-from{background-color:#ebf2f9}.board-list .board-item:last-child{margin-bottom:0}.board{float:left;width:250px;margin-right:10px}.board.drop-in-empty .board-item-empty{height:0;padding:0;margin:0;overflow:hidden;border:transparent}.board:last-child{margin-right:0}.board>.panel-body{padding:5px;background:#f1f1f1}.boards:before,.boards:after{display:table;content:" "}.boards:after{clear:both}.boards.dragging .board.drop-in{border-color:#c4c4c4;-webkit-box-shadow:1px 1px 15px rgba(0,0,0,.25);box-shadow:1px 1px 15px rgba(0,0,0,.25)}.boards.dragging .board.drop-in .board-item-shadow{display:block}.boards.dragging .board .board-item.board-item-empty{display:block}.boards.dragging .board-item.disable-drop{display:none}.boards.drop-in .board-item.drag-from{height:0;padding:0;margin:0;overflow:hidden;border:transparent} \ No newline at end of file diff --git a/web/static/plugs/board/board.min.js b/web/static/plugs/board/board.min.js new file mode 100644 index 00000000..b605f4ad --- /dev/null +++ b/web/static/plugs/board/board.min.js @@ -0,0 +1,8 @@ +/*! + * ZUI - v1.3.1 - 2015-05-19 + * http://zui.sexy + * GitHub: https://github.com/easysoft/zui.git + * Copyright (c) 2015 cnezsoft.com; Licensed MIT + */ + +!function(a){"use strict";if(!a.fn.droppable)throw new Error("droppable requires for boards");var b=function(b,c){this.$=a(b),this.options=this.getOptions(c),this.getLang(),this.init()};b.DEFAULTS={lang:"zh-cn",langs:{"zh-cn":{append2end:"移动到末尾"},"zh-tw":{append2end:"移动到末尾"},en:{append2end:"Move to the end."}}},b.prototype.getOptions=function(c){return c=a.extend({},b.DEFAULTS,this.$.data(),c)},b.prototype.getLang=function(){var c=window.config;if(!this.options.lang){if("undefined"!=typeof c&&c.clientLang)this.options.lang=c.clientLang;else{var d=a("html").attr("lang");this.options.lang=d?d:"en"}this.options.lang=this.options.lang.replace(/-/,"_").toLowerCase()}this.lang=this.options.langs[this.options.lang]||this.options.langs[b.DEFAULTS.lang]},b.prototype.init=function(){var b=1,c=this.lang;this.$.find('.board-item:not(".disable-drop"), .board:not(".disable-drop")').each(function(){var d=a(this);d.attr("id")?d.attr("data-id",d.attr("id")):d.attr("data-id")||d.attr("data-id","board"+b++),d.hasClass("board")&&d.find(".board-list").append('
{append2end}
'.format(c)).append('
'.format(c))}),this.bind()},b.prototype.bind=function(b){var c=this.$,d=this.options;"undefined"==typeof b&&(b=c.find('.board-item:not(".disable-drop, .board-item-shadow")')),b.droppable({target:'.board-item:not(".disable-drop, .board-item-shadow")',flex:!0,start:function(a){c.addClass("dragging").find(".board-item-shadow").height(a.element.outerHeight())},drag:function(a){if(c.find(".board.drop-in-empty").removeClass("drop-in-empty"),a.isIn){var b=a.target.closest(".board").addClass("drop-in"),d=b.find(".board-item-shadow"),e=a.target;c.addClass("drop-in").find(".board.drop-in").not(b).removeClass("drop-in"),d.insertBefore(e),b.toggleClass("drop-in-empty",e.hasClass("board-item-empty"))}},drop:function(b){if(b.isNew){var c,e="drop";d.hasOwnProperty(e)&&a.isFunction(d[e])&&(c=d[e](b)),c!==!1&&b.element.insertBefore(b.target)}},finish:function(){c.removeClass("dragging").removeClass("drop-in").find(".board.drop-in").removeClass("drop-in")}})},a.fn.boards=function(c){return this.each(function(){var d=a(this),e=d.data("zui.boards"),f="object"==typeof c&&c;e||d.data("zui.boards",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.boards.Constructor=b,a(function(){a('[data-toggle="boards"]').boards()})}(jQuery); \ No newline at end of file diff --git a/web/static/plugs/cropper/cropper.css b/web/static/plugs/cropper/cropper.css new file mode 100644 index 00000000..5802c3ee --- /dev/null +++ b/web/static/plugs/cropper/cropper.css @@ -0,0 +1,379 @@ +/*! + * Cropper.js v0.5.6 + * https://github.com/fengyuanchen/cropperjs + * + * Copyright (c) 2015-2016 Fengyuan Chen + * Released under the MIT license + * + * Date: 2016-01-18T05:33:19.322Z + */ +.cropper-container { + font-size: 0; + line-height: 0; + + position: relative; + + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + direction: ltr !important; + -ms-touch-action: none; + touch-action: none; + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; +} + +.cropper-container img { + display: block; + + width: 100%; + min-width: 0 !important; + max-width: none !important; + height: 100%; + min-height: 0 !important; + max-height: none !important; + + image-orientation: 0deg !important; +} + +.cropper-wrap-box, +.cropper-canvas, +.cropper-drag-box, +.cropper-crop-box, +.cropper-modal { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; +} + +.cropper-wrap-box { + overflow: hidden; +} + +.cropper-drag-box { + opacity: 0; + background-color: #fff; + + filter: alpha(opacity=0); +} + +.cropper-modal { + opacity: .5; + background-color: #000; + + filter: alpha(opacity=50); +} + +.cropper-view-box { + display: block; + overflow: hidden; + + width: 100%; + height: 100%; + + outline: 1px solid #39f; + outline-color: rgba(51, 153, 255, .75); +} + +.cropper-dashed { + position: absolute; + + display: block; + + opacity: .5; + border: 0 dashed #eee; + + filter: alpha(opacity=50); +} + +.cropper-dashed.dashed-h { + top: 33.33333%; + left: 0; + + width: 100%; + height: 33.33333%; + + border-top-width: 1px; + border-bottom-width: 1px; +} + +.cropper-dashed.dashed-v { + top: 0; + left: 33.33333%; + + width: 33.33333%; + height: 100%; + + border-right-width: 1px; + border-left-width: 1px; +} + +.cropper-center { + position: absolute; + top: 50%; + left: 50%; + + display: block; + + width: 0; + height: 0; + + opacity: .75; + + filter: alpha(opacity=75); +} + +.cropper-center:before, +.cropper-center:after { + position: absolute; + + display: block; + + content: ' '; + + background-color: #eee; +} + +.cropper-center:before { + top: 0; + left: -3px; + + width: 7px; + height: 1px; +} + +.cropper-center:after { + top: -3px; + left: 0; + + width: 1px; + height: 7px; +} + +.cropper-face, +.cropper-line, +.cropper-point { + position: absolute; + + display: block; + + width: 100%; + height: 100%; + + opacity: .1; + + filter: alpha(opacity=10); +} + +.cropper-face { + top: 0; + left: 0; + + background-color: #fff; +} + +.cropper-line { + background-color: #39f; +} + +.cropper-line.line-e { + top: 0; + right: -3px; + + width: 5px; + + cursor: e-resize; +} + +.cropper-line.line-n { + top: -3px; + left: 0; + + height: 5px; + + cursor: n-resize; +} + +.cropper-line.line-w { + top: 0; + left: -3px; + + width: 5px; + + cursor: w-resize; +} + +.cropper-line.line-s { + bottom: -3px; + left: 0; + + height: 5px; + + cursor: s-resize; +} + +.cropper-point { + width: 5px; + height: 5px; + + opacity: .75; + background-color: #39f; + + filter: alpha(opacity=75); +} + +.cropper-point.point-e { + top: 50%; + right: -3px; + + margin-top: -3px; + + cursor: e-resize; +} + +.cropper-point.point-n { + top: -3px; + left: 50%; + + margin-left: -3px; + + cursor: n-resize; +} + +.cropper-point.point-w { + top: 50%; + left: -3px; + + margin-top: -3px; + + cursor: w-resize; +} + +.cropper-point.point-s { + bottom: -3px; + left: 50%; + + margin-left: -3px; + + cursor: s-resize; +} + +.cropper-point.point-ne { + top: -3px; + right: -3px; + + cursor: ne-resize; +} + +.cropper-point.point-nw { + top: -3px; + left: -3px; + + cursor: nw-resize; +} + +.cropper-point.point-sw { + bottom: -3px; + left: -3px; + + cursor: sw-resize; +} + +.cropper-point.point-se { + right: -3px; + bottom: -3px; + + width: 20px; + height: 20px; + + cursor: se-resize; + + opacity: 1; + + filter: alpha(opacity=100); +} + +.cropper-point.point-se:before { + position: absolute; + right: -50%; + bottom: -50%; + + display: block; + + width: 200%; + height: 200%; + + content: ' '; + + opacity: 0; + background-color: #39f; + + filter: alpha(opacity=0); +} + +@media (min-width: 768px) { + .cropper-point.point-se { + width: 15px; + height: 15px; + } +} + +@media (min-width: 992px) { + .cropper-point.point-se { + width: 10px; + height: 10px; + } +} + +@media (min-width: 1200px) { + .cropper-point.point-se { + width: 5px; + height: 5px; + + opacity: .75; + + filter: alpha(opacity=75); + } +} + +.cropper-invisible { + opacity: 0; + + filter: alpha(opacity=0); +} + +.cropper-bg { + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC'); +} + +.cropper-hide { + position: absolute; + + display: block; + + width: 0; + height: 0; +} + +.cropper-hidden { + display: none !important; +} + +.cropper-move { + cursor: move; +} + +.cropper-crop { + cursor: crosshair; +} + +.cropper-disabled .cropper-drag-box, +.cropper-disabled .cropper-face, +.cropper-disabled .cropper-line, +.cropper-disabled .cropper-point { + cursor: not-allowed; +} diff --git a/web/static/plugs/cropper/cropper.custom.js b/web/static/plugs/cropper/cropper.custom.js new file mode 100644 index 00000000..131fe12b --- /dev/null +++ b/web/static/plugs/cropper/cropper.custom.js @@ -0,0 +1,149 @@ +window.onload = function() { + 'use strict'; + var Cropper = window.Cropper; + var console = window.console || { + log: function() {} + }; + var container = document.querySelector('.img-container'); + var image = container.getElementsByTagName('img').item(0); + var actions = document.getElementById('actions'); + var options = { + aspectRatio: 1 / 1, + preview: '.img-preview', + build: function() { + //console.log('build'); + }, + built: function() { + //console.log('built'); + }, + cropstart: function(data) { + //console.log('cropstart', data.action); + }, + cropmove: function(data) { + //console.log('cropmove', data.action); + }, + cropend: function(data) { + //console.log('cropend', data.action); + }, + crop: function(data) {}, + zoom: function(data) { + console.log('zoom', data.ratio); + } + }; + var cropper = new Cropper(image, options); + + function isUndefined(obj) { + return typeof obj === 'undefined'; + } + + function preventDefault(e) { + if (e) { + if (e.preventDefault) { + e.preventDefault(); + } else { + e.returnValue = false; + } + } + } + // Tooltip + $('[data-toggle="tooltip"]').tooltip(); + // Buttons + if (!document.createElement('canvas').getContext) { + $('button[data-method="getCroppedCanvas"]').prop('disabled', true); + } + if (typeof document.createElement('cropper').style.transition === 'undefined') { + $('button[data-method="rotate"]').prop('disabled', true); + $('button[data-method="scale"]').prop('disabled', true); + } + + // Methods + actions.querySelector('.docs-buttons').onclick = function(event) { + var e = event || window.event; + var target = e.target || e.srcElement; + var result; + var input; + var data; + if (!cropper) { + return; + } + while (target !== this) { + if (target.getAttribute('data-method')) { + break; + } + target = target.parentNode; + } + if (target === this || target.disabled || target.className.indexOf('disabled') > -1) { + return; + } + data = { + method: target.getAttribute('data-method'), + target: target.getAttribute('data-target'), + option: target.getAttribute('data-option'), + secondOption: target.getAttribute('data-second-option') + }; + if (data.method) { + if (typeof data.target !== 'undefined') { + input = document.querySelector(data.target); + if (!target.hasAttribute('data-option') && data.target && input) { + try { + data.option = JSON.parse(input.value); + } catch (e) { + console.log(e.message); + } + } + } + if (data.method === 'getCroppedCanvas') { + data.option = JSON.parse(data.option); + } + result = cropper[data.method](data.option, data.secondOption); + switch (data.method) { + case 'scaleX': + case 'scaleY': + target.setAttribute('data-option', -data.option); + break; + case 'getCroppedCanvas': + if (result) { + // Bootstrap's Modal + $('#getCroppedCanvasModal').modal().find('.modal-body').html(result); + if (!download.disabled) { + download.href = result.toDataURL(); + } + } + break; + case 'destroy': + cropper = null; + break; + } + if (typeof result === 'object' && result !== cropper && input) { + try { + input.value = JSON.stringify(result); + } catch (e) { + console.log(e.message); + } + } + } + }; + // Import image + var inputImage = document.getElementById('inputImage'); + var URL = window.URL || window.webkitURL; + var blobURL; + if (URL) { + inputImage.onchange = function() { + var files = this.files; + var file; + if (cropper && files && files.length) { + file = files[0]; + if (/^image\/\w+/.test(file.type)) { + blobURL = URL.createObjectURL(file); + cropper.reset().replace(blobURL); + inputImage.value = null; + } else { + window.alert('Please choose an image file.'); + } + } + }; + } else { + inputImage.disabled = true; + inputImage.parentNode.className += ' disabled'; + } +}; \ No newline at end of file diff --git a/web/static/plugs/cropper/cropper.js b/web/static/plugs/cropper/cropper.js new file mode 100644 index 00000000..09b5b661 --- /dev/null +++ b/web/static/plugs/cropper/cropper.js @@ -0,0 +1,3417 @@ +/*! + * Cropper.js v0.5.6 + * https://github.com/fengyuanchen/cropperjs + * + * Copyright (c) 2015-2016 Fengyuan Chen + * Released under the MIT license + * + * Date: 2016-01-18T05:33:43.542Z + */ + +(function (global, factory) { + if (typeof module === 'object' && typeof module.exports === 'object') { + module.exports = global.document ? factory(global, true) : function (window) { + if (!window.document) { + throw new Error('Cropper requires a window with a document'); + } + + return factory(window); + }; + } else { + factory(global); + } +})(typeof window !== 'undefined' ? window : this, function (window, noGlobal) { + + 'use strict'; + + // Globals + var document = window.document; + var location = window.location; + var ArrayBuffer = window.ArrayBuffer; + var Object = window.Object; + var Array = window.Array; + var String = window.String; + var Number = window.Number; + var Math = window.Math; + + // Constants + var NAMESPACE = 'cropper'; + + // Classes + var CLASS_MODAL = NAMESPACE + '-modal'; + var CLASS_HIDE = NAMESPACE + '-hide'; + var CLASS_HIDDEN = NAMESPACE + '-hidden'; + var CLASS_INVISIBLE = NAMESPACE + '-invisible'; + var CLASS_MOVE = NAMESPACE + '-move'; + var CLASS_CROP = NAMESPACE + '-crop'; + var CLASS_DISABLED = NAMESPACE + '-disabled'; + var CLASS_BG = NAMESPACE + '-bg'; + + // Events + var EVENT_MOUSE_DOWN = 'mousedown touchstart pointerdown MSPointerDown'; + var EVENT_MOUSE_MOVE = 'mousemove touchmove pointermove MSPointerMove'; + var EVENT_MOUSE_UP = 'mouseup touchend touchcancel pointerup pointercancel MSPointerUp MSPointerCancel'; + var EVENT_WHEEL = 'wheel mousewheel DOMMouseScroll'; + var EVENT_DBLCLICK = 'dblclick'; + var EVENT_RESIZE = 'resize'; + var EVENT_ERROR = 'error'; + var EVENT_LOAD = 'load'; + + // RegExps + var REGEXP_ACTIONS = /e|w|s|n|se|sw|ne|nw|all|crop|move|zoom/; + var REGEXP_SUFFIX = /width|height|left|top|marginLeft|marginTop/; + var REGEXP_ORIGINS = /^(https?:)\/\/([^\:\/\?#]+):?(\d*)/i; + var REGEXP_TRIM = /^\s+(.*)\s+$/; + var REGEXP_SPACES = /\s+/; + var REGEXP_DATA_URL = /^data\:/; + var REGEXP_DATA_URL_HEAD = /^data\:([^\;]+)\;base64,/; + var REGEXP_DATA_URL_JPEG = /^data\:image\/jpeg.*;base64,/; + + // Data + var DATA_PREVIEW = 'preview'; + var DATA_ACTION = 'action'; + + // Actions + var ACTION_EAST = 'e'; + var ACTION_WEST = 'w'; + var ACTION_SOUTH = 's'; + var ACTION_NORTH = 'n'; + var ACTION_SOUTH_EAST = 'se'; + var ACTION_SOUTH_WEST = 'sw'; + var ACTION_NORTH_EAST = 'ne'; + var ACTION_NORTH_WEST = 'nw'; + var ACTION_ALL = 'all'; + var ACTION_CROP = 'crop'; + var ACTION_MOVE = 'move'; + var ACTION_ZOOM = 'zoom'; + var ACTION_NONE = 'none'; + + // Supports + var SUPPORT_CANVAS = !!document.createElement('canvas').getContext; + + // Maths + var min = Math.min; + var max = Math.max; + var abs = Math.abs; + var sin = Math.sin; + var cos = Math.cos; + var sqrt = Math.sqrt; + var round = Math.round; + var floor = Math.floor; + var PI = Math.PI; + + // Utilities + var objectProto = Object.prototype; + var toString = objectProto.toString; + var hasOwnProperty = objectProto.hasOwnProperty; + var slice = Array.prototype.slice; + var fromCharCode = String.fromCharCode; + + function typeOf(obj) { + return toString.call(obj).slice(8, -1).toLowerCase(); + } + + function isNumber(num) { + return typeof num === 'number' && !isNaN(num); + } + + function isUndefined(obj) { + return typeof obj === 'undefined'; + } + + function isObject(obj) { + return typeof obj === 'object' && obj !== null; + } + + function isPlainObject(obj) { + var constructor; + var prototype; + + if (!isObject(obj)) { + return false; + } + + try { + constructor = obj.constructor; + prototype = constructor.prototype; + + return constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf'); + } catch (e) { + return false; + } + } + + function isFunction(fn) { + return typeOf(fn) === 'function'; + } + + function isArray(arr) { + return Array.isArray ? Array.isArray(arr) : typeOf(arr) === 'array'; + } + + function toArray(obj, offset) { + offset = offset >= 0 ? offset : 0; + + if (Array.from) { + return Array.from(obj).slice(offset); + } + + return slice.call(obj, offset); + } + + function trim(str) { + if (typeof str === 'string') { + str = str.trim ? str.trim() : str.replace(REGEXP_TRIM, '$1'); + } + + return str; + } + + function each(obj, callback) { + var length; + var i; + + if (obj && isFunction(callback)) { + if (isArray(obj) || isNumber(obj.length)/* array-like */) { + for (i = 0, length = obj.length; i < length; i++) { + if (callback.call(obj, obj[i], i, obj) === false) { + break; + } + } + } else if (isObject(obj)) { + for (i in obj) { + if (obj.hasOwnProperty(i)) { + if (callback.call(obj, obj[i], i, obj) === false) { + break; + } + } + } + } + } + + return obj; + } + + function extend(obj) { + var args; + + if (arguments.length > 1) { + args = toArray(arguments); + + if (Object.assign) { + return Object.assign.apply(Object, args); + } + + args.shift(); + + each(args, function (arg) { + each(arg, function (prop, i) { + obj[i] = prop; + }); + }); + } + + return obj; + } + + function proxy(fn, context) { + var args = toArray(arguments, 2); + + return function () { + return fn.apply(context, args.concat(toArray(arguments))); + }; + } + + function setStyle(element, styles) { + var style = element.style; + + each(styles, function (value, property) { + if (REGEXP_SUFFIX.test(property) && isNumber(value)) { + value += 'px'; + } + + style[property] = value; + }); + } + + function hasClass(element, value) { + return element.classList ? + element.classList.contains(value) : + element.className.indexOf(value) > -1; + } + + function addClass(element, value) { + var className; + + if (isNumber(element.length)) { + return each(element, function (elem) { + addClass(elem, value); + }); + } + + if (element.classList) { + return element.classList.add(value); + } + + className = trim(element.className); + + if (!className) { + element.className = value; + } else if (className.indexOf(value) < 0) { + element.className = className + ' ' + value; + } + } + + function removeClass(element, value) { + if (isNumber(element.length)) { + return each(element, function (elem) { + removeClass(elem, value); + }); + } + + if (element.classList) { + return element.classList.remove(value); + } + + if (element.className.indexOf(value) >= 0) { + element.className = element.className.replace(value, ''); + } + } + + function toggleClass(element, value, added) { + if (isNumber(element.length)) { + return each(element, function (elem) { + toggleClass(elem, value, added); + }); + } + + // IE10-11 doesn't support the second parameter of `classList.toggle` + if (added) { + addClass(element, value); + } else { + removeClass(element, value); + } + } + + function getData(element, name) { + return isObject(element[name]) ? + element[name] : + element.dataset ? + element.dataset[name] : + element.getAttribute('data-' + name); + } + + function setData(element, name, data) { + if (isObject(data) && isUndefined(element[name])) { + element[name] = data; + } else if (element.dataset) { + element.dataset[name] = data; + } else { + element.setAttribute('data-' + name, data); + } + } + + function removeData(element, name) { + if (isObject(element[name])) { + delete element[name]; + } else if (element.dataset) { + delete element.dataset[name]; + } else { + element.removeAttribute('data-' + name); + } + } + + function addListener(element, type, handler) { + var types = trim(type).split(REGEXP_SPACES); + + if (types.length > 1) { + return each(types, function (type) { + addListener(element, type, handler); + }); + } + + if (element.addEventListener) { + element.addEventListener(type, handler, false); + } else if (element.attachEvent) { + element.attachEvent('on' + type, handler); + } + } + + function removeListener(element, type, handler) { + var types = trim(type).split(REGEXP_SPACES); + + if (types.length > 1) { + return each(types, function (type) { + removeListener(element, type, handler); + }); + } + + if (element.removeEventListener) { + element.removeEventListener(type, handler, false); + } else if (element.detachEvent) { + element.detachEvent('on' + type, handler); + } + } + + function preventDefault(e) { + if (e.preventDefault) { + e.preventDefault(); + } else { + e.returnValue = false; + } + } + + function getEvent(event) { + var e = event || window.event; + var doc; + + // Fix target property (IE8) + if (!e.target) { + e.target = e.srcElement || document; + } + + if (!isNumber(e.pageX)) { + doc = document.documentElement; + e.pageX = e.clientX + (window.scrollX || doc && doc.scrollLeft || 0) - (doc && doc.clientLeft || 0); + e.pageY = e.clientY + (window.scrollY || doc && doc.scrollTop || 0) - (doc && doc.clientTop || 0); + } + + return e; + } + + function getOffset(element) { + var doc = document.documentElement; + var box = element.getBoundingClientRect(); + + return { + left: box.left + (window.scrollX || doc && doc.scrollLeft || 0) - (doc && doc.clientLeft || 0), + top: box.top + (window.scrollY || doc && doc.scrollTop || 0) - (doc && doc.clientTop || 0) + }; + } + + function getTouchesCenter(touches) { + var length = touches.length; + var pageX = 0; + var pageY = 0; + + if (length) { + each(touches, function (touch) { + pageX += touch.pageX; + pageY += touch.pageY; + }); + + pageX /= length; + pageY /= length; + } + + return { + pageX: pageX, + pageY: pageY + }; + } + + function getByTag(element, tagName) { + return element.getElementsByTagName(tagName); + } + + function getByClass(element, className) { + return element.getElementsByClassName ? + element.getElementsByClassName(className) : + element.querySelectorAll('.' + className); + } + + function createElement(tagName) { + return document.createElement(tagName); + } + + function appendChild(element, elem) { + element.appendChild(elem); + } + + function removeChild(element) { + if (element.parentNode) { + element.parentNode.removeChild(element); + } + } + + function empty(element) { + while (element.firstChild) { + element.removeChild(element.firstChild); + } + } + + function isCrossOriginURL(url) { + var parts = url.match(REGEXP_ORIGINS); + + return parts && ( + parts[1] !== location.protocol || + parts[2] !== location.hostname || + parts[3] !== location.port + ); + } + + function addTimestamp(url) { + var timestamp = 'timestamp=' + (new Date()).getTime(); + + return (url + (url.indexOf('?') === -1 ? '?' : '&') + timestamp); + } + + function getImageSize(image, callback) { + var newImage; + + // Modern browsers + if (image.naturalWidth) { + return callback(image.naturalWidth, image.naturalHeight); + } + + // IE8: Don't use `new Image()` here + newImage = createElement('img'); + + newImage.onload = function () { + callback(this.width, this.height); + }; + + newImage.src = image.src; + } + + function getTransform(data) { + var transforms = []; + var rotate = data.rotate; + var scaleX = data.scaleX; + var scaleY = data.scaleY; + + if (isNumber(rotate)) { + transforms.push('rotate(' + rotate + 'deg)'); + } + + if (isNumber(scaleX) && isNumber(scaleY)) { + transforms.push('scale(' + scaleX + ',' + scaleY + ')'); + } + + return transforms.length ? transforms.join(' ') : 'none'; + } + + function getRotatedSizes(data, reversed) { + var deg = abs(data.degree) % 180; + var arc = (deg > 90 ? (180 - deg) : deg) * PI / 180; + var sinArc = sin(arc); + var cosArc = cos(arc); + var width = data.width; + var height = data.height; + var aspectRatio = data.aspectRatio; + var newWidth; + var newHeight; + + if (!reversed) { + newWidth = width * cosArc + height * sinArc; + newHeight = width * sinArc + height * cosArc; + } else { + newWidth = width / (cosArc + sinArc / aspectRatio); + newHeight = newWidth / aspectRatio; + } + + return { + width: newWidth, + height: newHeight + }; + } + + function getSourceCanvas(image, data) { + var canvas = createElement('canvas'); + var context = canvas.getContext('2d'); + var x = 0; + var y = 0; + var width = data.naturalWidth; + var height = data.naturalHeight; + var rotate = data.rotate; + var scaleX = data.scaleX; + var scaleY = data.scaleY; + var scalable = isNumber(scaleX) && isNumber(scaleY) && (scaleX !== 1 || scaleY !== 1); + var rotatable = isNumber(rotate) && rotate !== 0; + var advanced = rotatable || scalable; + var canvasWidth = width; + var canvasHeight = height; + var translateX; + var translateY; + var rotated; + + if (scalable) { + translateX = width / 2; + translateY = height / 2; + } + + if (rotatable) { + rotated = getRotatedSizes({ + width: width, + height: height, + degree: rotate + }); + + canvasWidth = rotated.width; + canvasHeight = rotated.height; + translateX = rotated.width / 2; + translateY = rotated.height / 2; + } + + canvas.width = canvasWidth; + canvas.height = canvasHeight; + + if (advanced) { + x = -width / 2; + y = -height / 2; + + context.save(); + context.translate(translateX, translateY); + } + + if (rotatable) { + context.rotate(rotate * PI / 180); + } + + // Should call `scale` after rotated + if (scalable) { + context.scale(scaleX, scaleY); + } + + context.drawImage(image, floor(x), floor(y), floor(width), floor(height)); + + if (advanced) { + context.restore(); + } + + return canvas; + } + + function getStringFromCharCode(dataView, start, length) { + var str = ''; + var i = start; + + for (length += start; i < length; i++) { + str += fromCharCode(dataView.getUint8(i)); + } + + return str; + } + + function getOrientation(arrayBuffer) { + var dataView = new DataView(arrayBuffer); + var length = dataView.byteLength; + var orientation; + var exifIDCode; + var tiffOffset; + var firstIFDOffset; + var littleEndian; + var endianness; + var app1Start; + var ifdStart; + var offset; + var i; + + // Only handle JPEG image (start by 0xFFD8) + if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) { + offset = 2; + + while (offset < length) { + if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) { + app1Start = offset; + break; + } + + offset++; + } + } + + if (app1Start) { + exifIDCode = app1Start + 4; + tiffOffset = app1Start + 10; + + if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') { + endianness = dataView.getUint16(tiffOffset); + littleEndian = endianness === 0x4949; + + if (littleEndian || endianness === 0x4D4D /* bigEndian */) { + if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) { + firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian); + + if (firstIFDOffset >= 0x00000008) { + ifdStart = tiffOffset + firstIFDOffset; + } + } + } + } + } + + if (ifdStart) { + length = dataView.getUint16(ifdStart, littleEndian); + + for (i = 0; i < length; i++) { + offset = ifdStart + i * 12 + 2; + + if (dataView.getUint16(offset, littleEndian) === 0x0112 /* Orientation */) { + + // 8 is the offset of the current tag's value + offset += 8; + + // Get the original orientation value + orientation = dataView.getUint16(offset, littleEndian); + + // Override the orientation with the default value: 1 + dataView.setUint16(offset, 1, littleEndian); + break; + } + } + } + + return orientation; + } + + function dataURLToArrayBuffer(dataURL) { + var base64 = dataURL.replace(REGEXP_DATA_URL_HEAD, ''); + var binary = atob(base64); + var length = binary.length; + var arrayBuffer = new ArrayBuffer(length); + var dataView = new Uint8Array(arrayBuffer); + var i; + + for (i = 0; i < length; i++) { + dataView[i] = binary.charCodeAt(i); + } + + return arrayBuffer; + } + + // Only available for JPEG image + function arrayBufferToDataURL(arrayBuffer) { + var dataView = new Uint8Array(arrayBuffer); + var length = dataView.length; + var base64 = ''; + var i; + + for (i = 0; i < length; i++) { + base64 += fromCharCode(dataView[i]); + } + + return 'data:image/jpeg;base64,' + btoa(base64); + } + + function Cropper(element, options) { + var _this = this; + + _this.element = element; + _this.options = extend({}, Cropper.DEFAULTS, isPlainObject(options) && options); + _this.ready = false; + _this.built = false; + _this.complete = false; + _this.rotated = false; + _this.cropped = false; + _this.disabled = false; + _this.replaced = false; + _this.limited = false; + _this.wheeling = false; + _this.isImg = false; + _this.originalUrl = ''; + _this.canvasData = null; + _this.cropBoxData = null; + _this.previews = null; + _this.init(); + } + + Cropper.prototype = { + constructor: Cropper, + + init: function () { + var _this = this; + var element = _this.element; + var tagName = element.tagName.toLowerCase(); + var url; + + if (getData(element, NAMESPACE)) { + return; + } + + setData(element, NAMESPACE, _this); + + if (tagName === 'img') { + _this.isImg = true; + + // e.g.: "img/picture.jpg" + _this.originalUrl = url = element.getAttribute('src'); + + // Stop when it's a blank image + if (!url) { + return; + } + + // e.g.: "http://example.com/img/picture.jpg" + url = element.src; + } else if (tagName === 'canvas' && SUPPORT_CANVAS) { + url = element.toDataURL(); + } + + _this.load(url); + }, + + load: function (url) { + var _this = this; + var options = _this.options; + var xhr; + + if (!url) { + return; + } + + if (isFunction(options.build) && options.build.call(_this.element) === false) { + return; + } + + _this.url = url; + _this.imageData = {}; + + if (!options.checkOrientation || !ArrayBuffer) { + return _this.clone(); + } + + // XMLHttpRequest disallows to open a Data URL in some browsers like IE11 and Safari + if (REGEXP_DATA_URL.test(url)) { + return REGEXP_DATA_URL_JPEG.test(url) ? + _this.read(dataURLToArrayBuffer(url)) : + _this.clone(); + } + + xhr = new XMLHttpRequest(); + + xhr.onerror = xhr.onabort = function () { + _this.clone(); + }; + + xhr.onload = function () { + _this.read(this.response); + }; + + xhr.open('get', url); + xhr.responseType = 'arraybuffer'; + xhr.send(); + }, + + read: function (arrayBuffer) { + var _this = this; + var options = _this.options; + var orientation = getOrientation(arrayBuffer); + var imageData = _this.imageData; + var rotate; + var scaleX; + var scaleY; + + if (orientation > 1) { + _this.url = arrayBufferToDataURL(arrayBuffer); + + switch (orientation) { + + // flip horizontal + case 2: + scaleX = -1; + break; + + // rotate left 180° + case 3: + rotate = -180; + break; + + // flip vertical + case 4: + scaleY = -1; + break; + + // flip vertical + rotate right 90° + case 5: + rotate = 90; + scaleY = -1; + break; + + // rotate right 90° + case 6: + rotate = 90; + break; + + // flip horizontal + rotate right 90° + case 7: + rotate = 90; + scaleX = -1; + break; + + // rotate left 90° + case 8: + rotate = -90; + break; + } + } + + if (options.rotatable) { + imageData.rotate = rotate; + } + + if (options.scalable) { + imageData.scaleX = scaleX; + imageData.scaleY = scaleY; + } + + _this.clone(); + }, + + clone: function () { + var _this = this; + var element = _this.element; + var url = _this.url; + var crossOrigin; + var crossOriginUrl; + var image; + var start; + var stop; + + if (_this.options.checkCrossOrigin && isCrossOriginURL(url)) { + crossOrigin = element.crossOrigin; + + if (crossOrigin) { + crossOriginUrl = url; + } else { + crossOrigin = 'anonymous'; + + // Bust cache when there is not a "crossOrigin" property + crossOriginUrl = addTimestamp(url); + } + } + + _this.crossOrigin = crossOrigin; + _this.crossOriginUrl = crossOriginUrl; + image = createElement('img'); + + if (crossOrigin) { + image.crossOrigin = crossOrigin; + } + + image.src = crossOriginUrl || url; + _this.image = image; + _this._start = start = proxy(_this.start, _this); + _this._stop = stop = proxy(_this.stop, _this); + + if (_this.isImg) { + if (element.complete) { + _this.start(); + } else { + addListener(element, EVENT_LOAD, start); + } + } else { + addListener(image, EVENT_LOAD, start); + addListener(image, EVENT_ERROR, stop); + addClass(image, CLASS_HIDE); + element.parentNode.insertBefore(image, element.nextSibling); + } + }, + + start: function (event) { + var _this = this; + var image = _this.isImg ? _this.element : _this.image; + + if (event) { + removeListener(image, EVENT_LOAD, _this._start); + removeListener(image, EVENT_ERROR, _this._stop); + } + + getImageSize(image, function (naturalWidth, naturalHeight) { + extend(_this.imageData, { + naturalWidth: naturalWidth, + naturalHeight: naturalHeight, + aspectRatio: naturalWidth / naturalHeight + }); + + _this.ready = true; + _this.build(); + }); + }, + + stop: function () { + var _this = this; + var image = _this.image; + + removeListener(image, EVENT_LOAD, _this._start); + removeListener(image, EVENT_ERROR, _this._stop); + + removeChild(image); + _this.image = null; + }, + + build: function () { + var _this = this; + var options = _this.options; + var element = _this.element; + var image = _this.image; + var container; + var template; + var cropper; + var canvas; + var dragBox; + var cropBox; + var face; + + if (!_this.ready) { + return; + } + + // Unbuild first when replace + if (_this.built) { + _this.unbuild(); + } + + template = createElement('div'); + template.innerHTML = Cropper.TEMPLATE; + + // Create cropper elements + _this.container = container = element.parentNode; + _this.cropper = cropper = getByClass(template, 'cropper-container')[0]; + _this.canvas = canvas = getByClass(cropper, 'cropper-canvas')[0]; + _this.dragBox = dragBox = getByClass(cropper, 'cropper-drag-box')[0]; + _this.cropBox = cropBox = getByClass(cropper, 'cropper-crop-box')[0]; + _this.viewBox = getByClass(cropper, 'cropper-view-box')[0]; + _this.face = face = getByClass(cropBox, 'cropper-face')[0]; + + appendChild(canvas, image); + + // Hide the original image + addClass(element, CLASS_HIDDEN); + + // Inserts the cropper after to the current image + container.insertBefore(cropper, element.nextSibling); + + // Show the image if is hidden + if (!_this.isImg) { + removeClass(image, CLASS_HIDE); + } + + _this.initPreview(); + _this.bind(); + + options.aspectRatio = max(0, options.aspectRatio) || NaN; + options.viewMode = max(0, min(3, round(options.viewMode))) || 0; + + if (options.autoCrop) { + _this.cropped = true; + + if (options.modal) { + addClass(dragBox, CLASS_MODAL); + } + } else { + addClass(cropBox, CLASS_HIDDEN); + } + + if (!options.guides) { + addClass(getByClass(cropBox, 'cropper-dashed'), CLASS_HIDDEN); + } + + if (!options.center) { + addClass(getByClass(cropBox, 'cropper-center'), CLASS_HIDDEN); + } + + if (options.background) { + addClass(cropper, CLASS_BG); + } + + if (!options.highlight) { + addClass(face, CLASS_INVISIBLE); + } + + if (options.cropBoxMovable) { + addClass(face, CLASS_MOVE); + setData(face, DATA_ACTION, ACTION_ALL); + } + + if (!options.cropBoxResizable) { + addClass(getByClass(cropBox, 'cropper-line'), CLASS_HIDDEN); + addClass(getByClass(cropBox, 'cropper-point'), CLASS_HIDDEN); + } + + _this.setDragMode(options.dragMode); + _this.render(); + _this.built = true; + _this.setData(options.data); + + // Call the built asynchronously to keep "image.cropper" is defined + setTimeout(function () { + if (isFunction(options.built)) { + options.built.call(element); + } + + if (isFunction(options.crop)) { + options.crop.call(element, _this.getData()); + } + + _this.complete = true; + }, 0); + }, + + unbuild: function () { + var _this = this; + + if (!_this.built) { + return; + } + + _this.built = false; + _this.complete = false; + _this.initialImageData = null; + + // Clear `initialCanvasData` is necessary when replace + _this.initialCanvasData = null; + _this.initialCropBoxData = null; + _this.containerData = null; + _this.canvasData = null; + + // Clear `cropBoxData` is necessary when replace + _this.cropBoxData = null; + _this.unbind(); + + _this.resetPreview(); + _this.previews = null; + + _this.viewBox = null; + _this.cropBox = null; + _this.dragBox = null; + _this.canvas = null; + _this.container = null; + + removeChild(_this.cropper); + _this.cropper = null; + }, + + render: function () { + var _this = this; + + _this.initContainer(); + _this.initCanvas(); + _this.initCropBox(); + + _this.renderCanvas(); + + if (_this.cropped) { + _this.renderCropBox(); + } + }, + + initContainer: function () { + var _this = this; + var options = _this.options; + var element = _this.element; + var container = _this.container; + var cropper = _this.cropper; + var containerData; + + addClass(cropper, CLASS_HIDDEN); + removeClass(element, CLASS_HIDDEN); + + _this.containerData = containerData = { + width: max( + container.offsetWidth, + Number(options.minContainerWidth) || 200 + ), + height: max( + container.offsetHeight, + Number(options.minContainerHeight) || 100 + ) + }; + + setStyle(cropper, { + width: containerData.width, + height: containerData.height + }); + + addClass(element, CLASS_HIDDEN); + removeClass(cropper, CLASS_HIDDEN); + }, + + // Canvas (image wrapper) + initCanvas: function () { + var _this = this; + var viewMode = _this.options.viewMode; + var containerData = _this.containerData; + var imageData = _this.imageData; + var rotated = abs(imageData.rotate) === 90; + var naturalWidth = rotated ? imageData.naturalHeight : imageData.naturalWidth; + var naturalHeight = rotated ? imageData.naturalWidth : imageData.naturalHeight; + var aspectRatio = naturalWidth / naturalHeight; + var canvasWidth = containerData.width; + var canvasHeight = containerData.height; + var canvasData; + + if (containerData.height * aspectRatio > containerData.width) { + if (viewMode === 3) { + canvasWidth = containerData.height * aspectRatio; + } else { + canvasHeight = containerData.width / aspectRatio; + } + } else { + if (viewMode === 3) { + canvasHeight = containerData.width / aspectRatio; + } else { + canvasWidth = containerData.height * aspectRatio; + } + } + + canvasData = { + naturalWidth: naturalWidth, + naturalHeight: naturalHeight, + aspectRatio: aspectRatio, + width: canvasWidth, + height: canvasHeight + }; + + canvasData.oldLeft = canvasData.left = (containerData.width - canvasWidth) / 2; + canvasData.oldTop = canvasData.top = (containerData.height - canvasHeight) / 2; + + _this.canvasData = canvasData; + _this.limited = (viewMode === 1 || viewMode === 2); + _this.limitCanvas(true, true); + _this.initialImageData = extend({}, imageData); + _this.initialCanvasData = extend({}, canvasData); + }, + + limitCanvas: function (sizeLimited, positionLimited) { + var _this = this; + var options = _this.options; + var viewMode = options.viewMode; + var containerData = _this.containerData; + var canvasData = _this.canvasData; + var aspectRatio = canvasData.aspectRatio; + var cropBoxData = _this.cropBoxData; + var cropped = _this.cropped && cropBoxData; + var minCanvasWidth; + var minCanvasHeight; + var newCanvasLeft; + var newCanvasTop; + + if (sizeLimited) { + minCanvasWidth = Number(options.minCanvasWidth) || 0; + minCanvasHeight = Number(options.minCanvasHeight) || 0; + + if (viewMode > 1) { + minCanvasWidth = max(minCanvasWidth, containerData.width); + minCanvasHeight = max(minCanvasHeight, containerData.height); + + if (viewMode === 3) { + if (minCanvasHeight * aspectRatio > minCanvasWidth) { + minCanvasWidth = minCanvasHeight * aspectRatio; + } else { + minCanvasHeight = minCanvasWidth / aspectRatio; + } + } + } else if (viewMode > 0) { + if (minCanvasWidth) { + minCanvasWidth = max( + minCanvasWidth, + cropped ? cropBoxData.width : 0 + ); + } else if (minCanvasHeight) { + minCanvasHeight = max( + minCanvasHeight, + cropped ? cropBoxData.height : 0 + ); + } else if (cropped) { + minCanvasWidth = cropBoxData.width; + minCanvasHeight = cropBoxData.height; + + if (minCanvasHeight * aspectRatio > minCanvasWidth) { + minCanvasWidth = minCanvasHeight * aspectRatio; + } else { + minCanvasHeight = minCanvasWidth / aspectRatio; + } + } + } + + if (minCanvasWidth && minCanvasHeight) { + if (minCanvasHeight * aspectRatio > minCanvasWidth) { + minCanvasHeight = minCanvasWidth / aspectRatio; + } else { + minCanvasWidth = minCanvasHeight * aspectRatio; + } + } else if (minCanvasWidth) { + minCanvasHeight = minCanvasWidth / aspectRatio; + } else if (minCanvasHeight) { + minCanvasWidth = minCanvasHeight * aspectRatio; + } + + canvasData.minWidth = minCanvasWidth; + canvasData.minHeight = minCanvasHeight; + canvasData.maxWidth = Infinity; + canvasData.maxHeight = Infinity; + } + + if (positionLimited) { + if (viewMode) { + newCanvasLeft = containerData.width - canvasData.width; + newCanvasTop = containerData.height - canvasData.height; + + canvasData.minLeft = min(0, newCanvasLeft); + canvasData.minTop = min(0, newCanvasTop); + canvasData.maxLeft = max(0, newCanvasLeft); + canvasData.maxTop = max(0, newCanvasTop); + + if (cropped && _this.limited) { + canvasData.minLeft = min( + cropBoxData.left, + cropBoxData.left + cropBoxData.width - canvasData.width + ); + canvasData.minTop = min( + cropBoxData.top, + cropBoxData.top + cropBoxData.height - canvasData.height + ); + canvasData.maxLeft = cropBoxData.left; + canvasData.maxTop = cropBoxData.top; + + if (viewMode === 2) { + if (canvasData.width >= containerData.width) { + canvasData.minLeft = min(0, newCanvasLeft); + canvasData.maxLeft = max(0, newCanvasLeft); + } + + if (canvasData.height >= containerData.height) { + canvasData.minTop = min(0, newCanvasTop); + canvasData.maxTop = max(0, newCanvasTop); + } + } + } + } else { + canvasData.minLeft = -canvasData.width; + canvasData.minTop = -canvasData.height; + canvasData.maxLeft = containerData.width; + canvasData.maxTop = containerData.height; + } + } + }, + + renderCanvas: function (changed) { + var _this = this; + var canvasData = _this.canvasData; + var imageData = _this.imageData; + var rotate = imageData.rotate; + var aspectRatio; + var rotatedData; + + if (_this.rotated) { + _this.rotated = false; + + // Computes rotated sizes with image sizes + rotatedData = getRotatedSizes({ + width: imageData.width, + height: imageData.height, + degree: rotate + }); + + aspectRatio = rotatedData.width / rotatedData.height; + + if (aspectRatio !== canvasData.aspectRatio) { + canvasData.left -= (rotatedData.width - canvasData.width) / 2; + canvasData.top -= (rotatedData.height - canvasData.height) / 2; + canvasData.width = rotatedData.width; + canvasData.height = rotatedData.height; + canvasData.aspectRatio = aspectRatio; + canvasData.naturalWidth = imageData.naturalWidth; + canvasData.naturalHeight = imageData.naturalHeight; + + // Computes rotated sizes with natural image sizes + if (rotate % 180) { + rotatedData = getRotatedSizes({ + width: imageData.naturalWidth, + height: imageData.naturalHeight, + degree: rotate + }); + + canvasData.naturalWidth = rotatedData.width; + canvasData.naturalHeight = rotatedData.height; + } + + _this.limitCanvas(true, false); + } + } + + if (canvasData.width > canvasData.maxWidth || + canvasData.width < canvasData.minWidth) { + canvasData.left = canvasData.oldLeft; + } + + if (canvasData.height > canvasData.maxHeight || + canvasData.height < canvasData.minHeight) { + canvasData.top = canvasData.oldTop; + } + + canvasData.width = min( + max(canvasData.width, canvasData.minWidth), + canvasData.maxWidth + ); + canvasData.height = min( + max(canvasData.height, canvasData.minHeight), + canvasData.maxHeight + ); + + _this.limitCanvas(false, true); + + canvasData.oldLeft = canvasData.left = min( + max(canvasData.left, canvasData.minLeft), + canvasData.maxLeft + ); + canvasData.oldTop = canvasData.top = min( + max(canvasData.top, canvasData.minTop), + canvasData.maxTop + ); + + setStyle(_this.canvas, { + width: canvasData.width, + height: canvasData.height, + left: canvasData.left, + top: canvasData.top + }); + + _this.renderImage(); + + if (_this.cropped && _this.limited) { + _this.limitCropBox(true, true); + } + + if (changed) { + _this.output(); + } + }, + + renderImage: function (changed) { + var _this = this; + var canvasData = _this.canvasData; + var imageData = _this.imageData; + var newImageData; + var reversedData; + var reversedWidth; + var reversedHeight; + var transform; + + if (imageData.rotate) { + reversedData = getRotatedSizes({ + width: canvasData.width, + height: canvasData.height, + degree: imageData.rotate, + aspectRatio: imageData.aspectRatio + }, true); + + reversedWidth = reversedData.width; + reversedHeight = reversedData.height; + + newImageData = { + width: reversedWidth, + height: reversedHeight, + left: (canvasData.width - reversedWidth) / 2, + top: (canvasData.height - reversedHeight) / 2 + }; + } + + extend(imageData, newImageData || { + width: canvasData.width, + height: canvasData.height, + left: 0, + top: 0 + }); + + transform = getTransform(imageData); + + setStyle(_this.image, { + width: imageData.width, + height: imageData.height, + marginLeft: imageData.left, + marginTop: imageData.top, + WebkitTransform: transform, + msTransform: transform, + transform: transform + }); + + if (changed) { + _this.output(); + } + }, + + initCropBox: function () { + var _this = this; + var options = _this.options; + var aspectRatio = options.aspectRatio; + var autoCropArea = Number(options.autoCropArea) || 0.8; + var canvasData = _this.canvasData; + var cropBoxData = { + width: canvasData.width, + height: canvasData.height + }; + + if (aspectRatio) { + if (canvasData.height * aspectRatio > canvasData.width) { + cropBoxData.height = cropBoxData.width / aspectRatio; + } else { + cropBoxData.width = cropBoxData.height * aspectRatio; + } + } + + _this.cropBoxData = cropBoxData; + _this.limitCropBox(true, true); + + // Initialize auto crop area + cropBoxData.width = min( + max(cropBoxData.width, cropBoxData.minWidth), + cropBoxData.maxWidth + ); + cropBoxData.height = min( + max(cropBoxData.height, cropBoxData.minHeight), + cropBoxData.maxHeight + ); + + // The width/height of auto crop area must large than "minWidth/Height" + cropBoxData.width = max( + cropBoxData.minWidth, + cropBoxData.width * autoCropArea + ); + cropBoxData.height = max( + cropBoxData.minHeight, + cropBoxData.height * autoCropArea + ); + cropBoxData.oldLeft = cropBoxData.left = ( + canvasData.left + (canvasData.width - cropBoxData.width) / 2 + ); + cropBoxData.oldTop = cropBoxData.top = ( + canvasData.top + (canvasData.height - cropBoxData.height) / 2 + ); + + _this.initialCropBoxData = extend({}, cropBoxData); + }, + + limitCropBox: function (sizeLimited, positionLimited) { + var _this = this; + var options = _this.options; + var aspectRatio = options.aspectRatio; + var containerData = _this.containerData; + var canvasData = _this.canvasData; + var cropBoxData = _this.cropBoxData; + var limited = _this.limited; + var minCropBoxWidth; + var minCropBoxHeight; + var maxCropBoxWidth; + var maxCropBoxHeight; + + if (sizeLimited) { + minCropBoxWidth = Number(options.minCropBoxWidth) || 0; + minCropBoxHeight = Number(options.minCropBoxHeight) || 0; + + // The min/maxCropBoxWidth/Height must be less than containerWidth/Height + minCropBoxWidth = min(minCropBoxWidth, containerData.width); + minCropBoxHeight = min(minCropBoxHeight, containerData.height); + maxCropBoxWidth = min( + containerData.width, + limited ? canvasData.width : containerData.width + ); + maxCropBoxHeight = min( + containerData.height, + limited ? canvasData.height : containerData.height + ); + + if (aspectRatio) { + if (minCropBoxWidth && minCropBoxHeight) { + if (minCropBoxHeight * aspectRatio > minCropBoxWidth) { + minCropBoxHeight = minCropBoxWidth / aspectRatio; + } else { + minCropBoxWidth = minCropBoxHeight * aspectRatio; + } + } else if (minCropBoxWidth) { + minCropBoxHeight = minCropBoxWidth / aspectRatio; + } else if (minCropBoxHeight) { + minCropBoxWidth = minCropBoxHeight * aspectRatio; + } + + if (maxCropBoxHeight * aspectRatio > maxCropBoxWidth) { + maxCropBoxHeight = maxCropBoxWidth / aspectRatio; + } else { + maxCropBoxWidth = maxCropBoxHeight * aspectRatio; + } + } + + // The minWidth/Height must be less than maxWidth/Height + cropBoxData.minWidth = min(minCropBoxWidth, maxCropBoxWidth); + cropBoxData.minHeight = min(minCropBoxHeight, maxCropBoxHeight); + cropBoxData.maxWidth = maxCropBoxWidth; + cropBoxData.maxHeight = maxCropBoxHeight; + } + + if (positionLimited) { + if (limited) { + cropBoxData.minLeft = max(0, canvasData.left); + cropBoxData.minTop = max(0, canvasData.top); + cropBoxData.maxLeft = min( + containerData.width, + canvasData.left + canvasData.width + ) - cropBoxData.width; + cropBoxData.maxTop = min( + containerData.height, + canvasData.top + canvasData.height + ) - cropBoxData.height; + } else { + cropBoxData.minLeft = 0; + cropBoxData.minTop = 0; + cropBoxData.maxLeft = containerData.width - cropBoxData.width; + cropBoxData.maxTop = containerData.height - cropBoxData.height; + } + } + }, + + renderCropBox: function () { + var _this = this; + var options = _this.options; + var containerData = _this.containerData; + var cropBoxData = _this.cropBoxData; + + if (cropBoxData.width > cropBoxData.maxWidth || + cropBoxData.width < cropBoxData.minWidth) { + cropBoxData.left = cropBoxData.oldLeft; + } + + if (cropBoxData.height > cropBoxData.maxHeight || + cropBoxData.height < cropBoxData.minHeight) { + cropBoxData.top = cropBoxData.oldTop; + } + + cropBoxData.width = min( + max(cropBoxData.width, cropBoxData.minWidth), + cropBoxData.maxWidth + ); + cropBoxData.height = min( + max(cropBoxData.height, cropBoxData.minHeight), + cropBoxData.maxHeight + ); + + _this.limitCropBox(false, true); + + cropBoxData.oldLeft = cropBoxData.left = min( + max(cropBoxData.left, cropBoxData.minLeft), + cropBoxData.maxLeft + ); + cropBoxData.oldTop = cropBoxData.top = min( + max(cropBoxData.top, cropBoxData.minTop), + cropBoxData.maxTop + ); + + if (options.movable && options.cropBoxMovable) { + + // Turn to move the canvas when the crop box is equal to the container + setData(_this.face, DATA_ACTION, cropBoxData.width === containerData.width && + cropBoxData.height === containerData.height ? ACTION_MOVE : ACTION_ALL); + } + + setStyle(_this.cropBox, { + width: cropBoxData.width, + height: cropBoxData.height, + left: cropBoxData.left, + top: cropBoxData.top + }); + + if (_this.cropped && _this.limited) { + _this.limitCanvas(true, true); + } + + if (!_this.disabled) { + _this.output(); + } + }, + + output: function () { + var _this = this; + var options = _this.options; + + _this.preview(); + + if (_this.complete && isFunction(options.crop)) { + options.crop.call(_this.element, _this.getData()); + } + }, + + initPreview: function () { + var _this = this; + var preview = _this.options.preview; + var image = createElement('img'); + var crossOrigin = _this.crossOrigin; + var url = crossOrigin ? _this.crossOriginUrl : _this.url; + var previews; + + if (crossOrigin) { + image.crossOrigin = crossOrigin; + } + + image.src = url; + appendChild(_this.viewBox, image); + + if (!preview) { + return; + } + + _this.previews = previews = document.querySelectorAll(preview); + + each(previews, function (element) { + var image = createElement('img'); + + // Save the original size for recover + setData(element, DATA_PREVIEW, { + width: element.offsetWidth, + height: element.offsetHeight, + html: element.innerHTML + }); + + if (crossOrigin) { + image.crossOrigin = crossOrigin; + } + + image.src = url; + + /** + * Override img element styles + * Add `display:block` to avoid margin top issue + * Add `height:auto` to override `height` attribute on IE8 + * (Occur only when margin-top <= -height) + */ + + image.style.cssText = ( + 'display:block;' + + 'width:100%;' + + 'height:auto;' + + 'min-width:0!important;' + + 'min-height:0!important;' + + 'max-width:none!important;' + + 'max-height:none!important;' + + 'image-orientation:0deg!important;"' + ); + + empty(element); + appendChild(element, image); + }); + }, + + resetPreview: function () { + each(this.previews, function (element) { + var data = getData(element, DATA_PREVIEW); + + setStyle(element, { + width: data.width, + height: data.height + }); + + element.innerHTML = data.html; + removeData(element, DATA_PREVIEW); + }); + }, + + preview: function () { + var _this = this; + var imageData = _this.imageData; + var canvasData = _this.canvasData; + var cropBoxData = _this.cropBoxData; + var cropBoxWidth = cropBoxData.width; + var cropBoxHeight = cropBoxData.height; + var width = imageData.width; + var height = imageData.height; + var left = cropBoxData.left - canvasData.left - imageData.left; + var top = cropBoxData.top - canvasData.top - imageData.top; + var transform = getTransform(imageData); + var transforms = { + WebkitTransform: transform, + msTransform: transform, + transform: transform + }; + + if (!_this.cropped || _this.disabled) { + return; + } + + setStyle(getByTag(_this.viewBox, 'img')[0], extend({ + width: width, + height: height, + marginLeft: -left, + marginTop: -top + }, transforms)); + + each(_this.previews, function (element) { + var data = getData(element, DATA_PREVIEW); + var originalWidth = data.width; + var originalHeight = data.height; + var newWidth = originalWidth; + var newHeight = originalHeight; + var ratio = 1; + + if (cropBoxWidth) { + ratio = originalWidth / cropBoxWidth; + newHeight = cropBoxHeight * ratio; + } + + if (cropBoxHeight && newHeight > originalHeight) { + ratio = originalHeight / cropBoxHeight; + newWidth = cropBoxWidth * ratio; + newHeight = originalHeight; + } + + setStyle(element, { + width: newWidth, + height: newHeight + }); + + setStyle(getByTag(element, 'img')[0], extend({ + width: width * ratio, + height: height * ratio, + marginLeft: -left * ratio, + marginTop: -top * ratio + }, transforms)); + }); + }, + + bind: function () { + var _this = this; + var options = _this.options; + var cropper = _this.cropper; + + addListener(cropper, EVENT_MOUSE_DOWN, (_this._cropStart = proxy(_this.cropStart, _this))); + + if (options.zoomable && options.zoomOnWheel) { + addListener(cropper, EVENT_WHEEL, (_this._wheel = proxy(_this.wheel, _this))); + } + + if (options.toggleDragModeOnDblclick) { + addListener(cropper, EVENT_DBLCLICK, (_this._dblclick = proxy(_this.dblclick, _this))); + } + + addListener(document, EVENT_MOUSE_MOVE, (_this._cropMove = proxy(_this.cropMove, _this))); + addListener(document, EVENT_MOUSE_UP, (_this._cropEnd = proxy(_this.cropEnd, _this))); + + if (options.responsive) { + addListener(window, EVENT_RESIZE, (_this._resize = proxy(_this.resize, _this))); + } + }, + + unbind: function () { + var _this = this; + var options = _this.options; + var cropper = _this.cropper; + + removeListener(cropper, EVENT_MOUSE_DOWN, _this._cropStart); + + if (options.zoomable && options.zoomOnWheel) { + removeListener(cropper, EVENT_WHEEL, _this._wheel); + } + + if (options.toggleDragModeOnDblclick) { + removeListener(cropper, EVENT_DBLCLICK, _this._dblclick); + } + + removeListener(document, EVENT_MOUSE_MOVE, _this._cropMove); + removeListener(document, EVENT_MOUSE_UP, _this._cropEnd); + + if (options.responsive) { + removeListener(window, EVENT_RESIZE, _this._resize); + } + }, + + resize: function () { + var _this = this; + var restore = _this.options.restore; + var container = _this.container; + var containerData = _this.containerData; + var canvasData; + var cropBoxData; + var ratio; + + // Check `container` is necessary for IE8 + if (_this.disabled || !containerData) { + return; + } + + ratio = container.offsetWidth / containerData.width; + + // Resize when width changed or height changed + if (ratio !== 1 || container.offsetHeight !== containerData.height) { + if (restore) { + canvasData = _this.getCanvasData(); + cropBoxData = _this.getCropBoxData(); + } + + _this.render(); + + if (restore) { + _this.setCanvasData(each(canvasData, function (n, i) { + canvasData[i] = n * ratio; + })); + _this.setCropBoxData(each(cropBoxData, function (n, i) { + cropBoxData[i] = n * ratio; + })); + } + } + }, + + dblclick: function () { + var _this = this; + + if (_this.disabled) { + return; + } + + _this.setDragMode(hasClass(_this.dragBox, CLASS_CROP) ? ACTION_MOVE : ACTION_CROP); + }, + + wheel: function (event) { + var _this = this; + var e = getEvent(event); + var ratio = Number(_this.options.wheelZoomRatio) || 0.1; + var delta = 1; + + if (_this.disabled) { + return; + } + + preventDefault(e); + + // Limit wheel speed to prevent zoom too fast (#21) + if (_this.wheeling) { + return; + } + + _this.wheeling = true; + + setTimeout(function () { + _this.wheeling = false; + }, 50); + + if (e.deltaY) { + delta = e.deltaY > 0 ? 1 : -1; + } else if (e.wheelDelta) { + delta = -e.wheelDelta / 120; + } else if (e.detail) { + delta = e.detail > 0 ? 1 : -1; + } + + _this.zoom(-delta * ratio, e); + }, + + cropStart: function (event) { + var _this = this; + var options = _this.options; + var e = getEvent(event); + var touches = e.touches; + var touchesLength; + var touch; + var action; + + if (_this.disabled) { + return; + } + + if (touches) { + touchesLength = touches.length; + + if (touchesLength > 1) { + if (options.zoomable && options.zoomOnTouch && touchesLength === 2) { + touch = touches[1]; + _this.startX2 = touch.pageX; + _this.startY2 = touch.pageY; + action = ACTION_ZOOM; + } else { + return; + } + } + + touch = touches[0]; + } + + action = action || getData(e.target, DATA_ACTION); + + if (REGEXP_ACTIONS.test(action)) { + if (isFunction(options.cropstart) && options.cropstart.call(_this.element, { + originalEvent: e, + action: action + }) === false) { + return; + } + + preventDefault(e); + + _this.action = action; + _this.cropping = false; + + _this.startX = touch ? touch.pageX : e.pageX; + _this.startY = touch ? touch.pageY : e.pageY; + + if (action === ACTION_CROP) { + _this.cropping = true; + addClass(_this.dragBox, CLASS_MODAL); + } + } + }, + + cropMove: function (event) { + var _this = this; + var options = _this.options; + var e = getEvent(event); + var touches = e.touches; + var action = _this.action; + var touchesLength; + var touch; + + if (_this.disabled) { + return; + } + + if (touches) { + touchesLength = touches.length; + + if (touchesLength > 1) { + if (options.zoomable && options.zoomOnTouch && touchesLength === 2) { + touch = touches[1]; + _this.endX2 = touch.pageX; + _this.endY2 = touch.pageY; + } else { + return; + } + } + + touch = touches[0]; + } + + if (action) { + if (isFunction(options.cropmove) && options.cropmove.call(_this.element, { + originalEvent: e, + action: action + }) === false) { + return; + } + + preventDefault(e); + + _this.endX = touch ? touch.pageX : e.pageX; + _this.endY = touch ? touch.pageY : e.pageY; + + _this.change(e.shiftKey, action === ACTION_ZOOM ? e : null); + } + }, + + cropEnd: function (event) { + var _this = this; + var options = _this.options; + var e = getEvent(event); + var action = _this.action; + + if (_this.disabled) { + return; + } + + if (action) { + preventDefault(e); + + if (_this.cropping) { + _this.cropping = false; + toggleClass(_this.dragBox, CLASS_MODAL, _this.cropped && options.modal); + } + + _this.action = ''; + + if (isFunction(options.cropend)) { + options.cropend.call(_this.element, { + originalEvent: e, + action: action + }); + } + } + }, + + change: function (shiftKey, originalEvent) { + var _this = this; + var options = _this.options; + var aspectRatio = options.aspectRatio; + var action = _this.action; + var containerData = _this.containerData; + var canvasData = _this.canvasData; + var cropBoxData = _this.cropBoxData; + var width = cropBoxData.width; + var height = cropBoxData.height; + var left = cropBoxData.left; + var top = cropBoxData.top; + var right = left + width; + var bottom = top + height; + var minLeft = 0; + var minTop = 0; + var maxWidth = containerData.width; + var maxHeight = containerData.height; + var renderable = true; + var offset; + var range; + + // Locking aspect ratio in "free mode" by holding shift key + if (!aspectRatio && shiftKey) { + aspectRatio = width && height ? width / height : 1; + } + + if (_this.limited) { + minLeft = cropBoxData.minLeft; + minTop = cropBoxData.minTop; + maxWidth = minLeft + min(containerData.width, canvasData.width); + maxHeight = minTop + min(containerData.height, canvasData.height); + } + + range = { + x: _this.endX - _this.startX, + y: _this.endY - _this.startY + }; + + if (aspectRatio) { + range.X = range.y * aspectRatio; + range.Y = range.x / aspectRatio; + } + + switch (action) { + // Move crop box + case ACTION_ALL: + left += range.x; + top += range.y; + break; + + // Resize crop box + case ACTION_EAST: + if (range.x >= 0 && (right >= maxWidth || aspectRatio && + (top <= minTop || bottom >= maxHeight))) { + + renderable = false; + break; + } + + width += range.x; + + if (aspectRatio) { + height = width / aspectRatio; + top -= range.Y / 2; + } + + if (width < 0) { + action = ACTION_WEST; + width = 0; + } + + break; + + case ACTION_NORTH: + if (range.y <= 0 && (top <= minTop || aspectRatio && + (left <= minLeft || right >= maxWidth))) { + + renderable = false; + break; + } + + height -= range.y; + top += range.y; + + if (aspectRatio) { + width = height * aspectRatio; + left += range.X / 2; + } + + if (height < 0) { + action = ACTION_SOUTH; + height = 0; + } + + break; + + case ACTION_WEST: + if (range.x <= 0 && (left <= minLeft || aspectRatio && + (top <= minTop || bottom >= maxHeight))) { + + renderable = false; + break; + } + + width -= range.x; + left += range.x; + + if (aspectRatio) { + height = width / aspectRatio; + top += range.Y / 2; + } + + if (width < 0) { + action = ACTION_EAST; + width = 0; + } + + break; + + case ACTION_SOUTH: + if (range.y >= 0 && (bottom >= maxHeight || aspectRatio && + (left <= minLeft || right >= maxWidth))) { + + renderable = false; + break; + } + + height += range.y; + + if (aspectRatio) { + width = height * aspectRatio; + left -= range.X / 2; + } + + if (height < 0) { + action = ACTION_NORTH; + height = 0; + } + + break; + + case ACTION_NORTH_EAST: + if (aspectRatio) { + if (range.y <= 0 && (top <= minTop || right >= maxWidth)) { + renderable = false; + break; + } + + height -= range.y; + top += range.y; + width = height * aspectRatio; + } else { + if (range.x >= 0) { + if (right < maxWidth) { + width += range.x; + } else if (range.y <= 0 && top <= minTop) { + renderable = false; + } + } else { + width += range.x; + } + + if (range.y <= 0) { + if (top > minTop) { + height -= range.y; + top += range.y; + } + } else { + height -= range.y; + top += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_SOUTH_WEST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_NORTH_WEST; + width = 0; + } else if (height < 0) { + action = ACTION_SOUTH_EAST; + height = 0; + } + + break; + + case ACTION_NORTH_WEST: + if (aspectRatio) { + if (range.y <= 0 && (top <= minTop || left <= minLeft)) { + renderable = false; + break; + } + + height -= range.y; + top += range.y; + width = height * aspectRatio; + left += range.X; + } else { + if (range.x <= 0) { + if (left > minLeft) { + width -= range.x; + left += range.x; + } else if (range.y <= 0 && top <= minTop) { + renderable = false; + } + } else { + width -= range.x; + left += range.x; + } + + if (range.y <= 0) { + if (top > minTop) { + height -= range.y; + top += range.y; + } + } else { + height -= range.y; + top += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_SOUTH_EAST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_NORTH_EAST; + width = 0; + } else if (height < 0) { + action = ACTION_SOUTH_WEST; + height = 0; + } + + break; + + case ACTION_SOUTH_WEST: + if (aspectRatio) { + if (range.x <= 0 && (left <= minLeft || bottom >= maxHeight)) { + renderable = false; + break; + } + + width -= range.x; + left += range.x; + height = width / aspectRatio; + } else { + if (range.x <= 0) { + if (left > minLeft) { + width -= range.x; + left += range.x; + } else if (range.y >= 0 && bottom >= maxHeight) { + renderable = false; + } + } else { + width -= range.x; + left += range.x; + } + + if (range.y >= 0) { + if (bottom < maxHeight) { + height += range.y; + } + } else { + height += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_NORTH_EAST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_SOUTH_EAST; + width = 0; + } else if (height < 0) { + action = ACTION_NORTH_WEST; + height = 0; + } + + break; + + case ACTION_SOUTH_EAST: + if (aspectRatio) { + if (range.x >= 0 && (right >= maxWidth || bottom >= maxHeight)) { + renderable = false; + break; + } + + width += range.x; + height = width / aspectRatio; + } else { + if (range.x >= 0) { + if (right < maxWidth) { + width += range.x; + } else if (range.y >= 0 && bottom >= maxHeight) { + renderable = false; + } + } else { + width += range.x; + } + + if (range.y >= 0) { + if (bottom < maxHeight) { + height += range.y; + } + } else { + height += range.y; + } + } + + if (width < 0 && height < 0) { + action = ACTION_NORTH_WEST; + height = 0; + width = 0; + } else if (width < 0) { + action = ACTION_SOUTH_WEST; + width = 0; + } else if (height < 0) { + action = ACTION_NORTH_EAST; + height = 0; + } + + break; + + // Move canvas + case ACTION_MOVE: + _this.move(range.x, range.y); + renderable = false; + break; + + // Zoom canvas + case ACTION_ZOOM: + _this.zoom((function (x1, y1, x2, y2) { + var z1 = sqrt(x1 * x1 + y1 * y1); + var z2 = sqrt(x2 * x2 + y2 * y2); + + return (z2 - z1) / z1; + })( + abs(_this.startX - _this.startX2), + abs(_this.startY - _this.startY2), + abs(_this.endX - _this.endX2), + abs(_this.endY - _this.endY2) + ), originalEvent); + _this.startX2 = _this.endX2; + _this.startY2 = _this.endY2; + renderable = false; + break; + + // Create crop box + case ACTION_CROP: + if (!range.x || !range.y) { + renderable = false; + break; + } + + offset = getOffset(_this.cropper); + left = _this.startX - offset.left; + top = _this.startY - offset.top; + width = cropBoxData.minWidth; + height = cropBoxData.minHeight; + + if (range.x > 0) { + action = range.y > 0 ? ACTION_SOUTH_EAST : ACTION_NORTH_EAST; + } else if (range.x < 0) { + left -= width; + action = range.y > 0 ? ACTION_SOUTH_WEST : ACTION_NORTH_WEST; + } + + if (range.y < 0) { + top -= height; + } + + // Show the crop box if is hidden + if (!_this.cropped) { + removeClass(_this.cropBox, CLASS_HIDDEN); + _this.cropped = true; + + if (_this.limited) { + _this.limitCropBox(true, true); + } + } + + break; + + // No default + } + + if (renderable) { + cropBoxData.width = width; + cropBoxData.height = height; + cropBoxData.left = left; + cropBoxData.top = top; + _this.action = action; + + _this.renderCropBox(); + } + + // Override + _this.startX = _this.endX; + _this.startY = _this.endY; + }, + + // Show the crop box manually + crop: function () { + var _this = this; + + if (_this.built && !_this.disabled) { + if (!_this.cropped) { + _this.cropped = true; + _this.limitCropBox(true, true); + + if (_this.options.modal) { + addClass(_this.dragBox, CLASS_MODAL); + } + + removeClass(_this.cropBox, CLASS_HIDDEN); + } + + _this.setCropBoxData(_this.initialCropBoxData); + } + + return _this; + }, + + // Reset the image and crop box to their initial states + reset: function () { + var _this = this; + + if (_this.built && !_this.disabled) { + _this.imageData = extend({}, _this.initialImageData); + _this.canvasData = extend({}, _this.initialCanvasData); + _this.cropBoxData = extend({}, _this.initialCropBoxData); + + _this.renderCanvas(); + + if (_this.cropped) { + _this.renderCropBox(); + } + } + + return _this; + }, + + // Clear the crop box + clear: function () { + var _this = this; + + if (_this.cropped && !_this.disabled) { + extend(_this.cropBoxData, { + left: 0, + top: 0, + width: 0, + height: 0 + }); + + _this.cropped = false; + _this.renderCropBox(); + + _this.limitCanvas(); + + // Render canvas after crop box rendered + _this.renderCanvas(); + + removeClass(_this.dragBox, CLASS_MODAL); + addClass(_this.cropBox, CLASS_HIDDEN); + } + + return _this; + }, + + /** + * Replace the image's src and rebuild the cropper + * + * @param {String} url + */ + replace: function (url) { + var _this = this; + + if (!_this.disabled && url) { + if (_this.isImg) { + _this.replaced = true; + _this.element.src = url; + } + + // Clear previous data + _this.options.data = null; + _this.load(url); + } + + return _this; + }, + + // Enable (unfreeze) the cropper + enable: function () { + var _this = this; + + if (_this.built) { + _this.disabled = false; + removeClass(_this.cropper, CLASS_DISABLED); + } + + return _this; + }, + + // Disable (freeze) the cropper + disable: function () { + var _this = this; + + if (_this.built) { + _this.disabled = true; + addClass(_this.cropper, CLASS_DISABLED); + } + + return _this; + }, + + // Destroy the cropper and remove the instance from the image + destroy: function () { + var _this = this; + var element = _this.element; + var image = _this.image; + + if (_this.ready) { + if (_this.isImg && _this.replaced) { + element.src = _this.originalUrl; + } + + _this.unbuild(); + removeClass(element, CLASS_HIDDEN); + } else { + if (_this.isImg) { + removeListener(element, EVENT_LOAD, _this.start); + } else if (image) { + removeChild(image); + } + } + + removeData(element, NAMESPACE); + + return _this; + }, + + /** + * Move the canvas with relative offsets + * + * @param {Number} offsetX + * @param {Number} offsetY (optional) + */ + move: function (offsetX, offsetY) { + var _this = this; + var canvasData = _this.canvasData; + + return _this.moveTo( + isUndefined(offsetX) ? offsetX : canvasData.left + Number(offsetX), + isUndefined(offsetY) ? offsetY : canvasData.top + Number(offsetY) + ); + }, + + /** + * Move the canvas to an absolute point + * + * @param {Number} x + * @param {Number} y (optional) + */ + moveTo: function (x, y) { + var _this = this; + var canvasData = _this.canvasData; + var changed = false; + + // If "y" is not present, its default value is "x" + if (isUndefined(y)) { + y = x; + } + + x = Number(x); + y = Number(y); + + if (_this.built && !_this.disabled && _this.options.movable) { + if (isNumber(x)) { + canvasData.left = x; + changed = true; + } + + if (isNumber(y)) { + canvasData.top = y; + changed = true; + } + + if (changed) { + _this.renderCanvas(true); + } + } + + return _this; + }, + + /** + * Zoom the canvas with a relative ratio + * + * @param {Number} ratio + * @param {Event} _originalEvent (private) + */ + zoom: function (ratio, _originalEvent) { + var _this = this; + var canvasData = _this.canvasData; + + ratio = Number(ratio); + + if (ratio < 0) { + ratio = 1 / (1 - ratio); + } else { + ratio = 1 + ratio; + } + + return _this.zoomTo(canvasData.width * ratio / canvasData.naturalWidth, _originalEvent); + }, + + /** + * Zoom the canvas to an absolute ratio + * + * @param {Number} ratio + * @param {Event} _originalEvent (private) + */ + zoomTo: function (ratio, _originalEvent) { + var _this = this; + var options = _this.options; + var canvasData = _this.canvasData; + var width = canvasData.width; + var height = canvasData.height; + var naturalWidth = canvasData.naturalWidth; + var naturalHeight = canvasData.naturalHeight; + var newWidth; + var newHeight; + var offset; + var center; + + ratio = Number(ratio); + + if (ratio >= 0 && _this.built && !_this.disabled && options.zoomable) { + newWidth = naturalWidth * ratio; + newHeight = naturalHeight * ratio; + + if (isFunction(options.zoom) && options.zoom.call(_this.element, { + originalEvent: _originalEvent, + oldRatio: width / naturalWidth, + ratio: newWidth / naturalWidth + }) === false) { + return _this; + } + + if (_originalEvent) { + offset = getOffset(_this.cropper); + center = _originalEvent.touches ? getTouchesCenter(_originalEvent.touches) : { + pageX: _originalEvent.pageX, + pageY: _originalEvent.pageY + }; + + // Zoom from the triggering point of the event + canvasData.left -= (newWidth - width) * ( + ((center.pageX - offset.left) - canvasData.left) / width + ); + canvasData.top -= (newHeight - height) * ( + ((center.pageY - offset.top) - canvasData.top) / height + ); + } else { + + // Zoom from the center of the canvas + canvasData.left -= (newWidth - width) / 2; + canvasData.top -= (newHeight - height) / 2; + } + + canvasData.width = newWidth; + canvasData.height = newHeight; + _this.renderCanvas(true); + } + + return _this; + }, + + /** + * Rotate the canvas with a relative degree + * + * @param {Number} degree + */ + rotate: function (degree) { + var _this = this; + + return _this.rotateTo((_this.imageData.rotate || 0) + Number(degree)); + }, + + /** + * Rotate the canvas to an absolute degree + * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function#rotate() + * + * @param {Number} degree + */ + rotateTo: function (degree) { + var _this = this; + + degree = Number(degree); + + if (isNumber(degree) && _this.built && !_this.disabled && _this.options.rotatable) { + _this.imageData.rotate = degree % 360; + _this.rotated = true; + _this.renderCanvas(true); + } + + return _this; + }, + + /** + * Scale the image + * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function#scale() + * + * @param {Number} scaleX + * @param {Number} scaleY (optional) + */ + scale: function (scaleX, scaleY) { + var _this = this; + var imageData = _this.imageData; + var changed = false; + + // If "scaleY" is not present, its default value is "scaleX" + if (isUndefined(scaleY)) { + scaleY = scaleX; + } + + scaleX = Number(scaleX); + scaleY = Number(scaleY); + + if (_this.built && !_this.disabled && _this.options.scalable) { + if (isNumber(scaleX)) { + imageData.scaleX = scaleX; + changed = true; + } + + if (isNumber(scaleY)) { + imageData.scaleY = scaleY; + changed = true; + } + + if (changed) { + _this.renderImage(true); + } + } + + return _this; + }, + + /** + * Scale the abscissa of the image + * + * @param {Number} scaleX + */ + scaleX: function (scaleX) { + var _this = this; + var scaleY = _this.imageData.scaleY; + + return _this.scale(scaleX, isNumber(scaleY) ? scaleY : 1); + }, + + /** + * Scale the ordinate of the image + * + * @param {Number} scaleY + */ + scaleY: function (scaleY) { + var _this = this; + var scaleX = _this.imageData.scaleX; + + return _this.scale(isNumber(scaleX) ? scaleX : 1, scaleY); + }, + + /** + * Get the cropped area position and size data (base on the original image) + * + * @param {Boolean} rounded (optional) + * @return {Object} data + */ + getData: function (rounded) { + var _this = this; + var options = _this.options; + var imageData = _this.imageData; + var canvasData = _this.canvasData; + var cropBoxData = _this.cropBoxData; + var ratio; + var data; + + if (_this.built && _this.cropped) { + data = { + x: cropBoxData.left - canvasData.left, + y: cropBoxData.top - canvasData.top, + width: cropBoxData.width, + height: cropBoxData.height + }; + + ratio = imageData.width / imageData.naturalWidth; + + each(data, function (n, i) { + n = n / ratio; + data[i] = rounded ? round(n) : n; + }); + + } else { + data = { + x: 0, + y: 0, + width: 0, + height: 0 + }; + } + + if (options.rotatable) { + data.rotate = imageData.rotate || 0; + } + + if (options.scalable) { + data.scaleX = imageData.scaleX || 1; + data.scaleY = imageData.scaleY || 1; + } + + return data; + }, + + /** + * Set the cropped area position and size with new data + * + * @param {Object} data + */ + setData: function (data) { + var _this = this; + var options = _this.options; + var imageData = _this.imageData; + var canvasData = _this.canvasData; + var cropBoxData = {}; + var rotated; + var scaled; + var ratio; + + if (isFunction(data)) { + data = data.call(_this.element); + } + + if (_this.built && !_this.disabled && isPlainObject(data)) { + if (options.rotatable) { + if (isNumber(data.rotate) && data.rotate !== imageData.rotate) { + imageData.rotate = data.rotate; + _this.rotated = rotated = true; + } + } + + if (options.scalable) { + if (isNumber(data.scaleX) && data.scaleX !== imageData.scaleX) { + imageData.scaleX = data.scaleX; + scaled = true; + } + + if (isNumber(data.scaleY) && data.scaleY !== imageData.scaleY) { + imageData.scaleY = data.scaleY; + scaled = true; + } + } + + if (rotated) { + _this.renderCanvas(); + } else if (scaled) { + _this.renderImage(); + } + + ratio = imageData.width / imageData.naturalWidth; + + if (isNumber(data.x)) { + cropBoxData.left = data.x * ratio + canvasData.left; + } + + if (isNumber(data.y)) { + cropBoxData.top = data.y * ratio + canvasData.top; + } + + if (isNumber(data.width)) { + cropBoxData.width = data.width * ratio; + } + + if (isNumber(data.height)) { + cropBoxData.height = data.height * ratio; + } + + _this.setCropBoxData(cropBoxData); + } + + return _this; + }, + + /** + * Get the container size data + * + * @return {Object} data + */ + getContainerData: function () { + var _this = this; + + return _this.built ? _this.containerData : {}; + }, + + /** + * Get the image position and size data + * + * @return {Object} data + */ + getImageData: function () { + var _this = this; + + return _this.ready ? _this.imageData : {}; + }, + + /** + * Get the canvas position and size data + * + * @return {Object} data + */ + getCanvasData: function () { + var _this = this; + var canvasData = _this.canvasData; + var data = {}; + + if (_this.built) { + each([ + 'left', + 'top', + 'width', + 'height', + 'naturalWidth', + 'naturalHeight' + ], function (n) { + data[n] = canvasData[n]; + }); + } + + return data; + }, + + /** + * Set the canvas position and size with new data + * + * @param {Object} data + */ + setCanvasData: function (data) { + var _this = this; + var canvasData = _this.canvasData; + var aspectRatio = canvasData.aspectRatio; + + if (isFunction(data)) { + data = data.call(_this.element); + } + + if (_this.built && !_this.disabled && isPlainObject(data)) { + if (isNumber(data.left)) { + canvasData.left = data.left; + } + + if (isNumber(data.top)) { + canvasData.top = data.top; + } + + if (isNumber(data.width)) { + canvasData.width = data.width; + canvasData.height = data.width / aspectRatio; + } else if (isNumber(data.height)) { + canvasData.height = data.height; + canvasData.width = data.height * aspectRatio; + } + + _this.renderCanvas(true); + } + + return _this; + }, + + /** + * Get the crop box position and size data + * + * @return {Object} data + */ + getCropBoxData: function () { + var _this = this; + var cropBoxData = _this.cropBoxData; + var data; + + if (_this.built && _this.cropped) { + data = { + left: cropBoxData.left, + top: cropBoxData.top, + width: cropBoxData.width, + height: cropBoxData.height + }; + } + + return data || {}; + }, + + /** + * Set the crop box position and size with new data + * + * @param {Object} data + */ + setCropBoxData: function (data) { + var _this = this; + var cropBoxData = _this.cropBoxData; + var aspectRatio = _this.options.aspectRatio; + var widthChanged; + var heightChanged; + + if (isFunction(data)) { + data = data.call(_this.element); + } + + if (_this.built && _this.cropped && !_this.disabled && isPlainObject(data)) { + + if (isNumber(data.left)) { + cropBoxData.left = data.left; + } + + if (isNumber(data.top)) { + cropBoxData.top = data.top; + } + + if (isNumber(data.width)) { + widthChanged = true; + cropBoxData.width = data.width; + } + + if (isNumber(data.height)) { + heightChanged = true; + cropBoxData.height = data.height; + } + + if (aspectRatio) { + if (widthChanged) { + cropBoxData.height = cropBoxData.width / aspectRatio; + } else if (heightChanged) { + cropBoxData.width = cropBoxData.height * aspectRatio; + } + } + + _this.renderCropBox(); + } + + return _this; + }, + + /** + * Get a canvas drawn the cropped image + * + * @param {Object} options (optional) + * @return {HTMLCanvasElement} canvas + */ + getCroppedCanvas: function (options) { + var _this = this; + var originalWidth; + var originalHeight; + var canvasWidth; + var canvasHeight; + var scaledWidth; + var scaledHeight; + var scaledRatio; + var aspectRatio; + var canvas; + var context; + var data; + + if (!_this.built || !_this.cropped || !SUPPORT_CANVAS) { + return; + } + + if (!isPlainObject(options)) { + options = {}; + } + + data = _this.getData(); + originalWidth = data.width; + originalHeight = data.height; + aspectRatio = originalWidth / originalHeight; + + if (isPlainObject(options)) { + scaledWidth = options.width; + scaledHeight = options.height; + + if (scaledWidth) { + scaledHeight = scaledWidth / aspectRatio; + scaledRatio = scaledWidth / originalWidth; + } else if (scaledHeight) { + scaledWidth = scaledHeight * aspectRatio; + scaledRatio = scaledHeight / originalHeight; + } + } + + // The canvas element will use `Math.floor` on a float number, so floor first + canvasWidth = floor(scaledWidth || originalWidth); + canvasHeight = floor(scaledHeight || originalHeight); + + canvas = createElement('canvas'); + canvas.width = canvasWidth; + canvas.height = canvasHeight; + context = canvas.getContext('2d'); + + if (options.fillColor) { + context.fillStyle = options.fillColor; + context.fillRect(0, 0, canvasWidth, canvasHeight); + } + + // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.drawImage + context.drawImage.apply(context, (function () { + var source = getSourceCanvas(_this.image, _this.imageData); + var sourceWidth = source.width; + var sourceHeight = source.height; + var args = [source]; + + // Source canvas + var srcX = data.x; + var srcY = data.y; + var srcWidth; + var srcHeight; + + // Destination canvas + var dstX; + var dstY; + var dstWidth; + var dstHeight; + + if (srcX <= -originalWidth || srcX > sourceWidth) { + srcX = srcWidth = dstX = dstWidth = 0; + } else if (srcX <= 0) { + dstX = -srcX; + srcX = 0; + srcWidth = dstWidth = min(sourceWidth, originalWidth + srcX); + } else if (srcX <= sourceWidth) { + dstX = 0; + srcWidth = dstWidth = min(originalWidth, sourceWidth - srcX); + } + + if (srcWidth <= 0 || srcY <= -originalHeight || srcY > sourceHeight) { + srcY = srcHeight = dstY = dstHeight = 0; + } else if (srcY <= 0) { + dstY = -srcY; + srcY = 0; + srcHeight = dstHeight = min(sourceHeight, originalHeight + srcY); + } else if (srcY <= sourceHeight) { + dstY = 0; + srcHeight = dstHeight = min(originalHeight, sourceHeight - srcY); + } + + args.push(floor(srcX), floor(srcY), floor(srcWidth), floor(srcHeight)); + + // Scale destination sizes + if (scaledRatio) { + dstX *= scaledRatio; + dstY *= scaledRatio; + dstWidth *= scaledRatio; + dstHeight *= scaledRatio; + } + + // Avoid "IndexSizeError" in IE and Firefox + if (dstWidth > 0 && dstHeight > 0) { + args.push(floor(dstX), floor(dstY), floor(dstWidth), floor(dstHeight)); + } + + return args; + }).call(_this)); + + return canvas; + }, + + /** + * Change the aspect ratio of the crop box + * + * @param {Number} aspectRatio + */ + setAspectRatio: function (aspectRatio) { + var _this = this; + var options = _this.options; + + if (!_this.disabled && !isUndefined(aspectRatio)) { + + // 0 -> NaN + options.aspectRatio = max(0, aspectRatio) || NaN; + + if (_this.built) { + _this.initCropBox(); + + if (_this.cropped) { + _this.renderCropBox(); + } + } + } + + return _this; + }, + + /** + * Change the drag mode + * + * @param {String} mode (optional) + */ + setDragMode: function (mode) { + var _this = this; + var options = _this.options; + var dragBox = _this.dragBox; + var face = _this.face; + var croppable; + var movable; + + if (_this.ready && !_this.disabled) { + croppable = mode === ACTION_CROP; + movable = options.movable && mode === ACTION_MOVE; + mode = (croppable || movable) ? mode : ACTION_NONE; + + setData(dragBox, DATA_ACTION, mode); + toggleClass(dragBox, CLASS_CROP, croppable); + toggleClass(dragBox, CLASS_MOVE, movable); + + if (!options.cropBoxMovable) { + + // Sync drag mode to crop box when it is not movable + setData(face, DATA_ACTION, mode); + toggleClass(face, CLASS_CROP, croppable); + toggleClass(face, CLASS_MOVE, movable); + } + } + + return _this; + } + }; + + Cropper.DEFAULTS = { + + // Define the view mode of the cropper + viewMode: 0, // 0, 1, 2, 3 + + // Define the dragging mode of the cropper + dragMode: 'crop', // 'crop', 'move' or 'none' + + // Define the aspect ratio of the crop box + aspectRatio: NaN, + + // An object with the previous cropping result data + data: null, + + // A selector for adding extra containers to preview + preview: '', + + // Re-render the cropper when resize the window + responsive: true, + + // Restore the cropped area after resize the window + restore: true, + + // Check if the current image is a cross-origin image + checkCrossOrigin: true, + + // Check the current image's Exif Orientation information + checkOrientation: true, + + // Show the black modal + modal: true, + + // Show the dashed lines for guiding + guides: true, + + // Show the center indicator for guiding + center: true, + + // Show the white modal to highlight the crop box + highlight: true, + + // Show the grid background + background: true, + + // Enable to crop the image automatically when initialize + autoCrop: true, + + // Define the percentage of automatic cropping area when initializes + autoCropArea: 0.8, + + // Enable to move the image + movable: true, + + // Enable to rotate the image + rotatable: true, + + // Enable to scale the image + scalable: true, + + // Enable to zoom the image + zoomable: true, + + // Enable to zoom the image by dragging touch + zoomOnTouch: true, + + // Enable to zoom the image by wheeling mouse + zoomOnWheel: true, + + // Define zoom ratio when zoom the image by wheeling mouse + wheelZoomRatio: 0.1, + + // Enable to move the crop box + cropBoxMovable: true, + + // Enable to resize the crop box + cropBoxResizable: true, + + // Toggle drag mode between "crop" and "move" when click twice on the cropper + toggleDragModeOnDblclick: true, + + // Size limitation + minCanvasWidth: 0, + minCanvasHeight: 0, + minCropBoxWidth: 0, + minCropBoxHeight: 0, + minContainerWidth: 200, + minContainerHeight: 100, + + // Shortcuts of events + build: null, + built: null, + cropstart: null, + cropmove: null, + cropend: null, + crop: null, + zoom: null + }; + + Cropper.TEMPLATE = (function (source, words) { + words = words.split(','); + + return source.replace(/\d+/g, function (i) { + return words[i]; + }); + })('<0 6="5-container"><0 6="5-wrap-9"><0 6="5-canvas"><0 6="5-drag-9"><0 6="5-crop-9"><1 6="5-view-9"><1 6="5-8 8-h"><1 6="5-8 8-v"><1 6="5-center"><1 6="5-face"><1 6="5-7 7-e" 3-2="e"><1 6="5-7 7-n" 3-2="n"><1 6="5-7 7-w" 3-2="w"><1 6="5-7 7-s" 3-2="s"><1 6="5-4 4-e" 3-2="e"><1 6="5-4 4-n" 3-2="n"><1 6="5-4 4-w" 3-2="w"><1 6="5-4 4-s" 3-2="s"><1 6="5-4 4-ne" 3-2="ne"><1 6="5-4 4-nw" 3-2="nw"><1 6="5-4 4-sw" 3-2="sw"><1 6="5-4 4-se" 3-2="se">', 'div,span,action,data,point,cropper,class,line,dashed,box'); + + /*Cropper.TEMPLATE = ( + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
' + + '
' + );*/ + + var _Cropper = window.Cropper; + + Cropper.noConflict = function () { + window.Cropper = _Cropper; + return Cropper; + }; + + Cropper.setDefaults = function (options) { + extend(Cropper.DEFAULTS, options); + }; + + if (typeof define === 'function' && define.amd) { + define('cropper', [], function () { + return Cropper; + }); + } + + if (!noGlobal) { + window.Cropper = Cropper; + } + + return Cropper; + +}); diff --git a/web/static/plugs/cropper/cropper.min.css b/web/static/plugs/cropper/cropper.min.css new file mode 100644 index 00000000..2a219c25 --- /dev/null +++ b/web/static/plugs/cropper/cropper.min.css @@ -0,0 +1,9 @@ +/*! + * Cropper.js v0.5.6 + * https://github.com/fengyuanchen/cropperjs + * + * Copyright (c) 2015-2016 Fengyuan Chen + * Released under the MIT license + * + * Date: 2016-01-18T05:33:19.322Z + */.cropper-container{font-size:0;line-height:0;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;direction:ltr!important;-ms-touch-action:none;touch-action:none;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none}.cropper-container img{display:block;width:100%;min-width:0!important;max-width:none!important;height:100%;min-height:0!important;max-height:none!important;image-orientation:0deg!important}.cropper-canvas,.cropper-crop-box,.cropper-drag-box,.cropper-modal,.cropper-wrap-box{position:absolute;top:0;right:0;bottom:0;left:0}.cropper-wrap-box{overflow:hidden}.cropper-drag-box{opacity:0;background-color:#fff;filter:alpha(opacity=0)}.cropper-dashed,.cropper-modal{opacity:.5;filter:alpha(opacity=50)}.cropper-modal{background-color:#000}.cropper-view-box{display:block;overflow:hidden;width:100%;height:100%;outline:#39f solid 1px;outline-color:rgba(51,153,255,.75)}.cropper-dashed{position:absolute;display:block;border:0 dashed #eee}.cropper-dashed.dashed-h{top:33.33333%;left:0;width:100%;height:33.33333%;border-top-width:1px;border-bottom-width:1px}.cropper-dashed.dashed-v{top:0;left:33.33333%;width:33.33333%;height:100%;border-right-width:1px;border-left-width:1px}.cropper-center{position:absolute;top:50%;left:50%;display:block;width:0;height:0;opacity:.75;filter:alpha(opacity=75)}.cropper-center:after,.cropper-center:before{position:absolute;display:block;content:' ';background-color:#eee}.cropper-center:before{top:0;left:-3px;width:7px;height:1px}.cropper-center:after{top:-3px;left:0;width:1px;height:7px}.cropper-face,.cropper-line,.cropper-point{position:absolute;display:block;width:100%;height:100%;opacity:.1;filter:alpha(opacity=10)}.cropper-face{top:0;left:0;background-color:#fff}.cropper-line,.cropper-point{background-color:#39f}.cropper-line.line-e{top:0;right:-3px;width:5px;cursor:e-resize}.cropper-line.line-n{top:-3px;left:0;height:5px;cursor:n-resize}.cropper-line.line-w{top:0;left:-3px;width:5px;cursor:w-resize}.cropper-line.line-s{bottom:-3px;left:0;height:5px;cursor:s-resize}.cropper-point{width:5px;height:5px;opacity:.75;filter:alpha(opacity=75)}.cropper-point.point-e{top:50%;right:-3px;margin-top:-3px;cursor:e-resize}.cropper-point.point-n{top:-3px;left:50%;margin-left:-3px;cursor:n-resize}.cropper-point.point-w{top:50%;left:-3px;margin-top:-3px;cursor:w-resize}.cropper-point.point-s{bottom:-3px;left:50%;margin-left:-3px;cursor:s-resize}.cropper-point.point-ne{top:-3px;right:-3px;cursor:ne-resize}.cropper-point.point-nw{top:-3px;left:-3px;cursor:nw-resize}.cropper-point.point-sw{bottom:-3px;left:-3px;cursor:sw-resize}.cropper-point.point-se{right:-3px;bottom:-3px;width:20px;height:20px;cursor:se-resize;opacity:1;filter:alpha(opacity=100)}.cropper-point.point-se:before{position:absolute;right:-50%;bottom:-50%;display:block;width:200%;height:200%;content:' ';opacity:0;background-color:#39f;filter:alpha(opacity=0)}@media (min-width:768px){.cropper-point.point-se{width:15px;height:15px}}@media (min-width:992px){.cropper-point.point-se{width:10px;height:10px}}@media (min-width:1200px){.cropper-point.point-se{width:5px;height:5px;opacity:.75;filter:alpha(opacity=75)}}.cropper-invisible{opacity:0;filter:alpha(opacity=0)}.cropper-bg{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC)}.cropper-hide{position:absolute;display:block;width:0;height:0}.cropper-hidden{display:none!important}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed} \ No newline at end of file diff --git a/web/static/plugs/cropper/cropper.min.js b/web/static/plugs/cropper/cropper.min.js new file mode 100644 index 00000000..843e41d9 --- /dev/null +++ b/web/static/plugs/cropper/cropper.min.js @@ -0,0 +1,10 @@ +/*! + * Cropper.js v0.5.6 + * https://github.com/fengyuanchen/cropperjs + * + * Copyright (c) 2015-2016 Fengyuan Chen + * Released under the MIT license + * + * Date: 2016-01-18T05:33:43.542Z + */ +!function(t,e){"object"==typeof module&&"object"==typeof module.exports?module.exports=t.document?e(t,!0):function(t){if(!t.document)throw new Error("Cropper requires a window with a document");return e(t)}:e(t)}("undefined"!=typeof window?window:this,function(t,e){"use strict";function i(t){return Kt.call(t).slice(8,-1).toLowerCase()}function a(t){return"number"==typeof t&&!isNaN(t)}function n(t){return"undefined"==typeof t}function o(t){return"object"==typeof t&&null!==t}function r(t){var e,i;if(!o(t))return!1;try{return e=t.constructor,i=e.prototype,e&&i&&Gt.call(i,"isPrototypeOf")}catch(a){return!1}}function h(t){return"function"===i(t)}function l(t){return $.isArray?$.isArray(t):"array"===i(t)}function c(t,e){return e=e>=0?e:0,$.from?$.from(t).slice(e):Jt.call(t,e)}function s(t){return"string"==typeof t&&(t=t.trim?t.trim():t.replace(bt,"$1")),t}function d(t,e){var i,n;if(t&&h(e))if(l(t)||a(t.length))for(n=0,i=t.length;i>n&&e.call(t,t[n],n,t)!==!1;n++);else if(o(t))for(n in t)if(t.hasOwnProperty(n)&&e.call(t,t[n],n,t)===!1)break;return t}function p(t){var e;if(arguments.length>1){if(e=c(arguments),Z.assign)return Z.assign.apply(Z,e);e.shift(),d(e,function(e){d(e,function(e,i){t[i]=e})})}return t}function u(t,e){var i=c(arguments,2);return function(){return t.apply(e,i.concat(c(arguments)))}}function g(t,e){var i=t.style;d(e,function(t,e){vt.test(e)&&a(t)&&(t+="px"),i[e]=t})}function f(t,e){return t.classList?t.classList.contains(e):t.className.indexOf(e)>-1}function m(t,e){var i;return a(t.length)?d(t,function(t){m(t,e)}):t.classList?t.classList.add(e):(i=s(t.className),void(i?i.indexOf(e)<0&&(t.className=i+" "+e):t.className=e))}function v(t,e){return a(t.length)?d(t,function(t){v(t,e)}):t.classList?t.classList.remove(e):void(t.className.indexOf(e)>=0&&(t.className=t.className.replace(e,"")))}function w(t,e,i){return a(t.length)?d(t,function(t){w(t,e,i)}):void(i?m(t,e):v(t,e))}function b(t,e){return o(t[e])?t[e]:t.dataset?t.dataset[e]:t.getAttribute("data-"+e)}function x(t,e,i){o(i)&&n(t[e])?t[e]=i:t.dataset?t.dataset[e]=i:t.setAttribute("data-"+e,i)}function D(t,e){o(t[e])?delete t[e]:t.dataset?delete t.dataset[e]:t.removeAttribute("data-"+e)}function C(t,e,i){var a=s(e).split(xt);return a.length>1?d(a,function(e){C(t,e,i)}):void(t.addEventListener?t.addEventListener(e,i,!1):t.attachEvent&&t.attachEvent("on"+e,i))}function y(t,e,i){var a=s(e).split(xt);return a.length>1?d(a,function(e){y(t,e,i)}):void(t.removeEventListener?t.removeEventListener(e,i,!1):t.detachEvent&&t.detachEvent("on"+e,i))}function B(t){t.preventDefault?t.preventDefault():t.returnValue=!1}function T(e){var i,n=e||t.event;return n.target||(n.target=n.srcElement||q),a(n.pageX)||(i=q.documentElement,n.pageX=n.clientX+(t.scrollX||i&&i.scrollLeft||0)-(i&&i.clientLeft||0),n.pageY=n.clientY+(t.scrollY||i&&i.scrollTop||0)-(i&&i.clientTop||0)),n}function L(e){var i=q.documentElement,a=e.getBoundingClientRect();return{left:a.left+(t.scrollX||i&&i.scrollLeft||0)-(i&&i.clientLeft||0),top:a.top+(t.scrollY||i&&i.scrollTop||0)-(i&&i.clientTop||0)}}function X(t){var e=t.length,i=0,a=0;return e&&(d(t,function(t){i+=t.pageX,a+=t.pageY}),i/=e,a/=e),{pageX:i,pageY:a}}function Y(t,e){return t.getElementsByTagName(e)}function k(t,e){return t.getElementsByClassName?t.getElementsByClassName(e):t.querySelectorAll("."+e)}function W(t){return q.createElement(t)}function H(t,e){t.appendChild(e)}function M(t){t.parentNode&&t.parentNode.removeChild(t)}function E(t){for(;t.firstChild;)t.removeChild(t.firstChild)}function O(t){var e=t.match(wt);return e&&(e[1]!==F.protocol||e[2]!==F.hostname||e[3]!==F.port)}function z(t){var e="timestamp="+(new Date).getTime();return t+(-1===t.indexOf("?")?"?":"&")+e}function R(t,e){var i;return t.naturalWidth?e(t.naturalWidth,t.naturalHeight):(i=W("img"),i.onload=function(){e(this.width,this.height)},void(i.src=t.src))}function N(t){var e=[],i=t.rotate,n=t.scaleX,o=t.scaleY;return a(i)&&e.push("rotate("+i+"deg)"),a(n)&&a(o)&&e.push("scale("+n+","+o+")"),e.length?e.join(" "):"none"}function U(t,e){var i,a,n=_t(t.degree)%180,o=(n>90?180-n:n)*Zt/180,r=Pt(o),h=jt(o),l=t.width,c=t.height,s=t.aspectRatio;return e?(i=l/(h+r/s),a=i/s):(i=l*h+c*r,a=l*r+c*h),{width:i,height:a}}function A(t,e){var i,n,o,r=W("canvas"),h=r.getContext("2d"),l=0,c=0,s=e.naturalWidth,d=e.naturalHeight,p=e.rotate,u=e.scaleX,g=e.scaleY,f=a(u)&&a(g)&&(1!==u||1!==g),m=a(p)&&0!==p,v=m||f,w=s,b=d;return f&&(i=s/2,n=d/2),m&&(o=U({width:s,height:d,degree:p}),w=o.width,b=o.height,i=o.width/2,n=o.height/2),r.width=w,r.height=b,v&&(l=-s/2,c=-d/2,h.save(),h.translate(i,n)),m&&h.rotate(p*Zt/180),f&&h.scale(u,g),h.drawImage(t,Vt(l),Vt(c),Vt(s),Vt(d)),v&&h.restore(),r}function I(t,e,i){var a="",n=e;for(i+=e;i>n;n++)a+=Qt(t.getUint8(n));return a}function S(t){var e,i,a,n,o,r,h,l,c,s,d=new DataView(t),p=d.byteLength;if(255===d.getUint8(0)&&216===d.getUint8(1))for(c=2;p>c;){if(255===d.getUint8(c)&&225===d.getUint8(c+1)){h=c;break}c++}if(h&&(i=h+4,a=h+10,"Exif"===I(d,i,4)&&(r=d.getUint16(a),o=18761===r,(o||19789===r)&&42===d.getUint16(a+2,o)&&(n=d.getUint32(a+4,o),n>=8&&(l=a+n)))),l)for(p=d.getUint16(l,o),s=0;p>s;s++)if(c=l+12*s+2,274===d.getUint16(c,o)){c+=8,e=d.getUint16(c,o),d.setUint16(c,1,o);break}return e}function _(t){var e,i=t.replace(Ct,""),a=atob(i),n=a.length,o=new V(n),r=new Uint8Array(o);for(e=0;n>e;e++)r[e]=a.charCodeAt(e);return o}function P(t){var e,i=new Uint8Array(t),a=i.length,n="";for(e=0;a>e;e++)n+=Qt(i[e]);return"data:image/jpeg;base64,"+btoa(n)}function j(t,e){var i=this;i.element=t,i.options=p({},j.DEFAULTS,r(e)&&e),i.ready=!1,i.built=!1,i.complete=!1,i.rotated=!1,i.cropped=!1,i.disabled=!1,i.replaced=!1,i.limited=!1,i.wheeling=!1,i.isImg=!1,i.originalUrl="",i.canvasData=null,i.cropBoxData=null,i.previews=null,i.init()}var q=t.document,F=t.location,V=t.ArrayBuffer,Z=t.Object,$=t.Array,K=t.String,G=t.Number,J=t.Math,Q="cropper",tt=Q+"-modal",et=Q+"-hide",it=Q+"-hidden",at=Q+"-invisible",nt=Q+"-move",ot=Q+"-crop",rt=Q+"-disabled",ht=Q+"-bg",lt="mousedown touchstart pointerdown MSPointerDown",ct="mousemove touchmove pointermove MSPointerMove",st="mouseup touchend touchcancel pointerup pointercancel MSPointerUp MSPointerCancel",dt="wheel mousewheel DOMMouseScroll",pt="dblclick",ut="resize",gt="error",ft="load",mt=/e|w|s|n|se|sw|ne|nw|all|crop|move|zoom/,vt=/width|height|left|top|marginLeft|marginTop/,wt=/^(https?:)\/\/([^\:\/\?#]+):?(\d*)/i,bt=/^\s+(.*)\s+$/,xt=/\s+/,Dt=/^data\:/,Ct=/^data\:([^\;]+)\;base64,/,yt=/^data\:image\/jpeg.*;base64,/,Bt="preview",Tt="action",Lt="e",Xt="w",Yt="s",kt="n",Wt="se",Ht="sw",Mt="ne",Et="nw",Ot="all",zt="crop",Rt="move",Nt="zoom",Ut="none",At=!!q.createElement("canvas").getContext,It=J.min,St=J.max,_t=J.abs,Pt=J.sin,jt=J.cos,qt=J.sqrt,Ft=J.round,Vt=J.floor,Zt=J.PI,$t=Z.prototype,Kt=$t.toString,Gt=$t.hasOwnProperty,Jt=$.prototype.slice,Qt=K.fromCharCode;j.prototype={constructor:j,init:function(){var t,e=this,i=e.element,a=i.tagName.toLowerCase();if(!b(i,Q)){if(x(i,Q,e),"img"===a){if(e.isImg=!0,e.originalUrl=t=i.getAttribute("src"),!t)return;t=i.src}else"canvas"===a&&At&&(t=i.toDataURL());e.load(t)}},load:function(t){var e,i=this,a=i.options;if(t&&(!h(a.build)||a.build.call(i.element)!==!1)){if(i.url=t,i.imageData={},!a.checkOrientation||!V)return i.clone();if(Dt.test(t))return yt.test(t)?i.read(_(t)):i.clone();e=new XMLHttpRequest,e.onerror=e.onabort=function(){i.clone()},e.onload=function(){i.read(this.response)},e.open("get",t),e.responseType="arraybuffer",e.send()}},read:function(t){var e,i,a,n=this,o=n.options,r=S(t),h=n.imageData;if(r>1)switch(n.url=P(t),r){case 2:i=-1;break;case 3:e=-180;break;case 4:a=-1;break;case 5:e=90,a=-1;break;case 6:e=90;break;case 7:e=90,i=-1;break;case 8:e=-90}o.rotatable&&(h.rotate=e),o.scalable&&(h.scaleX=i,h.scaleY=a),n.clone()},clone:function(){var t,e,i,a,n,o=this,r=o.element,h=o.url;o.options.checkCrossOrigin&&O(h)&&(t=r.crossOrigin,t?e=h:(t="anonymous",e=z(h))),o.crossOrigin=t,o.crossOriginUrl=e,i=W("img"),t&&(i.crossOrigin=t),i.src=e||h,o.image=i,o._start=a=u(o.start,o),o._stop=n=u(o.stop,o),o.isImg?r.complete?o.start():C(r,ft,a):(C(i,ft,a),C(i,gt,n),m(i,et),r.parentNode.insertBefore(i,r.nextSibling))},start:function(t){var e=this,i=e.isImg?e.element:e.image;t&&(y(i,ft,e._start),y(i,gt,e._stop)),R(i,function(t,i){p(e.imageData,{naturalWidth:t,naturalHeight:i,aspectRatio:t/i}),e.ready=!0,e.build()})},stop:function(){var t=this,e=t.image;y(e,ft,t._start),y(e,gt,t._stop),M(e),t.image=null},build:function(){var t,e,i,a,n,o,r,l=this,c=l.options,s=l.element,d=l.image;l.ready&&(l.built&&l.unbuild(),e=W("div"),e.innerHTML=j.TEMPLATE,l.container=t=s.parentNode,l.cropper=i=k(e,"cropper-container")[0],l.canvas=a=k(i,"cropper-canvas")[0],l.dragBox=n=k(i,"cropper-drag-box")[0],l.cropBox=o=k(i,"cropper-crop-box")[0],l.viewBox=k(i,"cropper-view-box")[0],l.face=r=k(o,"cropper-face")[0],H(a,d),m(s,it),t.insertBefore(i,s.nextSibling),l.isImg||v(d,et),l.initPreview(),l.bind(),c.aspectRatio=St(0,c.aspectRatio)||NaN,c.viewMode=St(0,It(3,Ft(c.viewMode)))||0,c.autoCrop?(l.cropped=!0,c.modal&&m(n,tt)):m(o,it),c.guides||m(k(o,"cropper-dashed"),it),c.center||m(k(o,"cropper-center"),it),c.background&&m(i,ht),c.highlight||m(r,at),c.cropBoxMovable&&(m(r,nt),x(r,Tt,Ot)),c.cropBoxResizable||(m(k(o,"cropper-line"),it),m(k(o,"cropper-point"),it)),l.setDragMode(c.dragMode),l.render(),l.built=!0,l.setData(c.data),setTimeout(function(){h(c.built)&&c.built.call(s),h(c.crop)&&c.crop.call(s,l.getData()),l.complete=!0},0))},unbuild:function(){var t=this;t.built&&(t.built=!1,t.complete=!1,t.initialImageData=null,t.initialCanvasData=null,t.initialCropBoxData=null,t.containerData=null,t.canvasData=null,t.cropBoxData=null,t.unbind(),t.resetPreview(),t.previews=null,t.viewBox=null,t.cropBox=null,t.dragBox=null,t.canvas=null,t.container=null,M(t.cropper),t.cropper=null)},render:function(){var t=this;t.initContainer(),t.initCanvas(),t.initCropBox(),t.renderCanvas(),t.cropped&&t.renderCropBox()},initContainer:function(){var t,e=this,i=e.options,a=e.element,n=e.container,o=e.cropper;m(o,it),v(a,it),e.containerData=t={width:St(n.offsetWidth,G(i.minContainerWidth)||200),height:St(n.offsetHeight,G(i.minContainerHeight)||100)},g(o,{width:t.width,height:t.height}),m(a,it),v(o,it)},initCanvas:function(){var t,e=this,i=e.options.viewMode,a=e.containerData,n=e.imageData,o=90===_t(n.rotate),r=o?n.naturalHeight:n.naturalWidth,h=o?n.naturalWidth:n.naturalHeight,l=r/h,c=a.width,s=a.height;a.height*l>a.width?3===i?c=a.height*l:s=a.width/l:3===i?s=a.width/l:c=a.height*l,t={naturalWidth:r,naturalHeight:h,aspectRatio:l,width:c,height:s},t.oldLeft=t.left=(a.width-c)/2,t.oldTop=t.top=(a.height-s)/2,e.canvasData=t,e.limited=1===i||2===i,e.limitCanvas(!0,!0),e.initialImageData=p({},n),e.initialCanvasData=p({},t)},limitCanvas:function(t,e){var i,a,n,o,r=this,h=r.options,l=h.viewMode,c=r.containerData,s=r.canvasData,d=s.aspectRatio,p=r.cropBoxData,u=r.cropped&&p;t&&(i=G(h.minCanvasWidth)||0,a=G(h.minCanvasHeight)||0,l>1?(i=St(i,c.width),a=St(a,c.height),3===l&&(a*d>i?i=a*d:a=i/d)):l>0&&(i?i=St(i,u?p.width:0):a?a=St(a,u?p.height:0):u&&(i=p.width,a=p.height,a*d>i?i=a*d:a=i/d)),i&&a?a*d>i?a=i/d:i=a*d:i?a=i/d:a&&(i=a*d),s.minWidth=i,s.minHeight=a,s.maxWidth=1/0,s.maxHeight=1/0),e&&(l?(n=c.width-s.width,o=c.height-s.height,s.minLeft=It(0,n),s.minTop=It(0,o),s.maxLeft=St(0,n),s.maxTop=St(0,o),u&&r.limited&&(s.minLeft=It(p.left,p.left+p.width-s.width),s.minTop=It(p.top,p.top+p.height-s.height),s.maxLeft=p.left,s.maxTop=p.top,2===l&&(s.width>=c.width&&(s.minLeft=It(0,n),s.maxLeft=St(0,n)),s.height>=c.height&&(s.minTop=It(0,o),s.maxTop=St(0,o))))):(s.minLeft=-s.width,s.minTop=-s.height,s.maxLeft=c.width,s.maxTop=c.height))},renderCanvas:function(t){var e,i,a=this,n=a.canvasData,o=a.imageData,r=o.rotate;a.rotated&&(a.rotated=!1,i=U({width:o.width,height:o.height,degree:r}),e=i.width/i.height,e!==n.aspectRatio&&(n.left-=(i.width-n.width)/2,n.top-=(i.height-n.height)/2,n.width=i.width,n.height=i.height,n.aspectRatio=e,n.naturalWidth=o.naturalWidth,n.naturalHeight=o.naturalHeight,r%180&&(i=U({width:o.naturalWidth,height:o.naturalHeight,degree:r}),n.naturalWidth=i.width,n.naturalHeight=i.height),a.limitCanvas(!0,!1))),(n.width>n.maxWidth||n.widthn.maxHeight||n.heightn.width?o.height=o.width/i:o.width=o.height*i),t.cropBoxData=o,t.limitCropBox(!0,!0),o.width=It(St(o.width,o.minWidth),o.maxWidth),o.height=It(St(o.height,o.minHeight),o.maxHeight),o.width=St(o.minWidth,o.width*a),o.height=St(o.minHeight,o.height*a),o.oldLeft=o.left=n.left+(n.width-o.width)/2,o.oldTop=o.top=n.top+(n.height-o.height)/2,t.initialCropBoxData=p({},o)},limitCropBox:function(t,e){var i,a,n,o,r=this,h=r.options,l=h.aspectRatio,c=r.containerData,s=r.canvasData,d=r.cropBoxData,p=r.limited;t&&(i=G(h.minCropBoxWidth)||0,a=G(h.minCropBoxHeight)||0,i=It(i,c.width),a=It(a,c.height),n=It(c.width,p?s.width:c.width),o=It(c.height,p?s.height:c.height),l&&(i&&a?a*l>i?a=i/l:i=a*l:i?a=i/l:a&&(i=a*l),o*l>n?o=n/l:n=o*l),d.minWidth=It(i,n),d.minHeight=It(a,o),d.maxWidth=n,d.maxHeight=o),e&&(p?(d.minLeft=St(0,s.left),d.minTop=St(0,s.top),d.maxLeft=It(c.width,s.left+s.width)-d.width,d.maxTop=It(c.height,s.top+s.height)-d.height):(d.minLeft=0,d.minTop=0,d.maxLeft=c.width-d.width,d.maxTop=c.height-d.height))},renderCropBox:function(){var t=this,e=t.options,i=t.containerData,a=t.cropBoxData;(a.width>a.maxWidth||a.widtha.maxHeight||a.heighta&&(f=a/o,s=n*f,d=a),g(t,{width:s,height:d}),g(Y(t,"img")[0],p({width:r*f,height:h*f,marginLeft:-l*f,marginTop:-c*f},u))}))},bind:function(){var e=this,i=e.options,a=e.cropper;C(a,lt,e._cropStart=u(e.cropStart,e)),i.zoomable&&i.zoomOnWheel&&C(a,dt,e._wheel=u(e.wheel,e)),i.toggleDragModeOnDblclick&&C(a,pt,e._dblclick=u(e.dblclick,e)),C(q,ct,e._cropMove=u(e.cropMove,e)),C(q,st,e._cropEnd=u(e.cropEnd,e)),i.responsive&&C(t,ut,e._resize=u(e.resize,e))},unbind:function(){var e=this,i=e.options,a=e.cropper;y(a,lt,e._cropStart),i.zoomable&&i.zoomOnWheel&&y(a,dt,e._wheel),i.toggleDragModeOnDblclick&&y(a,pt,e._dblclick),y(q,ct,e._cropMove),y(q,st,e._cropEnd),i.responsive&&y(t,ut,e._resize)},resize:function(){var t,e,i,a=this,n=a.options.restore,o=a.container,r=a.containerData;!a.disabled&&r&&(i=o.offsetWidth/r.width,(1!==i||o.offsetHeight!==r.height)&&(n&&(t=a.getCanvasData(),e=a.getCropBoxData()),a.render(),n&&(a.setCanvasData(d(t,function(e,a){t[a]=e*i})),a.setCropBoxData(d(e,function(t,a){e[a]=t*i})))))},dblclick:function(){var t=this;t.disabled||t.setDragMode(f(t.dragBox,ot)?Rt:zt)},wheel:function(t){var e=this,i=T(t),a=G(e.options.wheelZoomRatio)||.1,n=1;e.disabled||(B(i),e.wheeling||(e.wheeling=!0,setTimeout(function(){e.wheeling=!1},50),i.deltaY?n=i.deltaY>0?1:-1:i.wheelDelta?n=-i.wheelDelta/120:i.detail&&(n=i.detail>0?1:-1),e.zoom(-n*a,i)))},cropStart:function(t){var e,i,a,n=this,o=n.options,r=T(t),l=r.touches;if(!n.disabled){if(l){if(e=l.length,e>1){if(!o.zoomable||!o.zoomOnTouch||2!==e)return;i=l[1],n.startX2=i.pageX,n.startY2=i.pageY,a=Nt}i=l[0]}if(a=a||b(r.target,Tt),mt.test(a)){if(h(o.cropstart)&&o.cropstart.call(n.element,{originalEvent:r,action:a})===!1)return;B(r),n.action=a,n.cropping=!1,n.startX=i?i.pageX:r.pageX,n.startY=i?i.pageY:r.pageY,a===zt&&(n.cropping=!0,m(n.dragBox,tt))}}},cropMove:function(t){var e,i,a=this,n=a.options,o=T(t),r=o.touches,l=a.action;if(!a.disabled){if(r){if(e=r.length,e>1){if(!n.zoomable||!n.zoomOnTouch||2!==e)return;i=r[1],a.endX2=i.pageX,a.endY2=i.pageY}i=r[0]}if(l){if(h(n.cropmove)&&n.cropmove.call(a.element,{originalEvent:o,action:l})===!1)return;B(o),a.endX=i?i.pageX:o.pageX,a.endY=i?i.pageY:o.pageY,a.change(o.shiftKey,l===Nt?o:null)}}},cropEnd:function(t){var e=this,i=e.options,a=T(t),n=e.action;e.disabled||n&&(B(a),e.cropping&&(e.cropping=!1,w(e.dragBox,tt,e.cropped&&i.modal)),e.action="",h(i.cropend)&&i.cropend.call(e.element,{originalEvent:a,action:n}))},change:function(t,e){var i,a,n=this,o=n.options,r=o.aspectRatio,h=n.action,l=n.containerData,c=n.canvasData,s=n.cropBoxData,d=s.width,p=s.height,u=s.left,g=s.top,f=u+d,m=g+p,w=0,b=0,x=l.width,D=l.height,C=!0;switch(!r&&t&&(r=d&&p?d/p:1),n.limited&&(w=s.minLeft,b=s.minTop,x=w+It(l.width,c.width),D=b+It(l.height,c.height)),a={x:n.endX-n.startX,y:n.endY-n.startY},r&&(a.X=a.y*r,a.Y=a.x/r),h){case Ot:u+=a.x,g+=a.y;break;case Lt:if(a.x>=0&&(f>=x||r&&(b>=g||m>=D))){C=!1;break}d+=a.x,r&&(p=d/r,g-=a.Y/2),0>d&&(h=Xt,d=0);break;case kt:if(a.y<=0&&(b>=g||r&&(w>=u||f>=x))){C=!1;break}p-=a.y,g+=a.y,r&&(d=p*r,u+=a.X/2),0>p&&(h=Yt,p=0);break;case Xt:if(a.x<=0&&(w>=u||r&&(b>=g||m>=D))){C=!1;break}d-=a.x,u+=a.x,r&&(p=d/r,g+=a.Y/2),0>d&&(h=Lt,d=0);break;case Yt:if(a.y>=0&&(m>=D||r&&(w>=u||f>=x))){C=!1;break}p+=a.y,r&&(d=p*r,u-=a.X/2),0>p&&(h=kt,p=0);break;case Mt:if(r){if(a.y<=0&&(b>=g||f>=x)){C=!1;break}p-=a.y,g+=a.y,d=p*r}else a.x>=0?x>f?d+=a.x:a.y<=0&&b>=g&&(C=!1):d+=a.x,a.y<=0?g>b&&(p-=a.y,g+=a.y):(p-=a.y,g+=a.y);0>d&&0>p?(h=Ht,p=0,d=0):0>d?(h=Et,d=0):0>p&&(h=Wt,p=0);break;case Et:if(r){if(a.y<=0&&(b>=g||w>=u)){C=!1;break}p-=a.y,g+=a.y,d=p*r,u+=a.X}else a.x<=0?u>w?(d-=a.x,u+=a.x):a.y<=0&&b>=g&&(C=!1):(d-=a.x,u+=a.x),a.y<=0?g>b&&(p-=a.y,g+=a.y):(p-=a.y,g+=a.y);0>d&&0>p?(h=Wt,p=0,d=0):0>d?(h=Mt,d=0):0>p&&(h=Ht,p=0);break;case Ht:if(r){if(a.x<=0&&(w>=u||m>=D)){C=!1;break}d-=a.x,u+=a.x,p=d/r}else a.x<=0?u>w?(d-=a.x,u+=a.x):a.y>=0&&m>=D&&(C=!1):(d-=a.x,u+=a.x),a.y>=0?D>m&&(p+=a.y):p+=a.y;0>d&&0>p?(h=Mt,p=0,d=0):0>d?(h=Wt,d=0):0>p&&(h=Et,p=0);break;case Wt:if(r){if(a.x>=0&&(f>=x||m>=D)){C=!1;break}d+=a.x,p=d/r}else a.x>=0?x>f?d+=a.x:a.y>=0&&m>=D&&(C=!1):d+=a.x,a.y>=0?D>m&&(p+=a.y):p+=a.y;0>d&&0>p?(h=Et,p=0,d=0):0>d?(h=Ht,d=0):0>p&&(h=Mt,p=0);break;case Rt:n.move(a.x,a.y),C=!1;break;case Nt:n.zoom(function(t,e,i,a){var n=qt(t*t+e*e),o=qt(i*i+a*a);return(o-n)/n}(_t(n.startX-n.startX2),_t(n.startY-n.startY2),_t(n.endX-n.endX2),_t(n.endY-n.endY2)),e),n.startX2=n.endX2,n.startY2=n.endY2,C=!1;break;case zt:if(!a.x||!a.y){C=!1;break}i=L(n.cropper),u=n.startX-i.left,g=n.startY-i.top,d=s.minWidth,p=s.minHeight,a.x>0?h=a.y>0?Wt:Mt:a.x<0&&(u-=d,h=a.y>0?Ht:Et),a.y<0&&(g-=p),n.cropped||(v(n.cropBox,it),n.cropped=!0,n.limited&&n.limitCropBox(!0,!0))}C&&(s.width=d,s.height=p,s.left=u,s.top=g,n.action=h,n.renderCropBox()),n.startX=n.endX,n.startY=n.endY},crop:function(){var t=this;return t.built&&!t.disabled&&(t.cropped||(t.cropped=!0,t.limitCropBox(!0,!0),t.options.modal&&m(t.dragBox,tt),v(t.cropBox,it)),t.setCropBoxData(t.initialCropBoxData)),t},reset:function(){var t=this;return t.built&&!t.disabled&&(t.imageData=p({},t.initialImageData),t.canvasData=p({},t.initialCanvasData),t.cropBoxData=p({},t.initialCropBoxData),t.renderCanvas(),t.cropped&&t.renderCropBox()),t},clear:function(){var t=this;return t.cropped&&!t.disabled&&(p(t.cropBoxData,{left:0,top:0,width:0,height:0}),t.cropped=!1,t.renderCropBox(),t.limitCanvas(),t.renderCanvas(),v(t.dragBox,tt),m(t.cropBox,it)),t},replace:function(t){var e=this;return!e.disabled&&t&&(e.isImg&&(e.replaced=!0,e.element.src=t),e.options.data=null,e.load(t)),e},enable:function(){var t=this;return t.built&&(t.disabled=!1,v(t.cropper,rt)),t},disable:function(){var t=this;return t.built&&(t.disabled=!0,m(t.cropper,rt)),t},destroy:function(){var t=this,e=t.element,i=t.image;return t.ready?(t.isImg&&t.replaced&&(e.src=t.originalUrl),t.unbuild(),v(e,it)):t.isImg?y(e,ft,t.start):i&&M(i),D(e,Q),t},move:function(t,e){var i=this,a=i.canvasData;return i.moveTo(n(t)?t:a.left+G(t),n(e)?e:a.top+G(e))},moveTo:function(t,e){var i=this,o=i.canvasData,r=!1;return n(e)&&(e=t),t=G(t),e=G(e),i.built&&!i.disabled&&i.options.movable&&(a(t)&&(o.left=t,r=!0),a(e)&&(o.top=e,r=!0),r&&i.renderCanvas(!0)),i},zoom:function(t,e){var i=this,a=i.canvasData;return t=G(t),t=0>t?1/(1-t):1+t,i.zoomTo(a.width*t/a.naturalWidth,e)},zoomTo:function(t,e){var i,a,n,o,r=this,l=r.options,c=r.canvasData,s=c.width,d=c.height,p=c.naturalWidth,u=c.naturalHeight;if(t=G(t),t>=0&&r.built&&!r.disabled&&l.zoomable){if(i=p*t,a=u*t,h(l.zoom)&&l.zoom.call(r.element,{originalEvent:e,oldRatio:s/p,ratio:i/p})===!1)return r;e?(n=L(r.cropper),o=e.touches?X(e.touches):{pageX:e.pageX,pageY:e.pageY},c.left-=(i-s)*((o.pageX-n.left-c.left)/s),c.top-=(a-d)*((o.pageY-n.top-c.top)/d)):(c.left-=(i-s)/2,c.top-=(a-d)/2),c.width=i,c.height=a,r.renderCanvas(!0)}return r},rotate:function(t){var e=this;return e.rotateTo((e.imageData.rotate||0)+G(t))},rotateTo:function(t){var e=this;return t=G(t),a(t)&&e.built&&!e.disabled&&e.options.rotatable&&(e.imageData.rotate=t%360,e.rotated=!0,e.renderCanvas(!0)),e},scale:function(t,e){var i=this,o=i.imageData,r=!1;return n(e)&&(e=t),t=G(t),e=G(e),i.built&&!i.disabled&&i.options.scalable&&(a(t)&&(o.scaleX=t,r=!0),a(e)&&(o.scaleY=e,r=!0),r&&i.renderImage(!0)),i},scaleX:function(t){var e=this,i=e.imageData.scaleY;return e.scale(t,a(i)?i:1)},scaleY:function(t){var e=this,i=e.imageData.scaleX;return e.scale(a(i)?i:1,t)},getData:function(t){var e,i,a=this,n=a.options,o=a.imageData,r=a.canvasData,h=a.cropBoxData;return a.built&&a.cropped?(i={x:h.left-r.left,y:h.top-r.top,width:h.width,height:h.height},e=o.width/o.naturalWidth,d(i,function(a,n){a/=e,i[n]=t?Ft(a):a})):i={x:0,y:0,width:0,height:0},n.rotatable&&(i.rotate=o.rotate||0),n.scalable&&(i.scaleX=o.scaleX||1,i.scaleY=o.scaleY||1),i},setData:function(t){var e,i,n,o=this,l=o.options,c=o.imageData,s=o.canvasData,d={};return h(t)&&(t=t.call(o.element)),o.built&&!o.disabled&&r(t)&&(l.rotatable&&a(t.rotate)&&t.rotate!==c.rotate&&(c.rotate=t.rotate,o.rotated=e=!0),l.scalable&&(a(t.scaleX)&&t.scaleX!==c.scaleX&&(c.scaleX=t.scaleX,i=!0),a(t.scaleY)&&t.scaleY!==c.scaleY&&(c.scaleY=t.scaleY,i=!0)),e?o.renderCanvas():i&&o.renderImage(),n=c.width/c.naturalWidth,a(t.x)&&(d.left=t.x*n+s.left),a(t.y)&&(d.top=t.y*n+s.top),a(t.width)&&(d.width=t.width*n),a(t.height)&&(d.height=t.height*n),o.setCropBoxData(d)),o},getContainerData:function(){var t=this;return t.built?t.containerData:{}},getImageData:function(){var t=this;return t.ready?t.imageData:{}},getCanvasData:function(){var t=this,e=t.canvasData,i={};return t.built&&d(["left","top","width","height","naturalWidth","naturalHeight"],function(t){i[t]=e[t]}),i},setCanvasData:function(t){var e=this,i=e.canvasData,n=i.aspectRatio;return h(t)&&(t=t.call(e.element)),e.built&&!e.disabled&&r(t)&&(a(t.left)&&(i.left=t.left),a(t.top)&&(i.top=t.top),a(t.width)?(i.width=t.width,i.height=t.width/n):a(t.height)&&(i.height=t.height,i.width=t.height*n),e.renderCanvas(!0)),e},getCropBoxData:function(){var t,e=this,i=e.cropBoxData;return e.built&&e.cropped&&(t={left:i.left,top:i.top,width:i.width,height:i.height}),t||{}},setCropBoxData:function(t){var e,i,n=this,o=n.cropBoxData,l=n.options.aspectRatio;return h(t)&&(t=t.call(n.element)),n.built&&n.cropped&&!n.disabled&&r(t)&&(a(t.left)&&(o.left=t.left),a(t.top)&&(o.top=t.top),a(t.width)&&(e=!0,o.width=t.width),a(t.height)&&(i=!0,o.height=t.height),l&&(e?o.height=o.width/l:i&&(o.width=o.height*l)),n.renderCropBox()),n},getCroppedCanvas:function(t){var e,i,a,n,o,h,l,c,s,d,p,u=this;return u.built&&u.cropped&&At?(r(t)||(t={}),p=u.getData(),e=p.width,i=p.height,c=e/i,r(t)&&(o=t.width,h=t.height,o?(h=o/c,l=o/e):h&&(o=h*c,l=h/i)),a=Vt(o||e),n=Vt(h||i),s=W("canvas"),s.width=a,s.height=n,d=s.getContext("2d"),t.fillColor&&(d.fillStyle=t.fillColor,d.fillRect(0,0,a,n)),d.drawImage.apply(d,function(){var t,a,n,o,r,h,c=A(u.image,u.imageData),s=c.width,d=c.height,g=[c],f=p.x,m=p.y;return-e>=f||f>s?f=t=n=r=0:0>=f?(n=-f,f=0,t=r=It(s,e+f)):s>=f&&(n=0,t=r=It(e,s-f)),0>=t||-i>=m||m>d?m=a=o=h=0:0>=m?(o=-m,m=0,a=h=It(d,i+m)):d>=m&&(o=0,a=h=It(i,d-m)),g.push(Vt(f),Vt(m),Vt(t),Vt(a)),l&&(n*=l,o*=l,r*=l,h*=l),r>0&&h>0&&g.push(Vt(n),Vt(o),Vt(r),Vt(h)),g}.call(u)),s):void 0},setAspectRatio:function(t){var e=this,i=e.options;return e.disabled||n(t)||(i.aspectRatio=St(0,t)||NaN,e.built&&(e.initCropBox(),e.cropped&&e.renderCropBox())),e},setDragMode:function(t){var e,i,a=this,n=a.options,o=a.dragBox,r=a.face;return a.ready&&!a.disabled&&(e=t===zt,i=n.movable&&t===Rt,t=e||i?t:Ut,x(o,Tt,t),w(o,ot,e),w(o,nt,i),n.cropBoxMovable||(x(r,Tt,t),w(r,ot,e),w(r,nt,i))),a}},j.DEFAULTS={viewMode:0,dragMode:"crop",aspectRatio:NaN,data:null,preview:"",responsive:!0,restore:!0,checkCrossOrigin:!0,checkOrientation:!0,modal:!0,guides:!0,center:!0,highlight:!0,background:!0,autoCrop:!0,autoCropArea:.8,movable:!0,rotatable:!0,scalable:!0,zoomable:!0,zoomOnTouch:!0,zoomOnWheel:!0,wheelZoomRatio:.1,cropBoxMovable:!0,cropBoxResizable:!0,toggleDragModeOnDblclick:!0,minCanvasWidth:0,minCanvasHeight:0,minCropBoxWidth:0,minCropBoxHeight:0,minContainerWidth:200,minContainerHeight:100,build:null,built:null,cropstart:null,cropmove:null,cropend:null,crop:null,zoom:null},j.TEMPLATE=function(t,e){return e=e.split(","),t.replace(/\d+/g,function(t){return e[t]})}('<0 6="5-container"><0 6="5-wrap-9"><0 6="5-canvas"><0 6="5-drag-9"><0 6="5-crop-9"><1 6="5-view-9"><1 6="5-8 8-h"><1 6="5-8 8-v"><1 6="5-center"><1 6="5-face"><1 6="5-7 7-e" 3-2="e"><1 6="5-7 7-n" 3-2="n"><1 6="5-7 7-w" 3-2="w"><1 6="5-7 7-s" 3-2="s"><1 6="5-4 4-e" 3-2="e"><1 6="5-4 4-n" 3-2="n"><1 6="5-4 4-w" 3-2="w"><1 6="5-4 4-s" 3-2="s"><1 6="5-4 4-ne" 3-2="ne"><1 6="5-4 4-nw" 3-2="nw"><1 6="5-4 4-sw" 3-2="sw"><1 6="5-4 4-se" 3-2="se">',"div,span,action,data,point,cropper,class,line,dashed,box");var te=t.Cropper;return j.noConflict=function(){return t.Cropper=te,j},j.setDefaults=function(t){p(j.DEFAULTS,t)},"function"==typeof define&&define.amd&&define("cropper",[],function(){return j}),e||(t.Cropper=j),j}); \ No newline at end of file diff --git a/web/static/plugs/datepicker/css/foundation-datepicker.min.css b/web/static/plugs/datepicker/css/foundation-datepicker.min.css new file mode 100644 index 00000000..edbaab2f --- /dev/null +++ b/web/static/plugs/datepicker/css/foundation-datepicker.min.css @@ -0,0 +1 @@ +.datepicker{display:none;position:absolute;padding:4px;margin-top:1px;direction:ltr}.datepicker.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;float:left;display:none;min-width:160px;list-style:none;background-color:#fff;border:1px solid rgba(0,0,0,.2);-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;color:#333;font-size:13px;line-height:18px}.datepicker.dropdown-menu td,.datepicker.dropdown-menu th{padding:4px 5px}.datepicker table{border:0;margin:0;width:auto}.datepicker table tr td span{display:block;width:23%;height:54px;line-height:54px;float:left;margin:1%;cursor:pointer}.datepicker td,.datepicker th{text-align:center;width:20px;height:20px;border:0;font-size:12px;padding:4px 8px;cursor:pointer}.datepicker td{background:#fff}.datepicker td span.active,.datepicker td.active.day,.datepicker td.active.year{background:#2ba6cb}.datepicker td.new,.datepicker td.old{color:#999}.datepicker td.day.disabled{color:#eee}.datepicker th{background:#fff}.datepicker th span.active,.datepicker th.active.day,.datepicker th.active.year{background:#2ba6cb}.datepicker th.date-switch{width:145px}.datepicker .cw{font-size:10px;width:12px;padding:0 2px 0 5px;vertical-align:middle}.datepicker.days div.datepicker-days,.datepicker.months div.datepicker-months,.datepicker.years div.datepicker-years{display:block}.datepicker-dropdown:after,.datepicker-dropdown:before{content:'';display:inline-block;position:absolute}.datepicker thead tr:first-child th{cursor:pointer}.datepicker thead tr:first-child th.cw{cursor:default;background-color:transparent}.datepicker tfoot tr:first-child th{cursor:pointer}.datepicker-inline{width:220px}.datepicker-rtl{direction:rtl}.datepicker-rtl table tr td span{float:right}.datepicker-dropdown{top:0;left:0}.datepicker-dropdown:before{border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:1px solid rgba(0,0,0,.2);top:-7px;left:6px}.datepicker-dropdown:after{border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;top:-6px;left:7px}.datepicker-dropdown::after,.datepicker-dropdown::before,.datepicker>div{display:none}.datepicker-close{position:absolute;top:-30px;right:0;width:15px;height:30px;padding:0;display:none}.table-striped .datepicker table tr td,.table-striped .datepicker table tr th{background-color:transparent} \ No newline at end of file diff --git a/web/static/plugs/datepicker/js/foundation-datepicker.js b/web/static/plugs/datepicker/js/foundation-datepicker.js new file mode 100644 index 00000000..f607c535 --- /dev/null +++ b/web/static/plugs/datepicker/js/foundation-datepicker.js @@ -0,0 +1,1325 @@ +/* ========================================================= + * foundation-datepicker.js + * Copyright 2015 Peter Beno, najlepsiwebdesigner@gmail.com, @benopeter + * project website http://foundation-datepicker.peterbeno.com + * ========================================================= */ +! function($) { + + function UTCDate() { + return new Date(Date.UTC.apply(Date, arguments)); + } + + function UTCToday() { + var today = new Date(); + return UTCDate(today.getUTCFullYear(), today.getUTCMonth(), today.getUTCDate()); + } + + var Datepicker = function(element, options) { + var that = this; + + this.element = $(element); + this.autoShow = options.autoShow || true; + this.appendTo = options.appendTo || 'body'; + this.closeButton = options.closeButton; + this.language = options.language || this.element.data('date-language') || "zh-CN"; + this.language = this.language in dates ? this.language : this.language.split('-')[0]; //Check if "de-DE" style date is available, if not language should fallback to 2 letter code eg "de" + this.language = this.language in dates ? this.language : "zh-CN"; + this.isRTL = dates[this.language].rtl || false; + this.format = DPGlobal.parseFormat(options.format || this.element.data('date-format') || dates[this.language].format || 'mm/dd/yyyy'); + this.isInline = false; + this.isInput = this.element.is('input'); + this.component = this.element.is('.date') ? this.element.find('.prefix, .postfix') : false; + this.hasInput = this.component && this.element.find('input').length; + this.disableDblClickSelection = options.disableDblClickSelection; + this.onRender = options.onRender || function() {}; + if (this.component && this.component.length === 0) { + this.component = false; + } + this.linkField = options.linkField || this.element.data('link-field') || false; + this.linkFormat = DPGlobal.parseFormat(options.linkFormat || this.element.data('link-format') || 'yyyy-mm-dd hh:ii:ss'); + this.minuteStep = options.minuteStep || this.element.data('minute-step') || 5; + this.pickerPosition = options.pickerPosition || this.element.data('picker-position') || 'bottom-right'; + + this._attachEvents(); + + + this.minView = 0; + if ('minView' in options) { + this.minView = options.minView; + } else if ('minView' in this.element.data()) { + this.minView = this.element.data('min-view'); + } + this.minView = DPGlobal.convertViewMode(this.minView); + + this.maxView = DPGlobal.modes.length - 1; + if ('maxView' in options) { + this.maxView = options.maxView; + } else if ('maxView' in this.element.data()) { + this.maxView = this.element.data('max-view'); + } + this.maxView = DPGlobal.convertViewMode(this.maxView); + + this.startViewMode = 'month'; + if ('startView' in options) { + this.startViewMode = options.startView; + } else if ('startView' in this.element.data()) { + this.startViewMode = this.element.data('start-view'); + } + this.startViewMode = DPGlobal.convertViewMode(this.startViewMode); + this.viewMode = this.startViewMode; + + if (!('minView' in options) && !('maxView' in options) && !(this.element.data('min-view') && !(this.element.data('max-view')))) { + this.pickTime = false; + if ('pickTime' in options) { + this.pickTime = options.pickTime; + } + if (this.pickTime == true) { + this.minView = 0; + this.maxView = 4; + } else { + this.minView = 2; + this.maxView = 4; + } + } + + this.forceParse = true; + if ('forceParse' in options) { + this.forceParse = options.forceParse; + } else if ('dateForceParse' in this.element.data()) { + this.forceParse = this.element.data('date-force-parse'); + } + + + this.picker = $(DPGlobal.template) + .appendTo(this.isInline ? this.element : this.appendTo) + .on({ + click: $.proxy(this.click, this), + mousedown: $.proxy(this.mousedown, this) + }); + if (this.closeButton) { + this.picker.find('a.datepicker-close').show(); + } else { + this.picker.find('a.datepicker-close').hide(); + } + + if (this.isInline) { + this.picker.addClass('datepicker-inline'); + } else { + this.picker.addClass('datepicker-dropdown dropdown-menu'); + } + if (this.isRTL) { + this.picker.addClass('datepicker-rtl'); + this.picker.find('.prev i, .next i') + .toggleClass('fa fa-chevron-left fa-chevron-right').toggleClass('fa-chevron-left fa-chevron-right'); + } + $(document).on('mousedown', function(e) { + // Clicked outside the datepicker, hide it + if ($(e.target).closest('.datepicker.datepicker-inline, .datepicker.datepicker-dropdown').length === 0) { + that.hide(); + } + }); + + this.autoclose = true; + if ('autoclose' in options) { + this.autoclose = options.autoclose; + } else if ('dateAutoclose' in this.element.data()) { + this.autoclose = this.element.data('date-autoclose'); + } + + this.keyboardNavigation = true; + if ('keyboardNavigation' in options) { + this.keyboardNavigation = options.keyboardNavigation; + } else if ('dateKeyboardNavigation' in this.element.data()) { + this.keyboardNavigation = this.element.data('date-keyboard-navigation'); + } + + this.todayBtn = (options.todayBtn || this.element.data('date-today-btn') || false); + this.todayHighlight = (options.todayHighlight || this.element.data('date-today-highlight') || false); + + this.calendarWeeks = false; + if ('calendarWeeks' in options) { + this.calendarWeeks = options.calendarWeeks; + } else if ('dateCalendarWeeks' in this.element.data()) { + this.calendarWeeks = this.element.data('date-calendar-weeks'); + } + if (this.calendarWeeks) + this.picker.find('tfoot th.today') + .attr('colspan', function(i, val) { + return parseInt(val) + 1; + }); + + this.weekStart = ((options.weekStart || this.element.data('date-weekstart') || dates[this.language].weekStart || 0) % 7); + this.weekEnd = ((this.weekStart + 6) % 7); + this.startDate = -Infinity; + this.endDate = Infinity; + this.daysOfWeekDisabled = []; + this.setStartDate(options.startDate || this.element.data('date-startdate')); + this.setEndDate(options.endDate || this.element.data('date-enddate')); + this.setDaysOfWeekDisabled(options.daysOfWeekDisabled || this.element.data('date-days-of-week-disabled')); + + this.fillDow(); + this.fillMonths(); + this.update(); + + this.showMode(); + + if (this.isInline) { + this.show(); + } + }; + + Datepicker.prototype = { + constructor: Datepicker, + + _events: [], + _attachEvents: function() { + this._detachEvents(); + if (this.isInput) { // single input + this._events = [ + [this.element, { + focus: (this.autoShow) ? $.proxy(this.show, this) : function() {}, + keyup: $.proxy(this.update, this), + keydown: $.proxy(this.keydown, this) + }] + ]; + } else if (this.component && this.hasInput) { // component: input + button + this._events = [ + // For components that are not readonly, allow keyboard nav + [this.element.find('input'), { + focus: (this.autoShow) ? $.proxy(this.show, this) : function() {}, + keyup: $.proxy(this.update, this), + keydown: $.proxy(this.keydown, this) + }], + [this.component, { + click: $.proxy(this.show, this) + }] + ]; + } else if (this.element.is('div')) { // inline datepicker + this.isInline = true; + } else { + this._events = [ + [this.element, { + click: $.proxy(this.show, this) + }] + ]; + } + + if (this.disableDblClickSelection) { + this._events[this._events.length] = [ + this.element, { + dblclick: function(e) { + e.preventDefault(); + e.stopPropagation(); + $(this).blur() + } + } + ]; + } + + for (var i = 0, el, ev; i < this._events.length; i++) { + el = this._events[i][0]; + ev = this._events[i][1]; + el.on(ev); + } + }, + _detachEvents: function() { + for (var i = 0, el, ev; i < this._events.length; i++) { + el = this._events[i][0]; + ev = this._events[i][1]; + el.off(ev); + } + this._events = []; + }, + + show: function(e) { + this.picker.show(); + this.height = this.component ? this.component.outerHeight() : this.element.outerHeight(); + this.update(); + this.place(); + $(window).on('resize', $.proxy(this.place, this)); + if (e) { + e.stopPropagation(); + e.preventDefault(); + } + this.element.trigger({ + type: 'show', + date: this.date + }); + }, + + hide: function(e) { + if (this.isInline) return; + if (!this.picker.is(':visible')) return; + this.picker.hide(); + $(window).off('resize', this.place); + this.viewMode = this.startViewMode; + this.showMode(); + if (!this.isInput) { + $(document).off('mousedown', this.hide); + } + + if ( + this.forceParse && + ( + this.isInput && this.element.val() || + this.hasInput && this.element.find('input').val() + ) + ) + this.setValue(); + this.element.trigger({ + type: 'hide', + date: this.date + }); + }, + + remove: function() { + this._detachEvents(); + this.picker.remove(); + delete this.element.data().datepicker; + }, + + getDate: function() { + var d = this.getUTCDate(); + return new Date(d.getTime() + (d.getTimezoneOffset() * 60000)); + }, + + getUTCDate: function() { + return this.date; + }, + + setDate: function(d) { + this.setUTCDate(new Date(d.getTime() - (d.getTimezoneOffset() * 60000))); + }, + + setUTCDate: function(d) { + this.date = d; + this.setValue(); + }, + + setValue: function() { + var formatted = this.getFormattedDate(); + if (!this.isInput) { + if (this.component) { + this.element.find('input').val(formatted); + } + this.element.data('date', formatted); + } else { + this.element.val(formatted); + } + }, + + getFormattedDate: function(format) { + if (format === undefined) + format = this.format; + return DPGlobal.formatDate(this.date, format, this.language); + }, + + setStartDate: function(startDate) { + this.startDate = startDate || -Infinity; + if (this.startDate !== -Infinity) { + this.startDate = DPGlobal.parseDate(this.startDate, this.format, this.language); + } + this.update(); + this.updateNavArrows(); + }, + + setEndDate: function(endDate) { + this.endDate = endDate || Infinity; + if (this.endDate !== Infinity) { + this.endDate = DPGlobal.parseDate(this.endDate, this.format, this.language); + } + this.update(); + this.updateNavArrows(); + }, + + setDaysOfWeekDisabled: function(daysOfWeekDisabled) { + this.daysOfWeekDisabled = daysOfWeekDisabled || []; + if (!$.isArray(this.daysOfWeekDisabled)) { + this.daysOfWeekDisabled = this.daysOfWeekDisabled.split(/,\s*/); + } + this.daysOfWeekDisabled = $.map(this.daysOfWeekDisabled, function(d) { + return parseInt(d, 10); + }); + this.update(); + this.updateNavArrows(); + }, + + place: function() { + if (this.isInline) return; + var zIndex = parseInt(this.element.parents().filter(function() { + return $(this).css('z-index') != 'auto'; + }).first().css('z-index')) + 10; + var textbox = this.component ? this.component : this.element; + var offset = textbox.offset(); + var height = textbox.outerHeight() + parseInt(textbox.css('margin-top')); + var width = textbox.outerWidth() + parseInt(textbox.css('margin-left')); + var fullOffsetTop = offset.top + height; + var offsetLeft = offset.left; + // if the datepicker is going to be below the window, show it on top of the input + if ((fullOffsetTop + this.picker.outerHeight()) >= $(window).scrollTop() + $(window).height()) { + fullOffsetTop = offset.top - this.picker.outerHeight(); + } + + // if the datepicker is going to go past the right side of the window, we want + // to set the right position so the datepicker lines up with the textbox + if (offset.left + this.picker.width() >= $(window).width()) { + offsetLeft = (offset.left + width) - this.picker.width(); + } + this.picker.css({ + top: fullOffsetTop, + left: offsetLeft, + zIndex: zIndex + }); + }, + + update: function() { + var date, fromArgs = false; + if (arguments && arguments.length && (typeof arguments[0] === 'string' || arguments[0] instanceof Date)) { + date = arguments[0]; + fromArgs = true; + } else { + date = this.isInput ? this.element.val() : this.element.data('date') || this.element.find('input').val(); + } + + this.date = DPGlobal.parseDate(date, this.format, this.language); + + if (fromArgs) this.setValue(); + + if (this.date < this.startDate) { + this.viewDate = new Date(this.startDate.valueOf()); + } else if (this.date > this.endDate) { + this.viewDate = new Date(this.endDate.valueOf()); + } else { + this.viewDate = new Date(this.date.valueOf()); + } + this.fill(); + }, + + fillDow: function() { + var dowCnt = this.weekStart, + html = ''; + if (this.calendarWeeks) { + var cell = ' '; + html += cell; + this.picker.find('.datepicker-days thead tr:first-child').prepend(cell); + } + while (dowCnt < this.weekStart + 7) { + html += '' + dates[this.language].daysMin[(dowCnt++) % 7] + ''; + } + html += ''; + this.picker.find('.datepicker-days thead').append(html); + }, + + fillMonths: function() { + var html = '', + i = 0; + while (i < 12) { + html += '' + dates[this.language].monthsShort[i++] + ''; + } + this.picker.find('.datepicker-months td').html(html); + }, + + fill: function() { + if (this.date == null || this.viewDate == null) { + return; + } + + var d = new Date(this.viewDate.valueOf()), + year = d.getUTCFullYear(), + month = d.getUTCMonth(), + dayMonth = d.getUTCDate(), + hours = d.getUTCHours(), + minutes = d.getUTCMinutes(), + startYear = this.startDate !== -Infinity ? this.startDate.getUTCFullYear() : -Infinity, + startMonth = this.startDate !== -Infinity ? this.startDate.getUTCMonth() : -Infinity, + endYear = this.endDate !== Infinity ? this.endDate.getUTCFullYear() : Infinity, + endMonth = this.endDate !== Infinity ? this.endDate.getUTCMonth() : Infinity, + currentDate = this.date && this.date.valueOf(), + today = new Date(), + titleFormat = dates[this.language].titleFormat || dates['en'].titleFormat; + // this.picker.find('.datepicker-days thead th.date-switch') + // .text(DPGlobal.formatDate(new UTCDate(year, month), titleFormat, this.language)); + + this.picker.find('.datepicker-days thead th:eq(1)') + .text(dates[this.language].months[month] + ' ' + year); + this.picker.find('.datepicker-hours thead th:eq(1)') + .text(dayMonth + ' ' + dates[this.language].months[month] + ' ' + year); + this.picker.find('.datepicker-minutes thead th:eq(1)') + .text(dayMonth + ' ' + dates[this.language].months[month] + ' ' + year); + + + this.picker.find('tfoot th.today') + .text(dates[this.language].today) + .toggle(this.todayBtn !== false); + this.updateNavArrows(); + this.fillMonths(); + var prevMonth = UTCDate(year, month - 1, 28, 0, 0, 0, 0), + day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth()); + prevMonth.setUTCDate(day); + prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.weekStart + 7) % 7); + var nextMonth = new Date(prevMonth.valueOf()); + nextMonth.setUTCDate(nextMonth.getUTCDate() + 42); + nextMonth = nextMonth.valueOf(); + var html = []; + var clsName; + while (prevMonth.valueOf() < nextMonth) { + if (prevMonth.getUTCDay() == this.weekStart) { + html.push(''); + if (this.calendarWeeks) { + // adapted from https://github.com/timrwood/moment/blob/master/moment.js#L128 + var a = new Date(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth(), prevMonth.getUTCDate() - prevMonth.getDay() + 10 - (this.weekStart && this.weekStart % 7 < 5 && 7)), + b = new Date(a.getFullYear(), 0, 4), + calWeek = ~~((a - b) / 864e5 / 7 + 1.5); + html.push('' + calWeek + ''); + } + } + clsName = ' ' + this.onRender(prevMonth) + ' '; + if (prevMonth.getUTCFullYear() < year || (prevMonth.getUTCFullYear() == year && prevMonth.getUTCMonth() < month)) { + clsName += ' old'; + } else if (prevMonth.getUTCFullYear() > year || (prevMonth.getUTCFullYear() == year && prevMonth.getUTCMonth() > month)) { + clsName += ' new'; + } + // Compare internal UTC date with local today, not UTC today + if (this.todayHighlight && + prevMonth.getUTCFullYear() == today.getFullYear() && + prevMonth.getUTCMonth() == today.getMonth() && + prevMonth.getUTCDate() == today.getDate()) { + clsName += ' today'; + } + if (currentDate && prevMonth.valueOf() == currentDate) { + clsName += ' active'; + } + if (prevMonth.valueOf() < this.startDate || prevMonth.valueOf() > this.endDate || + $.inArray(prevMonth.getUTCDay(), this.daysOfWeekDisabled) !== -1) { + clsName += ' disabled'; + } + html.push('' + prevMonth.getUTCDate() + ''); + if (prevMonth.getUTCDay() == this.weekEnd) { + html.push(''); + } + prevMonth.setUTCDate(prevMonth.getUTCDate() + 1); + } + this.picker.find('.datepicker-days tbody').empty().append(html.join('')); + + html = []; + for (var i = 0; i < 24; i++) { + var actual = UTCDate(year, month, dayMonth, i); + clsName = ''; + // We want the previous hour for the startDate + if ((actual.valueOf() + 3600000) < this.startDate || actual.valueOf() > this.endDate) { + clsName += ' disabled'; + } else if (hours == i) { + clsName += ' active'; + } + html.push('' + i + ':00'); + } + this.picker.find('.datepicker-hours td').html(html.join('')); + + html = []; + for (var i = 0; i < 60; i += this.minuteStep) { + var actual = UTCDate(year, month, dayMonth, hours, i); + clsName = ''; + if (actual.valueOf() < this.startDate || actual.valueOf() > this.endDate) { + clsName += ' disabled'; + } else if (Math.floor(minutes / this.minuteStep) == Math.floor(i / this.minuteStep)) { + clsName += ' active'; + } + html.push('' + hours + ':' + (i < 10 ? '0' + i : i) + ''); + } + this.picker.find('.datepicker-minutes td').html(html.join('')); + + + var currentYear = this.date && this.date.getUTCFullYear(); + var months = this.picker.find('.datepicker-months') + .find('th:eq(1)') + .text(year) + .end() + .find('span').removeClass('active'); + if (currentYear && currentYear == year) { + months.eq(this.date.getUTCMonth()).addClass('active'); + } + if (year < startYear || year > endYear) { + months.addClass('disabled'); + } + if (year == startYear) { + months.slice(0, startMonth).addClass('disabled'); + } + if (year == endYear) { + months.slice(endMonth + 1).addClass('disabled'); + } + + html = ''; + year = parseInt(year / 10, 10) * 10; + var yearCont = this.picker.find('.datepicker-years') + .find('th:eq(1)') + .text(year + '-' + (year + 9)) + .end() + .find('td'); + year -= 1; + for (var i = -1; i < 11; i++) { + html += '' + year + ''; + year += 1; + } + yearCont.html(html); + }, + + updateNavArrows: function() { + var d = new Date(this.viewDate), + year = d.getUTCFullYear(), + month = d.getUTCMonth(), + day = d.getUTCDate(), + hour = d.getUTCHours(); + switch (this.viewMode) { + case 0: + if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear() && month <= this.startDate.getUTCMonth() && day <= this.startDate.getUTCDate() && hour <= this.startDate.getUTCHours()) { + this.picker.find('.prev').css({ + visibility: 'hidden' + }); + } else { + this.picker.find('.prev').css({ + visibility: 'visible' + }); + } + if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear() && month >= this.endDate.getUTCMonth() && day >= this.endDate.getUTCDate() && hour >= this.endDate.getUTCHours()) { + this.picker.find('.next').css({ + visibility: 'hidden' + }); + } else { + this.picker.find('.next').css({ + visibility: 'visible' + }); + } + break; + case 1: + if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear() && month <= this.startDate.getUTCMonth() && day <= this.startDate.getUTCDate()) { + this.picker.find('.prev').css({ + visibility: 'hidden' + }); + } else { + this.picker.find('.prev').css({ + visibility: 'visible' + }); + } + if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear() && month >= this.endDate.getUTCMonth() && day >= this.endDate.getUTCDate()) { + this.picker.find('.next').css({ + visibility: 'hidden' + }); + } else { + this.picker.find('.next').css({ + visibility: 'visible' + }); + } + break; + case 2: + if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear() && month <= this.startDate.getUTCMonth()) { + this.picker.find('.prev').css({ + visibility: 'hidden' + }); + } else { + this.picker.find('.prev').css({ + visibility: 'visible' + }); + } + if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear() && month >= this.endDate.getUTCMonth()) { + this.picker.find('.next').css({ + visibility: 'hidden' + }); + } else { + this.picker.find('.next').css({ + visibility: 'visible' + }); + } + break; + case 3: + case 4: + if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear()) { + this.picker.find('.prev').css({ + visibility: 'hidden' + }); + } else { + this.picker.find('.prev').css({ + visibility: 'visible' + }); + } + if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear()) { + this.picker.find('.next').css({ + visibility: 'hidden' + }); + } else { + this.picker.find('.next').css({ + visibility: 'visible' + }); + } + break; + } + }, + + click: function(e) { + e.stopPropagation(); + e.preventDefault(); + + if ($(e.target).hasClass('datepicker-close') || $(e.target).parent().hasClass('datepicker-close')) { + this.hide(); + } + + var target = $(e.target).closest('span, td, th'); + if (target.length == 1) { + if (target.is('.disabled')) { + this.element.trigger({ + type: 'outOfRange', + date: this.viewDate, + startDate: this.startDate, + endDate: this.endDate + }); + return; + } + + switch (target[0].nodeName.toLowerCase()) { + case 'th': + switch (target[0].className) { + case 'date-switch': + this.showMode(1); + break; + case 'prev': + case 'next': + var dir = DPGlobal.modes[this.viewMode].navStep * (target[0].className == 'prev' ? -1 : 1); + switch (this.viewMode) { + case 0: + this.viewDate = this.moveHour(this.viewDate, dir); + break; + case 1: + this.viewDate = this.moveDate(this.viewDate, dir); + break; + case 2: + this.viewDate = this.moveMonth(this.viewDate, dir); + break; + case 3: + case 4: + this.viewDate = this.moveYear(this.viewDate, dir); + break; + } + this.fill(); + break; + case 'today': + var date = new Date(); + date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds()); + + this.viewMode = this.startViewMode; + this.showMode(0); + this._setDate(date); + break; + } + break; + case 'span': + if (!target.is('.disabled')) { + if (target.is('.month')) { + this.viewDate.setUTCDate(1); + var month = target.parent().find('span').index(target); + this.viewDate.setUTCMonth(month); + this.element.trigger({ + type: 'changeMonth', + date: this.viewDate + }); + } else if (target.is('.year')) { + this.viewDate.setUTCDate(1); + var year = parseInt(target.text(), 10) || 0; + this.viewDate.setUTCFullYear(year); + this.element.trigger({ + type: 'changeYear', + date: this.viewDate + }); + } else if (target.is('.hour')) { + var hours = parseInt(target.text(), 10) || 0; + var year = this.viewDate.getUTCFullYear(), + month = this.viewDate.getUTCMonth(), + day = this.viewDate.getUTCDate(), + minutes = this.viewDate.getUTCMinutes(), + seconds = this.viewDate.getUTCSeconds(); + this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0)); + } else if (target.is('.minute')) { + var minutes = parseInt(target.text().substr(target.text().indexOf(':') + 1), 10) || 0; + var year = this.viewDate.getUTCFullYear(), + month = this.viewDate.getUTCMonth(), + day = this.viewDate.getUTCDate(), + hours = this.viewDate.getUTCHours(), + seconds = this.viewDate.getUTCSeconds(); + this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0)); + } + + + + if (this.viewMode != 0) { + + + + var oldViewMode = this.viewMode; + this.showMode(-1); + this.fill(); + if (oldViewMode == this.viewMode && this.autoclose) { + this.hide(); + } + } else { + this.fill(); + if (this.autoclose) { + this.hide(); + } + } + } + break; + case 'td': + + + + if (target.is('.day') && !target.is('.disabled')) { + var day = parseInt(target.text(), 10) || 1; + var year = this.viewDate.getUTCFullYear(), + month = this.viewDate.getUTCMonth(), + hours = this.viewDate.getUTCHours(), + minutes = this.viewDate.getUTCMinutes(), + seconds = this.viewDate.getUTCSeconds(); + if (target.is('.old')) { + if (month === 0) { + month = 11; + year -= 1; + } else { + month -= 1; + } + } else if (target.is('.new')) { + if (month == 11) { + month = 0; + year += 1; + } else { + month += 1; + } + } + this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0)); + } + + + + var oldViewMode = this.viewMode; + + + this.showMode(-1); + + + this.fill(); + if (oldViewMode == this.viewMode && this.autoclose) { + this.hide(); + } + break; + } + } + }, + + _setDate: function(date, which) { + + if (!which || which == 'date') + this.date = date; + if (!which || which == 'view') + this.viewDate = date; + this.fill(); + this.setValue(); + this.element.trigger({ + type: 'changeDate', + date: this.date + }); + var element; + if (this.isInput) { + element = this.element; + } else if (this.component) { + element = this.element.find('input'); + } + if (element) { + element.change(); + if (this.autoclose && (!which || which == 'date')) { + // this.hide(); + } + } + }, + + moveHour: function(date, dir) { + if (!dir) return date; + var new_date = new Date(date.valueOf()); + dir = dir > 0 ? 1 : -1; + new_date.setUTCHours(new_date.getUTCHours() + dir); + return new_date; + }, + + moveDate: function(date, dir) { + if (!dir) return date; + var new_date = new Date(date.valueOf()); + dir = dir > 0 ? 1 : -1; + new_date.setUTCDate(new_date.getUTCDate() + dir); + return new_date; + }, + + moveMonth: function(date, dir) { + if (!dir) return date; + var new_date = new Date(date.valueOf()), + day = new_date.getUTCDate(), + month = new_date.getUTCMonth(), + mag = Math.abs(dir), + new_month, test; + dir = dir > 0 ? 1 : -1; + if (mag == 1) { + test = dir == -1 + // If going back one month, make sure month is not current month + // (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02) + ? function() { + return new_date.getUTCMonth() == month; + } + // If going forward one month, make sure month is as expected + // (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02) + : function() { + return new_date.getUTCMonth() != new_month; + }; + new_month = month + dir; + new_date.setUTCMonth(new_month); + // Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11 + if (new_month < 0 || new_month > 11) + new_month = (new_month + 12) % 12; + } else { + // For magnitudes >1, move one month at a time... + for (var i = 0; i < mag; i++) + // ...which might decrease the day (eg, Jan 31 to Feb 28, etc)... + new_date = this.moveMonth(new_date, dir); + // ...then reset the day, keeping it in the new month + new_month = new_date.getUTCMonth(); + new_date.setUTCDate(day); + test = function() { + return new_month != new_date.getUTCMonth(); + }; + } + // Common date-resetting loop -- if date is beyond end of month, make it + // end of month + while (test()) { + new_date.setUTCDate(--day); + new_date.setUTCMonth(new_month); + } + return new_date; + }, + + moveYear: function(date, dir) { + return this.moveMonth(date, dir * 12); + }, + + dateWithinRange: function(date) { + return date >= this.startDate && date <= this.endDate; + }, + + keydown: function(e) { + if (this.picker.is(':not(:visible)')) { + if (e.keyCode == 27) // allow escape to hide and re-show picker + this.show(); + return; + } + var dateChanged = false, + dir, day, month, + newDate, newViewDate; + switch (e.keyCode) { + case 27: // escape + this.hide(); + e.preventDefault(); + break; + case 37: // left + case 39: // right + if (!this.keyboardNavigation) break; + dir = e.keyCode == 37 ? -1 : 1; + if (e.ctrlKey) { + newDate = this.moveYear(this.date, dir); + newViewDate = this.moveYear(this.viewDate, dir); + } else if (e.shiftKey) { + newDate = this.moveMonth(this.date, dir); + newViewDate = this.moveMonth(this.viewDate, dir); + } else { + newDate = new Date(this.date.valueOf()); + newDate.setUTCDate(this.date.getUTCDate() + dir); + newViewDate = new Date(this.viewDate.valueOf()); + newViewDate.setUTCDate(this.viewDate.getUTCDate() + dir); + } + if (this.dateWithinRange(newDate)) { + this.date = newDate; + this.viewDate = newViewDate; + this.setValue(); + this.update(); + e.preventDefault(); + dateChanged = true; + } + break; + case 38: // up + case 40: // down + if (!this.keyboardNavigation) break; + dir = e.keyCode == 38 ? -1 : 1; + if (e.ctrlKey) { + newDate = this.moveYear(this.date, dir); + newViewDate = this.moveYear(this.viewDate, dir); + } else if (e.shiftKey) { + newDate = this.moveMonth(this.date, dir); + newViewDate = this.moveMonth(this.viewDate, dir); + } else { + newDate = new Date(this.date.valueOf()); + newDate.setUTCDate(this.date.getUTCDate() + dir * 7); + newViewDate = new Date(this.viewDate.valueOf()); + newViewDate.setUTCDate(this.viewDate.getUTCDate() + dir * 7); + } + if (this.dateWithinRange(newDate)) { + this.date = newDate; + this.viewDate = newViewDate; + this.setValue(); + this.update(); + e.preventDefault(); + dateChanged = true; + } + break; + case 13: // enter + this.hide(); + e.preventDefault(); + break; + case 9: // tab + this.hide(); + break; + } + if (dateChanged) { + this.element.trigger({ + type: 'changeDate', + date: this.date + }); + var element; + if (this.isInput) { + element = this.element; + } else if (this.component) { + element = this.element.find('input'); + } + if (element) { + element.change(); + } + } + }, + + showMode: function(dir) { + + if (dir) { + var newViewMode = Math.max(0, Math.min(DPGlobal.modes.length - 1, this.viewMode + dir)); + if (newViewMode >= this.minView && newViewMode <= this.maxView) { + this.viewMode = newViewMode; + } + } + /* + vitalets: fixing bug of very special conditions: + jquery 1.7.1 + webkit + show inline datepicker in bootstrap popover. + Method show() does not set display css correctly and datepicker is not shown. + Changed to .css('display', 'block') solve the problem. + See https://github.com/vitalets/x-editable/issues/37 + + In jquery 1.7.2+ everything works fine. + */ + //this.picker.find('>div').hide().filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName).show(); + this.picker.find('>div').hide().filter('.datepicker-' + DPGlobal.modes[this.viewMode].clsName).css('display', 'block'); + this.updateNavArrows(); + }, + reset: function(e) { + this._setDate(null, 'date'); + } + }; + + $.fn.fdatepicker = function(option) { + var args = Array.apply(null, arguments); + args.shift(); + return this.each(function() { + var $this = $(this), + data = $this.data('datepicker'), + options = typeof option == 'object' && option; + if (!data) { + $this.data('datepicker', (data = new Datepicker(this, $.extend({}, $.fn.fdatepicker.defaults, options)))); + } + if (typeof option == 'string' && typeof data[option] == 'function') { + data[option].apply(data, args); + } + }); + }; + + $.fn.fdatepicker.defaults = { + onRender: function(date) { + return ''; + } + }; + $.fn.fdatepicker.Constructor = Datepicker; + var dates = $.fn.fdatepicker.dates = { + 'en': { + days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], + daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], + daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"], + months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], + monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], + today: "Today", + titleFormat: "MM yyyy" + } + }; + + var DPGlobal = { + modes: [{ + clsName: 'minutes', + navFnc: 'Hours', + navStep: 1 + }, { + clsName: 'hours', + navFnc: 'Date', + navStep: 1 + }, { + clsName: 'days', + navFnc: 'Month', + navStep: 1 + }, { + clsName: 'months', + navFnc: 'FullYear', + navStep: 1 + }, { + clsName: 'years', + navFnc: 'FullYear', + navStep: 10 + }], + isLeapYear: function(year) { + return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)); + }, + getDaysInMonth: function(year, month) { + return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]; + }, + validParts: /hh?|ii?|ss?|dd?|mm?|MM?|yy(?:yy)?/g, + nonpunctuation: /[^ -\/:-@\[\u3400-\u9fff-`{-~\t\n\r]+/g, + parseFormat: function(format) { + // IE treats \0 as a string end in inputs (truncating the value), + // so it's a bad format delimiter, anyway + var separators = format.replace(this.validParts, '\0').split('\0'), + parts = format.match(this.validParts); + if (!separators || !separators.length || !parts || parts.length === 0) { + throw new Error("Invalid date format."); + } + return { + separators: separators, + parts: parts + }; + }, + parseDate: function(date, format, language) { + if (date instanceof Date) return new Date(date.valueOf() - date.getTimezoneOffset() * 60000); + if (/^\d{4}\-\d{1,2}\-\d{1,2}$/.test(date)) { + format = this.parseFormat('yyyy-mm-dd'); + } + if (/^\d{4}\-\d{1,2}\-\d{1,2}[T ]\d{1,2}\:\d{1,2}$/.test(date)) { + format = this.parseFormat('yyyy-mm-dd hh:ii'); + } + if (/^\d{4}\-\d{1,2}\-\d{1,2}[T ]\d{1,2}\:\d{1,2}\:\d{1,2}[Z]{0,1}$/.test(date)) { + format = this.parseFormat('yyyy-mm-dd hh:ii:ss'); + } + if (/^[-+]\d+[dmwy]([\s,]+[-+]\d+[dmwy])*$/.test(date)) { + var part_re = /([-+]\d+)([dmwy])/, + parts = date.match(/([-+]\d+)([dmwy])/g), + part, dir; + date = new Date(); + for (var i = 0; i < parts.length; i++) { + part = part_re.exec(parts[i]); + dir = parseInt(part[1]); + switch (part[2]) { + case 'd': + date.setUTCDate(date.getUTCDate() + dir); + break; + case 'm': + date = Datetimepicker.prototype.moveMonth.call(Datetimepicker.prototype, date, dir); + break; + case 'w': + date.setUTCDate(date.getUTCDate() + dir * 7); + break; + case 'y': + date = Datetimepicker.prototype.moveYear.call(Datetimepicker.prototype, date, dir); + break; + } + } + return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()); + } + var parts = date && date.match(this.nonpunctuation) || [], + date = new Date(), + parsed = {}, + setters_order = ['hh', 'h', 'ii', 'i', 'ss', 's', 'yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'], + setters_map = { + hh: function(d, v) { + return d.setUTCHours(v); + }, + h: function(d, v) { + return d.setUTCHours(v); + }, + ii: function(d, v) { + return d.setUTCMinutes(v); + }, + i: function(d, v) { + return d.setUTCMinutes(v); + }, + ss: function(d, v) { + return d.setUTCSeconds(v); + }, + s: function(d, v) { + return d.setUTCSeconds(v); + }, + yyyy: function(d, v) { + return d.setUTCFullYear(v); + }, + yy: function(d, v) { + return d.setUTCFullYear(2000 + v); + }, + m: function(d, v) { + v -= 1; + while (v < 0) v += 12; + v %= 12; + d.setUTCMonth(v); + while (d.getUTCMonth() != v) + d.setUTCDate(d.getUTCDate() - 1); + return d; + }, + d: function(d, v) { + return d.setUTCDate(v); + } + }, + val, filtered, part; + setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m']; + setters_map['dd'] = setters_map['d']; + date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0); //date.getHours(), date.getMinutes(), date.getSeconds()); + if (parts.length == format.parts.length) { + for (var i = 0, cnt = format.parts.length; i < cnt; i++) { + val = parseInt(parts[i], 10); + part = format.parts[i]; + if (isNaN(val)) { + switch (part) { + case 'MM': + filtered = $(dates[language].months).filter(function() { + var m = this.slice(0, parts[i].length), + p = parts[i].slice(0, m.length); + return m == p; + }); + val = $.inArray(filtered[0], dates[language].months) + 1; + break; + case 'M': + filtered = $(dates[language].monthsShort).filter(function() { + var m = this.slice(0, parts[i].length), + p = parts[i].slice(0, m.length); + return m == p; + }); + val = $.inArray(filtered[0], dates[language].monthsShort) + 1; + break; + } + } + parsed[part] = val; + } + for (var i = 0, s; i < setters_order.length; i++) { + s = setters_order[i]; + if (s in parsed && !isNaN(parsed[s])) + setters_map[s](date, parsed[s]) + } + } + return date; + }, + formatDate: function(date, format, language) { + if (date == null) { + return ''; + } + var val = { + h: date.getUTCHours(), + i: date.getUTCMinutes(), + s: date.getUTCSeconds(), + d: date.getUTCDate(), + m: date.getUTCMonth() + 1, + M: dates[language].monthsShort[date.getUTCMonth()], + MM: dates[language].months[date.getUTCMonth()], + yy: date.getUTCFullYear().toString().substring(2), + yyyy: date.getUTCFullYear() + }; + val.hh = (val.h < 10 ? '0' : '') + val.h; + val.ii = (val.i < 10 ? '0' : '') + val.i; + val.ss = (val.s < 10 ? '0' : '') + val.s; + val.dd = (val.d < 10 ? '0' : '') + val.d; + val.mm = (val.m < 10 ? '0' : '') + val.m; + var date = [], + seps = $.extend([], format.separators); + for (var i = 0, cnt = format.parts.length; i < cnt; i++) { + if (seps.length) + date.push(seps.shift()) + date.push(val[format.parts[i]]); + } + return date.join(''); + }, + convertViewMode: function(viewMode) { + switch (viewMode) { + case 4: + case 'decade': + viewMode = 4; + break; + case 3: + case 'year': + viewMode = 3; + break; + case 2: + case 'month': + viewMode = 2; + break; + case 1: + case 'day': + viewMode = 1; + break; + case 0: + case 'hour': + viewMode = 0; + break; + } + + return viewMode; + }, + headTemplate: '' + + '' + + '' + + '' + + '' + + '' + + '', + contTemplate: '', + footTemplate: '' + }; + DPGlobal.template = '
' + + '
' + + '' + + DPGlobal.headTemplate + + DPGlobal.contTemplate + + DPGlobal.footTemplate + + '
' + + '
' + + '
' + + '' + + DPGlobal.headTemplate + + DPGlobal.contTemplate + + DPGlobal.footTemplate + + '
' + + '
' + + '
' + + '' + + DPGlobal.headTemplate + + '' + + DPGlobal.footTemplate + + '
' + + '
' + + '
' + + '' + + DPGlobal.headTemplate + + DPGlobal.contTemplate + + DPGlobal.footTemplate + + '
' + + '
' + + '
' + + '' + + DPGlobal.headTemplate + + DPGlobal.contTemplate + + DPGlobal.footTemplate + + '
' + + '
' + + '' + + '
'; + + $.fn.fdatepicker.DPGlobal = DPGlobal; + +}(window.jQuery); \ No newline at end of file diff --git a/web/static/plugs/datepicker/js/foundation-datepicker.zh-CN.js b/web/static/plugs/datepicker/js/foundation-datepicker.zh-CN.js new file mode 100644 index 00000000..ca2e255a --- /dev/null +++ b/web/static/plugs/datepicker/js/foundation-datepicker.zh-CN.js @@ -0,0 +1,14 @@ +/** + * Simplified Chinese translation for foundation-datepicker + * Yuan Cheung + */ +;(function($){ + $.fn.fdatepicker.dates['zh-CN'] = { + days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"], + daysShort: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"], + daysMin: ["日", "一", "二", "三", "四", "五", "六"], + months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], + monthsShort: ["一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"], + today: '今天' + }; +}(jQuery)); diff --git a/web/static/plugs/flot/jquery.flot.axislabels.js b/web/static/plugs/flot/jquery.flot.axislabels.js new file mode 100644 index 00000000..68339289 --- /dev/null +++ b/web/static/plugs/flot/jquery.flot.axislabels.js @@ -0,0 +1,39 @@ +(function($){var options={axisLabels:{show:true}};function canvasSupported(){return!!document.createElement('canvas').getContext;} +function canvasTextSupported(){if(!canvasSupported()){return false;} +var dummy_canvas=document.createElement('canvas');var context=dummy_canvas.getContext('2d');return typeof context.fillText=='function';} +function css3TransitionSupported(){var div=document.createElement('div');return typeof div.style.MozTransition!='undefined'||typeof div.style.OTransition!='undefined'||typeof div.style.webkitTransition!='undefined'||typeof div.style.transition!='undefined';} +function AxisLabel(axisName,position,padding,plot,opts){this.axisName=axisName;this.position=position;this.padding=padding;this.plot=plot;this.opts=opts;this.width=0;this.height=0;} +AxisLabel.prototype.cleanup=function(){};CanvasAxisLabel.prototype=new AxisLabel();CanvasAxisLabel.prototype.constructor=CanvasAxisLabel;function CanvasAxisLabel(axisName,position,padding,plot,opts){AxisLabel.prototype.constructor.call(this,axisName,position,padding,plot,opts);} +CanvasAxisLabel.prototype.calculateSize=function(){if(!this.opts.axisLabelFontSizePixels) +this.opts.axisLabelFontSizePixels=14;if(!this.opts.axisLabelFontFamily) +this.opts.axisLabelFontFamily='sans-serif';var textWidth=this.opts.axisLabelFontSizePixels+ this.padding;var textHeight=this.opts.axisLabelFontSizePixels+ this.padding;if(this.position=='left'||this.position=='right'){this.width=this.opts.axisLabelFontSizePixels+ this.padding;this.height=0;}else{this.width=0;this.height=this.opts.axisLabelFontSizePixels+ this.padding;}};CanvasAxisLabel.prototype.draw=function(box){if(!this.opts.axisLabelColour) +this.opts.axisLabelColour='black';var ctx=this.plot.getCanvas().getContext('2d');ctx.save();ctx.font=this.opts.axisLabelFontSizePixels+'px '+ +this.opts.axisLabelFontFamily;ctx.fillStyle=this.opts.axisLabelColour;var width=ctx.measureText(this.opts.axisLabel).width;var height=this.opts.axisLabelFontSizePixels;var x,y,angle=0;if(this.position=='top'){x=box.left+ box.width/2- width/2;y=box.top+ height*0.72;}else if(this.position=='bottom'){x=box.left+ box.width/2- width/2;y=box.top+ box.height- height*0.72;}else if(this.position=='left'){x=box.left+ height*0.72;y=box.height/2+ box.top+ width/2;angle=-Math.PI/2;}else if(this.position=='right'){x=box.left+ box.width- height*0.72;y=box.height/2+ box.top- width/2;angle=Math.PI/2;} +ctx.translate(x,y);ctx.rotate(angle);ctx.fillText(this.opts.axisLabel,0,0);ctx.restore();};HtmlAxisLabel.prototype=new AxisLabel();HtmlAxisLabel.prototype.constructor=HtmlAxisLabel;function HtmlAxisLabel(axisName,position,padding,plot,opts){AxisLabel.prototype.constructor.call(this,axisName,position,padding,plot,opts);this.elem=null;} +HtmlAxisLabel.prototype.calculateSize=function(){var elem=$('
'+ +this.opts.axisLabel+'
');this.plot.getPlaceholder().append(elem);this.labelWidth=elem.outerWidth(true);this.labelHeight=elem.outerHeight(true);elem.remove();this.width=this.height=0;if(this.position=='left'||this.position=='right'){this.width=this.labelWidth+ this.padding;}else{this.height=this.labelHeight+ this.padding;}};HtmlAxisLabel.prototype.cleanup=function(){if(this.elem){this.elem.remove();}};HtmlAxisLabel.prototype.draw=function(box){this.plot.getPlaceholder().find('#'+ this.axisName+'Label').remove();this.elem=$('
' ++ this.opts.axisLabel+'
');this.plot.getPlaceholder().append(this.elem);if(this.position=='top'){this.elem.css('left',box.left+ box.width/2- this.labelWidth/2+'px');this.elem.css('top',box.top+'px');}else if(this.position=='bottom'){this.elem.css('left',box.left+ box.width/2- this.labelWidth/2+'px');this.elem.css('top',box.top+ box.height- this.labelHeight+'px');}else if(this.position=='left'){this.elem.css('top',box.top+ box.height/2- this.labelHeight/2+'px');this.elem.css('left',box.left+'px');}else if(this.position=='right'){this.elem.css('top',box.top+ box.height/2- this.labelHeight/2+'px');this.elem.css('left',box.left+ box.width- this.labelWidth+'px');}};CssTransformAxisLabel.prototype=new HtmlAxisLabel();CssTransformAxisLabel.prototype.constructor=CssTransformAxisLabel;function CssTransformAxisLabel(axisName,position,padding,plot,opts){HtmlAxisLabel.prototype.constructor.call(this,axisName,position,padding,plot,opts);} +CssTransformAxisLabel.prototype.calculateSize=function(){HtmlAxisLabel.prototype.calculateSize.call(this);this.width=this.height=0;if(this.position=='left'||this.position=='right'){this.width=this.labelHeight+ this.padding;}else{this.height=this.labelHeight+ this.padding;}};CssTransformAxisLabel.prototype.transforms=function(degrees,x,y){var stransforms={'-moz-transform':'','-webkit-transform':'','-o-transform':'','-ms-transform':''};if(x!=0||y!=0){var stdTranslate=' translate('+ x+'px, '+ y+'px)';stransforms['-moz-transform']+=stdTranslate;stransforms['-webkit-transform']+=stdTranslate;stransforms['-o-transform']+=stdTranslate;stransforms['-ms-transform']+=stdTranslate;} +if(degrees!=0){var rotation=degrees/90;var stdRotate=' rotate('+ degrees+'deg)';stransforms['-moz-transform']+=stdRotate;stransforms['-webkit-transform']+=stdRotate;stransforms['-o-transform']+=stdRotate;stransforms['-ms-transform']+=stdRotate;} +var s='top: 0; left: 0; ';for(var prop in stransforms){if(stransforms[prop]){s+=prop+':'+ stransforms[prop]+';';}} +s+=';';return s;};CssTransformAxisLabel.prototype.calculateOffsets=function(box){var offsets={x:0,y:0,degrees:0};if(this.position=='bottom'){offsets.x=box.left+ box.width/2- this.labelWidth/2;offsets.y=box.top+ box.height- this.labelHeight;}else if(this.position=='top'){offsets.x=box.left+ box.width/2- this.labelWidth/2;offsets.y=box.top;}else if(this.position=='left'){offsets.degrees=-90;offsets.x=box.left- this.labelWidth/2+ this.labelHeight/2;offsets.y=box.height/2+ box.top;}else if(this.position=='right'){offsets.degrees=90;offsets.x=box.left+ box.width- this.labelWidth/2 +- this.labelHeight/2;offsets.y=box.height/2+ box.top;} +return offsets;};CssTransformAxisLabel.prototype.draw=function(box){this.plot.getPlaceholder().find("."+ this.axisName+"Label").remove();var offsets=this.calculateOffsets(box);this.elem=$('
'+ this.opts.axisLabel+'
');this.plot.getPlaceholder().append(this.elem);};IeTransformAxisLabel.prototype=new CssTransformAxisLabel();IeTransformAxisLabel.prototype.constructor=IeTransformAxisLabel;function IeTransformAxisLabel(axisName,position,padding,plot,opts){CssTransformAxisLabel.prototype.constructor.call(this,axisName,position,padding,plot,opts);this.requiresResize=false;} +IeTransformAxisLabel.prototype.transforms=function(degrees,x,y){var s='';if(degrees!=0){var rotation=degrees/90;while(rotation<0){rotation+=4;} +s+=' filter: progid:DXImageTransform.Microsoft.BasicImage(rotation='+ rotation+'); ';this.requiresResize=(this.position=='right');} +if(x!=0){s+='left: '+ x+'px; ';} +if(y!=0){s+='top: '+ y+'px; ';} +return s;};IeTransformAxisLabel.prototype.calculateOffsets=function(box){var offsets=CssTransformAxisLabel.prototype.calculateOffsets.call(this,box);if(this.position=='top'){offsets.y=box.top+ 1;}else if(this.position=='left'){offsets.x=box.left;offsets.y=box.height/2+ box.top- this.labelWidth/2;}else if(this.position=='right'){offsets.x=box.left+ box.width- this.labelHeight;offsets.y=box.height/2+ box.top- this.labelWidth/2;} +return offsets;};IeTransformAxisLabel.prototype.draw=function(box){CssTransformAxisLabel.prototype.draw.call(this,box);if(this.requiresResize){this.elem=this.plot.getPlaceholder().find("."+ this.axisName+"Label");this.elem.css('width',this.labelWidth);this.elem.css('height',this.labelHeight);}};function init(plot){plot.hooks.processOptions.push(function(plot,options){if(!options.axisLabels.show) +return;var secondPass=false;var axisLabels={};var axisOffsetCounts={left:0,right:0,top:0,bottom:0};var defaultPadding=2;plot.hooks.draw.push(function(plot,ctx){var hasAxisLabels=false;if(!secondPass){$.each(plot.getAxes(),function(axisName,axis){var opts=axis.options||plot.getOptions()[axisName];if(axisName in axisLabels){axis.labelHeight=axis.labelHeight- +axisLabels[axisName].height;axis.labelWidth=axis.labelWidth- +axisLabels[axisName].width;opts.labelHeight=axis.labelHeight;opts.labelWidth=axis.labelWidth;axisLabels[axisName].cleanup();delete axisLabels[axisName];} +if(!opts||!opts.axisLabel||!axis.show) +return;hasAxisLabels=true;var renderer=null;if(!opts.axisLabelUseHtml&&navigator.appName=='Microsoft Internet Explorer'){var ua=navigator.userAgent;var re=new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");if(re.exec(ua)!=null){rv=parseFloat(RegExp.$1);} +if(rv>=9&&!opts.axisLabelUseCanvas&&!opts.axisLabelUseHtml){renderer=CssTransformAxisLabel;}else if(!opts.axisLabelUseCanvas&&!opts.axisLabelUseHtml){renderer=IeTransformAxisLabel;}else if(opts.axisLabelUseCanvas){renderer=CanvasAxisLabel;}else{renderer=HtmlAxisLabel;}}else{if(opts.axisLabelUseHtml||(!css3TransitionSupported()&&!canvasTextSupported())&&!opts.axisLabelUseCanvas){renderer=HtmlAxisLabel;}else if(opts.axisLabelUseCanvas||!css3TransitionSupported()){renderer=CanvasAxisLabel;}else{renderer=CssTransformAxisLabel;}} +var padding=opts.axisLabelPadding===undefined?defaultPadding:opts.axisLabelPadding;axisLabels[axisName]=new renderer(axisName,axis.position,padding,plot,opts);axisLabels[axisName].calculateSize();opts.labelHeight=axis.labelHeight+ +axisLabels[axisName].height;opts.labelWidth=axis.labelWidth+ +axisLabels[axisName].width;});if(hasAxisLabels){secondPass=true;plot.setupGrid();plot.draw();}}else{secondPass=false;$.each(plot.getAxes(),function(axisName,axis){var opts=axis.options||plot.getOptions()[axisName];if(!opts||!opts.axisLabel||!axis.show) +return;axisLabels[axisName].draw(axis.box);});}});});} +$.plot.plugins.push({init:init,options:options,name:'axisLabels',version:'2.0'});})(jQuery); \ No newline at end of file diff --git a/web/static/plugs/flot/jquery.flot.js b/web/static/plugs/flot/jquery.flot.js new file mode 100644 index 00000000..05c26524 --- /dev/null +++ b/web/static/plugs/flot/jquery.flot.js @@ -0,0 +1,427 @@ +(function(B){B.color={};B.color.make=function(F,E,C,D){var G={};G.r=F||0;G.g=E||0;G.b=C||0;G.a=D!=null?D:1;G.add=function(J,I){for(var H=0;H=1){return"rgb("+[G.r,G.g,G.b].join(",")+")"}else{return"rgba("+[G.r,G.g,G.b,G.a].join(",")+")"}};G.normalize=function(){function H(J,K,I){return KI?I:K)}G.r=H(0,parseInt(G.r),255);G.g=H(0,parseInt(G.g),255);G.b=H(0,parseInt(G.b),255);G.a=H(0,G.a,1);return G};G.clone=function(){return B.color.make(G.r,G.b,G.g,G.a)};return G.normalize()};B.color.extract=function(D,C){var E;do{E=D.css(C).toLowerCase();if(E!=""&&E!="transparent"){break}D=D.parent()}while(!B.nodeName(D.get(0),"body"));if(E=="rgba(0, 0, 0, 0)"){E="transparent"}return B.color.parse(E)};B.color.parse=function(F){var E,C=B.color.make;if(E=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10))}if(E=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10),parseFloat(E[4]))}if(E=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55)}if(E=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55,parseFloat(E[4]))}if(E=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(F)){return C(parseInt(E[1],16),parseInt(E[2],16),parseInt(E[3],16))}if(E=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(F)){return C(parseInt(E[1]+E[1],16),parseInt(E[2]+E[2],16),parseInt(E[3]+E[3],16))}var D=B.trim(F).toLowerCase();if(D=="transparent"){return C(255,255,255,0)}else{E=A[D]||[0,0,0];return C(E[0],E[1],E[2])}};var A={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery);(function($){var hasOwnProperty=Object.prototype.hasOwnProperty;function Canvas(cls,container){var element=container.children("."+ cls)[0];if(element==null){element=document.createElement("canvas");element.className=cls;$(element).css({direction:"ltr",position:"absolute",left:0,top:0}).appendTo(container);if(!element.getContext){if(window.G_vmlCanvasManager){element=window.G_vmlCanvasManager.initElement(element);}else{throw new Error("Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode.");}}} +this.element=element;var context=this.context=element.getContext("2d");var devicePixelRatio=window.devicePixelRatio||1,backingStoreRatio=context.webkitBackingStorePixelRatio||context.mozBackingStorePixelRatio||context.msBackingStorePixelRatio||context.oBackingStorePixelRatio||context.backingStorePixelRatio||1;this.pixelRatio=devicePixelRatio/backingStoreRatio;this.resize(container.width(),container.height());this.textContainer=null;this.text={};this._textCache={};} +Canvas.prototype.resize=function(width,height){if(width<=0||height<=0){throw new Error("Invalid dimensions for plot, width = "+ width+", height = "+ height);} +var element=this.element,context=this.context,pixelRatio=this.pixelRatio;if(this.width!=width){element.width=width*pixelRatio;element.style.width=width+"px";this.width=width;} +if(this.height!=height){element.height=height*pixelRatio;element.style.height=height+"px";this.height=height;} +context.restore();context.save();context.scale(pixelRatio,pixelRatio);};Canvas.prototype.clear=function(){this.context.clearRect(0,0,this.width,this.height);};Canvas.prototype.render=function(){var cache=this._textCache;for(var layerKey in cache){if(hasOwnProperty.call(cache,layerKey)){var layer=this.getTextLayer(layerKey),layerCache=cache[layerKey];layer.hide();for(var styleKey in layerCache){if(hasOwnProperty.call(layerCache,styleKey)){var styleCache=layerCache[styleKey];for(var key in styleCache){if(hasOwnProperty.call(styleCache,key)){var positions=styleCache[key].positions;for(var i=0,position;position=positions[i];i++){if(position.active){if(!position.rendered){layer.append(position.element);position.rendered=true;}}else{positions.splice(i--,1);if(position.rendered){position.element.detach();}}} +if(positions.length==0){delete styleCache[key];}}}}} +layer.show();}}};Canvas.prototype.getTextLayer=function(classes){var layer=this.text[classes];if(layer==null){if(this.textContainer==null){this.textContainer=$("
").css({position:"absolute",top:0,left:0,bottom:0,right:0,'font-size':"smaller",color:"#545454"}).insertAfter(this.element);} +layer=this.text[classes]=$("
").addClass(classes).css({position:"absolute",top:0,left:0,bottom:0,right:0}).appendTo(this.textContainer);} +return layer;};Canvas.prototype.getTextInfo=function(layer,text,font,angle,width){var textStyle,layerCache,styleCache,info;text=""+ text;if(typeof font==="object"){textStyle=font.style+" "+ font.variant+" "+ font.weight+" "+ font.size+"px/"+ font.lineHeight+"px "+ font.family;}else{textStyle=font;} +layerCache=this._textCache[layer];if(layerCache==null){layerCache=this._textCache[layer]={};} +styleCache=layerCache[textStyle];if(styleCache==null){styleCache=layerCache[textStyle]={};} +info=styleCache[text];if(info==null){var element=$("
").html(text).css({position:"absolute",'max-width':width,top:-9999}).appendTo(this.getTextLayer(layer));if(typeof font==="object"){element.css({font:textStyle,color:font.color});}else if(typeof font==="string"){element.addClass(font);} +info=styleCache[text]={width:element.outerWidth(true),height:element.outerHeight(true),element:element,positions:[]};element.detach();} +return info;};Canvas.prototype.addText=function(layer,x,y,text,font,angle,width,halign,valign){var info=this.getTextInfo(layer,text,font,angle,width),positions=info.positions;if(halign=="center"){x-=info.width/2;}else if(halign=="right"){x-=info.width;} +if(valign=="middle"){y-=info.height/2;}else if(valign=="bottom"){y-=info.height;} +for(var i=0,position;position=positions[i];i++){if(position.x==x&&position.y==y){position.active=true;return;}} +position={active:true,rendered:false,element:positions.length?info.element.clone():info.element,x:x,y:y} +positions.push(position);position.element.css({top:Math.round(y),left:Math.round(x),'text-align':halign});};Canvas.prototype.removeText=function(layer,x,y,text,font,angle){if(text==null){var layerCache=this._textCache[layer];if(layerCache!=null){for(var styleKey in layerCache){if(hasOwnProperty.call(layerCache,styleKey)){var styleCache=layerCache[styleKey];for(var key in styleCache){if(hasOwnProperty.call(styleCache,key)){var positions=styleCache[key].positions;for(var i=0,position;position=positions[i];i++){position.active=false;}}}}}}}else{var positions=this.getTextInfo(layer,text,font,angle).positions;for(var i=0,position;position=positions[i];i++){if(position.x==x&&position.y==y){position.active=false;}}}};function Plot(placeholder,data_,options_,plugins){var series=[],options={colors:["#edc240","#afd8f8","#cb4b4b","#4da74d","#9440ed"],legend:{show:true,noColumns:1,labelFormatter:null,labelBoxBorderColor:"#ccc",container:null,position:"ne",margin:5,backgroundColor:null,backgroundOpacity:0.85,sorted:null},xaxis:{show:null,position:"bottom",mode:null,font:null,color:null,tickColor:null,transform:null,inverseTransform:null,min:null,max:null,autoscaleMargin:null,ticks:null,tickFormatter:null,labelWidth:null,labelHeight:null,reserveSpace:null,tickLength:null,alignTicksWithAxis:null,tickDecimals:null,tickSize:null,minTickSize:null},yaxis:{autoscaleMargin:0.02,position:"left"},xaxes:[],yaxes:[],series:{points:{show:false,radius:3,lineWidth:2,fill:true,fillColor:"#ffffff",symbol:"circle"},lines:{lineWidth:2,fill:false,fillColor:null,steps:false},bars:{show:false,lineWidth:2,barWidth:1,fill:true,fillColor:null,align:"left",horizontal:false,zero:true},shadowSize:3,highlightColor:null},grid:{show:true,aboveData:false,color:"#545454",backgroundColor:null,borderColor:null,tickColor:null,margin:0,labelMargin:5,axisMargin:8,borderWidth:2,minBorderMargin:null,markings:null,markingsColor:"#f4f4f4",markingsLineWidth:2,clickable:false,hoverable:false,autoHighlight:true,mouseActiveRadius:10},interaction:{redrawOverlayInterval:1000/60},hooks:{}},surface=null,overlay=null,eventHolder=null,ctx=null,octx=null,xaxes=[],yaxes=[],plotOffset={left:0,right:0,top:0,bottom:0},plotWidth=0,plotHeight=0,hooks={processOptions:[],processRawData:[],processDatapoints:[],processOffset:[],drawBackground:[],drawSeries:[],draw:[],bindEvents:[],drawOverlay:[],shutdown:[]},plot=this;plot.setData=setData;plot.setupGrid=setupGrid;plot.draw=draw;plot.getPlaceholder=function(){return placeholder;};plot.getCanvas=function(){return surface.element;};plot.getPlotOffset=function(){return plotOffset;};plot.width=function(){return plotWidth;};plot.height=function(){return plotHeight;};plot.offset=function(){var o=eventHolder.offset();o.left+=plotOffset.left;o.top+=plotOffset.top;return o;};plot.getData=function(){return series;};plot.getAxes=function(){var res={},i;$.each(xaxes.concat(yaxes),function(_,axis){if(axis) +res[axis.direction+(axis.n!=1?axis.n:"")+"axis"]=axis;});return res;};plot.getXAxes=function(){return xaxes;};plot.getYAxes=function(){return yaxes;};plot.c2p=canvasToAxisCoords;plot.p2c=axisToCanvasCoords;plot.getOptions=function(){return options;};plot.highlight=highlight;plot.unhighlight=unhighlight;plot.triggerRedrawOverlay=triggerRedrawOverlay;plot.pointOffset=function(point){return{left:parseInt(xaxes[axisNumber(point,"x")- 1].p2c(+point.x)+ plotOffset.left,10),top:parseInt(yaxes[axisNumber(point,"y")- 1].p2c(+point.y)+ plotOffset.top,10)};};plot.shutdown=shutdown;plot.resize=function(){var width=placeholder.width(),height=placeholder.height();surface.resize(width,height);overlay.resize(width,height);};plot.hooks=hooks;initPlugins(plot);parseOptions(options_);setupCanvases();setData(data_);setupGrid();draw();bindEvents();function executeHooks(hook,args){args=[plot].concat(args);for(var i=0;imaxIndex){maxIndex=sc;}}} +if(neededColors<=maxIndex){neededColors=maxIndex+ 1;} +var c,colors=[],colorPool=options.colors,colorPoolSize=colorPool.length,variation=0;for(i=0;i=0){if(variation<0.5){variation=-variation- 0.2;}else variation=0;}else variation=-variation;} +colors[i]=c.scale('rgb',1+ variation);} +var colori=0,s;for(i=0;iaxis.datamax&&max!=fakeInfinity) +axis.datamax=max;} +$.each(allAxes(),function(_,axis){axis.datamin=topSentry;axis.datamax=bottomSentry;axis.used=false;});for(i=0;i0&&points[k- ps]!=null&&points[k- ps]!=points[k]&&points[k- ps+ 1]!=points[k+ 1]){for(m=0;mxmax) +xmax=val;} +if(f.y){if(valymax) +ymax=val;}}} +if(s.bars.show){var delta;switch(s.bars.align){case"left":delta=0;break;case"right":delta=-s.bars.barWidth;break;case"center":delta=-s.bars.barWidth/2;break;default:throw new Error("Invalid bar alignment: "+ s.bars.align);} +if(s.bars.horizontal){ymin+=delta;ymax+=delta+ s.bars.barWidth;} +else{xmin+=delta;xmax+=delta+ s.bars.barWidth;}} +updateAxis(s.xaxis,xmin,xmax);updateAxis(s.yaxis,ymin,ymax);} +$.each(allAxes(),function(_,axis){if(axis.datamin==topSentry) +axis.datamin=null;if(axis.datamax==bottomSentry) +axis.datamax=null;});} +function setupCanvases(){placeholder.css("padding",0).children(":not(.flot-base,.flot-overlay)").remove();if(placeholder.css("position")=='static') +placeholder.css("position","relative");surface=new Canvas("flot-base",placeholder);overlay=new Canvas("flot-overlay",placeholder);ctx=surface.context;octx=overlay.context;eventHolder=$(overlay.element).unbind();var existing=placeholder.data("plot");if(existing){existing.shutdown();overlay.clear();} +placeholder.data("plot",plot);} +function bindEvents(){if(options.grid.hoverable){eventHolder.mousemove(onMouseMove);eventHolder.bind("mouseleave",onMouseLeave);} +if(options.grid.clickable) +eventHolder.click(onClick);executeHooks(hooks.bindEvents,[eventHolder]);} +function shutdown(){if(redrawTimeout) +clearTimeout(redrawTimeout);eventHolder.unbind("mousemove",onMouseMove);eventHolder.unbind("mouseleave",onMouseLeave);eventHolder.unbind("click",onClick);executeHooks(hooks.shutdown,[eventHolder]);} +function setTransformationHelpers(axis){function identity(x){return x;} +var s,m,t=axis.options.transform||identity,it=axis.options.inverseTransform;if(axis.direction=="x"){s=axis.scale=plotWidth/Math.abs(t(axis.max)- t(axis.min));m=Math.min(t(axis.max),t(axis.min));} +else{s=axis.scale=plotHeight/Math.abs(t(axis.max)- t(axis.min));s=-s;m=Math.max(t(axis.max),t(axis.min));} +if(t==identity) +axis.p2c=function(p){return(p- m)*s;};else +axis.p2c=function(p){return(t(p)- m)*s;};if(!it) +axis.c2p=function(c){return m+ c/s;};else +axis.c2p=function(c){return it(m+ c/s);};} +function measureTickLabels(axis){var opts=axis.options,ticks=axis.ticks||[],labelWidth=opts.labelWidth||0,labelHeight=opts.labelHeight||0,maxWidth=labelWidth||axis.direction=="x"?Math.floor(surface.width/(ticks.length||1)):null;legacyStyles=axis.direction+"Axis "+ axis.direction+ axis.n+"Axis",layer="flot-"+ axis.direction+"-axis flot-"+ axis.direction+ axis.n+"-axis "+ legacyStyles,font=opts.font||"flot-tick-label tickLabel";for(var i=0;i=0;--i) +allocateAxisBoxFirstPhase(allocatedAxes[i]);adjustLayoutForThingsStickingOut();$.each(allocatedAxes,function(_,axis){allocateAxisBoxSecondPhase(axis);});} +plotWidth=surface.width- plotOffset.left- plotOffset.right;plotHeight=surface.height- plotOffset.bottom- plotOffset.top;$.each(axes,function(_,axis){setTransformationHelpers(axis);});if(showGrid){drawAxisLabels();} +insertLegend();} +function setRange(axis){var opts=axis.options,min=+(opts.min!=null?opts.min:axis.datamin),max=+(opts.max!=null?opts.max:axis.datamax),delta=max- min;if(delta==0.0){var widen=max==0?1:0.01;if(opts.min==null) +min-=widen;if(opts.max==null||opts.min!=null) +max+=widen;} +else{var margin=opts.autoscaleMargin;if(margin!=null){if(opts.min==null){min-=delta*margin;if(min<0&&axis.datamin!=null&&axis.datamin>=0) +min=0;} +if(opts.max==null){max+=delta*margin;if(max>0&&axis.datamax!=null&&axis.datamax<=0) +max=0;}}} +axis.min=min;axis.max=max;} +function setupTickGeneration(axis){var opts=axis.options;var noTicks;if(typeof opts.ticks=="number"&&opts.ticks>0) +noTicks=opts.ticks;else +noTicks=0.3*Math.sqrt(axis.direction=="x"?surface.width:surface.height);var delta=(axis.max- axis.min)/ noTicks, +dec=-Math.floor(Math.log(delta)/ Math.LN10), +maxDec=opts.tickDecimals;if(maxDec!=null&&dec>maxDec){dec=maxDec;} +var magn=Math.pow(10,-dec),norm=delta/magn,size;if(norm<1.5){size=1;}else if(norm<3){size=2;if(norm>2.25&&(maxDec==null||dec+ 1<=maxDec)){size=2.5;++dec;}}else if(norm<7.5){size=5;}else{size=10;} +size*=magn;if(opts.minTickSize!=null&&size0){if(opts.min==null) +axis.min=Math.min(axis.min,niceTicks[0]);if(opts.max==null&&niceTicks.length>1) +axis.max=Math.max(axis.max,niceTicks[niceTicks.length- 1]);} +axis.tickGenerator=function(axis){var ticks=[],v,i;for(i=0;i1&&/\..*0$/.test((ts[1]- ts[0]).toFixed(extraDec)))) +axis.tickDecimals=extraDec;}}}} +function setTicks(axis){var oticks=axis.options.ticks,ticks=[];if(oticks==null||(typeof oticks=="number"&&oticks>0)) +ticks=axis.tickGenerator(axis);else if(oticks){if($.isFunction(oticks)) +ticks=oticks(axis);else +ticks=oticks;} +var i,v;axis.ticks=[];for(i=0;i1) +label=t[1];} +else +v=+t;if(label==null) +label=axis.tickFormatter(v,axis);if(!isNaN(v)) +axis.ticks.push({v:v,label:label});}} +function snapRangeToTicks(axis,ticks){if(axis.options.autoscaleMargin&&ticks.length>0){if(axis.options.min==null) +axis.min=Math.min(axis.min,ticks[0].v);if(axis.options.max==null&&ticks.length>1) +axis.max=Math.max(axis.max,ticks[ticks.length- 1].v);}} +function draw(){surface.clear();executeHooks(hooks.drawBackground,[ctx]);var grid=options.grid;if(grid.show&&grid.backgroundColor) +drawBackground();if(grid.show&&!grid.aboveData){drawGrid();} +for(var i=0;ito){var tmp=from;from=to;to=tmp;} +return{from:from,to:to,axis:axis};} +function drawBackground(){ctx.save();ctx.translate(plotOffset.left,plotOffset.top);ctx.fillStyle=getColorOrGradient(options.grid.backgroundColor,plotHeight,0,"rgba(255, 255, 255, 0)");ctx.fillRect(0,0,plotWidth,plotHeight);ctx.restore();} +function drawGrid(){var i,axes,bw,bc;ctx.save();ctx.translate(plotOffset.left,plotOffset.top);var markings=options.grid.markings;if(markings){if($.isFunction(markings)){axes=plot.getAxes();axes.xmin=axes.xaxis.min;axes.xmax=axes.xaxis.max;axes.ymin=axes.yaxis.min;axes.ymax=axes.yaxis.max;markings=markings(axes);} +for(i=0;ixrange.axis.max||yrange.toyrange.axis.max) +continue;xrange.from=Math.max(xrange.from,xrange.axis.min);xrange.to=Math.min(xrange.to,xrange.axis.max);yrange.from=Math.max(yrange.from,yrange.axis.min);yrange.to=Math.min(yrange.to,yrange.axis.max);if(xrange.from==xrange.to&&yrange.from==yrange.to) +continue;xrange.from=xrange.axis.p2c(xrange.from);xrange.to=xrange.axis.p2c(xrange.to);yrange.from=yrange.axis.p2c(yrange.from);yrange.to=yrange.axis.p2c(yrange.to);if(xrange.from==xrange.to||yrange.from==yrange.to){ctx.beginPath();ctx.strokeStyle=m.color||options.grid.markingsColor;ctx.lineWidth=m.lineWidth||options.grid.markingsLineWidth;ctx.moveTo(xrange.from,yrange.from);ctx.lineTo(xrange.to,yrange.to);ctx.stroke();} +else{ctx.fillStyle=m.color||options.grid.markingsColor;ctx.fillRect(xrange.from,yrange.to,xrange.to- xrange.from,yrange.from- yrange.to);}}} +axes=allAxes();bw=options.grid.borderWidth;for(var j=0;jaxis.max||(t=="full"&&((typeof bw=="object"&&bw[axis.position]>0)||bw>0)&&(v==axis.min||v==axis.max))) +continue;if(axis.direction=="x"){x=axis.p2c(v);yoff=t=="full"?-plotHeight:t;if(axis.position=="top") +yoff=-yoff;} +else{y=axis.p2c(v);xoff=t=="full"?-plotWidth:t;if(axis.position=="left") +xoff=-xoff;} +if(ctx.lineWidth==1){if(axis.direction=="x") +x=Math.floor(x)+ 0.5;else +y=Math.floor(y)+ 0.5;} +ctx.moveTo(x,y);ctx.lineTo(x+ xoff,y+ yoff);} +ctx.stroke();} +if(bw){bc=options.grid.borderColor;if(typeof bw=="object"||typeof bc=="object"){if(typeof bw!=="object"){bw={top:bw,right:bw,bottom:bw,left:bw};} +if(typeof bc!=="object"){bc={top:bc,right:bc,bottom:bc,left:bc};} +if(bw.top>0){ctx.strokeStyle=bc.top;ctx.lineWidth=bw.top;ctx.beginPath();ctx.moveTo(0- bw.left,0- bw.top/2);ctx.lineTo(plotWidth,0- bw.top/2);ctx.stroke();} +if(bw.right>0){ctx.strokeStyle=bc.right;ctx.lineWidth=bw.right;ctx.beginPath();ctx.moveTo(plotWidth+ bw.right/2,0- bw.top);ctx.lineTo(plotWidth+ bw.right/2,plotHeight);ctx.stroke();} +if(bw.bottom>0){ctx.strokeStyle=bc.bottom;ctx.lineWidth=bw.bottom;ctx.beginPath();ctx.moveTo(plotWidth+ bw.right,plotHeight+ bw.bottom/2);ctx.lineTo(0,plotHeight+ bw.bottom/2);ctx.stroke();} +if(bw.left>0){ctx.strokeStyle=bc.left;ctx.lineWidth=bw.left;ctx.beginPath();ctx.moveTo(0- bw.left/2,plotHeight+ bw.bottom);ctx.lineTo(0- bw.left/2,0);ctx.stroke();}} +else{ctx.lineWidth=bw;ctx.strokeStyle=options.grid.borderColor;ctx.strokeRect(-bw/2,-bw/2,plotWidth+ bw,plotHeight+ bw);}} +ctx.restore();} +function drawAxisLabels(){$.each(allAxes(),function(_,axis){if(!axis.show||axis.ticks.length==0) +return;var box=axis.box,legacyStyles=axis.direction+"Axis "+ axis.direction+ axis.n+"Axis",layer="flot-"+ axis.direction+"-axis flot-"+ axis.direction+ axis.n+"-axis "+ legacyStyles,font=axis.options.font||"flot-tick-label tickLabel",tick,x,y,halign,valign;surface.removeText(layer);for(var i=0;iaxis.max) +continue;if(axis.direction=="x"){halign="center";x=plotOffset.left+ axis.p2c(tick.v);if(axis.position=="bottom"){y=box.top+ box.padding;}else{y=box.top+ box.height- box.padding;valign="bottom";}}else{valign="middle";y=plotOffset.top+ axis.p2c(tick.v);if(axis.position=="left"){x=box.left+ box.width- box.padding;halign="right";}else{x=box.left+ box.padding;}} +surface.addText(layer,x,y,tick.label,font,null,null,halign,valign);}});} +function drawSeries(series){if(series.lines.show) +drawSeriesLines(series);if(series.bars.show) +drawSeriesBars(series);if(series.points.show) +drawSeriesPoints(series);} +function drawSeriesLines(series){function plotLine(datapoints,xoffset,yoffset,axisx,axisy){var points=datapoints.points,ps=datapoints.pointsize,prevx=null,prevy=null;ctx.beginPath();for(var i=ps;i=y2&&y1>axisy.max){if(y2>axisy.max) +continue;x1=(axisy.max- y1)/ (y2 - y1) * (x2 - x1) + x1; +y1=axisy.max;} +else if(y2>=y1&&y2>axisy.max){if(y1>axisy.max) +continue;x2=(axisy.max- y1)/ (y2 - y1) * (x2 - x1) + x1; +y2=axisy.max;} +if(x1<=x2&&x1=x2&&x1>axisx.max){if(x2>axisx.max) +continue;y1=(axisx.max- x1)/ (x2 - x1) * (y2 - y1) + y1; +x1=axisx.max;} +else if(x2>=x1&&x2>axisx.max){if(x1>axisx.max) +continue;y2=(axisx.max- x1)/ (x2 - x1) * (y2 - y1) + y1; +x2=axisx.max;} +if(x1!=prevx||y1!=prevy) +ctx.moveTo(axisx.p2c(x1)+ xoffset,axisy.p2c(y1)+ yoffset);prevx=x2;prevy=y2;ctx.lineTo(axisx.p2c(x2)+ xoffset,axisy.p2c(y2)+ yoffset);} +ctx.stroke();} +function plotLineArea(datapoints,axisx,axisy){var points=datapoints.points,ps=datapoints.pointsize,bottom=Math.min(Math.max(0,axisy.min),axisy.max),i=0,top,areaOpen=false,ypos=1,segmentStart=0,segmentEnd=0;while(true){if(ps>0&&i>points.length+ ps) +break;i+=ps;var x1=points[i- ps],y1=points[i- ps+ ypos],x2=points[i],y2=points[i+ ypos];if(areaOpen){if(ps>0&&x1!=null&&x2==null){segmentEnd=i;ps=-ps;ypos=2;continue;} +if(ps<0&&i==segmentStart+ ps){ctx.fill();areaOpen=false;ps=-ps;ypos=1;i=segmentStart=segmentEnd+ ps;continue;}} +if(x1==null||x2==null) +continue;if(x1<=x2&&x1=x2&&x1>axisx.max){if(x2>axisx.max) +continue;y1=(axisx.max- x1)/ (x2 - x1) * (y2 - y1) + y1; +x1=axisx.max;} +else if(x2>=x1&&x2>axisx.max){if(x1>axisx.max) +continue;y2=(axisx.max- x1)/ (x2 - x1) * (y2 - y1) + y1; +x2=axisx.max;} +if(!areaOpen){ctx.beginPath();ctx.moveTo(axisx.p2c(x1),axisy.p2c(bottom));areaOpen=true;} +if(y1>=axisy.max&&y2>=axisy.max){ctx.lineTo(axisx.p2c(x1),axisy.p2c(axisy.max));ctx.lineTo(axisx.p2c(x2),axisy.p2c(axisy.max));continue;} +else if(y1<=axisy.min&&y2<=axisy.min){ctx.lineTo(axisx.p2c(x1),axisy.p2c(axisy.min));ctx.lineTo(axisx.p2c(x2),axisy.p2c(axisy.min));continue;} +var x1old=x1,x2old=x2;if(y1<=y2&&y1=axisy.min){x1=(axisy.min- y1)/ (y2 - y1) * (x2 - x1) + x1; +y1=axisy.min;} +else if(y2<=y1&&y2=axisy.min){x2=(axisy.min- y1)/ (y2 - y1) * (x2 - x1) + x1; +y2=axisy.min;} +if(y1>=y2&&y1>axisy.max&&y2<=axisy.max){x1=(axisy.max- y1)/ (y2 - y1) * (x2 - x1) + x1; +y1=axisy.max;} +else if(y2>=y1&&y2>axisy.max&&y1<=axisy.max){x2=(axisy.max- y1)/ (y2 - y1) * (x2 - x1) + x1; +y2=axisy.max;} +if(x1!=x1old){ctx.lineTo(axisx.p2c(x1old),axisy.p2c(y1));} +ctx.lineTo(axisx.p2c(x1),axisy.p2c(y1));ctx.lineTo(axisx.p2c(x2),axisy.p2c(y2));if(x2!=x2old){ctx.lineTo(axisx.p2c(x2),axisy.p2c(y2));ctx.lineTo(axisx.p2c(x2old),axisy.p2c(y2));}}} +ctx.save();ctx.translate(plotOffset.left,plotOffset.top);ctx.lineJoin="round";var lw=series.lines.lineWidth,sw=series.shadowSize;if(lw>0&&sw>0){ctx.lineWidth=sw;ctx.strokeStyle="rgba(0,0,0,0.1)";var angle=Math.PI/18;plotLine(series.datapoints,Math.sin(angle)*(lw/2+ sw/2),Math.cos(angle)*(lw/2+ sw/2),series.xaxis,series.yaxis);ctx.lineWidth=sw/2;plotLine(series.datapoints,Math.sin(angle)*(lw/2+ sw/4),Math.cos(angle)*(lw/2+ sw/4),series.xaxis,series.yaxis);} +ctx.lineWidth=lw;ctx.strokeStyle=series.color;var fillStyle=getFillStyle(series.lines,series.color,0,plotHeight);if(fillStyle){ctx.fillStyle=fillStyle;plotLineArea(series.datapoints,series.xaxis,series.yaxis);} +if(lw>0) +plotLine(series.datapoints,0,0,series.xaxis,series.yaxis);ctx.restore();} +function drawSeriesPoints(series){function plotPoints(datapoints,radius,fillStyle,offset,shadow,axisx,axisy,symbol){var points=datapoints.points,ps=datapoints.pointsize;for(var i=0;iaxisx.max||yaxisy.max) +continue;ctx.beginPath();x=axisx.p2c(x);y=axisy.p2c(y)+ offset;if(symbol=="circle") +ctx.arc(x,y,radius,0,shadow?Math.PI:Math.PI*2,false);else +symbol(ctx,x,y,radius,shadow);ctx.closePath();if(fillStyle){ctx.fillStyle=fillStyle;ctx.fill();} +ctx.stroke();}} +ctx.save();ctx.translate(plotOffset.left,plotOffset.top);var lw=series.points.lineWidth,sw=series.shadowSize,radius=series.points.radius,symbol=series.points.symbol;if(lw==0) +lw=0.0001;if(lw>0&&sw>0){var w=sw/2;ctx.lineWidth=w;ctx.strokeStyle="rgba(0,0,0,0.1)";plotPoints(series.datapoints,radius,null,w+ w/2,true,series.xaxis,series.yaxis,symbol);ctx.strokeStyle="rgba(0,0,0,0.2)";plotPoints(series.datapoints,radius,null,w/2,true,series.xaxis,series.yaxis,symbol);} +ctx.lineWidth=lw;ctx.strokeStyle=series.color;plotPoints(series.datapoints,radius,getFillStyle(series.points,series.color),0,false,series.xaxis,series.yaxis,symbol);ctx.restore();} +function drawBar(x,y,b,barLeft,barRight,offset,fillStyleCallback,axisx,axisy,c,horizontal,lineWidth){var left,right,bottom,top,drawLeft,drawRight,drawTop,drawBottom,tmp;if(horizontal){drawBottom=drawRight=drawTop=true;drawLeft=false;left=b;right=x;top=y+ barLeft;bottom=y+ barRight;if(rightaxisx.max||topaxisy.max) +return;if(leftaxisx.max){right=axisx.max;drawRight=false;} +if(bottomaxisy.max){top=axisy.max;drawTop=false;} +left=axisx.p2c(left);bottom=axisy.p2c(bottom);right=axisx.p2c(right);top=axisy.p2c(top);if(fillStyleCallback){c.beginPath();c.moveTo(left,bottom);c.lineTo(left,top);c.lineTo(right,top);c.lineTo(right,bottom);c.fillStyle=fillStyleCallback(bottom,top);c.fill();} +if(lineWidth>0&&(drawLeft||drawRight||drawTop||drawBottom)){c.beginPath();c.moveTo(left,bottom+ offset);if(drawLeft) +c.lineTo(left,top+ offset);else +c.moveTo(left,top+ offset);if(drawTop) +c.lineTo(right,top+ offset);else +c.moveTo(right,top+ offset);if(drawRight) +c.lineTo(right,bottom+ offset);else +c.moveTo(right,bottom+ offset);if(drawBottom) +c.lineTo(left,bottom+ offset);else +c.moveTo(left,bottom+ offset);c.stroke();}} +function drawSeriesBars(series){function plotBars(datapoints,barLeft,barRight,offset,fillStyleCallback,axisx,axisy){var points=datapoints.points,ps=datapoints.pointsize;for(var i=0;i');fragments.push('');rowStarted=true;} +fragments.push('
'+''+ entry.label+'');} +if(rowStarted) +fragments.push('');if(fragments.length==0) +return;var table=''+ fragments.join("")+'
';if(options.legend.container!=null) +$(options.legend.container).html(table);else{var pos="",p=options.legend.position,m=options.legend.margin;if(m[0]==null) +m=[m,m];if(p.charAt(0)=="n") +pos+='top:'+(m[1]+ plotOffset.top)+'px;';else if(p.charAt(0)=="s") +pos+='bottom:'+(m[1]+ plotOffset.bottom)+'px;';if(p.charAt(1)=="e") +pos+='right:'+(m[0]+ plotOffset.right)+'px;';else if(p.charAt(1)=="w") +pos+='left:'+(m[0]+ plotOffset.left)+'px;';var legend=$('
'+ table.replace('style="','style="position:absolute;'+ pos+';')+'
').appendTo(placeholder);if(options.legend.backgroundOpacity!=0.0){var c=options.legend.backgroundColor;if(c==null){c=options.grid.backgroundColor;if(c&&typeof c=="string") +c=$.color.parse(c);else +c=$.color.extract(legend,'background-color');c.a=1;c=c.toString();} +var div=legend.children();$('
').prependTo(legend).css('opacity',options.legend.backgroundOpacity);}}} +var highlights=[],redrawTimeout=null;function findNearbyItem(mouseX,mouseY,seriesFilter){var maxDistance=options.grid.mouseActiveRadius,smallestDistance=maxDistance*maxDistance+ 1,item=null,foundPoint=false,i,j,ps;for(i=series.length- 1;i>=0;--i){if(!seriesFilter(series[i])) +continue;var s=series[i],axisx=s.xaxis,axisy=s.yaxis,points=s.datapoints.points,mx=axisx.c2p(mouseX),my=axisy.c2p(mouseY),maxx=maxDistance/axisx.scale,maxy=maxDistance/axisy.scale;ps=s.datapoints.pointsize;if(axisx.options.inverseTransform) +maxx=Number.MAX_VALUE;if(axisy.options.inverseTransform) +maxy=Number.MAX_VALUE;if(s.lines.show||s.points.show){for(j=0;jmaxx||x- mx<-maxx||y- my>maxy||y- my<-maxy) +continue;var dx=Math.abs(axisx.p2c(x)- mouseX),dy=Math.abs(axisy.p2c(y)- mouseY),dist=dx*dx+ dy*dy;if(dist=Math.min(b,x)&&my>=y+ barLeft&&my<=y+ barRight):(mx>=x+ barLeft&&mx<=x+ barRight&&my>=Math.min(b,y)&&my<=Math.max(b,y))) +item=[i,j/ps];}}} +if(item){i=item[0];j=item[1];ps=series[i].datapoints.pointsize;return{datapoint:series[i].datapoints.points.slice(j*ps,(j+ 1)*ps),dataIndex:j,series:series[i],seriesIndex:i};} +return null;} +function onMouseMove(e){if(options.grid.hoverable) +triggerClickHoverEvent("plothover",e,function(s){return s["hoverable"]!=false;});} +function onMouseLeave(e){if(options.grid.hoverable) +triggerClickHoverEvent("plothover",e,function(s){return false;});} +function onClick(e){triggerClickHoverEvent("plotclick",e,function(s){return s["clickable"]!=false;});} +function triggerClickHoverEvent(eventname,event,seriesFilter){var offset=eventHolder.offset(),canvasX=event.pageX- offset.left- plotOffset.left,canvasY=event.pageY- offset.top- plotOffset.top,pos=canvasToAxisCoords({left:canvasX,top:canvasY});pos.pageX=event.pageX;pos.pageY=event.pageY;var item=findNearbyItem(canvasX,canvasY,seriesFilter);if(item){item.pageX=parseInt(item.series.xaxis.p2c(item.datapoint[0])+ offset.left+ plotOffset.left,10);item.pageY=parseInt(item.series.yaxis.p2c(item.datapoint[1])+ offset.top+ plotOffset.top,10);} +if(options.grid.autoHighlight){for(var i=0;iaxisx.max||yaxisy.max) +return;var pointRadius=series.points.radius+ series.points.lineWidth/2;octx.lineWidth=pointRadius;octx.strokeStyle=highlightColor;var radius=1.5*pointRadius;x=axisx.p2c(x);y=axisy.p2c(y);octx.beginPath();if(series.points.symbol=="circle") +octx.arc(x,y,radius,0,2*Math.PI,false);else +series.points.symbol(octx,x,y,radius,false);octx.closePath();octx.stroke();} +function drawBarHighlight(series,point){var highlightColor=(typeof series.highlightColor==="string")?series.highlightColor:$.color.parse(series.color).scale('a',0.5).toString(),fillStyle=highlightColor,barLeft=series.bars.align=="left"?0:-series.bars.barWidth/2;octx.lineWidth=series.bars.lineWidth;octx.strokeStyle=highlightColor;drawBar(point[0],point[1],point[2]||0,barLeft,barLeft+ series.bars.barWidth,0,function(){return fillStyle;},series.xaxis,series.yaxis,octx,series.bars.horizontal,series.bars.lineWidth);} +function getColorOrGradient(spec,bottom,top,defaultColor){if(typeof spec=="string") +return spec;else{var gradient=ctx.createLinearGradient(0,top,0,bottom);for(var i=0,l=spec.colors.length;i=1?"rgb("+[s.r,s.g,s.b].join(",")+")":"rgba("+[s.r,s.g,s.b,s.a].join(",")+")"},s.normalize=function(){function e(e,t,n){return tn?n:t}return s.r=e(0,parseInt(s.r),255),s.g=e(0,parseInt(s.g),255),s.b=e(0,parseInt(s.b),255),s.a=e(0,s.a,1),s},s.clone=function(){return e.color.make(s.r,s.b,s.g,s.a)},s.normalize()},e.color.extract=function(t,n){var r;do{r=t.css(n).toLowerCase();if(r!=""&&r!="transparent")break;t=t.parent()}while(!e.nodeName(t.get(0),"body"));return r=="rgba(0, 0, 0, 0)"&&(r="transparent"),e.color.parse(r)},e.color.parse=function(n){var r,i=e.color.make;if(r=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(n))return i(parseInt(r[1],10),parseInt(r[2],10),parseInt(r[3],10));if(r=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(n))return i(parseInt(r[1],10),parseInt(r[2],10),parseInt(r[3],10),parseFloat(r[4]));if(r=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(n))return i(parseFloat(r[1])*2.55,parseFloat(r[2])*2.55,parseFloat(r[3])*2.55);if(r=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(n))return i(parseFloat(r[1])*2.55,parseFloat(r[2])*2.55,parseFloat(r[3])*2.55,parseFloat(r[4]));if(r=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(n))return i(parseInt(r[1],16),parseInt(r[2],16),parseInt(r[3],16));if(r=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(n))return i(parseInt(r[1]+r[1],16),parseInt(r[2]+r[2],16),parseInt(r[3]+r[3],16));var s=e.trim(n).toLowerCase();return s=="transparent"?i(255,255,255,0):(r=t[s]||[0,0,0],i(r[0],r[1],r[2]))};var t={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery),function(e){function n(t,n){var r=n.children("."+t)[0];if(r==null){r=document.createElement("canvas"),r.className=t,e(r).css({direction:"ltr",position:"absolute",left:0,top:0}).appendTo(n);if(!r.getContext){if(!window.G_vmlCanvasManager)throw new Error("Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode.");r=window.G_vmlCanvasManager.initElement(r)}}this.element=r;var i=this.context=r.getContext("2d"),s=window.devicePixelRatio||1,o=i.webkitBackingStorePixelRatio||i.mozBackingStorePixelRatio||i.msBackingStorePixelRatio||i.oBackingStorePixelRatio||i.backingStorePixelRatio||1;this.pixelRatio=s/o,this.resize(n.width(),n.height()),this.textContainer=null,this.text={},this._textCache={}}function r(t,r,s,o){function E(e,t){t=[w].concat(t);for(var n=0;nn&&(n=i))}t<=n&&(t=n+1);var s,o=[],f=a.colors,l=f.length,c=0;for(r=0;r=0?c<.5?c=-c-.2:c=0:c=-c),o[r]=s.scale("rgb",1+c);var h=0,p;for(r=0;re.datamax&&n!=r&&(e.datamax=n)}var t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,r=Number.MAX_VALUE,i,s,o,a,f,l,c,h,p,d,v,m,g,y,w,S;e.each(k(),function(e,r){r.datamin=t,r.datamax=n,r.used=!1});for(i=0;i0&&c[o-h]!=null&&c[o-h]!=c[o]&&c[o-h+1]!=c[o+1]){for(a=0;aO&&(O=m)),g.y&&(mM&&(M=m))}}if(l.bars.show){var _;switch(l.bars.align){case"left":_=0;break;case"right":_=-l.bars.barWidth;break;case"center":_=-l.bars.barWidth/2;break;default:throw new Error("Invalid bar alignment: "+l.bars.align)}l.bars.horizontal?(A+=_,M+=_+l.bars.barWidth):(L+=_,O+=_+l.bars.barWidth)}x(l.xaxis,L,O),x(l.yaxis,A,M)}e.each(k(),function(e,r){r.datamin==t&&(r.datamin=null),r.datamax==n&&(r.datamax=null)})}function D(){t.css("padding",0).children(":not(.flot-base,.flot-overlay)").remove(),t.css("position")=="static"&&t.css("position","relative"),f=new n("flot-base",t),l=new n("flot-overlay",t),h=f.context,p=l.context,c=e(l.element).unbind();var r=t.data("plot");r&&(r.shutdown(),l.clear()),t.data("plot",w)}function P(){a.grid.hoverable&&(c.mousemove(at),c.bind("mouseleave",ft)),a.grid.clickable&&c.click(lt),E(b.bindEvents,[c])}function H(){ot&&clearTimeout(ot),c.unbind("mousemove",at),c.unbind("mouseleave",ft),c.unbind("click",lt),E(b.shutdown,[c])}function B(e){function t(e){return e}var n,r,i=e.options.transform||t,s=e.options.inverseTransform;e.direction=="x"?(n=e.scale=g/Math.abs(i(e.max)-i(e.min)),r=Math.min(i(e.max),i(e.min))):(n=e.scale=y/Math.abs(i(e.max)-i(e.min)),n=-n,r=Math.max(i(e.max),i(e.min))),i==t?e.p2c=function(e){return(e-r)*n}:e.p2c=function(e){return(i(e)-r)*n},s?e.c2p=function(e){return s(r+e/n)}:e.c2p=function(e){return r+e/n}}function j(e){var t=e.options,n=e.ticks||[],r=t.labelWidth||0,i=t.labelHeight||0,s=r||e.direction=="x"?Math.floor(f.width/(n.length||1)):null;legacyStyles=e.direction+"Axis "+e.direction+e.n+"Axis",layer="flot-"+e.direction+"-axis flot-"+e.direction+e.n+"-axis "+legacyStyles,font=t.font||"flot-tick-label tickLabel";for(var o=0;o=0;--t)F(o[t]);q(),e.each(o,function(e,t){I(t)})}g=f.width-m.left-m.right,y=f.height-m.bottom-m.top,e.each(n,function(e,t){B(t)}),r&&G(),it()}function U(e){var t=e.options,n=+(t.min!=null?t.min:e.datamin),r=+(t.max!=null?t.max:e.datamax),i=r-n;if(i==0){var s=r==0?1:.01;t.min==null&&(n-=s);if(t.max==null||t.min!=null)r+=s}else{var o=t.autoscaleMargin;o!=null&&(t.min==null&&(n-=i*o,n<0&&e.datamin!=null&&e.datamin>=0&&(n=0)),t.max==null&&(r+=i*o,r>0&&e.datamax!=null&&e.datamax<=0&&(r=0)))}e.min=n,e.max=r}function z(t){var n=t.options,r;typeof n.ticks=="number"&&n.ticks>0?r=n.ticks:r=.3*Math.sqrt(t.direction=="x"?f.width:f.height);var s=(t.max-t.min)/r,o=-Math.floor(Math.log(s)/Math.LN10),u=n.tickDecimals;u!=null&&o>u&&(o=u);var a=Math.pow(10,-o),l=s/a,c;l<1.5?c=1:l<3?(c=2,l>2.25&&(u==null||o+1<=u)&&(c=2.5,++o)):l<7.5?c=5:c=10,c*=a,n.minTickSize!=null&&c0&&(n.min==null&&(t.min=Math.min(t.min,p[0])),n.max==null&&p.length>1&&(t.max=Math.max(t.max,p[p.length-1]))),t.tickGenerator=function(e){var t=[],n,r;for(r=0;r1&&/\..*0$/.test((g[1]-g[0]).toFixed(m))||(t.tickDecimals=m)}}}}function W(t){var n=t.options.ticks,r=[];n==null||typeof n=="number"&&n>0?r=t.tickGenerator(t):n&&(e.isFunction(n)?r=n(t):r=n);var i,s;t.ticks=[];for(i=0;i1&&(o=u[1])):s=+u,o==null&&(o=t.tickFormatter(s,t)),isNaN(s)||t.ticks.push({v:s,label:o})}}function X(e,t){e.options.autoscaleMargin&&t.length>0&&(e.options.min==null&&(e.min=Math.min(e.min,t[0].v)),e.options.max==null&&t.length>1&&(e.max=Math.max(e.max,t[t.length-1].v)))}function V(){f.clear(),E(b.drawBackground,[h]);var e=a.grid;e.show&&e.backgroundColor&&K(),e.show&&!e.aboveData&&Q();for(var t=0;ti){var a=r;r=i,i=a}return{from:r,to:i,axis:n}}function K(){h.save(),h.translate(m.left,m.top),h.fillStyle=bt(a.grid.backgroundColor,y,0,"rgba(255, 255, 255, 0)"),h.fillRect(0,0,g,y),h.restore()}function Q(){var t,n,r,i;h.save(),h.translate(m.left,m.top);var s=a.grid.markings;if(s){e.isFunction(s)&&(n=w.getAxes(),n.xmin=n.xaxis.min,n.xmax=n.xaxis.max,n.ymin=n.yaxis.min,n.ymax=n.yaxis.max,s=s(n));for(t=0;tu.axis.max||f.tof.axis.max)continue;u.from=Math.max(u.from,u.axis.min),u.to=Math.min(u.to,u.axis.max),f.from=Math.max(f.from,f.axis.min),f.to=Math.min(f.to,f.axis.max);if(u.from==u.to&&f.from==f.to)continue;u.from=u.axis.p2c(u.from),u.to=u.axis.p2c(u.to),f.from=f.axis.p2c(f.from),f.to=f.axis.p2c(f.to),u.from==u.to||f.from==f.to?(h.beginPath(),h.strokeStyle=o.color||a.grid.markingsColor,h.lineWidth=o.lineWidth||a.grid.markingsLineWidth,h.moveTo(u.from,f.from),h.lineTo(u.to,f.to),h.stroke()):(h.fillStyle=o.color||a.grid.markingsColor,h.fillRect(u.from,f.to,u.to-u.from,f.from-f.to))}}n=k(),r=a.grid.borderWidth;for(var l=0;lc.max||d=="full"&&(typeof r=="object"&&r[c.position]>0||r>0)&&(x==c.min||x==c.max))continue;c.direction=="x"?(v=c.p2c(x),S=d=="full"?-y:d,c.position=="top"&&(S=-S)):(b=c.p2c(x),E=d=="full"?-g:d,c.position=="left"&&(E=-E)),h.lineWidth==1&&(c.direction=="x"?v=Math.floor(v)+.5:b=Math.floor(b)+.5),h.moveTo(v,b),h.lineTo(v+E,b+S)}h.stroke()}r&&(i=a.grid.borderColor,typeof r=="object"||typeof i=="object"?(typeof r!="object"&&(r={top:r,right:r,bottom:r,left:r}),typeof i!="object"&&(i={top:i,right:i,bottom:i,left:i}),r.top>0&&(h.strokeStyle=i.top,h.lineWidth=r.top,h.beginPath(),h.moveTo(0-r.left,0-r.top/2),h.lineTo(g,0-r.top/2),h.stroke()),r.right>0&&(h.strokeStyle=i.right,h.lineWidth=r.right,h.beginPath(),h.moveTo(g+r.right/2,0-r.top),h.lineTo(g+r.right/2,y),h.stroke()),r.bottom>0&&(h.strokeStyle=i.bottom,h.lineWidth=r.bottom,h.beginPath(),h.moveTo(g+r.right,y+r.bottom/2),h.lineTo(0,y+r.bottom/2),h.stroke()),r.left>0&&(h.strokeStyle=i.left,h.lineWidth=r.left,h.beginPath(),h.moveTo(0-r.left/2,y+r.bottom),h.lineTo(0-r.left/2,0),h.stroke())):(h.lineWidth=r,h.strokeStyle=a.grid.borderColor,h.strokeRect(-r/2,-r/2,g+r,y+r))),h.restore()}function G(){e.each(k(),function(e,t){if(!t.show||t.ticks.length==0)return;var n=t.box,r=t.direction+"Axis "+t.direction+t.n+"Axis",i="flot-"+t.direction+"-axis flot-"+t.direction+t.n+"-axis "+r,s=t.options.font||"flot-tick-label tickLabel",o,u,a,l,c;f.removeText(i);for(var h=0;ht.max)continue;t.direction=="x"?(l="center",u=m.left+t.p2c(o.v),t.position=="bottom"?a=n.top+n.padding:(a=n.top+n.height-n.padding,c="bottom")):(c="middle",a=m.top+t.p2c(o.v),t.position=="left"?(u=n.left+n.width-n.padding,l="right"):u=n.left+n.padding),f.addText(i,u,a,o.label,s,null,null,l,c)}})}function Y(e){e.lines.show&&Z(e),e.bars.show&&nt(e),e.points.show&&et(e)}function Z(e){function t(e,t,n,r,i){var s=e.points,o=e.pointsize,u=null,a=null;h.beginPath();for(var f=o;f=d&&c>i.max){if(d>i.max)continue;l=(i.max-c)/(d-c)*(p-l)+l,c=i.max}else if(d>=c&&d>i.max){if(c>i.max)continue;p=(i.max-c)/(d-c)*(p-l)+l,d=i.max}if(l<=p&&l=p&&l>r.max){if(p>r.max)continue;c=(r.max-l)/(p-l)*(d-c)+c,l=r.max}else if(p>=l&&p>r.max){if(l>r.max)continue;d=(r.max-l)/(p-l)*(d-c)+c,p=r.max}(l!=u||c!=a)&&h.moveTo(r.p2c(l)+t,i.p2c(c)+n),u=p,a=d,h.lineTo(r.p2c(p)+t,i.p2c(d)+n)}h.stroke()}function n(e,t,n){var r=e.points,i=e.pointsize,s=Math.min(Math.max(0,n.min),n.max),o=0,u,a=!1,f=1,l=0,c=0;for(;;){if(i>0&&o>r.length+i)break;o+=i;var p=r[o-i],d=r[o-i+f],v=r[o],m=r[o+f];if(a){if(i>0&&p!=null&&v==null){c=o,i=-i,f=2;continue}if(i<0&&o==l+i){h.fill(),a=!1,i=-i,f=1,o=l=c+i;continue}}if(p==null||v==null)continue;if(p<=v&&p=v&&p>t.max){if(v>t.max)continue;d=(t.max-p)/(v-p)*(m-d)+d,p=t.max}else if(v>=p&&v>t.max){if(p>t.max)continue;m=(t.max-p)/(v-p)*(m-d)+d,v=t.max}a||(h.beginPath(),h.moveTo(t.p2c(p),n.p2c(s)),a=!0);if(d>=n.max&&m>=n.max){h.lineTo(t.p2c(p),n.p2c(n.max)),h.lineTo(t.p2c(v),n.p2c(n.max));continue}if(d<=n.min&&m<=n.min){h.lineTo(t.p2c(p),n.p2c(n.min)),h.lineTo(t.p2c(v),n.p2c(n.min));continue}var g=p,y=v;d<=m&&d=n.min?(p=(n.min-d)/(m-d)*(v-p)+p,d=n.min):m<=d&&m=n.min&&(v=(n.min-d)/(m-d)*(v-p)+p,m=n.min),d>=m&&d>n.max&&m<=n.max?(p=(n.max-d)/(m-d)*(v-p)+p,d=n.max):m>=d&&m>n.max&&d<=n.max&&(v=(n.max-d)/(m-d)*(v-p)+p,m=n.max),p!=g&&h.lineTo(t.p2c(g),n.p2c(d)),h.lineTo(t.p2c(p),n.p2c(d)),h.lineTo(t.p2c(v),n.p2c(m)),v!=y&&(h.lineTo(t.p2c(v),n.p2c(m)),h.lineTo(t.p2c(y),n.p2c(m)))}}h.save(),h.translate(m.left,m.top),h.lineJoin="round";var r=e.lines.lineWidth,i=e.shadowSize;if(r>0&&i>0){h.lineWidth=i,h.strokeStyle="rgba(0,0,0,0.1)";var s=Math.PI/18;t(e.datapoints,Math.sin(s)*(r/2+i/2),Math.cos(s)*(r/2+i/2),e.xaxis,e.yaxis),h.lineWidth=i/2,t(e.datapoints,Math.sin(s)*(r/2+i/4),Math.cos(s)*(r/2+i/4),e.xaxis,e.yaxis)}h.lineWidth=r,h.strokeStyle=e.color;var o=rt(e.lines,e.color,0,y);o&&(h.fillStyle=o,n(e.datapoints,e.xaxis,e.yaxis)),r>0&&t(e.datapoints,0,0,e.xaxis,e.yaxis),h.restore()}function et(e){function t(e,t,n,r,i,s,o,u){var a=e.points,f=e.pointsize;for(var l=0;ls.max||po.max)continue;h.beginPath(),c=s.p2c(c),p=o.p2c(p)+r,u=="circle"?h.arc(c,p,t,0,i?Math.PI:Math.PI*2,!1):u(h,c,p,t,i),h.closePath(),n&&(h.fillStyle=n,h.fill()),h.stroke()}}h.save(),h.translate(m.left,m.top);var n=e.points.lineWidth,r=e.shadowSize,i=e.points.radius,s=e.points.symbol;n==0&&(n=1e-4);if(n>0&&r>0){var o=r/2;h.lineWidth=o,h.strokeStyle="rgba(0,0,0,0.1)",t(e.datapoints,i,null,o+o/2,!0,e.xaxis,e.yaxis,s),h.strokeStyle="rgba(0,0,0,0.2)",t(e.datapoints,i,null,o/2,!0,e.xaxis,e.yaxis,s)}h.lineWidth=n,h.strokeStyle=e.color,t(e.datapoints,i,rt(e.points,e.color),0,!1,e.xaxis,e.yaxis,s),h.restore()}function tt(e,t,n,r,i,s,o,u,a,f,l,c){var h,p,d,v,m,g,y,b,w;l?(b=g=y=!0,m=!1,h=n,p=e,v=t+r,d=t+i,pu.max||va.max)return;hu.max&&(p=u.max,g=!1),da.max&&(v=a.max,y=!1),h=u.p2c(h),d=a.p2c(d),p=u.p2c(p),v=a.p2c(v),o&&(f.beginPath(),f.moveTo(h,d),f.lineTo(h,v),f.lineTo(p,v),f.lineTo(p,d),f.fillStyle=o(d,v),f.fill()),c>0&&(m||g||y||b)&&(f.beginPath(),f.moveTo(h,d+s),m?f.lineTo(h,v+s):f.moveTo(h,v+s),y?f.lineTo(p,v+s):f.moveTo(p,v+s),g?f.lineTo(p,d+s):f.moveTo(p,d+s),b?f.lineTo(h,d+s):f.moveTo(h,d+s),f.stroke())}function nt(e){function t(t,n,r,i,s,o,u){var a=t.points,f=t.pointsize;for(var l=0;l"),n.push(""),i=!0),n.push('
'+''+h.label+"")}i&&n.push("");if(n.length==0)return;var p=''+n.join("")+"
";if(a.legend.container!=null)e(a.legend.container).html(p);else{var d="",v=a.legend.position,g=a.legend.margin;g[0]==null&&(g=[g,g]),v.charAt(0)=="n"?d+="top:"+(g[1]+m.top)+"px;":v.charAt(0)=="s"&&(d+="bottom:"+(g[1]+m.bottom)+"px;"),v.charAt(1)=="e"?d+="right:"+(g[0]+m.right)+"px;":v.charAt(1)=="w"&&(d+="left:"+(g[0]+m.left)+"px;");var y=e('
'+p.replace('style="','style="position:absolute;'+d+";")+"
").appendTo(t);if(a.legend.backgroundOpacity!=0){var b=a.legend.backgroundColor;b==null&&(b=a.grid.backgroundColor,b&&typeof b=="string"?b=e.color.parse(b):b=e.color.extract(y,"background-color"),b.a=1,b=b.toString());var w=y.children();e('
').prependTo(y).css("opacity",a.legend.backgroundOpacity)}}}function ut(e,t,n){var r=a.grid.mouseActiveRadius,i=r*r+1,s=null,o=!1,f,l,c;for(f=u.length-1;f>=0;--f){if(!n(u[f]))continue;var h=u[f],p=h.xaxis,d=h.yaxis,v=h.datapoints.points,m=p.c2p(e),g=d.c2p(t),y=r/p.scale,b=r/d.scale;c=h.datapoints.pointsize,p.options.inverseTransform&&(y=Number.MAX_VALUE),d.options.inverseTransform&&(b=Number.MAX_VALUE);if(h.lines.show||h.points.show)for(l=0;ly||w-m<-y||E-g>b||E-g<-b)continue;var S=Math.abs(p.p2c(w)-e),x=Math.abs(d.p2c(E)-t),T=S*S+x*x;T=Math.min(k,w)&&g>=E+N&&g<=E+C:m>=w+N&&m<=w+C&&g>=Math.min(k,E)&&g<=Math.max(k,E))s=[f,l/c]}}}return s?(f=s[0],l=s[1],c=u[f].datapoints.pointsize,{datapoint:u[f].datapoints.points.slice(l*c,(l+1)*c),dataIndex:l,series:u[f],seriesIndex:f}):null}function at(e){a.grid.hoverable&&ct("plothover",e,function(e){return e["hoverable"]!=0})}function ft(e){a.grid.hoverable&&ct("plothover",e,function(e){return!1})}function lt(e){ct("plotclick",e,function(e){return e["clickable"]!=0})}function ct(e,n,r){var i=c.offset(),s=n.pageX-i.left-m.left,o=n.pageY-i.top-m.top,u=L({left:s,top:o});u.pageX=n.pageX,u.pageY=n.pageY;var f=ut(s,o,r);f&&(f.pageX=parseInt(f.series.xaxis.p2c(f.datapoint[0])+i.left+m.left,10),f.pageY=parseInt(f.series.yaxis.p2c(f.datapoint[1])+i.top+m.top,10));if(a.grid.autoHighlight){for(var l=0;ls.max||io.max)return;var a=t.points.radius+t.points.lineWidth/2;p.lineWidth=a,p.strokeStyle=u;var f=1.5*a;r=s.p2c(r),i=o.p2c(i),p.beginPath(),t.points.symbol=="circle"?p.arc(r,i,f,0,2*Math.PI,!1):t.points.symbol(p,r,i,f,!1),p.closePath(),p.stroke()}function yt(t,n){var r=typeof t.highlightColor=="string"?t.highlightColor:e.color.parse(t.color).scale("a",.5).toString(),i=r,s=t.bars.align=="left"?0:-t.bars.barWidth/2;p.lineWidth=t.bars.lineWidth,p.strokeStyle=r,tt(n[0],n[1],n[2]||0,s,s+t.bars.barWidth,0,function(){return i},t.xaxis,t.yaxis,p,t.bars.horizontal,t.bars.lineWidth)}function bt(t,n,r,i){if(typeof t=="string")return t;var s=h.createLinearGradient(0,r,0,n);for(var o=0,u=t.colors.length;o").css({position:"absolute",top:0,left:0,bottom:0,right:0,"font-size":"smaller",color:"#545454"}).insertAfter(this.element)),n=this.text[t]=e("
").addClass(t).css({position:"absolute",top:0,left:0,bottom:0,right:0}).appendTo(this.textContainer)),n},n.prototype.getTextInfo=function(t,n,r,i,s){var o,u,a,f;n=""+n,typeof r=="object"?o=r.style+" "+r.variant+" "+r.weight+" "+r.size+"px/"+r.lineHeight+"px "+r.family:o=r,u=this._textCache[t],u==null&&(u=this._textCache[t]={}),a=u[o],a==null&&(a=u[o]={}),f=a[n];if(f==null){var l=e("
").html(n).css({position:"absolute","max-width":s,top:-9999}).appendTo(this.getTextLayer(t));typeof r=="object"?l.css({font:o,color:r.color}):typeof r=="string"&&l.addClass(r),f=a[n]={width:l.outerWidth(!0),height:l.outerHeight(!0),element:l,positions:[]},l.detach()}return f},n.prototype.addText=function(e,t,n,r,i,s,o,u,a){var f=this.getTextInfo(e,r,i,s,o),l=f.positions;u=="center"?t-=f.width/2:u=="right"&&(t-=f.width),a=="middle"?n-=f.height/2:a=="bottom"&&(n-=f.height);for(var c=0,h;h=l[c];c++)if(h.x==t&&h.y==n){h.active=!0;return}h={active:!0,rendered:!1,element:l.length?f.element.clone():f.element,x:t,y:n},l.push(h),h.element.css({top:Math.round(n),left:Math.round(t),"text-align":u})},n.prototype.removeText=function(e,n,r,i,s,o){if(i==null){var u=this._textCache[e];if(u!=null)for(var a in u)if(t.call(u,a)){var f=u[a];for(var l in f)if(t.call(f,l)){var c=f[l].positions;for(var h=0,p;p=c[h];h++)p.active=!1}}}else{var c=this.getTextInfo(e,i,s,o).positions;for(var h=0,p;p=c[h];h++)p.x==n&&p.y==r&&(p.active=!1)}},e.plot=function(t,n,i){var s=new r(e(t),n,i,e.plot.plugins);return s},e.plot.version="0.8.1",e.plot.plugins=[],e.fn.plot=function(t,n){return this.each(function(){e.plot(this,t,n)})}}(jQuery); \ No newline at end of file diff --git a/web/static/plugs/flot/jquery.flot.orderBars.js b/web/static/plugs/flot/jquery.flot.orderBars.js new file mode 100644 index 00000000..6c015be5 --- /dev/null +++ b/web/static/plugs/flot/jquery.flot.orderBars.js @@ -0,0 +1,26 @@ +(function($){function init(plot){var orderedBarSeries;var nbOfBarsToOrder;var borderWidth;var borderWidthInXabsWidth;var pixelInXWidthEquivalent=1;var isHorizontal=false;function reOrderBars(plot,serie,datapoints){var shiftedPoints=null;if(serieNeedToBeReordered(serie)){checkIfGraphIsHorizontal(serie);calculPixel2XWidthConvert(plot);retrieveBarSeries(plot);calculBorderAndBarWidth(serie);if(nbOfBarsToOrder>=2){var position=findPosition(serie);var decallage=0;var centerBarShift=calculCenterBarShift();if(isBarAtLeftOfCenter(position)){decallage=-1*(sumWidth(orderedBarSeries,position-1,Math.floor(nbOfBarsToOrder/2)-1))- centerBarShift;}else{decallage=sumWidth(orderedBarSeries,Math.ceil(nbOfBarsToOrder/2),position-2)+ centerBarShift+ borderWidthInXabsWidth*2;} +shiftedPoints=shiftPoints(datapoints,serie,decallage);datapoints.points=shiftedPoints;}} +return shiftedPoints;} +function serieNeedToBeReordered(serie){return serie.bars!=null&&serie.bars.show&&serie.bars.order!=null;} +function calculPixel2XWidthConvert(plot){var gridDimSize=isHorizontal?plot.getPlaceholder().innerHeight():plot.getPlaceholder().innerWidth();var minMaxValues=isHorizontal?getAxeMinMaxValues(plot.getData(),1):getAxeMinMaxValues(plot.getData(),0);var AxeSize=minMaxValues[1]- minMaxValues[0];pixelInXWidthEquivalent=AxeSize/gridDimSize;} +function getAxeMinMaxValues(series,AxeIdx){var minMaxValues=new Array();for(var i=0;iy)?1:0));} +function calculBorderAndBarWidth(serie){borderWidth=serie.bars.lineWidth?serie.bars.lineWidth:2;borderWidthInXabsWidth=borderWidth*pixelInXWidthEquivalent;} +function checkIfGraphIsHorizontal(serie){if(serie.bars.horizontal){isHorizontal=true;}} +function findPosition(serie){var pos=0 +for(var i=0;ii.series.pie.combine.threshold)&&u.push({data:[[1,f]],color:t[a].color,label:t[a].label,angle:f*Math.PI*2/n,percent:f/(n/100)})}return s>1&&u.push({data:[[1,r]],color:o,label:i.series.pie.combine.label,angle:r*Math.PI*2/n,percent:r/(n/100)}),u}function v(r,s){function y(){c.clearRect(0,0,h,p),o.children().filter(".pieLabel, .pieLabelBackground").remove()}function b(){var e=i.series.pie.shadow.left,t=i.series.pie.shadow.top,n=10,r=i.series.pie.shadow.alpha,s=i.series.pie.radius>1?i.series.pie.radius:u*i.series.pie.radius;if(s>=h/2-e||s*i.series.pie.tilt>=p/2-t||s<=n)return;c.save(),c.translate(e,t),c.globalAlpha=r,c.fillStyle="#000",c.translate(a,f),c.scale(1,i.series.pie.tilt);for(var o=1;o<=n;o++)c.beginPath(),c.arc(0,0,s,0,Math.PI*2,!1),c.fill(),s-=o;c.restore()}function w(){function l(e,t,i){if(e<=0||isNaN(e))return;i?c.fillStyle=t:(c.strokeStyle=t,c.lineJoin="round"),c.beginPath(),Math.abs(e-Math.PI*2)>1e-9&&c.moveTo(0,0),c.arc(0,0,n,r,r+e/2,!1),c.arc(0,0,n,r+e/2,r+e,!1),c.closePath(),r+=e,i?c.fill():c.stroke()}function d(){function l(t,n,s){if(t.data[0][1]==0)return!0;var u=i.legend.labelFormatter,l,c=i.series.pie.label.formatter;u?l=u(t.label,t):l=t.label,c&&(l=c(l,t));var d=(n+t.angle+n)/2,v=a+Math.round(Math.cos(d)*r),m=f+Math.round(Math.sin(d)*r)*i.series.pie.tilt,g=""+l+"";o.append(g);var y=o.children("#pieLabel"+s),b=m-y.height()/2,w=v-y.width()/2;y.css("top",b),y.css("left",w);if(0-b>0||0-w>0||p-(b+y.height())<0||h-(w+y.width())<0)return!1;if(i.series.pie.label.background.opacity!=0){var E=i.series.pie.label.background.color;E==null&&(E=t.color);var S="top:"+b+"px;left:"+w+"px;";e("
").css("opacity",i.series.pie.label.background.opacity).insertBefore(y)}return!0}var n=t,r=i.series.pie.label.radius>1?i.series.pie.label.radius:u*i.series.pie.label.radius;for(var s=0;s=i.series.pie.label.threshold*100&&!l(v[s],n,s))return!1;n+=v[s].angle}return!0}var t=Math.PI*i.series.pie.startAngle,n=i.series.pie.radius>1?i.series.pie.radius:u*i.series.pie.radius;c.save(),c.translate(a,f),c.scale(1,i.series.pie.tilt),c.save();var r=t;for(var s=0;s0){c.save(),c.lineWidth=i.series.pie.stroke.width,r=t;for(var s=0;sh-u&&(a=h-u);var v=r.getData(),g=0;do g>0&&(u*=n),g+=1,y(),i.series.pie.tilt<=.8&&b();while(!w()&&g=t&&(y(),o.prepend("
Could not draw pie with labels contained inside canvas
")),r.setSeries&&r.insertLegend&&(r.setSeries(v),r.insertLegend())}function m(e){if(i.series.pie.innerRadius>0){e.save();var t=i.series.pie.innerRadius>1?i.series.pie.innerRadius:u*i.series.pie.innerRadius;e.globalCompositeOperation="destination-out",e.beginPath(),e.fillStyle=i.series.pie.stroke.color,e.arc(0,0,t,0,Math.PI*2,!1),e.fill(),e.closePath(),e.restore(),e.save(),e.beginPath(),e.strokeStyle=i.series.pie.stroke.color,e.arc(0,0,t,0,Math.PI*2,!1),e.stroke(),e.closePath(),e.restore()}}function g(e,t){for(var n=!1,r=-1,i=e.length,s=i-1;++r1?i.series.pie.radius:u*i.series.pie.radius,o,l;for(var h=0;h1e-9&&t.moveTo(0,0),t.arc(0,0,r,e.startAngle,e.startAngle+e.angle/2,!1),t.arc(0,0,r,e.startAngle+e.angle/2,e.startAngle+e.angle,!1),t.closePath(),t.fill()}var n=e.getOptions(),r=n.series.pie.radius>1?n.series.pie.radius:u*n.series.pie.radius;t.save(),t.translate(a,f),t.scale(1,n.series.pie.tilt);for(var i=0;i1?t.series.pie.tilt=1:t.series.pie.tilt<0&&(t.series.pie.tilt=0))}),r.hooks.bindEvents.push(function(e,t){var n=e.getOptions();n.series.pie.show&&(n.grid.hoverable&&t.unbind("mousemove").mousemove(b),n.grid.clickable&&t.unbind("click").click(w))}),r.hooks.processDatapoints.push(function(e,t,n,r){var i=e.getOptions();i.series.pie.show&&p(e,t,n,r)}),r.hooks.drawOverlay.push(function(e,t){var n=e.getOptions();n.series.pie.show&&N(e,t)}),r.hooks.draw.push(function(e,t){var n=e.getOptions();n.series.pie.show&&v(e,t)})}var t=10,n=.95,i={series:{pie:{show:!1,radius:"auto",innerRadius:0,startAngle:1.5,tilt:1,shadow:{left:5,top:15,alpha:.02},offset:{top:0,left:"auto"},stroke:{color:"#fff",width:1},label:{show:"auto",formatter:function(e,t){return"
"+e+"
"+Math.round(t.percent)+"%
"},radius:1,background:{color:null,opacity:0},threshold:0},combine:{threshold:-1,color:null,label:"Other"},highlight:{opacity:.5}}}};e.plot.plugins.push({init:r,options:i,name:"pie",version:"1.1"})})(jQuery); \ No newline at end of file diff --git a/web/static/plugs/flot/jquery.flot.resize.min.js b/web/static/plugs/flot/jquery.flot.resize.min.js new file mode 100644 index 00000000..b2ddec10 --- /dev/null +++ b/web/static/plugs/flot/jquery.flot.resize.min.js @@ -0,0 +1,19 @@ +/* Flot plugin for automatically redrawing plots as the placeholder resizes. + +Copyright (c) 2007-2013 IOLA and Ole Laursen. +Licensed under the MIT license. + +It works by listening for changes on the placeholder div (through the jQuery +resize event plugin) - if the size changes, it will redraw the plot. + +There are no options. If you need to disable the plugin for some plots, you +can just fix the size of their placeholders. + +*//* Inline dependency: + * jQuery resize event - v1.1 - 3/14/2010 + * http://benalman.com/projects/jquery-resize-plugin/ + * + * Copyright (c) 2010 "Cowboy" Ben Alman + * Dual licensed under the MIT and GPL licenses. + * http://benalman.com/about/license/ + */(function(e,t,n){function c(){s=t[o](function(){r.each(function(){var t=e(this),n=t.width(),r=t.height(),i=e.data(this,a);(n!==i.w||r!==i.h)&&t.trigger(u,[i.w=n,i.h=r])}),c()},i[f])}var r=e([]),i=e.resize=e.extend(e.resize,{}),s,o="setTimeout",u="resize",a=u+"-special-event",f="delay",l="throttleWindow";i[f]=250,i[l]=!0,e.event.special[u]={setup:function(){if(!i[l]&&this[o])return!1;var t=e(this);r=r.add(t),e.data(this,a,{w:t.width(),h:t.height()}),r.length===1&&c()},teardown:function(){if(!i[l]&&this[o])return!1;var t=e(this);r=r.not(t),t.removeData(a),r.length||clearTimeout(s)},add:function(t){function s(t,i,s){var o=e(this),u=e.data(this,a);u.w=i!==n?i:o.width(),u.h=s!==n?s:o.height(),r.apply(this,arguments)}if(!i[l]&&this[o])return!1;var r;if(e.isFunction(t))return r=t,s;r=t.handler,t.handler=s}}})(jQuery,this),function(e){function n(e){function t(){var t=e.getPlaceholder();if(t.width()==0||t.height()==0)return;e.resize(),e.setupGrid(),e.draw()}function n(e,n){e.getPlaceholder().resize(t)}function r(e,n){e.getPlaceholder().unbind("resize",t)}e.hooks.bindEvents.push(n),e.hooks.shutdown.push(r)}var t={};e.plot.plugins.push({init:n,options:t,name:"resize",version:"1.0"})}(jQuery); \ No newline at end of file diff --git a/web/static/plugs/flot/jquery.flot.stack.min.js b/web/static/plugs/flot/jquery.flot.stack.min.js new file mode 100644 index 00000000..14e9931f --- /dev/null +++ b/web/static/plugs/flot/jquery.flot.stack.min.js @@ -0,0 +1,36 @@ +/* Flot plugin for stacking data sets rather than overlyaing them. + +Copyright (c) 2007-2013 IOLA and Ole Laursen. +Licensed under the MIT license. + +The plugin assumes the data is sorted on x (or y if stacking horizontally). +For line charts, it is assumed that if a line has an undefined gap (from a +null point), then the line above it should have the same gap - insert zeros +instead of "null" if you want another behaviour. This also holds for the start +and end of the chart. Note that stacking a mix of positive and negative values +in most instances doesn't make sense (so it looks weird). + +Two or more series are stacked when their "stack" attribute is set to the same +key (which can be any number or string or just "true"). To specify the default +stack, you can set the stack option like this: + + series: { + stack: null/false, true, or a key (number/string) + } + +You can also specify it for a single series, like this: + + $.plot( $("#placeholder"), [{ + data: [ ... ], + stack: true + }]) + +The stacking order is determined by the order of the data series in the array +(later series end up on top of the previous). + +Internally, the plugin modifies the datapoints in each series, adding an +offset to the y value. For line series, extra data points are inserted through +interpolation. If there's a second y value, it's also adjusted (e.g for bar +charts or filled areas). + +*/(function(e){function n(e){function t(e,t){var n=null;for(var r=0;r2&&(g?r.format[2].x:r.format[2].y),b=m&&n.lines.steps,w=!0,E=g?1:0,S=g?0:1,x=0,T=0,N,C;for(;;){if(x>=o.length)break;N=f.length;if(o[x]==null){for(C=0;C=a.length){if(!m)for(C=0;Cp){if(m&&x>0&&o[x-s]!=null){h=c+(o[x-s+S]-c)*(p-l)/(o[x-s+E]-l),f.push(p),f.push(h+d);for(C=2;C0&&a[T-u]!=null&&(v=d+(a[T-u+S]-d)*(l-p)/(a[T-u+E]-p)),f[N+S]+=v,x+=s}w=!1,N!=f.length&&y&&(f[N+2]+=v)}if(b&&N!=f.length&&N>0&&f[N]!=null&&f[N]!=f[N-s]&&f[N+1]!=f[N-s+1]){for(C=0;C0&&origpoints[i- ps]!=null){var interx=x+(below- y)*(x- origpoints[i- ps])/ (y - origpoints[i - ps + 1]); +prevp.push(interx);prevp.push(below);for(m=2;m0){var origIndex=$.inArray(s,plot.getData());plot.getData().splice(origIndex+ 1,0,thresholded);}} +function processThresholds(plot,s,datapoints){if(!s.threshold) +return;if(s.threshold instanceof Array){s.threshold.sort(function(a,b){return a.below- b.below;});$(s.threshold).each(function(i,th){thresholdData(plot,s,datapoints,th.below,th.color);});} +else{thresholdData(plot,s,datapoints,s.threshold.below,s.threshold.color);}} +plot.hooks.processDatapoints.push(processThresholds);} +$.plot.plugins.push({init:init,options:options,name:'threshold',version:'1.2'});})(jQuery); \ No newline at end of file diff --git a/web/static/plugs/flot/jquery.flot.time.min.js b/web/static/plugs/flot/jquery.flot.time.min.js new file mode 100644 index 00000000..21d84772 --- /dev/null +++ b/web/static/plugs/flot/jquery.flot.time.min.js @@ -0,0 +1,9 @@ +/* Pretty handling of time axes. + +Copyright (c) 2007-2013 IOLA and Ole Laursen. +Licensed under the MIT license. + +Set axis.mode to "time" to enable. See the section "Time series data" in +API.txt for details. + +*/(function(e){function n(e,t){return t*Math.floor(e/t)}function r(e,t,n,r){if(typeof e.strftime=="function")return e.strftime(t);var i=function(e,t){return e=""+e,t=""+(t==null?"0":t),e.length==1?t+e:e},s=[],o=!1,u=e.getHours(),a=u<12;n==null&&(n=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]),r==null&&(r=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]);var f;u>12?f=u-12:u==0?f=12:f=u;for(var l=0;l=u)break;var h=l[c][0],p=l[c][1];if(p=="year"){if(i.minTickSize!=null&&i.minTickSize[1]=="year")h=Math.floor(i.minTickSize[0]);else{var d=Math.pow(10,Math.floor(Math.log(e.delta/o.year)/Math.LN10)),v=e.delta/o.year/d;v<1.5?h=1:v<3?h=2:v<7.5?h=5:h=10,h*=d}h<1&&(h=1)}e.tickSize=i.tickSize||[h,p];var m=e.tickSize[0];p=e.tickSize[1];var g=m*o[p];p=="second"?r.setSeconds(n(r.getSeconds(),m)):p=="minute"?r.setMinutes(n(r.getMinutes(),m)):p=="hour"?r.setHours(n(r.getHours(),m)):p=="month"?r.setMonth(n(r.getMonth(),m)):p=="quarter"?r.setMonth(3*n(r.getMonth()/3,m)):p=="year"&&r.setFullYear(n(r.getFullYear(),m)),r.setMilliseconds(0),g>=o.minute&&r.setSeconds(0),g>=o.hour&&r.setMinutes(0),g>=o.day&&r.setHours(0),g>=o.day*4&&r.setDate(1),g>=o.month*2&&r.setMonth(n(r.getMonth(),3)),g>=o.quarter*2&&r.setMonth(n(r.getMonth(),6)),g>=o.year&&r.setMonth(0);var y=0,b=Number.NaN,w;do{w=b,b=r.getTime(),t.push(b);if(p=="month"||p=="quarter")if(m<1){r.setDate(1);var E=r.getTime();r.setMonth(r.getMonth()+(p=="quarter"?3:1));var S=r.getTime();r.setTime(b+y*o.hour+(S-E)*m),y=r.getHours(),r.setHours(0)}else r.setMonth(r.getMonth()+m*(p=="quarter"?3:1));else p=="year"?r.setFullYear(r.getFullYear()+m):r.setTime(b+g)}while(b0?function g(){var c=a.extend;f.use(c[c[d]?d:d-1],d'+(i?f.title[0]:f.title)+"":"";return f.zIndex=g,b([f.shade?'
':"",'
'+(a&&2!=f.type?"":k)+'
'+(0==f.type&&-1!==f.icon?'':"")+(1==f.type&&a?"":f.content||"")+'
'+function(){var a=j?'':"";return f.closeBtn&&(a+=''),a}()+""+(f.btn?function(){var a="";"string"==typeof f.btn&&(f.btn=[f.btn]);for(var b=0,c=f.btn.length;c>b;b++)a+=''+f.btn[b]+"";return'
'+a+"
"}():"")+"
"],k),c},g.pt.creat=function(){var a=this,b=a.config,g=a.index,i=b.content,j="object"==typeof i;if(!c("#"+b.id)[0]){switch("string"==typeof b.area&&(b.area="auto"===b.area?["",""]:[b.area,""]),b.type){case 0:b.btn="btn"in b?b.btn:e.btn[0],f.closeAll("dialog");break;case 2:var i=b.content=j?b.content:[b.content||"http://layer.layui.com","auto"];b.content='';break;case 3:b.title=!1,b.closeBtn=!1,-1===b.icon&&0===b.icon,f.closeAll("loading");break;case 4:j||(b.content=[b.content,"body"]),b.follow=b.content[1],b.content=b.content[0]+'',b.title=!1,b.fix=!1,b.tips="object"==typeof b.tips?b.tips:[b.tips,!0],b.tipsMore||f.closeAll("tips")}a.vessel(j,function(d,e){c("body").append(d[0]),j?function(){2==b.type||4==b.type?function(){c("body").append(d[1])}():function(){i.parents("."+h[0])[0]||(i.show().addClass("layui-layer-wrap").wrap(d[1]),c("#"+h[0]+g).find("."+h[5]).before(e))}()}():c("body").append(d[1]),a.layero=c("#"+h[0]+g),b.scrollbar||h.html.css("overflow","hidden").attr("layer-full",g)}).auto(g),2==b.type&&f.ie6&&a.layero.find("iframe").attr("src",i[0]),c(document).off("keydown",e.enter).on("keydown",e.enter),a.layero.on("keydown",function(a){c(document).off("keydown",e.enter)}),4==b.type?a.tips():a.offset(),b.fix&&d.on("resize",function(){a.offset(),(/^\d+%$/.test(b.area[0])||/^\d+%$/.test(b.area[1]))&&a.auto(g),4==b.type&&a.tips()}),b.time<=0||setTimeout(function(){f.close(a.index)},b.time),a.move().callback()}},g.pt.auto=function(a){function b(a){a=g.find(a),a.height(i[1]-j-k-2*(0|parseFloat(a.css("padding"))))}var e=this,f=e.config,g=c("#"+h[0]+a);""===f.area[0]&&f.maxWidth>0&&(/MSIE 7/.test(navigator.userAgent)&&f.btn&&g.width(g.innerWidth()),g.outerWidth()>f.maxWidth&&g.width(f.maxWidth));var i=[g.innerWidth(),g.innerHeight()],j=g.find(h[1]).outerHeight()||0,k=g.find("."+h[6]).outerHeight()||0;switch(f.type){case 2:b("iframe");break;default:""===f.area[1]?f.fix&&i[1]>=d.height()&&(i[1]=d.height(),b("."+h[5])):b("."+h[5])}return e},g.pt.offset=function(){var a=this,b=a.config,c=a.layero,e=[c.outerWidth(),c.outerHeight()],f="object"==typeof b.offset;a.offsetTop=(d.height()-e[1])/2,a.offsetLeft=(d.width()-e[0])/2,f?(a.offsetTop=b.offset[0],a.offsetLeft=b.offset[1]||a.offsetLeft):"auto"!==b.offset&&(a.offsetTop=b.offset,"rb"===b.offset&&(a.offsetTop=d.height()-e[1],a.offsetLeft=d.width()-e[0])),b.fix||(a.offsetTop=/%$/.test(a.offsetTop)?d.height()*parseFloat(a.offsetTop)/100:parseFloat(a.offsetTop),a.offsetLeft=/%$/.test(a.offsetLeft)?d.width()*parseFloat(a.offsetLeft)/100:parseFloat(a.offsetLeft),a.offsetTop+=d.scrollTop(),a.offsetLeft+=d.scrollLeft()),c.css({top:a.offsetTop,left:a.offsetLeft})},g.pt.tips=function(){var a=this,b=a.config,e=a.layero,f=[e.outerWidth(),e.outerHeight()],g=c(b.follow);g[0]||(g=c("body"));var i={width:g.outerWidth(),height:g.outerHeight(),top:g.offset().top,left:g.offset().left},j=e.find(".layui-layer-TipsG"),k=b.tips[0];b.tips[1]||j.remove(),i.autoLeft=function(){i.left+f[0]-d.width()>0?(i.tipLeft=i.left+i.width-f[0],j.css({right:12,left:"auto"})):i.tipLeft=i.left},i.where=[function(){i.autoLeft(),i.tipTop=i.top-f[1]-10,j.removeClass("layui-layer-TipsB").addClass("layui-layer-TipsT").css("border-right-color",b.tips[1])},function(){i.tipLeft=i.left+i.width+10,i.tipTop=i.top,j.removeClass("layui-layer-TipsL").addClass("layui-layer-TipsR").css("border-bottom-color",b.tips[1])},function(){i.autoLeft(),i.tipTop=i.top+i.height+10,j.removeClass("layui-layer-TipsT").addClass("layui-layer-TipsB").css("border-right-color",b.tips[1])},function(){i.tipLeft=i.left-f[0]-10,i.tipTop=i.top,j.removeClass("layui-layer-TipsR").addClass("layui-layer-TipsL").css("border-bottom-color",b.tips[1])}],i.where[k-1](),1===k?i.top-(d.scrollTop()+f[1]+16)<0&&i.where[2]():2===k?d.width()-(i.left+i.width+f[0]+16)>0||i.where[3]():3===k?i.top-d.scrollTop()+i.height+f[1]+16-d.height()>0&&i.where[0]():4===k&&f[0]+16-i.left>0&&i.where[1](),e.find("."+h[5]).css({"background-color":b.tips[1],"padding-right":b.closeBtn?"30px":""}),e.css({left:i.tipLeft,top:i.tipTop})},g.pt.move=function(){var a=this,b=a.config,e={setY:0,moveLayer:function(){var a=e.layero,b=parseInt(a.css("margin-left")),c=parseInt(e.move.css("left"));0===b||(c-=b),"fixed"!==a.css("position")&&(c-=a.parent().offset().left,e.setY=0),a.css({left:c,top:parseInt(e.move.css("top"))-e.setY})}},f=a.layero.find(b.move);return b.move&&f.attr("move","ok"),f.css({cursor:b.move?"move":"auto"}),c(b.move).on("mousedown",function(a){if(a.preventDefault(),"ok"===c(this).attr("move")){e.ismove=!0,e.layero=c(this).parents("."+h[0]);var f=e.layero.offset().left,g=e.layero.offset().top,i=e.layero.outerWidth()-6,j=e.layero.outerHeight()-6;c("#layui-layer-moves")[0]||c("body").append('
'),e.move=c("#layui-layer-moves"),b.moveType&&e.move.css({visibility:"hidden"}),e.moveX=a.pageX-e.move.position().left,e.moveY=a.pageY-e.move.position().top,"fixed"!==e.layero.css("position")||(e.setY=d.scrollTop())}}),c(document).mousemove(function(a){if(e.ismove){var c=a.pageX-e.moveX,f=a.pageY-e.moveY;if(a.preventDefault(),!b.moveOut){e.setY=d.scrollTop();var g=d.width()-e.move.outerWidth(),h=e.setY;0>c&&(c=0),c>g&&(c=g),h>f&&(f=h),f>d.height()-e.move.outerHeight()+e.setY&&(f=d.height()-e.move.outerHeight()+e.setY)}e.move.css({left:c,top:f}),b.moveType&&e.moveLayer(),c=f=g=h=null}}).mouseup(function(){try{e.ismove&&(e.moveLayer(),e.move.remove(),b.moveEnd&&b.moveEnd()),e.ismove=!1}catch(a){e.ismove=!1}}),a},g.pt.callback=function(){function a(){var a=g.cancel&&g.cancel(b.index,d);a===!1||f.close(b.index)}var b=this,d=b.layero,g=b.config;b.openLayer(),g.success&&(2==g.type?d.find("iframe").on("load",function(){g.success(d,b.index)}):g.success(d,b.index)),f.ie6&&b.IE6(d),d.find("."+h[6]).children("a").on("click",function(){var a=c(this).index();if(0===a)g.yes?g.yes(b.index,d):g.btn1?g.btn1(b.index,d):f.close(b.index);else{var e=g["btn"+(a+1)]&&g["btn"+(a+1)](b.index,d);e===!1||f.close(b.index)}}),d.find("."+h[7]).on("click",a),g.shadeClose&&c("#layui-layer-shade"+b.index).on("click",function(){f.close(b.index)}),d.find(".layui-layer-min").on("click",function(){f.min(b.index,g),g.min&&g.min(d)}),d.find(".layui-layer-max").on("click",function(){c(this).hasClass("layui-layer-maxmin")?(f.restore(b.index),g.restore&&g.restore(d)):(f.full(b.index,g),g.full&&g.full(d))}),g.end&&(e.end[b.index]=g.end)},e.reselect=function(){c.each(c("select"),function(a,b){var d=c(this);d.parents("."+h[0])[0]||1==d.attr("layer")&&c("."+h[0]).length<1&&d.removeAttr("layer").show(),d=null})},g.pt.IE6=function(a){function b(){a.css({top:f+(e.config.fix?d.scrollTop():0)})}var e=this,f=a.offset().top;b(),d.scroll(b),c("select").each(function(a,b){var d=c(this);d.parents("."+h[0])[0]||"none"===d.css("display")||d.attr({layer:"1"}).hide(),d=null})},g.pt.openLayer=function(){var a=this;f.zIndex=a.config.zIndex,f.setTop=function(a){var b=function(){f.zIndex++,a.css("z-index",f.zIndex+1)};return f.zIndex=parseInt(a[0].style.zIndex),a.on("mousedown",b),f.zIndex}},e.record=function(a){var b=[a.outerWidth(),a.outerHeight(),a.position().top,a.position().left+parseFloat(a.css("margin-left"))];a.find(".layui-layer-max").addClass("layui-layer-maxmin"),a.attr({area:b})},e.rescollbar=function(a){h.html.attr("layer-full")==a&&(h.html[0].style.removeProperty?h.html[0].style.removeProperty("overflow"):h.html[0].style.removeAttribute("overflow"),h.html.removeAttr("layer-full"))},a.layer=f,f.getChildFrame=function(a,b){return b=b||c("."+h[4]).attr("times"),c("#"+h[0]+b).find("iframe").contents().find(a)},f.getFrameIndex=function(a){return c("#"+a).parents("."+h[4]).attr("times")},f.iframeAuto=function(a){if(a){var b=f.getChildFrame("html",a).outerHeight(),d=c("#"+h[0]+a),e=d.find(h[1]).outerHeight()||0,g=d.find("."+h[6]).outerHeight()||0;d.css({height:b+e+g}),d.find("iframe").css({height:b})}},f.iframeSrc=function(a,b){c("#"+h[0]+a).find("iframe").attr("src",b)},f.style=function(a,b){var d=c("#"+h[0]+a),f=d.attr("type"),g=d.find(h[1]).outerHeight()||0,i=d.find("."+h[6]).outerHeight()||0;(f===e.type[1]||f===e.type[2])&&(d.css(b),f===e.type[2]&&d.find("iframe").css({height:parseFloat(b.height)-g-i}))},f.min=function(a,b){var d=c("#"+h[0]+a),g=d.find(h[1]).outerHeight()||0;e.record(d),f.style(a,{width:180,height:g,overflow:"hidden"}),d.find(".layui-layer-min").hide(),"page"===d.attr("type")&&d.find(h[4]).hide(),e.rescollbar(a)},f.restore=function(a){var b=c("#"+h[0]+a),d=b.attr("area").split(",");b.attr("type");f.style(a,{width:parseFloat(d[0]),height:parseFloat(d[1]),top:parseFloat(d[2]),left:parseFloat(d[3]),overflow:"visible"}),b.find(".layui-layer-max").removeClass("layui-layer-maxmin"),b.find(".layui-layer-min").show(),"page"===b.attr("type")&&b.find(h[4]).show(),e.rescollbar(a)},f.full=function(a){var b,g=c("#"+h[0]+a);e.record(g),h.html.attr("layer-full")||h.html.css("overflow","hidden").attr("layer-full",a),clearTimeout(b),b=setTimeout(function(){var b="fixed"===g.css("position");f.style(a,{top:b?0:d.scrollTop(),left:b?0:d.scrollLeft(),width:d.width(),height:d.height()}),g.find(".layui-layer-min").hide()},100)},f.title=function(a,b){var d=c("#"+h[0]+(b||f.index)).find(h[1]);d.html(a)},f.close=function(a){var b=c("#"+h[0]+a),d=b.attr("type");if(b[0]){if(d===e.type[1]&&"object"===b.attr("conType")){b.children(":not(."+h[5]+")").remove();for(var g=0;2>g;g++)b.find(".layui-layer-wrap").unwrap().hide()}else{if(d===e.type[2])try{var i=c("#"+h[4]+a)[0];i.contentWindow.document.write(""),i.contentWindow.close(),b.find("."+h[5])[0].removeChild(i)}catch(j){}b[0].innerHTML="",b.remove()}c("#layui-layer-moves, #layui-layer-shade"+a).remove(),f.ie6&&e.reselect(),e.rescollbar(a),c(document).off("keydown",e.enter),"function"==typeof e.end[a]&&e.end[a](),delete e.end[a]}},f.closeAll=function(a){c.each(c("."+h[0]),function(){var b=c(this),d=a?b.attr("type")===a:1;d&&f.close(b.attr("times")),d=null})};var i=f.cache||{},j=function(a){return i.skin?" "+i.skin+" "+i.skin+"-"+a:""};f.prompt=function(a,b){a=a||{},"function"==typeof a&&(b=a);var d,e=2==a.formType?'":function(){return''}();return f.open(c.extend({btn:["确定","取消"],content:e,skin:"layui-layer-prompt"+j("prompt"),success:function(a){d=a.find(".layui-layer-input"),d.focus()},yes:function(c){var e=d.val();""===e?d.focus():e.length>(a.maxlength||500)?f.tips("最多输入"+(a.maxlength||500)+"个字数",d,{tips:1}):b&&b(e,c,d)}},a))},f.tab=function(a){a=a||{};var b=a.tab||{};return f.open(c.extend({type:1,skin:"layui-layer-tab"+j("tab"),title:function(){var a=b.length,c=1,d="";if(a>0)for(d=''+b[0].title+"";a>c;c++)d+=""+b[c].title+"";return d}(),content:'
    '+function(){var a=b.length,c=1,d="";if(a>0)for(d='
  • '+(b[0].content||"no content")+"
  • ";a>c;c++)d+='
  • '+(b[c].content||"no content")+"
  • ";return d}()+"
",success:function(b){var d=b.find(".layui-layer-title").children(),e=b.find(".layui-layer-tabmain").children();d.on("mousedown",function(b){b.stopPropagation?b.stopPropagation():b.cancelBubble=!0;var d=c(this),f=d.index();d.addClass("layui-layer-tabnow").siblings().removeClass("layui-layer-tabnow"),e.eq(f).show().siblings().hide(),"function"==typeof a.change&&a.change(f)})}},a))},f.photos=function(b,d,e){function g(a,b,c){var d=new Image;return d.src=a,d.complete?b(d):(d.onload=function(){d.onload=null,b(d)},void(d.onerror=function(a){d.onerror=null,c(a)}))}var h={};if(b=b||{},b.photos){var i=b.photos.constructor===Object,k=i?b.photos:{},l=k.data||[],m=k.start||0;if(h.imgIndex=(0|m)+1,b.img=b.img||"img",i){if(0===l.length)return f.msg("没有图片")}else{var n=c(b.photos),o=function(){l=[],n.find(b.img).each(function(a){var b=c(this);b.attr("layer-index",a),l.push({alt:b.attr("alt"),pid:b.attr("layer-pid"),src:b.attr("layer-src")||b.attr("src"),thumb:b.attr("src")})})};if(o(),0===l.length)return;if(d||n.on("click",b.img,function(){var a=c(this),d=a.attr("layer-index");f.photos(c.extend(b,{photos:{start:d,data:l,tab:b.tab},full:b.full}),!0),o()}),!d)return}h.imgprev=function(a){h.imgIndex--,h.imgIndex<1&&(h.imgIndex=l.length),h.tabimg(a)},h.imgnext=function(a,b){h.imgIndex++,h.imgIndex>l.length&&(h.imgIndex=1,b)||h.tabimg(a)},h.keyup=function(a){if(!h.end){var b=a.keyCode;a.preventDefault(),37===b?h.imgprev(!0):39===b?h.imgnext(!0):27===b&&f.close(h.index)}},h.tabimg=function(a){l.length<=1||(k.start=h.imgIndex-1,f.close(h.index),f.photos(b,!0,a))},h.event=function(){h.bigimg.hover(function(){h.imgsee.show()},function(){h.imgsee.hide()}),h.bigimg.find(".layui-layer-imgprev").on("click",function(a){a.preventDefault(),h.imgprev()}),h.bigimg.find(".layui-layer-imgnext").on("click",function(a){a.preventDefault(),h.imgnext()}),c(document).on("keyup",h.keyup)},h.loadi=f.load(1,{shade:"shade"in b?!1:.9,scrollbar:!1}),g(l[m].src,function(d){f.close(h.loadi),h.index=f.open(c.extend({type:1,area:function(){var e=[d.width,d.height],f=[c(a).width()-50,c(a).height()-50];return!b.full&&e[0]>f[0]&&(e[0]=f[0],e[1]=e[0]*d.height/d.width),[e[0]+"px",e[1]+"px"]}(),title:!1,shade:.9,shadeClose:!0,closeBtn:!1,move:".layui-layer-phimg img",moveType:1,scrollbar:!1,moveOut:!0,shift:5*Math.random()|0,skin:"layui-layer-photos"+j("photos"),content:'
'+(l[m].alt||
'+(l.length>1?'':"")+'
'+(l[m].alt||"")+""+h.imgIndex+"/"+l.length+"
",success:function(a,c){h.bigimg=a.find(".layui-layer-phimg"),h.imgsee=a.find(".layui-layer-imguide,.layui-layer-imgbar"),h.event(a),b.tab&&b.tab(l[m],a)},end:function(){h.end=!0,c(document).off("keyup",h.keyup)}},b))},function(){f.close(h.loadi),f.msg("当前图片地址异常
是否继续查看下一张?",{time:3e4,btn:["下一张","不看了"],yes:function(){l.length>1&&h.imgnext(!0,!0)}})})}},e.run=function(){c=jQuery,d=c(a),h.html=c("html"),f.open=function(a){var b=new g(a);return b.index}},"function"==typeof define?define(function(){return e.run(),f}):function(){e.run(),f.use("skin/layer.css")}()}(window); \ No newline at end of file diff --git a/web/static/plugs/layer/mobile/layer.js b/web/static/plugs/layer/mobile/layer.js new file mode 100644 index 00000000..2eb3e28d --- /dev/null +++ b/web/static/plugs/layer/mobile/layer.js @@ -0,0 +1,2 @@ +/*! layer mobile-v2.0 弹层组件移动版 License LGPL http://layer.layui.com/mobile By 贤心 */ +;!function(a){"use strict";var b=document,c="querySelectorAll",d="getElementsByClassName",e=function(a){return b[c](a)},f={type:0,shade:!0,shadeClose:!0,fixed:!0,anim:"scale"},g={extend:function(a){var b=JSON.parse(JSON.stringify(f));for(var c in a)b[c]=a[c];return b},timer:{},end:{}};g.touch=function(a,b){a.addEventListener("click",function(a){b.call(this,a)},!1)};var h=0,i=["layui-m-layer"],j=function(a){var b=this;b.config=g.extend(a),b.view()};j.prototype.view=function(){var a=this,c=a.config,f=b.createElement("div");a.id=f.id=i[0]+h,f.setAttribute("class",i[0]+" "+i[0]+(c.type||0)),f.setAttribute("index",h);var g=function(){var a="object"==typeof c.title;return c.title?'

'+(a?c.title[0]:c.title)+"

":""}(),j=function(){"string"==typeof c.btn&&(c.btn=[c.btn]);var a,b=(c.btn||[]).length;return 0!==b&&c.btn?(a=''+c.btn[0]+"",2===b&&(a=''+c.btn[1]+""+a),'
'+a+"
"):""}();if(c.fixed||(c.top=c.hasOwnProperty("top")?c.top:100,c.style=c.style||"",c.style+=" top:"+(b.body.scrollTop+c.top)+"px"),2===c.type&&(c.content='

'+(c.content||"")+"

"),c.skin&&(c.anim="up"),"msg"===c.skin&&(c.shade=!1),f.innerHTML=(c.shade?"
':"")+'
"+g+'
'+c.content+"
"+j+"
",!c.type||2===c.type){var k=b[d](i[0]+c.type),l=k.length;l>=1&&layer.close(k[0].getAttribute("index"))}document.body.appendChild(f);var m=a.elem=e("#"+a.id)[0];c.success&&c.success(m),a.index=h++,a.action(c,m)},j.prototype.action=function(a,b){var c=this;a.time&&(g.timer[c.index]=setTimeout(function(){layer.close(c.index)},1e3*a.time));var e=function(){var b=this.getAttribute("type");0==b?(a.no&&a.no(),layer.close(c.index)):a.yes?a.yes(c.index):layer.close(c.index)};if(a.btn)for(var f=b[d]("layui-m-layerbtn")[0].children,h=f.length,i=0;h>i;i++)g.touch(f[i],e);if(a.shade&&a.shadeClose){var j=b[d]("layui-m-layershade")[0];g.touch(j,function(){layer.close(c.index,a.end)})}a.end&&(g.end[c.index]=a.end)},a.layer={v:"2.0",index:h,open:function(a){var b=new j(a||{});return b.index},close:function(a){var c=e("#"+i[0]+a)[0];c&&(c.innerHTML="",b.body.removeChild(c),clearTimeout(g.timer[a]),delete g.timer[a],"function"==typeof g.end[a]&&g.end[a](),delete g.end[a])},closeAll:function(){for(var a=b[d](i[0]),c=0,e=a.length;e>c;c++)layer.close(0|a[0].getAttribute("index"))}},"function"==typeof define?define(function(){return layer}):function(){var a=document.scripts,c=a[a.length-1],d=c.src,e=d.substring(0,d.lastIndexOf("/")+1);c.getAttribute("merge")||document.head.appendChild(function(){var a=b.createElement("link");return a.href=e+"need/layer.css?2.0",a.type="text/css",a.rel="styleSheet",a.id="layermcss",a}())}()}(window); \ No newline at end of file diff --git a/web/static/plugs/layer/mobile/need/layer.css b/web/static/plugs/layer/mobile/need/layer.css new file mode 100644 index 00000000..b9dbf201 --- /dev/null +++ b/web/static/plugs/layer/mobile/need/layer.css @@ -0,0 +1 @@ +.layui-m-layer{position:relative;z-index:19891014}.layui-m-layer *{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.layui-m-layermain,.layui-m-layershade{position:fixed;left:0;top:0;width:100%;height:100%}.layui-m-layershade{background-color:rgba(0,0,0,.7);pointer-events:auto}.layui-m-layermain{display:table;font-family:Helvetica,arial,sans-serif;pointer-events:none}.layui-m-layermain .layui-m-layersection{display:table-cell;vertical-align:middle;text-align:center}.layui-m-layerchild{position:relative;display:inline-block;text-align:left;background-color:#fff;font-size:14px;border-radius:5px;box-shadow:0 0 8px rgba(0,0,0,.1);pointer-events:auto;-webkit-overflow-scrolling:touch;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.2s;animation-duration:.2s}@-webkit-keyframes layui-m-anim-scale{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes layui-m-anim-scale{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}.layui-m-anim-scale{animation-name:layui-m-anim-scale;-webkit-animation-name:layui-m-anim-scale}@-webkit-keyframes layui-m-anim-up{0%{opacity:0;-webkit-transform:translateY(800px);transform:translateY(800px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes layui-m-anim-up{0%{opacity:0;-webkit-transform:translateY(800px);transform:translateY(800px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}.layui-m-anim-up{-webkit-animation-name:layui-m-anim-up;animation-name:layui-m-anim-up}.layui-m-layer0 .layui-m-layerchild{width:90%;max-width:640px}.layui-m-layer1 .layui-m-layerchild{border:none;border-radius:0}.layui-m-layer2 .layui-m-layerchild{width:auto;max-width:260px;min-width:40px;border:none;background:0 0;box-shadow:none;color:#fff}.layui-m-layerchild h3{padding:0 10px;height:60px;line-height:60px;font-size:16px;font-weight:400;border-radius:5px 5px 0 0;text-align:center}.layui-m-layerbtn span,.layui-m-layerchild h3{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-m-layercont{padding:50px 30px;line-height:22px;text-align:center}.layui-m-layer1 .layui-m-layercont{padding:0;text-align:left}.layui-m-layer2 .layui-m-layercont{text-align:center;padding:0;line-height:0}.layui-m-layer2 .layui-m-layercont i{width:25px;height:25px;margin-left:8px;display:inline-block;background-color:#fff;border-radius:100%;-webkit-animation:layui-m-anim-loading 1.4s infinite ease-in-out;animation:layui-m-anim-loading 1.4s infinite ease-in-out;-webkit-animation-fill-mode:both;animation-fill-mode:both}.layui-m-layerbtn,.layui-m-layerbtn span{position:relative;text-align:center;border-radius:0 0 5px 5px}.layui-m-layer2 .layui-m-layercont p{margin-top:20px}@-webkit-keyframes layui-m-anim-loading{0%,100%,80%{transform:scale(0);-webkit-transform:scale(0)}40%{transform:scale(1);-webkit-transform:scale(1)}}@keyframes layui-m-anim-loading{0%,100%,80%{transform:scale(0);-webkit-transform:scale(0)}40%{transform:scale(1);-webkit-transform:scale(1)}}.layui-m-layer2 .layui-m-layercont i:first-child{margin-left:0;-webkit-animation-delay:-.32s;animation-delay:-.32s}.layui-m-layer2 .layui-m-layercont i.layui-m-layerload{-webkit-animation-delay:-.16s;animation-delay:-.16s}.layui-m-layer2 .layui-m-layercont>div{line-height:22px;padding-top:7px;margin-bottom:20px;font-size:14px}.layui-m-layerbtn{display:box;display:-moz-box;display:-webkit-box;width:100%;height:50px;line-height:50px;font-size:0;border-top:1px solid #D0D0D0;background-color:#F2F2F2}.layui-m-layerbtn span{display:block;-moz-box-flex:1;box-flex:1;-webkit-box-flex:1;font-size:14px;cursor:pointer}.layui-m-layerbtn span[yes]{color:#40AFFE}.layui-m-layerbtn span[no]{border-right:1px solid #D0D0D0;border-radius:0 0 0 5px}.layui-m-layerbtn span:active{background-color:#F6F6F6}.layui-m-layerend{position:absolute;right:7px;top:10px;width:30px;height:30px;border:0;font-weight:400;background:0 0;cursor:pointer;-webkit-appearance:none;font-size:30px}.layui-m-layerend::after,.layui-m-layerend::before{position:absolute;left:5px;top:15px;content:'';width:18px;height:1px;background-color:#999;transform:rotate(45deg);-webkit-transform:rotate(45deg);border-radius:3px}.layui-m-layerend::after{transform:rotate(-45deg);-webkit-transform:rotate(-45deg)}body .layui-m-layer .layui-m-layer-footer{position:fixed;width:95%;max-width:100%;margin:0 auto;left:0;right:0;bottom:10px;background:0 0}.layui-m-layer-footer .layui-m-layercont{padding:20px;border-radius:5px 5px 0 0;background-color:rgba(255,255,255,.8)}.layui-m-layer-footer .layui-m-layerbtn{display:block;height:auto;background:0 0;border-top:none}.layui-m-layer-footer .layui-m-layerbtn span{background-color:rgba(255,255,255,.8)}.layui-m-layer-footer .layui-m-layerbtn span[no]{color:#FD482C;border-top:1px solid #c2c2c2;border-radius:0 0 5px 5px}.layui-m-layer-footer .layui-m-layerbtn span[yes]{margin-top:10px;border-radius:5px}body .layui-m-layer .layui-m-layer-msg{width:auto;max-width:90%;margin:0 auto;bottom:-150px;background-color:rgba(0,0,0,.7);color:#fff}.layui-m-layer-msg .layui-m-layercont{padding:10px 20px} \ No newline at end of file diff --git a/web/static/plugs/layer/skin/default/icon-ext.png b/web/static/plugs/layer/skin/default/icon-ext.png new file mode 100644 index 00000000..bbbb669b Binary files /dev/null and b/web/static/plugs/layer/skin/default/icon-ext.png differ diff --git a/web/static/plugs/layer/skin/default/icon.png b/web/static/plugs/layer/skin/default/icon.png new file mode 100644 index 00000000..3e17da8b Binary files /dev/null and b/web/static/plugs/layer/skin/default/icon.png differ diff --git a/web/static/plugs/layer/skin/default/loading-0.gif b/web/static/plugs/layer/skin/default/loading-0.gif new file mode 100644 index 00000000..6f3c9539 Binary files /dev/null and b/web/static/plugs/layer/skin/default/loading-0.gif differ diff --git a/web/static/plugs/layer/skin/default/loading-1.gif b/web/static/plugs/layer/skin/default/loading-1.gif new file mode 100644 index 00000000..db3a483e Binary files /dev/null and b/web/static/plugs/layer/skin/default/loading-1.gif differ diff --git a/web/static/plugs/layer/skin/default/loading-2.gif b/web/static/plugs/layer/skin/default/loading-2.gif new file mode 100644 index 00000000..5bb90fd6 Binary files /dev/null and b/web/static/plugs/layer/skin/default/loading-2.gif differ diff --git a/web/static/plugs/layer/skin/layer.css b/web/static/plugs/layer/skin/layer.css new file mode 100644 index 00000000..a7457ad0 --- /dev/null +++ b/web/static/plugs/layer/skin/layer.css @@ -0,0 +1,7 @@ +/*! + + @Name: layer's style + @Author: 贤心 + @Blog: sentsin.com + + */.layui-layer-imgbar,.layui-layer-imgtit a,.layui-layer-tab .layui-layer-title span,.layui-layer-title{text-overflow:ellipsis;white-space:nowrap}*html{background-image:url(about:blank);background-attachment:fixed}html #layui_layer_skinlayercss{display:none;position:absolute;width:1989px}.layui-layer,.layui-layer-shade{position:fixed;_position:absolute;pointer-events:auto}.layui-layer-shade{top:0;left:0;width:100%;height:100%;_height:expression(document.body.offsetHeight+"px")}.layui-layer{top:150px;left:0;margin:0;padding:0;background-color:#fff;-webkit-background-clip:content;box-shadow:1px 1px 50px rgba(0,0,0,.3);border-radius:2px;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.3s;animation-duration:.3s}.layui-layer-close{position:absolute}.layui-layer-content{position:relative}.layui-layer-border{border:1px solid #B2B2B2;border:1px solid rgba(0,0,0,.3);box-shadow:1px 1px 5px rgba(0,0,0,.2)}.layui-layer-moves{position:absolute;border:3px solid #666;border:3px solid rgba(0,0,0,.5);cursor:move;background-color:#fff;background-color:rgba(255,255,255,.3);filter:alpha(opacity=50)}.layui-layer-load{background:url(default/loading-0.gif) center center no-repeat #fff}.layui-layer-ico{background:url(default/icon.png) no-repeat}.layui-layer-btn a,.layui-layer-dialog .layui-layer-ico,.layui-layer-setwin a{display:inline-block;*display:inline;*zoom:1;vertical-align:top}@-webkit-keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.5);-ms-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim{-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes bounceOut{100%{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.03);transform:scale(1.03)}0%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes bounceOut{100%{opacity:0;-webkit-transform:scale(.7);-ms-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.03);-ms-transform:scale(1.03);transform:scale(1.03)}0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-close{-webkit-animation-name:bounceOut;animation-name:bounceOut;-webkit-animation-duration:.2s;animation-duration:.2s}@-webkit-keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);-ms-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);-ms-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-01{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.layer-anim-02{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);-ms-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);-ms-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-03{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}@keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);-ms-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);-ms-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}.layer-anim-04{-webkit-animation-name:rollIn;animation-name:rollIn}@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.layer-anim-05{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.layer-anim-06{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.layui-layer-title{padding:0 80px 0 20px;height:42px;line-height:42px;border-bottom:1px solid #eee;font-size:14px;color:#333;overflow:hidden;background-color:#F8F8F8;border-radius:2px 2px 0 0}.layui-layer-setwin{position:absolute;right:15px;*right:0;top:15px;font-size:0;line-height:initial}.layui-layer-setwin a{position:relative;width:16px;height:16px;margin-left:10px;font-size:12px;_overflow:hidden}.layui-layer-setwin .layui-layer-min cite{position:absolute;width:14px;height:2px;left:0;top:50%;margin-top:-1px;background-color:#2E2D3C;cursor:pointer;_overflow:hidden}.layui-layer-setwin .layui-layer-min:hover cite{background-color:#2D93CA}.layui-layer-setwin .layui-layer-max{background-position:-32px -40px}.layui-layer-setwin .layui-layer-max:hover{background-position:-16px -40px}.layui-layer-setwin .layui-layer-maxmin{background-position:-65px -40px}.layui-layer-setwin .layui-layer-maxmin:hover{background-position:-49px -40px}.layui-layer-setwin .layui-layer-close1{background-position:0 -40px;cursor:pointer}.layui-layer-setwin .layui-layer-close1:hover{opacity:.7}.layui-layer-setwin .layui-layer-close2{position:absolute;right:-28px;top:-28px;width:30px;height:30px;margin-left:0;background-position:-149px -31px;*right:-18px;_display:none}.layui-layer-setwin .layui-layer-close2:hover{background-position:-180px -31px}.layui-layer-btn{text-align:right;padding:0 10px 12px;pointer-events:auto}.layui-layer-btn a{height:28px;line-height:28px;margin:0 6px;padding:0 15px;border:1px solid #dedede;background-color:#f1f1f1;color:#333;border-radius:2px;font-weight:400;cursor:pointer;text-decoration:none}.layui-layer-btn a:hover{opacity:.9;text-decoration:none}.layui-layer-btn a:active{opacity:.7}.layui-layer-btn .layui-layer-btn0{border-color:#4898d5;background-color:#2e8ded;color:#fff}.layui-layer-dialog{min-width:260px}.layui-layer-dialog .layui-layer-content{position:relative;padding:20px;line-height:24px;word-break:break-all;font-size:14px;overflow:auto}.layui-layer-dialog .layui-layer-content .layui-layer-ico{position:absolute;top:16px;left:15px;_left:-40px;width:30px;height:30px}.layui-layer-ico1{background-position:-30px 0}.layui-layer-ico2{background-position:-60px 0}.layui-layer-ico3{background-position:-90px 0}.layui-layer-ico4{background-position:-120px 0}.layui-layer-ico5{background-position:-150px 0}.layui-layer-ico6{background-position:-180px 0}.layui-layer-rim{border:6px solid #8D8D8D;border:6px solid rgba(0,0,0,.3);border-radius:5px;box-shadow:none}.layui-layer-msg{min-width:180px;border:1px solid #D3D4D3;box-shadow:none}.layui-layer-hui{min-width:100px;background-color:#000;filter:alpha(opacity=60);background-color:rgba(0,0,0,.6);color:#fff;border:none}.layui-layer-hui .layui-layer-content{padding:12px 25px;text-align:center}.layui-layer-dialog .layui-layer-padding{padding:20px 20px 20px 55px;text-align:left}.layui-layer-page .layui-layer-content{position:relative;overflow:auto}.layui-layer-iframe .layui-layer-btn,.layui-layer-page .layui-layer-btn{padding-top:10px}.layui-layer-nobg{background:0 0}.layui-layer-iframe .layui-layer-content{overflow:hidden}.layui-layer-iframe iframe{display:block;width:100%}.layui-layer-loading{border-radius:100%;background:0 0;box-shadow:none;border:none}.layui-layer-loading .layui-layer-content{width:60px;height:24px;background:url(default/loading-0.gif) no-repeat}.layui-layer-loading .layui-layer-loading1{width:37px;height:37px;background:url(default/loading-1.gif) no-repeat}.layui-layer-ico16,.layui-layer-loading .layui-layer-loading2{width:32px;height:32px;background:url(default/loading-2.gif) no-repeat}.layui-layer-tips{background:0 0;box-shadow:none;border:none}.layui-layer-tips .layui-layer-content{position:relative;line-height:22px;min-width:12px;padding:5px 10px;font-size:12px;_float:left;border-radius:3px;box-shadow:1px 1px 3px rgba(0,0,0,.3);background-color:#F90;color:#fff}.layui-layer-tips .layui-layer-close{right:-2px;top:-1px}.layui-layer-tips i.layui-layer-TipsG{position:absolute;width:0;height:0;border-width:8px;border-color:transparent;border-style:dashed;*overflow:hidden}.layui-layer-tips i.layui-layer-TipsB,.layui-layer-tips i.layui-layer-TipsT{left:5px;border-right-style:solid;border-right-color:#F90}.layui-layer-tips i.layui-layer-TipsT{bottom:-8px}.layui-layer-tips i.layui-layer-TipsB{top:-8px}.layui-layer-tips i.layui-layer-TipsL,.layui-layer-tips i.layui-layer-TipsR{top:1px;border-bottom-style:solid;border-bottom-color:#F90}.layui-layer-tips i.layui-layer-TipsR{left:-8px}.layui-layer-tips i.layui-layer-TipsL{right:-8px}.layui-layer-lan[type=dialog]{min-width:280px}.layui-layer-lan .layui-layer-title{background:#4476A7;color:#fff;border:none}.layui-layer-lan .layui-layer-btn{padding:10px;text-align:right;border-top:1px solid #E9E7E7}.layui-layer-lan .layui-layer-btn a{background:#BBB5B5;border:none}.layui-layer-lan .layui-layer-btn .layui-layer-btn1{background:#C9C5C5}.layui-layer-molv .layui-layer-title{background:#009f95;color:#fff;border:none}.layui-layer-molv .layui-layer-btn a{background:#009f95}.layui-layer-molv .layui-layer-btn .layui-layer-btn1{background:#92B8B1}.layui-layer-iconext{background:url(default/icon-ext.png) no-repeat}.layui-layer-prompt .layui-layer-input{display:block;width:220px;height:30px;margin:0 auto;line-height:30px;padding:0 5px;border:1px solid #ccc;box-shadow:1px 1px 5px rgba(0,0,0,.1) inset;color:#333}.layui-layer-prompt textarea.layui-layer-input{width:300px;height:100px;line-height:20px}.layui-layer-tab{box-shadow:1px 1px 50px rgba(0,0,0,.4)}.layui-layer-tab .layui-layer-title{padding-left:0;border-bottom:1px solid #ccc;background-color:#eee;overflow:visible}.layui-layer-tab .layui-layer-title span{position:relative;float:left;min-width:80px;max-width:260px;padding:0 20px;text-align:center;cursor:default;overflow:hidden}.layui-layer-tab .layui-layer-title span.layui-layer-tabnow{height:43px;border-left:1px solid #ccc;border-right:1px solid #ccc;background-color:#fff;z-index:10}.layui-layer-tab .layui-layer-title span:first-child{border-left:none}.layui-layer-tabmain{line-height:24px;clear:both}.layui-layer-tabmain .layui-layer-tabli{display:none}.layui-layer-tabmain .layui-layer-tabli.xubox_tab_layer{display:block}.xubox_tabclose{position:absolute;right:10px;top:5px;cursor:pointer}.layui-layer-photos{-webkit-animation-duration:1s;animation-duration:1s}.layui-layer-photos .layui-layer-content{overflow:hidden;text-align:center}.layui-layer-photos .layui-layer-phimg img{position:relative;width:100%;display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-imgbar,.layui-layer-imguide{display:none}.layui-layer-imgnext,.layui-layer-imgprev{position:absolute;top:50%;width:27px;_width:44px;height:44px;margin-top:-22px;outline:0;blr:expression(this.onFocus=this.blur())}.layui-layer-imgprev{left:10px;background-position:-5px -5px;_background-position:-70px -5px}.layui-layer-imgprev:hover{background-position:-33px -5px;_background-position:-120px -5px}.layui-layer-imgnext{right:10px;_right:8px;background-position:-5px -50px;_background-position:-70px -50px}.layui-layer-imgnext:hover{background-position:-33px -50px;_background-position:-120px -50px}.layui-layer-imgbar{position:absolute;left:0;bottom:0;width:100%;height:32px;line-height:32px;background-color:rgba(0,0,0,.8);background-color:#000\9;filter:Alpha(opacity=80);color:#fff;overflow:hidden;font-size:0}.layui-layer-imgtit *{display:inline-block;*display:inline;*zoom:1;vertical-align:top;font-size:12px}.layui-layer-imgtit a{max-width:65%;overflow:hidden;color:#fff}.layui-layer-imgtit a:hover{color:#fff;text-decoration:underline}.layui-layer-imgtit em{padding-left:10px;font-style:normal} \ No newline at end of file diff --git a/web/static/plugs/tagsinput/bootstrap-tagsinput.css b/web/static/plugs/tagsinput/bootstrap-tagsinput.css new file mode 100644 index 00000000..b31f01c7 --- /dev/null +++ b/web/static/plugs/tagsinput/bootstrap-tagsinput.css @@ -0,0 +1,55 @@ +.bootstrap-tagsinput { + background-color: #fff; + border: 1px solid #ccc; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + display: inline-block; + padding: 4px 6px; + color: #555; + vertical-align: middle; + border-radius: 4px; + max-width: 100%; + line-height: 22px; + cursor: text; +} +.bootstrap-tagsinput input { + border: none; + box-shadow: none; + outline: none; + background-color: transparent; + padding: 0 6px; + margin: 0; + width: auto; + max-width: inherit; +} +.bootstrap-tagsinput.form-control input::-moz-placeholder { + color: #777; + opacity: 1; +} +.bootstrap-tagsinput.form-control input:-ms-input-placeholder { + color: #777; +} +.bootstrap-tagsinput.form-control input::-webkit-input-placeholder { + color: #777; +} +.bootstrap-tagsinput input:focus { + border: none; + box-shadow: none; +} +.bootstrap-tagsinput .tag { + margin-right: 2px; + color: white; +} +.bootstrap-tagsinput .tag [data-role="remove"] { + margin-left: 8px; + cursor: pointer; +} +.bootstrap-tagsinput .tag [data-role="remove"]:after { + content: "x"; + padding: 0px 2px; +} +.bootstrap-tagsinput .tag [data-role="remove"]:hover { + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} +.bootstrap-tagsinput .tag [data-role="remove"]:hover:active { + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} diff --git a/web/static/plugs/tagsinput/bootstrap-tagsinput.js b/web/static/plugs/tagsinput/bootstrap-tagsinput.js new file mode 100644 index 00000000..e83ea50f --- /dev/null +++ b/web/static/plugs/tagsinput/bootstrap-tagsinput.js @@ -0,0 +1,673 @@ +(function ($) { + "use strict"; + + var defaultOptions = { + tagClass: function(item) { + return 'label label-info'; + }, + focusClass: 'focus', + itemValue: function(item) { + return item ? item.toString() : item; + }, + itemText: function(item) { + return this.itemValue(item); + }, + itemTitle: function(item) { + return null; + }, + freeInput: true, + addOnBlur: true, + maxTags: undefined, + maxChars: undefined, + confirmKeys: [13, 44], + delimiter: ',', + delimiterRegex: null, + cancelConfirmKeysOnEmpty: false, + onTagExists: function(item, $tag) { + $tag.hide().fadeIn(); + }, + trimValue: false, + allowDuplicates: false + }; + + /** + * Constructor function + */ + function TagsInput(element, options) { + this.isInit = true; + this.itemsArray = []; + + this.$element = $(element); + this.$element.hide(); + + this.isSelect = (element.tagName === 'SELECT'); + this.multiple = (this.isSelect && element.hasAttribute('multiple')); + this.objectItems = options && options.itemValue; + this.placeholderText = element.hasAttribute('placeholder') ? this.$element.attr('placeholder') : ''; + this.inputSize = Math.max(1, this.placeholderText.length); + + this.$container = $('
'); + this.$input = $('').appendTo(this.$container); + + this.$element.before(this.$container); + + this.build(options); + this.isInit = false; + } + + TagsInput.prototype = { + constructor: TagsInput, + + /** + * Adds the given item as a new tag. Pass true to dontPushVal to prevent + * updating the elements val() + */ + add: function(item, dontPushVal, options) { + var self = this; + + if (self.options.maxTags && self.itemsArray.length >= self.options.maxTags) + return; + + // Ignore falsey values, except false + if (item !== false && !item) + return; + + // Trim value + if (typeof item === "string" && self.options.trimValue) { + item = $.trim(item); + } + + // Throw an error when trying to add an object while the itemValue option was not set + if (typeof item === "object" && !self.objectItems) + throw("Can't add objects when itemValue option is not set"); + + // Ignore strings only containg whitespace + if (item.toString().match(/^\s*$/)) + return; + + // If SELECT but not multiple, remove current tag + if (self.isSelect && !self.multiple && self.itemsArray.length > 0) + self.remove(self.itemsArray[0]); + + if (typeof item === "string" && this.$element[0].tagName === 'INPUT') { + var delimiter = (self.options.delimiterRegex) ? self.options.delimiterRegex : self.options.delimiter; + var items = item.split(delimiter); + if (items.length > 1) { + for (var i = 0; i < items.length; i++) { + this.add(items[i], true); + } + + if (!dontPushVal) + self.pushVal(); + return; + } + } + + var itemValue = self.options.itemValue(item), + itemText = self.options.itemText(item), + tagClass = self.options.tagClass(item), + itemTitle = self.options.itemTitle(item); + + // Ignore items allready added + var existing = $.grep(self.itemsArray, function(item) { return self.options.itemValue(item) === itemValue; } )[0]; + if (existing && !self.options.allowDuplicates) { + // Invoke onTagExists + if (self.options.onTagExists) { + var $existingTag = $(".tag", self.$container).filter(function() { return $(this).data("item") === existing; }); + self.options.onTagExists(item, $existingTag); + } + return; + } + + // if length greater than limit + if (self.items().toString().length + item.length + 1 > self.options.maxInputLength) + return; + + // raise beforeItemAdd arg + var beforeItemAddEvent = $.Event('beforeItemAdd', { item: item, cancel: false, options: options}); + self.$element.trigger(beforeItemAddEvent); + if (beforeItemAddEvent.cancel) + return; + + // register item in internal array and map + self.itemsArray.push(item); + + // add a tag element + + var $tag = $('' + htmlEncode(itemText) + ''); + $tag.data('item', item); + self.findInputWrapper().before($tag); + $tag.after(' '); + + // Check to see if the tag exists in its raw or uri-encoded form + var optionExists = ( + $('option[value="' + encodeURIComponent(itemValue) + '"]', self.$element).length || + $('option[value="' + htmlEncode(itemValue) + '"]', self.$element).length + ); + + // add