实现套路:利用canvas的api,绘制图片,将canvas图片转成base64 保存在后台。后台将base64转换为png格式。前端请求就可看到显示的图片了。
效果图1:
效果图2:
所需图片:
//html 代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=750, user-scalable=0">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<meta name="keywords" content="">
<meta name="description" content="">
<link rel="stylesheet" href="app_shouqian.css">
<script src="jquery-2.1.4.js"></script>
<script src="jquery.easing.min.js"></script>
<title></title>
<script>
</script>
<style>
.canImg {
position: absolute;
;
left: 10px;
top: 10px;
width: 100px;
height: 100px;
background-color: #000;
}
.canImg img {
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div class="wrap ">
<div class="header clearfix">
<div class="btn left btn-undo cancel">首页</div>
<div class="btn left btn-reset" id="clear_btn">重做</div>
<div class="btn right btn-go save" id='img_btn'>发送</div>
</div>
<div class="container" style="background: #ff6633;">
<canvas id="canvas">
浏览器不支持canvas动画效果
</canvas>
</div>
<div class="footer">
<div class="pLi clearfix ">
<span class="pn left pn1 " data-width="20">马克笔</span>
<span class="pn left pn2 active" data-width="10">画笔</span>
<span class="pn left pn3 " data-width="2">钢笔</span>
<span class="pn rubber left" data-width="50">橡皮</span>
<span class="colors right" id="js_colorBar"></span>
</div>
<div class="cLi hidden">
<div class="pn"></div>
<ul class="cLs clearfix">
<li class="left active"></li>
<li class="left"></li>
<li class="left"></li>
<li class="left"></li>
<li class="left"></li>
<li class="left"></li>
<li class="left"></li>
<li class="left"></li>
<li class="left"></li>
<li class="left"></li>
</ul>
</div>
</div>
<div class="pop-box hidden">
<div>
<img id="pro-img" src="" />
<p id='btn-success'>提交成功</p>
</div>
</div>
</div>
<script src="app_shouqian.js"></script>
<script>
$(function() {
//获取活动id
shouhui.photoUrl = './images/';
shouhui.ajaxUrl = "";
shouhui.indexUrl = "";
shouhui.rand = '0';
shouhui.isTest = '1';
shouhui.recheck = '1';
shouhui.initEvent();
});
</script>
</body>
</html>
//css代码
body {
background: #fff;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
/*css resert*/
html,
body,
div,
p,
span,
label,
img,
a,
ol,
ul,
dl,
dt,
dd,
li,
table,
tr,
td,
th,
tbody,
thead,
tfoot,
form,
fieldset,
legent,
h1,
h2,
h3,
h4,
h5,
h6,
strong,
b,
em,
blockquote,
cite,
pre,
code,
hr,
br,
input,
button,
textarea,
article,
aside,
details,
figcaption,
figure,
footer,
header,
group,
menu,
nav,
section {
padding: 0px;
margin: 0px;
}
* {
padding: 0px;
margin: 0px;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-appearance: none;
outline: 0 none;
}
/* 要注意表单元素并不继承父级 font 的问题 */
button,
input,
select,
textarea {
font: 100% serif;
}
img,
input,
select {
vertical-align: middle;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: normal;
font-size: 1em;
}
ol,
ul {
list-style-type: none;
}
a img {
border: 0 none;
cursor: pointer;
}
fieldset,
img {
border: 0 none;
}
:focus {
outline: 0 none;
}
caption,
cite,
code,
em,
th,
var,
i {
font-weight: normal;
font-style: normal;
}
/******常用****/
.clearfix:before,
.clearfix:after {
content: "";
display: table;
}
.clearfix:after {
clear: both;
}
.clearfix {
zoom: 1;
}
.clear {
clear: both;
height: 0;
width: 0;
display: block;
visibility: hidden;
overflow: hidden;
}
.clearit {
clear: both;
zoom: 1;
}
.hidden {
display: none;
}
.vhidden {
visibility: hidden;
}
.hide-txt {
overflow: hidden;
text-indent: 100%;
white-space: nowrap;
}
.left {
float: left;
display: inline;
}
.right {
float: right;
display: inline;
}
.fnone {
float: none;
}
.txtleft {
text-align: left;
}
.txtright {
text-align: right;
}
.txtcenter {
text-align: center;
}
.middle {
vertical-align: middle;
}
.noborder {
border: 0 none !important;
}
.nobg {
background: none !important;
}
.sub {
vertical-align: sub;
}
.sup {
vertical-align:middle ;
}
.cursor {
cursor: pointer;
}
.zoom {
zoom: 1;
}
.vtop {
vertical-align: top;
}
.wrap {
width: 100%;
position: absolute;
;
left: 0;
top: 0;
bottom: 0;
background: #fdfdfd;
/*background: url(mob_shouqian_bg.jpg?v=323) no-repeat;*/
/*background-size: 100% 100%;*/
overflow: hidden;
}
/*header*/
.header {
padding: 0 30px;
height: 86px;
border-bottom: 1px solid #eee;
background: rgba(255, 255, 255, .9);
}
.header .btn {
color: #666;
font-size: 32px;
line-height: 86px;
height: 86px;
}
.header .btn-undo {
background: url(./images/undo-icon.png) no-repeat center right;
padding-right: 74px;
margin-right: 50px;
}
.header .btn-reset {
background: url(./images/reset-icon.png) no-repeat center left;
padding-left: 74px;
}
.header .btn-go {
color: #32b16c;
}
/*container*/
.container {
width: 100%;
position: absolute;
;
left: 0;
top: 87px;
bottom: 211px;
padding: 0
}
.container canvas {
width: 100%;
height: 100%;
position: absolute;
;
left: 0;
top: 0;
}
/*footer*/
.footer {
display: none;
position: fixed;
left: 0px;
bottom: 0px;
z-index: 11;
width: 100%;
height: 49px;
border-top: 1px solid #ccc;
background: #fff;
}
.footer {
width: 100%;
height: 210px;
border-top: 1px solid #fc0;
display: block;
background: #ffcc00;
}
.footer .pLi {
padding: 84px 70px 0 80px;
position: absolute;
left: 0;
top: 0;
}
.footer .pLi .pn {
width: 76px;
height: 314px;
margin-right: 40px;
text-indent: -999em;
}
.footer .pLi .pn.active {
margin-top: -55px;
}
.footer .pLi .pn1 {
background: url(./images/pan0.png) no-repeat;
}
.footer .pLi .pn2 {
background: url(./images/pan1.png) no-repeat;
}
.footer .pLi .pn3 {
background: url(./images/pan2.png) no-repeat;
}
.footer .pLi .rubber {
background: url(./images/rubber.png) no-repeat;
}
.footer .pLi .colors {
width: 100px;
height: 100px;
background: url(./images/color.png) no-repeat;
margin-top: 15px;
}
.footer .cLi {
width: 100%;
height: 210px;
position: absolute;
left: 0;
top: 0
}
.footer .cLi .pn {
position: absolute;
left: 65px;
top: 30px;
width: 76px;
height: 314px;
background: url(./images/pan1.png) no-repeat;
}
.footer .cLi .cLs {
margin-left: 215px;
height: 180px;
width: 550px;
padding-top: 30px;
}
.footer .cLi .cLs li {
width: 60px;
height: 60px;
border-radius: 50%;
margin: 0 50px 30px 0;
}
.footer .cLi .cLs li.active {
border: 8px solid #ebebeb;
margin: -8px 42px 22px -8px;
}
.footer .cLi .cLs li:nth-child(1) {
background-color: #e30052;
}
.footer .cLi .cLs li:nth-child(2) {
background-color: #32b16c;
}
.footer .cLi .cLs li:nth-child(3) {
background-color: #f19715;
}
.footer .cLi .cLs li:nth-child(4) {
background-color: #00b8ec;
}
.footer .cLi .cLs li:nth-child(5) {
background-color: #5f549e;
}
.footer .cLi .cLs li:nth-child(6) {
background-color: #b6a900;
}
.footer .cLi .cLs li:nth-child(7) {
background-color: #005752;
}
.footer .cLi .cLs li:nth-child(8) {
background-color: #03004a;
}
.footer .cLi .cLs li:nth-child(9) {
background-color: #824e00;
}
.footer .cLi .cLs li:nth-child(10) {
background-color: #362e2b;
}
/*弹层*/
.pop-box {
position: absolute;
;
left: 0;
top: 0;
bottom: 0;
width: 100%;
background: rgba(0, 0, 0, .5);
z-index: 99999
}
.pop-box>div {
width: 480px;
padding: 60px 10px 60px;
background: #fff;
position: absolute;
left: 50%;
margin-left: -250px;
top: 400px;
text-align: center;
}
.pop-box>div img {
width: 100px;
height: 100px;
margin-bottom: 60px;
}
.pop-box>div p {
font-size: 4em;
}
.pop-box>div .close {
width: 80px;
height: 80px;
position: absolute;
right: 20px;
top: 20px;
background: url(./images/icon-close.png) no-repeat;
background-size: 100%;
text-indent: -999em;
}
/*动画*/
/*灰色背景*/
.bg-gray .header {
border-bottom: 1px solid #c0c0c0;
}
.bg-gray .container {
background: #ccc;
}
.bg-gray .footer {
border-top: 1px solid #c0c0c0;
}
/*选择画笔*/
.panChecked {
animation: panUp 500ms ease 1 forwards;
-webkit-animation: panUp 500ms ease 1 forwards;
}
.panDelChecked {
animation: panDown 500ms ease 1 forwards;
-webkit-animation: panDown 500ms ease 1 forwards;
}
@keyframes panUp {
0% {
transform: translateY(55px);
-webkit-transform: translateY(55px);
}
100% {
transform: translateY(0);
-webkit-transform: translateY(0);
}
}
@-webkit-keyframes panUp {
0% {
transform: translateY(55px);
-webkit-transform: translateY(55px);
}
100% {
transform: translateY(0);
-webkit-transform: translateY(0);
}
}
@keyframes panDown {
0% {
transform: translateY(-55px);
-webkit-transform: translateY(-55px);
}
100% {
transform: translateY(0);
-webkit-transform: translateY(0);
}
}
@-webkit-keyframes panDown {
0% {
transform: translateY(-55px);
-webkit-transform: translateY(-55px);
}
100% {
transform: translateY(0);
-webkit-transform: translateY(0);
}
}
/*画笔到颜色盘*/
/*颜色盘*/
.colorIn {
animation: colorIn 300ms ease 1 forwards;
-webkit-animation: colorIn 300ms ease 1 forwards;
}
.colorOut {
animation: colorOut 300ms ease 1 forwards;
-webkit-animation: colorOut 300ms ease 1 forwards;
}
@keyframes colorIn {
0% {
transform: scale(0);
-webkit-transform: scale(0);
}
100% {
transform: scale(1);
-webkit-transform: scale(1);
}
}
@-webkit-keyframes colorIn {
0% {
transform: scale(0);
-webkit-transform: scale(0);
}
100% {
transform: scale(1);
-webkit-transform: scale(1);
}
}
@keyframes colorOut {
0% {
transform: scale(1);
-webkit-transform: scale(1);
}
100% {
transform: scale(0);
-webkit-transform: scale(0);
}
}
@-webkit-keyframes colorOut {
0% {
transform: scale(1);
-webkit-transform: scale(1);
}
100% {
transform: scale(0);
-webkit-transform: scale(0);
}
}
//js代码 app_shouhui.js
var shouhui = {
stopAnimate: "webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend",
websocketUrl: "",
sessionID: 0,
companyID: 0,
hID: 0,
userID: 0,
photoUrl: "",
isTest: 2,
rand: 0,
recheck: 0
},
flag = !0,
canvasWidth = $("#canvas").width(),
canvasHeight = $("#canvas").height(),
strokeColor = "rgb(277,0,82)",
lineWidth = 10,
isMouseDown = !1,
lastLoc = {x: 0, y: 0},
curLoc = {x: 0, y: 0},
imgArr = [],
isErase = !1,
canvas = document.getElementById("canvas"),
context = canvas.getContext("2d");
canvas.width = canvasWidth, canvas.height = canvasHeight,
//手绘初始化
shouhui.initEvent = function () {
function h(a) {
var b = document.createElement("canvas");
return b.width = a.width, b.height = a.height, a.toDataURL() == b.toDataURL()
}
function i(a) {
isMouseDown = !0, lastLoc = m(a.x, a.y), context.save(), context.beginPath(), context.moveTo(lastLoc.x, lastLoc.y)
}
function j() {
isMouseDown = !1;
var a = canvas.toDataURL();
imgArr.push(a)
}
//绘制图形函数
function k(a) {
curLoc = m(a.x, a.y), isErase ? (context.globalCompositeOperation = "destination-out", context.lineTo(curLoc.x, curLoc.y), context.strokeStyle = "rgba(255,255,255,1)", context.lineWidth = 100, context.stroke()) : (context.globalCompositeOperation = "source-over", context.lineTo(curLoc.x, curLoc.y), context.strokeStyle = "rgba(" + f[g] + ",.9)", context.lineWidth = lineWidth, "20" == context.lineWidth ? (context.strokeStyle = "rgba(" + f[g] + ",.1)", context.miterLimit = 5) : "2" == context.lineWidth && (context.miterLimit = 10, context.lineCap = "round"), context.stroke()), lastLoc = curLoc
}
function m(a, b) {
var c = canvas.getBoundingClientRect();
return {x: Math.round(a - c.left), y: Math.round(b - c.top)}
}
var a, b, c, d, e, f, g;
$(".cancel").on("click", function () {
location.href = shouhui.indexUrl;
}),
$("#clear_btn").click(function () {
context.clearRect(0, 0, canvasWidth, canvasHeight), imgArr = []
}),
a = 1, b = 1, c = 1, f = ["227, 0, 82", "50, 177, 108", "241, 151, 21", "0, 184, 236", "95, 84, 158", "182, 169, 0", "0, 87, 82", "3, 0, 74", "130, 78, 0", "54, 46, 43"], g = 0,
//画笔类型
$(".pLi .pn").on("click", function () {
a = $(".pLi .pn").index(this),
$(".pLi .pn").removeClass("panChecked"),
$(".pLi .pn").removeClass("panDelChecked"),
a == c || (
b = c, c = a,
$(".pLi .pn:eq(" + b + ")").addClass("panDelChecked"),
$(".pLi .pn:eq(" + b + ")").removeClass("active"),
$(this).addClass("panChecked"),
$(this).addClass("active")
),
lineWidth = $(this).attr("data-width"),
isErase = "3" == a ? !0 : !1
}),
//取色器
$("#js_colorBar").on("click", function () {
isErase = !1, 3 == a && (
$(".pLi .pn:eq(" + a + ")").removeClass("active"),
$(".pLi .pn:eq(" + b + ")").addClass("active"),
a = b, c = b
),
d = $(".pLi .pn:eq(" + a + ")").offset().left,
e = $(".pLi .pn:eq(" + a + ")").offset().top - ($(window).height() - 210),
$(".cLi").removeClass("hidden"),
$(".cLi .pn").css({left: d, top: e}),
$(".cLi .pn").animate({left: 65, top: 30}, 300, "linear"),
$(".pLi").animate({top: 210}, 300, "linear"),
$(".pLi .pn:eq(" + a + ")").css("opacity", 0),
$(".cLi .cLs li").removeClass("colorOut"),
$(".cLi .cLs li").addClass("colorIn"),
$(".cLi .pn").css("background", "url(" + shouhui.photoUrl + "pan" + a + ".png)"),
lineWidth = $(".pLi .pn:eq(" + a + ")").attr("data-width")
}),
$(".cLi .pn").on("click", function () {
$(".cLi .cLs li").removeClass("colorIn"),
$(".cLi .cLs li").addClass("colorOut"),
$(".cLi .pn").animate({left: d, top: e}, 300, "linear"),
$(".pLi").animate({top: 0}, 300, "linear"),
setTimeout(function () {
$(".cLi ").addClass("hidden"),
$(".pLi .pn:eq(" + a + ")").css("opacity", 1)
}, 300)
}),
$(".cLi li").on("click", function () {
$(".cLi li").removeClass("active"),
$(this).addClass("active"),
g = $(".cLi li").index(this)
}),
//发送canvas到后台
$("#img_btn").on("click", function () {
if (h(canvas)) return $("#btn-success").html("您还没有留下大名呢~"),
$("#pro-img").attr("src", shouhui.photoUrl + "icon-warn.png"),
$(".pop-box").fadeIn("slow"),
setTimeout(function () {
$(".pop-box").fadeOut("slow")
}, 1e3), void 0;
var a = canvas.toDataURL("image/png"),
b = new Image;
b.src = a,
context.clearRect(0, 0, canvasWidth, canvasHeight),
imgArr = [],
shouhui.fire("", {url: a})
}),
context.lineCap = "round",
context.lineJoin = "round",
canvas.onmousedown = function (a) {
a.preventDefault(),
i({x: a.clientX, y: a.clientY})
},
canvas.onmouseup = function (a) {
a.preventDefault(), j()
},
canvas.onmouseout = function (a) {
a.preventDefault(), j()
},
canvas.onmousemove = function (a) {
a.preventDefault(), isMouseDown && k({x: a.clientX, y: a.clientY})
},
canvas.addEventListener("touchstart", function (a) {
a.preventDefault(), touch = a.touches[0], i({x: touch.pageX, y: touch.pageY})
}),
canvas.addEventListener("touchmove", function (a) {
a.preventDefault(), isMouseDown && (touch = a.touches[0], k({x: touch.pageX, y: touch.pageY}))
}),
canvas.addEventListener("touchend", function (a) {
a.preventDefault(), j()
})
},
//发送函数
shouhui.fire = function (a, b) {
// console.log(b.url);
$.post(shouhui.ajaxUrl, {url: 1, params: b.url}, function (idata) {
$("#pro-img").attr("src", shouhui.photoUrl + "icon-warn.png");
$(".pop-box").fadeIn("slow");
setTimeout(function () {
location.href = shouhui.indexUrl;
}, 1e3);
// console.log(idata);
}, "json");
};