ycc.js
Version:
Mini and powerful canvas engine for creating App or Game.
465 lines (381 loc) • 10.9 kB
HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name=viewport content="width=device-width,initial-scale=1,user-scalable=0,viewport-fit=cover">
<title>简单的编辑器</title>
<link rel="stylesheet" href="../style.css">
<style>
*{margin: 0;padding: 0;}
body{
position: relative;
}
#canvas{
position: relative;
}
#canvas canvas{
border:1px solid #ccc;
}
.ctrl{
position: relative;
}
#photos{
border-top:1px solid #ccc;
margin-top: 10px;
padding-top:10px;
}
#photos canvas{
width:80px;
}
</style>
</head>
<body>
<div class="return-btn">
<a href="../">
返回首页
</a>
</div>
<div class="tip">
<h3>示例说明:</h3>
<div>
1、这个示例是一个简单的画板,类似QQ等截图软件截图后的编辑操作。<br>
2、点击不同的功能按钮后,PC端可以在绘图区拖动鼠标,移动端可以拖拽来查看不同的操作。<br>
3、每次操作完成之后,下方会生成当前的历史记录,以图片的形式显示。<br>
</div>
<br><br>
</div>
<div>
<div class="ctrl">
<button onclick="goBack()">回退</button>
<button onclick="zoomIn()">放大</button>
<button onclick="zoomOut()">缩小</button>
<button onclick="rotate()">旋转</button>
<button onclick="line()">直线</button>
<button onclick="pen()">钢笔</button>
<button onclick="rect()">方框</button>
<button onclick="ellipse()">椭圆</button>
<button onclick="gou()">勾勾</button>
<button onclick="cross()">叉叉</button>
<button onclick="text()">文字</button>
</div>
<br>
<div id="canvas">
</div>
<br>
历史操作:
<div id="photos"></div>
</div>
</body>
</html>
<script src="../common.js"></script>
<script src="http://localhost:9000/livereload.js"></script>
<script src="../../build/ycc.js"></script>
<script>
// 需要加载的图片资源路径和名称
var imageResources = [
{name:'tick',url:"./tick.png"},
{name:'cross',url:"./cross.png"},
{name:'paper',url:"./paper.jpg"},
];
// 资源加载完成后,所有资源的引用
var imageRes = null;
// ycc实例
var ycc = null;
// 本例所有操作都在一个图层完成
var layer = null;
// 画板底图
var paper = null;
// 放大缩小的比例
var scale = 1;
// canvas初始宽度
var originWidth = 0;
var originHeight = 0;
// 加载器实例
new Ycc.Loader().loadResParallel(imageResources,function (arr,imgs) {
imageRes = imgs;
// 新建渲染舞台
// var canvas = document.createElement("canvas");
// canvas.width = 300;//imageRes.paper.width;
// canvas.height = 200;//imageRes.paper.height;
// originWidth = canvas.width;
// document.getElementById("canvas").appendChild(canvas);
ycc = new Ycc();
var canvas = ycc.createCanvas({width:imgs.paper.width,height:imgs.paper.height,dpiAdaptation:true});
document.getElementById("canvas").appendChild(canvas);
ycc.bindCanvas(canvas);
originWidth = canvas.width;
originHeight = canvas.height;
layer = ycc.layerManager.newLayer({name:"试卷图层"});
layer.enableEventManager = true;
layer.onclick = function (e) {
console.log(this,e);
};
// layer.ui.image(imgs.paper,[0,0]);
paper = new Ycc.UI.Image({
rect:new Ycc.Math.Rect(0,0,imgs.paper.width,imgs.paper.height),
res:imgs.paper,
anchorX:imgs.paper.width/2,
anchorY:imgs.paper.height/2
});
layer.addUI(paper);
ycc.layerManager.reRenderAllLayerToStage();
ycc.photoManager.takePhoto();
});
function showPhotoToHtml() {
var dom = document.getElementById("photos");
dom.innerHTML = "";
for(var i = 0;i<ycc.photoManager._photos.length;i++){
var canvas = document.createElement("canvas");
canvas.width = 300;
canvas.height = 200;
canvas.create_time = ycc.photoManager._photos[i].createTime;
var ctx = canvas.getContext('2d');
ctx.putImageData(ycc.photoManager._photos[i].imageData,0,0);
dom.appendChild(canvas);
}
}
/**
* 放大
*/
function zoomIn() {
scale+=0.1;
// ycc.canvasDom.width = ycc.canvasDom.width*scale;
// ycc.canvasDom.height = ycc.canvasDom.height*scale;
// ycc.layerManager.reRenderAllLayerToStage();
ycc.canvasDom.style.width = originWidth*scale+"px";
ycc.layerList[0].uiList[0].scaleX = scale;
ycc.layerList[0].uiList[0].scaleY = scale;
ycc.layerManager.reRenderAllLayerToStage();
// ycc.canvasDom.style.width = originWidth*scale+"px";
}
/**
* 缩小
*/
function zoomOut() {
scale-=0.1;
ycc.canvasDom.style.width = originWidth*scale+"px";
}
/**
* 旋转
*/
function rotate(){
paper.rotation+=90;
paper.rotation = paper.rotation>=360?0:paper.rotation;
if(paper.rotation===90){
paper.rect.x = (paper.res.width-paper.res.height)/2;
paper.rect.y = (paper.res.width-paper.res.height)/2;
ycc.canvasDom.width = paper.res.height;
ycc.canvasDom.height = paper.res.width;
ycc.canvasDom.style.width=ycc.canvasDom.width*ycc.dpi*scale+'px';
}
if(paper.rotation===180 || paper.rotation===0){
paper.rect.x = 0;
paper.rect.y = 0;
ycc.canvasDom.width = paper.res.width;
ycc.canvasDom.height = paper.res.height;
ycc.canvasDom.style.width=ycc.canvasDom.width*ycc.dpi*scale+'px';
}
if(paper.rotation===270){
paper.rect.x = -(paper.res.width-paper.res.height)/2;
paper.rect.y = -(paper.res.width-paper.res.height)/2;
ycc.canvasDom.width = paper.res.height;
ycc.canvasDom.height = paper.res.width;
ycc.canvasDom.style.width=ycc.canvasDom.width*ycc.dpi*scale+'px';
}
ycc.layerManager.reRenderAllLayerToStage();
}
/**
* 画直线
*/
function line() {
var ui = null;
var hasDragged = false;
layer.onclick = function (e) { };
var startPos = null;
layer.ondragstart = function (e) {
startPos=new Ycc.Math.Dot(e);
ui = new Ycc.UI.Line();
layer.addUI(ui);
};
layer.ondragging = function (e) {
hasDragged = true;
ui.start = translateDotByScale(startPos);
ui.end = translateDotByScale(e);
console.log(ui.start,ui.end);
ycc.layerManager.reRenderAllLayerToStage();
};
layer.ondragend = function (e) {
ui = null;
if(!hasDragged) return null;
ycc.photoManager.takePhoto();
showPhotoToHtml();
hasDragged = false;
};
}
/**
* 钢笔
*/
function pen() {
var startDot = [];
var hasMoved = false;
var ui = null;
layer.onclick = function (e) {};
layer.ondragstart = function (e) {
startDot = translateDotByScale(new Ycc.Math.Dot(e.x,e.y));
ui = new Ycc.UI.BrokenLine({color:"red",width:3});
ui.pointList.push(startDot);
layer.addUI(ui);
};
layer.ondragging = function (e) {
hasMoved = true;
var moveDot = translateDotByScale(new Ycc.Math.Dot(e.x,e.y));
ui.pointList.push(moveDot);
ycc.layerManager.reRenderAllLayerToStage();
// startDot = moveDot;
};
layer.ondragend = function (e) {
if(!hasMoved) return null;
ycc.photoManager.takePhoto();
showPhotoToHtml();
hasMoved = false;
};
}
/**
* 画方框
*/
function rect() {
var hasDragged = false;
var rect;
layer.onclick = function (e) {};
var startPos = null,
startRect = null;
layer.ondragstart = function (e) {
rect = new Ycc.UI.Rect({
fill:false,
color:"red"
});
layer.addUI(rect);
startPos=new Ycc.Math.Dot(e);
startRect=new Ycc.Math.Rect(rect.rect);
};
layer.ondragging = function (e) {
hasDragged = true;
var startDot = new Ycc.Math.Dot(startPos.x,startPos.y);
var endDot = new Ycc.Math.Dot(e.x,e.y);
rect.rect = new Ycc.Math.Rect(startDot.x,startDot.y,endDot.x-startDot.x,endDot.y-startDot.y);
ycc.layerManager.reRenderAllLayerToStage();
};
layer.ondragend = function (e) {
if(!hasDragged) return null;
ycc.photoManager.takePhoto();
showPhotoToHtml();
hasDragged = false;
};
}
/**
* 画圈
* @param hasRotate {Boolean} 是否允许椭圆旋转
*/
function ellipse(hasRotate) {
var hasDragged = false;
var ui;
layer.onclick = function (e) {};
var startPos = null,
startRect = null;
layer.ondragstart = function (e) {
ui = new Ycc.UI.Ellipse();
layer.addUI(ui);
startPos=new Ycc.Math.Dot(e);
startRect=new Ycc.Math.Rect(ui.rect);
};
layer.ondragging = function (e) {
hasDragged = true;
var startDot = translateDotByScale(new Ycc.Math.Dot(startPos.x,startPos.y));
var endDot = translateDotByScale(new Ycc.Math.Dot(e.x,e.y));
ui.point.x = (startDot.x+endDot.x)/2;
ui.point.y = (startDot.y+endDot.y)/2;
ui.width = Math.abs(endDot.x - startDot.x)/2;
ui.height = Math.abs(endDot.y - startDot.y)/2;
ui.angle = 0;
ycc.layerManager.reRenderAllLayerToStage();
};
layer.ondragend = function (e) {
if(!hasDragged) return null;
ycc.photoManager.takePhoto();
showPhotoToHtml();
hasDragged = false;
};
}
/**
* 画勾
*/
function gou() {
layer.ondragging = function (e) {};
layer.ondragend = function (e) {};
layer.ontap = layer.ondragstart = function (e) {
var endDot = translateDotByScale(new Ycc.Math.Dot(e.x-22,e.y-56));
layer.addUI(new Ycc.UI.Image({res:imageRes.tick,rect:new Ycc.Math.Rect(endDot.x,endDot.y,64,64),fillMode:"scale"}));
ycc.layerManager.reRenderAllLayerToStage();
ycc.photoManager.takePhoto();
showPhotoToHtml();
}
}
/**
* 画叉
*/
function cross(){
layer.ondragging = function (e) {};
layer.ondragend = function (e) {};
layer.ontap = layer.ondragstart = function (e) {
var endDot = translateDotByScale(new Ycc.Math.Dot(e.x-30,e.y-38));
layer.addUI(new Ycc.UI.Image({res:imageRes.cross,rect:new Ycc.Math.Rect(endDot.x,endDot.y,64,64),fillMode:"scale"}));
ycc.layerManager.reRenderAllLayerToStage();
ycc.photoManager.takePhoto();
showPhotoToHtml();
}
}
function text() {
layer.ondragging = function (e) {};
layer.ondragend = function (e) {};
layer.ontap = layer.ondragstart = function (e) {
var endDot = translateDotByScale([e.x,e.y]);
layer.addUI(new Ycc.UI.MultiLineText({content:"1111111111111111111\n222222222222222222222",rect:new Ycc.Math.Rect(e.x,e.y,500,0)}));
ycc.layerManager.reRenderAllLayerToStage();
ycc.photoManager.takePhoto();
showPhotoToHtml();
}
}
/**
* 点击回退
*/
function goBack() {
layer.uiList.pop();
layer.clear();
var photos = ycc.photoManager.getHistoryPhotos();
if(photos.length>=2){
var photo = photos[photos.length-2];
ycc.photoManager.showPhoto(photo);
ycc.photoManager.delPhotoById(photo.id);
showPhotoToHtml();
}
}
/**
* 变换一个点,根据缩放比例变化一个点的坐标
* @param dot
* @param dot.x
* @param dot.y
* @returns {Ycc.Math.Dot}
*/
function translateDotByScale(dot){
// var res = [0,0];
// res[0]= dot[0]/scale;
// res[1]= dot[1]/scale;
// return res;
var res = {x:0,y:0};
res.x= dot.x/scale;
res.y= dot.y/scale;
return res;
}
</script>