Commit 8eb0c2d6 authored by liujiangnan's avatar liujiangnan

闪卡模板开发完成

parent 88f994c0
......@@ -39,12 +39,12 @@ var server = http.createServer(function (request, response) {
response.write("This request URL " + pathname + " was not found on this server.");
response.end();
} else {
fs.readFile(realPath, "binary", function (err, file) {
fs.readFile(realPath, "binary", function (err, file) {
if (err) {
response.writeHead(500, {
'Content-Type': 'text/plain'
});
response.end(err);
response.end(JSON.stringify(err));
} else {
var contentType = mine[ext] || "text/plain";
response.writeHead(200, {
......@@ -58,4 +58,6 @@ var server = http.createServer(function (request, response) {
});
});
server.listen(PORT);
console.log("Server runing at port: " + PORT + ".");
\ No newline at end of file
console.log("Server runing at port: " + PORT + ".");
console.log("http://localhost:" + PORT + "/index/index.html");
console.log("http://localhost:" + PORT + "/form/index.html");
\ No newline at end of file
.edit-form{
padding: 30px;
/* display: none; */
}
.img-area{
position: relative;
margin-bottom: 15px;
}
.check-item{
position: absolute;
top: 5px;
left: 25px;
display: none;
}
.info-area{
margin-top: 5px;
}
.alert{
display: none;
}
.preview{
width: 80px;
}
.close-view{
display: none;
position: absolute;
top: 5px;
right: 5px;
font-size: 25px;
}
#playView{
display: none;
}
\ No newline at end of file
......@@ -5,65 +5,205 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<base href="">
<title>h5-template-generator</title>
<script src="http://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<title>h5-template-generator</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet" >
<link href="./index.css" rel="stylesheet" >
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
<script type="text/javascript" src="/lib/js/jquery-1.12.3.min.js"></script>
<script type="text/javascript" src="/lib/js/vue.js"></script>
<!-- 引入样式 -->
<link href="/lib/js/element-ui/theme-chalk/index.css" rel="stylesheet">
<!-- 引入组件库 -->
<script src="/lib/js/element-ui/index.js"></script>
<script type="text/javascript" src="http://teach.cdn.ireadabc.com/h5template/h5-static-lib/js/air.js"></script>
</head>
<body>
<!-- 编辑区域 -->
<div class="edit-form container-fluid">
<div class="alert alert-danger" role="alert"></div>
<div class="row">
<div class="img-area col-xs-6 col-sm-6 col-md-6 col-lg-6">
<input class="check-item" type="checkbox" value="1" />
<img src="../lib/images/jiangzhuang_Img1@3x.png" class="img-thumbnail ">
</div>
<div class="img-area col-xs-6 col-sm-6 col-md-6 col-lg-6">
<input class="check-item" type="checkbox" value="2" />
<img src="../lib/images/jiangzhuang_Img2@3x.png" class="img-thumbnail ">
</div>
<div class="img-area col-xs-6 col-sm-6 col-md-6 col-lg-6">
<input class="check-item" type="checkbox" value="3" />
<img src="../lib/images/jiangzhuang_Img3@3x.png" class="img-thumbnail ">
</div>
<div class="img-area col-xs-6 col-sm-6 col-md-6 col-lg-6">
<input class="check-item" type="checkbox" value="4" />
<img src="../lib/images/jiangzhuang_Img4@3x.png" class="img-thumbnail ">
</div>
<div class="img-area col-xs-6 col-sm-6 col-md-6 col-lg-6">
<input class="check-item" type="checkbox" value="5" />
<img src="../lib/images/jiangzhuang_Img5@3x.png" class="img-thumbnail ">
</div>
<div class="img-area col-xs-6 col-sm-6 col-md-6 col-lg-6">
<input class="check-item" type="checkbox" value="6" />
<img src="../lib/images/jiangzhuang_Img6@3x.png" class="img-thumbnail ">
</div>
</div>
<form class="info-area">
<div class="form-group">
<input type="text" class="form-control" id="praise" placeholder="请填写表扬文本">
</div>
<div class="form-group">
<input type="date" class="form-control" id="date" placeholder="日期">
<div id="app" class="edit-form">
<template v-if="pageType==='form'">
<el-upload
class="avatar-uploader"
action=""
:auto-upload="false"
:show-file-list="false"
:on-change="handlechangeFile">
<img id="card-image" v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
<div class="img-text" :style="{fontSize: textsize + 'px', color: textcolor, 'font-weight': textStrong?'800':'100' }">{{imgText}}</div>
<br>
<div v-if="imgText" align="center">
<el-button-group>
<el-button size="small" type="primary" @click="handleTextStrong">字体加粗</el-button>
<el-button size="small" type="primary" @click="handleTextSize">字体大小</el-button>
<el-button size="small" type="primary" @click="handleTextColor">字体颜色</el-button>
</el-button-group>
<el-slider v-if="showSize" v-model="textsize" :min="13"></el-slider>
<el-color-picker v-if="showColor" v-model="textcolor"></el-color-picker>
</div>
<div class="form-group">
<input type="text" class="form-control" id="sign" placeholder="老师签名">
</div>
<button type="button" class="btn btn-success preview">预览</button>
</form>
</div>
<br>
<el-input v-model="imgText" placeholder="请输入内容"></el-input>
<el-select v-model="cardSize" placeholder="请选择尺寸" style="margin-top: 10px;">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
<el-button type="primary" @click="handleView" style="width: 50%; margin-top: 10px;">预览</el-button>
</template>
<template v-else>
<img :src="playView" style="width: 100%;"/>
<span class="el-icon-close close-view" @click="hidePlay"></span>
</template>
</div>
</body>
<script>
</script>
<script>
new Vue({
el: '#app',
created() {
},
data() {
return {
<!-- 展示区域 -->
<img id="playView" src="" />
<span class="glyphicon glyphicon-remove text-success close-view"></span>
pageType: 'form',
imageUrl: '',
imgText: '',
//字体加粗
textStrong: false,
//控制字体大小
showSize: false,
textsize: 15,
//控制字体颜色
showColor: false,
textcolor: '#000',
//闪卡的尺寸选择
cardSize: '',
options: [
{label:"A3",value: '842×1193'},
{label:"A4",value: '595×842'},
{label:"A5",value: '420×595'},
{label:"A6",value: '298×420'}
],
</body>
<script src="./index.js"></script>
play: null,
playView: ''
};
},
methods: {
hidePlay(){
let ctx = this.play.getContext("2d");
let cSize = this.cardSize.split("×");
let cardWidth = cSize[0];
let cardHeight = cSize[1];
ctx.clearRect(0, 0, cardWidth, cardHeight);
this.pageType = 'form';
},
handleTextStrong(){
this.textStrong = !this.textStrong;
},
handleTextSize(){
this.showColor = false;
this.showSize = true;
},
handleTextColor(){
this.showSize = false;
this.showColor = true;
},
handleView(){
if(!this.cardSize){
this.$message.error('请选择尺寸!');
return;
}
let cSize = this.cardSize.split("×");
let cardWidth = cSize[0];
let cardHeight = cSize[1];
if(!this.play){
this.play = document.createElement('canvas');
}
$(this.play).attr("width",cardWidth);
$(this.play).attr("height",cardHeight);
let ctx = this.play.getContext("2d");
ctx.clearRect(0, 0, cardWidth, cardHeight);
ctx.fillStyle="#fff";
ctx.fillRect(0,0,cardWidth,cardHeight);
let img = new Image();
img.onload = ()=>{
ctx.drawImage(img ,0,0,cardWidth, cardHeight-this.textsize-20);
ctx.font=`${this.textsize}px Arial`;
ctx.fillStyle = this.textcolor;
ctx.textAlign='center';
ctx.fillText(this.imgText,cardWidth/2,cardHeight-20);
this.playView = this.play.toDataURL('image/jpeg', 1.0);
this.pageType = 'play';
}
img.src = this.imageUrl;
},
handlechangeFile(file) {
const isJPG = file.raw.type.indexOf('image');
if (isJPG<0) {
this.$message.error('选择的图片只能是 JPG 格式!');
} else {
this.imageUrl = URL.createObjectURL(file.raw);
}
}
}
});
</script>
<style>
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
width: 100%;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 100%;
height: 178px;
line-height: 178px;
text-align: center;
}
.avatar {
width: 100%;
display: block;
}
.img-text{
padding-top: 10px;
text-align: center;
}
.edit-form{
padding: 30px;
}
.close-view{
position: absolute;
top: 5px;
right: 5px;
font-size: 25px;
}
</style>
</html>
\ No newline at end of file
var ctx, sprite, img, _w, _h, play;
function initPreviewPage(imgIndex, callback){
img = new Image();
img.onload = function(){
// play=$("#play");
// play.attr("width",img.width);
// play.attr("height",img.height);
play = document.createElement('canvas');
$(play).attr("width",img.width);
$(play).attr("height",img.height);
ctx=play.getContext("2d");
ctx.clearRect(0, 0, img.width, img.height);
ctx.drawImage(img,0,0);
renderText(imgIndex);
callback&&callback();
}
img.src = "../lib/images/jiangzhuang_Img"+imgIndex+"@3x.png";
}
function renderText(imgIndex){
var praise = $("#praise").val();
var date = $("#date").val();
var sign = $("#sign").val();
ctx.font="18px Arial";
ctx.textAlign='center';
if(imgIndex==1){
ctx.fillText(praise,230,170);
ctx.fillText(date,325,240);
ctx.fillText(sign,150,240);
} else if (imgIndex==2){
ctx.font="30px Arial";
ctx.fillText("You are very good!",410,330);
ctx.fillText("2019-12-24",275,495);
ctx.fillText("Tom",605,495);
} else if (imgIndex==3){
ctx.fillText(praise,230,155);
ctx.fillText(date,255,205);
ctx.fillText(sign,255,255);
} else if (imgIndex==4){
ctx.fillText(praise,250,120);
ctx.fillText(date,210,240);
ctx.fillText(sign,335,240);
} else if (imgIndex==5){
ctx.fillText(praise,250,165);
ctx.fillText(date,250,250);
} else if (imgIndex==6){
ctx.fillText(praise,270,185);
ctx.fillText(date,305,267);
ctx.fillText(sign,305,225);
}
}
$(function(){
_w = $(window).width();
_h = $(window).height();
$(".img-area").bind('click',function(){
$(".check-item").attr("checked",false).hide();
$(this).find(".check-item").attr("checked",true).show();
$(".alert").html("").hide();
});
$(".close-view").bind('click',function(){
$(this).hide();
$("#playView").hide();
$(".edit-form").show();
});
$(".preview").bind('click', function(){
let cardIndex = $('input:checkbox[class="check-item"]:checked').eq(0).val();
if(cardIndex==undefined){
$(".alert").html("请选择奖状!").show(300);
return;
}
$(".edit-form").hide();
initPreviewPage(cardIndex,function(){
let imgUrl = play.toDataURL('image/jpeg', 1.0);
$('#playView').attr('src', imgUrl);
$('#playView').css({height: _w});
$('#playView')[0].onload = function(){
var play_w = $('#playView').width();
var right = Math.floor(play_w/2)+35;
var top = _w-Math.floor(play_w/2)-35;
var margin_top = Math.floor((_h-play_w)/2);
$('#playView').css({
"position": "absolute",
"transform":"rotate(90deg)",
"right": (right-_w)+"px",
"top": (top+margin_top)+"px"
}).show();
};
});
$(".close-view").show();
});
});
\ No newline at end of file
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
class MySprite {
x = 0;
y = 0;
radius = 0;
margin = 0;
ctx;
_width = 0;
_height = 0;
_anchorX = 0;
_anchorY = 0;
_offX = 0;
_offY = 0;
scaleX = 1;
scaleY = 1;
_alpha = 1;
rotation = 0;
visible = true;
skewX = 0;
skewY = 0;
_shadowFlag = false;
_shadowColor;
_shadowOffsetX = 0;
_shadowOffsetY = 0;
_shadowBlur = 5;
_radius = 0;
children = [this];
childDepandVisible = true;
childDepandAlpha = false;
img;
_z = 0;
constructor(ctx = null) {
if (!ctx) {
this.ctx = window['curCtx'];
} else {
this.ctx = ctx;
}
}
init(imgObj = null, anchorX = 0.5, anchorY = 0.5) {
if (imgObj) {
this.img = imgObj;
this.width = this.img.width;
this.height = this.img.height;
}
this.anchorX = anchorX;
this.anchorY = anchorY;
}
setShadow(offX, offY, blur, color = 'rgba(0, 0, 0, 0.3)') {
this._shadowFlag = true;
this._shadowColor = color;
this._shadowOffsetX = offX;
this._shadowOffsetY = offY;
this._shadowBlur = blur;
}
setRadius(r) {
this._radius = r;
}
update($event = null) {
if (!this.visible && this.childDepandVisible) {
return;
}
this.draw();
}
draw() {
this.ctx.save();
this.drawInit();
this.updateChildren();
this.ctx.restore();
}
drawInit() {
this.ctx.translate(this.x, this.y);
this.ctx.rotate(this.rotation * Math.PI / 180);
this.ctx.scale(this.scaleX, this.scaleY);
this.ctx.globalAlpha = this.alpha;
this.ctx.transform(1, this.skewX, this.skewY, 1, 0, 0);
if (this._radius) {
const r = this._radius;
const w = this.width;
const h = this.height;
this.ctx.lineTo(-w / 2, h / 2); // 创建水平线
this.ctx.arcTo(-w / 2, -h / 2, -w / 2 + r, -h / 2, r);
this.ctx.arcTo(w / 2, -h / 2, w / 2, -h / 2 + r, r);
this.ctx.arcTo(w / 2, h / 2, w / 2 - r, h / 2, r);
this.ctx.arcTo(-w / 2, h / 2, -w / 2, h / 2 - r, r);
this.ctx.clip();
}
}
drawSelf() {
if (this._shadowFlag) {
this.ctx.shadowOffsetX = this._shadowOffsetX;
this.ctx.shadowOffsetY = this._shadowOffsetY;
this.ctx.shadowBlur = this._shadowBlur;
this.ctx.shadowColor = this._shadowColor;
} else {
this.ctx.shadowOffsetX = 0;
this.ctx.shadowOffsetY = 0;
this.ctx.shadowBlur = null;
this.ctx.shadowColor = null;
}
if (this.img) {
this.ctx.drawImage(this.img, this._offX, this._offY);
}
}
updateChildren() {
if (this.children.length <= 0) { return; }
for (let i = 0; i < this.children.length; i++) {
if (this.children[i] === this) {
if (this.visible) {
this.drawSelf();
}
} else {
this.children[i].update();
}
}
}
load(url, anchorX = 0.5, anchorY = 0.5) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = reject;
img.src = url;
}).then(img => {
this.init(img, anchorX, anchorY);
return img;
});
}
addChild(child, z = 1) {
if (this.children.indexOf(child) === -1) {
this.children.push(child);
child._z = z;
child.parent = this;
}
this.children.sort((a, b) => {
return a._z - b._z;
});
if (this.childDepandAlpha) {
child.alpha = this.alpha;
}
}
removeChild(child) {
const index = this.children.indexOf(child);
if (index !== -1) {
this.children.splice(index, 1);
}
}
removeChildren() {
for (let i = 0; i < this.children.length; i++) {
if (this.children[i]) {
if (this.children[i] != this) {
this.children.splice(i, 1);
i --;
}
}
}
}
_changeChildAlpha(alpha) {
for (let i = 0; i < this.children.length; i++) {
if (this.children[i] != this) {
this.children[i].alpha = alpha;
}
}
}
set alpha(v) {
this._alpha = v;
if (this.childDepandAlpha) {
this._changeChildAlpha(v);
}
}
get alpha() {
return this._alpha;
}
set width(v) {
this._width = v;
this.refreshAnchorOff();
}
get width() {
return this._width;
}
set height(v) {
this._height = v;
this.refreshAnchorOff();
}
get height() {
return this._height;
}
set anchorX(value) {
this._anchorX = value;
this.refreshAnchorOff();
}
get anchorX() {
return this._anchorX;
}
set anchorY(value) {
this._anchorY = value;
this.refreshAnchorOff();
}
get anchorY() {
return this._anchorY;
}
refreshAnchorOff() {
this._offX = -this._width * this.anchorX;
this._offY = -this._height * this.anchorY;
}
setScaleXY(value) {
this.scaleX = this.scaleY = value;
}
getBoundingBox() {
const getParentData = (item) => {
let px = item.x;
let py = item.y;
let sx = item.scaleX;
let sy = item.scaleY;
const parent = item.parent;
if (parent) {
const obj = getParentData(parent);
const _x = obj.px;
const _y = obj.py;
const _sx = obj.sx;
const _sy = obj.sy;
px = _x + item.x * _sx;
py = _y + item.y * _sy;
sx *= _sx;
sy *= _sy;
}
return {px, py, sx, sy};
};
const data = getParentData(this);
const x = data.px + this._offX * Math.abs(data.sx);
const y = data.py + this._offY * Math.abs(data.sy);
const width = this.width * Math.abs(data.sx);
const height = this.height * Math.abs(data.sy);
// const x = this.x + this._offX * Math.abs(this.scaleX);
// const y = this.y + this._offY * Math.abs(this.scaleY);
// const width = this.width * Math.abs(this.scaleX);
// const height = this.height * Math.abs(this.scaleY);
return {x, y, width, height};
}
}
\ No newline at end of file
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment