You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
399 lines
11 KiB
JavaScript
399 lines
11 KiB
JavaScript
6 years ago
|
// Handwriting plugin
|
||
|
;(function($) {
|
||
|
$.fn.handwriting = function(options) {
|
||
|
|
||
|
var settings = {
|
||
|
brushColor: "rgba(0, 0, 0, 0.25)"
|
||
|
};
|
||
|
|
||
|
settings = $.extend(settings, options || {});
|
||
|
|
||
|
return new handwritingClass(this, settings);
|
||
|
};
|
||
|
|
||
|
var handwritingClass = function($element, settings) {
|
||
|
|
||
|
this.$canvas = $element;
|
||
|
this.moveFlag = false;
|
||
|
this.upof = {};
|
||
|
// this.radius = 0;
|
||
|
// this.lineMax = 40;
|
||
|
// this.lineMin = 5;
|
||
|
// this.linePressure = 3;
|
||
|
// this.smoothness = 200;
|
||
|
|
||
|
this.radius = 0;
|
||
|
this.lineMax = 40;
|
||
|
this.lineMin = 10;
|
||
|
this.linePressure = 5;
|
||
|
this.smoothness = 200;
|
||
|
|
||
|
this.undoList = [];
|
||
|
this.stepList = [];
|
||
|
this.stepListener = settings.stepListener;
|
||
|
|
||
|
this.canvas = this.$canvas[0];
|
||
|
this.context2d = this.canvas.getContext("2d");
|
||
|
this.context2d.fillStyle = settings.brushColor;
|
||
|
|
||
|
var source = this;
|
||
|
|
||
|
this.canvas.addEventListener('mousedown', function(event) {
|
||
|
downEvent(source, event)
|
||
|
});
|
||
|
this.canvas.addEventListener('mousemove', function(event) {
|
||
|
moveEvent(source, event)
|
||
|
});
|
||
|
this.canvas.addEventListener('mouseup', function(event) {
|
||
|
upEvent(source, event)
|
||
|
});
|
||
|
this.canvas.addEventListener('mouseout', function(event) {
|
||
|
upEvent(source, event)
|
||
|
});
|
||
|
|
||
|
function downEvent(source, event) {
|
||
|
source.moveFlag = true;
|
||
|
source.has = [];
|
||
|
source.upof = getXY(source, event);
|
||
|
source.stepList = [];
|
||
|
}
|
||
|
|
||
|
function upEvent(source, event) {
|
||
|
if (source.moveFlag) {
|
||
|
source.undoList.push(source.stepList);
|
||
|
if (source.stepListener != null) {
|
||
|
source.stepListener(source, source.undoList.length);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
source.moveFlag = false;
|
||
|
}
|
||
|
|
||
|
function moveEvent(source, event) {
|
||
|
if (!source.moveFlag) return;
|
||
|
|
||
|
var xy = getXY(source, event);
|
||
|
var up = source.upof;
|
||
|
var ur = source.radius;
|
||
|
source.has.unshift({
|
||
|
time: new Date().getTime(),
|
||
|
dis: distance(up, xy)
|
||
|
});
|
||
|
var dis = 0;
|
||
|
var time = 0;
|
||
|
for (var n = 0; n < source.has.length - 1; n++) {
|
||
|
dis += source.has[n].dis;
|
||
|
time += source.has[n].time - source.has[n + 1].time;
|
||
|
if (dis > source.smoothness)
|
||
|
break;
|
||
|
}
|
||
|
var or = Math.min(time / dis * source.linePressure + source.lineMin, source.lineMax) / 2;
|
||
|
|
||
|
source.radius = or;
|
||
|
source.upof = xy;
|
||
|
|
||
|
if (source.has.length <= 4) return;
|
||
|
|
||
|
var len = Math.round(source.has[0].dis / 2) + 1;
|
||
|
var context2d = source.context2d;
|
||
|
var pathList = [];
|
||
|
for (var i = 0; i < len; i++) {
|
||
|
var x = up.x + (xy.x - up.x) / len * i;
|
||
|
var y = up.y + (xy.y - up.y) / len * i;
|
||
|
var r = ur + (or - ur) / len * i;
|
||
|
context2d.beginPath();
|
||
|
context2d.arc(x, y, r, 0, 2 * Math.PI, true);
|
||
|
context2d.fill();
|
||
|
pathList[i] = {
|
||
|
"x": x,
|
||
|
"y": y,
|
||
|
"r": r
|
||
|
};
|
||
|
}
|
||
|
source.stepList.push(pathList);
|
||
|
}
|
||
|
|
||
|
function getXY(source, event) {
|
||
|
var $offset = source.$canvas.offset();
|
||
|
return {
|
||
|
x: event.clientX - $offset.left + (document.body.scrollLeft || document.documentElement.scrollLeft),
|
||
|
y: event.clientY - $offset.top + (document.body.scrollTop || document.documentElement.scrollTop)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function distance(a, b) {
|
||
|
var x = b.x - a.x,
|
||
|
y = b.y - a.y;
|
||
|
return Math.sqrt(x * x + y * y);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
handwritingClass.prototype = {
|
||
|
toDataURL: function() {
|
||
|
return this.canvas.toDataURL("image/png");
|
||
|
},
|
||
|
clear: function() {
|
||
|
this.context2d.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
||
|
this.undoList = [];
|
||
|
this.stepList = [];
|
||
|
},
|
||
|
undo: function() {
|
||
|
this.context2d.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
||
|
this.undoList.splice(this.undoList.length - 1, 1);
|
||
|
|
||
|
for (var undoNum = 0; undoNum < this.undoList.length; undoNum++) {
|
||
|
var undoStep = this.undoList[undoNum];
|
||
|
|
||
|
for (var stepNum = 0; stepNum < undoStep.length; stepNum++) {
|
||
|
var stepPath = undoStep[stepNum];
|
||
|
|
||
|
for (var pathNum = 0; pathNum < stepPath.length; pathNum++) {
|
||
|
var path = stepPath[pathNum];
|
||
|
this.context2d.beginPath();
|
||
|
this.context2d.arc(path.x, path.y, path.r, 0, 2 * Math.PI, true);
|
||
|
this.context2d.fill();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
})(jQuery);
|
||
|
|
||
|
// Greeting card plugin
|
||
|
;(function($) {
|
||
|
$.fn.greetingCard = function(options) {
|
||
|
return new greetingCardClass(this);
|
||
|
};
|
||
|
|
||
|
var greetingCardClass = function($element, settings) {
|
||
|
this.$canvas = $element;
|
||
|
this.canvas = this.$canvas[0];
|
||
|
this.context2d = this.canvas.getContext("2d");
|
||
|
};
|
||
|
|
||
|
greetingCardClass.prototype = {
|
||
|
toDataURL: function() {
|
||
|
return this.canvas.toDataURL("image/png");
|
||
|
},
|
||
|
toDownloadURL: function() {
|
||
|
return this.canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
|
||
|
},
|
||
|
merge: function(dataURL, cardId, dx, dy, dwidth, dheight, callback) {
|
||
|
var self = this;
|
||
|
var mergeContext2d = this.context2d;
|
||
|
mergeContext2d.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
||
|
|
||
|
var cardImage = document.getElementById(cardId);
|
||
|
cardImage.crossOrigin = "Anonymous";
|
||
|
mergeContext2d.drawImage(cardImage, 0, 0);
|
||
|
|
||
|
var writeImage = new Image();
|
||
|
writeImage.crossOrigin = "Anonymous";
|
||
|
writeImage.src = dataURL;
|
||
|
writeImage.onload = function() {
|
||
|
var sx = sy = 0;
|
||
|
var swidth = writeImage.width;
|
||
|
var sheight = writeImage.height;
|
||
|
mergeContext2d.drawImage(writeImage, sx, sy, swidth, sheight, dx, dy, dwidth, dheight);
|
||
|
|
||
|
if (callback != undefined) callback(self.toDataURL());
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
})(jQuery);
|
||
|
|
||
|
// Preview card plugin
|
||
|
;
|
||
|
(function($) {
|
||
|
$.fn.previewCard = function(options) {
|
||
|
return new previewCardClass(this);
|
||
|
};
|
||
|
|
||
|
var previewCardClass = function($element, settings) {
|
||
|
this.canvas = document.createElement('canvas');
|
||
|
this.canvas.width = 610;
|
||
|
this.canvas.height = 394;
|
||
|
this.context2d = this.canvas.getContext("2d");
|
||
|
this.desc = $element.data("desc");
|
||
|
this.cardImage = $element[0];
|
||
|
this.originImage = new Image();
|
||
|
this.originImage.src = $element.data("src");
|
||
|
};
|
||
|
|
||
|
previewCardClass.prototype = {
|
||
|
mergeTo: function(dataURL) {
|
||
|
var self = this;
|
||
|
var cardDesc = this.desc;
|
||
|
this.context2d.drawImage(this.originImage, 0, 0);
|
||
|
|
||
|
var writeImage = new Image();
|
||
|
writeImage.src = dataURL;
|
||
|
writeImage.onload = function() {
|
||
|
var sx = sy = 0;
|
||
|
var swidth = writeImage.width;
|
||
|
var sheight = writeImage.height;
|
||
|
|
||
|
self.context2d.drawImage(writeImage,
|
||
|
sx, sy, swidth, sheight,
|
||
|
self.desc.dx, self.desc.dy, self.desc.dw, self.desc.dh);
|
||
|
var mergeDataURL = self.canvas.toDataURL("image/png");
|
||
|
self.cardImage.src = mergeDataURL;
|
||
|
};
|
||
|
}
|
||
|
};
|
||
|
})(jQuery);
|
||
|
|
||
|
$(function() {
|
||
|
var THIRD_STEP_ACTION = 1;
|
||
|
var UNDO_ACTION = 2;
|
||
|
var CLEAR_ACTION = 3;
|
||
|
var FINISH_ACTION = 4;
|
||
|
var SEND_ACTION = 5;
|
||
|
|
||
|
var $handwriting = $("#writeCanvas").handwriting({
|
||
|
stepListener: function(source, step) {
|
||
|
if (step == 3) {
|
||
|
sendGreetingCardLog(THIRD_STEP_ACTION);
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
var $greetingCard = $("#greetingCardCanvas").greetingCard();
|
||
|
var newYearCard1 = $("#new-year-card-1").previewCard();
|
||
|
var newYearCard2 = $("#new-year-card-2").previewCard();
|
||
|
var newYearCard3 = $("#new-year-card-3").previewCard();
|
||
|
var newYearCard4 = $("#new-year-card-4").previewCard();
|
||
|
|
||
|
var $cardForm = $("#card_form");
|
||
|
var $toNameResult = $("#to_name_result");
|
||
|
var $toEmailResult = $("#to_email_result");
|
||
|
var $thanksArea = $("#thanksArea");
|
||
|
var $successMessage = $("#successMessage");
|
||
|
var $sendingMessage = $("#sendingMessage");
|
||
|
|
||
|
var $sendToButton = $("#sendToButton");
|
||
|
var $sendArea = $("#sendArea");
|
||
|
|
||
|
$(".cardList").each(function(index, element) {
|
||
|
$(element).on("click", function() {
|
||
|
$("#greetingCardPreview").fadeIn();
|
||
|
var desc = $("img", this).data("desc");
|
||
|
|
||
|
$greetingCard.merge(
|
||
|
$handwriting.toDataURL(), desc.cardId,
|
||
|
desc.dx, desc.dy, desc.dw, desc.dh);
|
||
|
|
||
|
var base64 = $greetingCard.toDataURL();
|
||
|
$("#image_data").attr("value", base64);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
$("#finishButton").click(function() {
|
||
|
sendGreetingCardLog(FINISH_ACTION);
|
||
|
var $cardSelect = $("#cardSelect");
|
||
|
$cardSelect.fadeIn();
|
||
|
var scrollTo = $cardSelect.offset().top - $cardSelect.height();
|
||
|
$("body").animate({
|
||
|
scrollTop: scrollTo
|
||
|
});
|
||
|
|
||
|
newYearCard1.mergeTo($handwriting.toDataURL());
|
||
|
newYearCard2.mergeTo($handwriting.toDataURL());
|
||
|
newYearCard3.mergeTo($handwriting.toDataURL());
|
||
|
newYearCard4.mergeTo($handwriting.toDataURL());
|
||
|
});
|
||
|
|
||
|
$("#saveCardButton").click(function() {
|
||
|
var saveLink = document.createElement("a");
|
||
|
saveLink.href = $greetingCard.toDownloadURL();
|
||
|
saveLink.download = "chinese-new-year-" + (new Date()).getTime() + ".png";
|
||
|
|
||
|
var clickEvent = document.createEvent("MouseEvents");
|
||
|
clickEvent.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
|
||
|
saveLink.dispatchEvent(clickEvent);
|
||
|
});
|
||
|
|
||
|
$("#clearButton").click(function() {
|
||
|
sendGreetingCardLog(CLEAR_ACTION);
|
||
|
$handwriting.clear();
|
||
|
});
|
||
|
|
||
|
$("#undoButton").click(function() {
|
||
|
sendGreetingCardLog(UNDO_ACTION);
|
||
|
$handwriting.undo();
|
||
|
});
|
||
|
|
||
|
$("#closeButton").click(function() {
|
||
|
$("#greetingCardPreview").fadeOut();
|
||
|
$thanksArea.fadeOut();
|
||
|
|
||
|
$sendToButton.addClass("sending");
|
||
|
$sendArea.attr("data-status", "display");
|
||
|
$sendArea.fadeIn();
|
||
|
|
||
|
});
|
||
|
|
||
|
$sendToButton.click(function() {
|
||
|
var areaStatus = $sendArea.attr("data-status");
|
||
|
$thanksArea.hide();
|
||
|
|
||
|
if (areaStatus == "hidden") {
|
||
|
$sendToButton.addClass("sending");
|
||
|
$sendArea.attr("data-status", "display");
|
||
|
$sendArea.fadeIn();
|
||
|
} else {
|
||
|
$sendArea.attr("data-status", "hidden");
|
||
|
$sendArea.fadeOut();
|
||
|
$sendToButton.removeClass("sending");
|
||
|
}
|
||
|
});
|
||
|
|
||
|
$cardForm.submit(function() {
|
||
|
$sendToButton.removeClass("sending");
|
||
|
$sendArea.attr("data-status", "hidden");
|
||
|
$sendArea.hide();
|
||
|
|
||
|
$successMessage.hide();
|
||
|
$sendingMessage.show();
|
||
|
$thanksArea.fadeIn();
|
||
|
|
||
|
$.ajax({
|
||
|
type: "POST",
|
||
|
url: "/guide-use.php/travelguide/sendGreetingCardByAjax/",
|
||
|
dataType: "json",
|
||
|
data: $cardForm.serializeArray(),
|
||
|
success: function(result) {
|
||
|
if (result.hasError) {
|
||
|
$sendingMessage.text(result.errorMessage);
|
||
|
console.info(result.detailMessage);
|
||
|
return false;
|
||
|
} else {
|
||
|
$successMessage.show();
|
||
|
$sendingMessage.hide();
|
||
|
$toNameResult.text(result.data.M_ToName);
|
||
|
$toEmailResult.text(result.data.M_ToEmail);
|
||
|
return true;
|
||
|
}
|
||
|
},
|
||
|
error: function(err) {
|
||
|
console.info(err);
|
||
|
return false;
|
||
|
}
|
||
|
});
|
||
|
return false;
|
||
|
});
|
||
|
|
||
|
function sendGreetingCardLog(action) {
|
||
|
$.ajax({
|
||
|
type: "POST",
|
||
|
url: "/guide-use.php/travelguide/logGreetingCard/",
|
||
|
dataType: "json",
|
||
|
data: {log_action: action},
|
||
|
success: function(result) {
|
||
|
},
|
||
|
error: function(err) {
|
||
|
return false;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
});
|