From de1e835fe87b7434732a99c7b7184b56ce2f0174 Mon Sep 17 00:00:00 2001 From: mkwiser Date: Sat, 30 Aug 2014 13:37:05 +0800 Subject: [PATCH] add quadratic bezier test --- demo/js/glyf.js | 1 + demo/js/quadraticBezier.js | 105 ++++++++++++++++++++++++ demo/js/ttfparse.js | 61 ++++++++++++++ demo/quadraticBezier.html | 52 ++++++++++++ demo/ttfparse.html | 27 ++++++ index.html | 7 -- src/editor/common/computeBoundingBox.js | 105 ++++++++++++++++++++++++ src/main.js | 41 +-------- 8 files changed, 354 insertions(+), 45 deletions(-) create mode 100644 demo/js/quadraticBezier.js create mode 100644 demo/js/ttfparse.js create mode 100644 demo/quadraticBezier.html create mode 100644 demo/ttfparse.html create mode 100644 src/editor/common/computeBoundingBox.js diff --git a/demo/js/glyf.js b/demo/js/glyf.js index 9325a11..cba6ed1 100644 --- a/demo/js/glyf.js +++ b/demo/js/glyf.js @@ -26,6 +26,7 @@ define( // 查看ttf glyf function showTTFGlyf(ttfData) { + console.log(ttfData); ttf = new TTF(ttfData); var chars = ttf.chars(); diff --git a/demo/js/quadraticBezier.js b/demo/js/quadraticBezier.js new file mode 100644 index 0000000..1cefdff --- /dev/null +++ b/demo/js/quadraticBezier.js @@ -0,0 +1,105 @@ +/** + * @file quadraticBezier.js + * @author mengke01 + * @date + * @description + * 二次贝塞尔演示 + */ + +define( + function(require) { + + var computeBoundingBox = require('editor/editor/common/computeBoundingBox'); + + var entry = { + + /** + * 初始化 + */ + init: function() { + var ctx = document.getElementById('canvas').getContext('2d'); + var width = ctx.offsetWidth; + var height = ctx.offsetHeight; + + var points = []; + [0, 1, 2].forEach(function(i) { + var p = { + x: Math.floor(Math.random() * 400 + 50), + y: Math.floor(Math.random() * 400 + 50) + } + points[i] = p; + $($('.point').get(i)).css({ + left: p.x, + top: p.y + }); + }); + + var point; + + $('.point').on('mousedown', function(e) { + point = $(this); + }); + + $(document.body).on('mousemove', onMove); + $(document.body).on('mouseup', function(e) { + onMove.call(this, e); + point = null; + }); + + function onMove(e) { + var px = e.pageX; + var py = e.pageY; + if(point) { + point.css({ + left: px, + top: py + }); + var p = points[+point.attr('data-index')]; + p.x = px; + p.y = py; + draw(); + } + } + + function draw() { + ctx.clearRect(0, 0, 500, 500); + //绘制2次贝塞尔曲线 + ctx.beginPath(); + ctx.strokeStyle='black'; + ctx.moveTo(points[0].x, points[0].y); + ctx.quadraticCurveTo(points[1].x, points[1].y, points[2].x, points[2].y); + ctx.lineWidth = 1; + ctx.stroke(); + + var min = {}; + var max = {}; + computeBoundingBox.quadraticBezier( + [points[0].x, points[0].y], + [points[1].x, points[1].y], + [points[2].x, points[2].y], + min, + max + ); + min[0] = Math.floor(min[0]); + min[1] = Math.floor(min[1]); + max[0] = Math.floor(max[0]); + max[0] = Math.floor(max[0]); + ctx.beginPath(); + ctx.strokeStyle='green'; + ctx.moveTo(min[0], min[1]); + ctx.lineTo(min[0], max[1]); + ctx.lineTo(max[0], max[1]); + ctx.lineTo(max[0], min[1]); + ctx.lineTo(min[0], min[1]); + ctx.stroke(); + } + + draw(); + } + }; + + entry.init(); + + return entry; + } +); \ No newline at end of file diff --git a/demo/js/ttfparse.js b/demo/js/ttfparse.js new file mode 100644 index 0000000..f0486e5 --- /dev/null +++ b/demo/js/ttfparse.js @@ -0,0 +1,61 @@ +/** + * @file ttfparse.js + * @author mengke01 + * @date + * @description + * ttf解析函数入口 + */ + + +define( + function(require) { + var ttfreader = require('editor/ttf/ttfreader'); + var TTF = require('editor/ttf/ttf'); + var ajaxBinaryFile = require('editor/common/ajaxBinaryFile'); + + function onUpFileChange(e) { + var file = e.target.files[0]; + var reader = new FileReader(); + reader.onload = function(e) { + var ttf = new ttfreader().read(e.target.result); + } + + reader.onerror = function(e) { + console.error(e); + }; + + reader.readAsArrayBuffer(file); + } + + var entry = { + + /** + * 初始化 + */ + init: function() { + var upFile = document.getElementById('upload-file'); + upFile.addEventListener('change', onUpFileChange); + + ajaxBinaryFile({ + url: '../font/baiduHealth.ttf', + onSuccess: function(binaryData) { + var ttfData = new ttfreader().read(binaryData); + console.log(ttfData); + + var ttf = new TTF(ttfData); + + }, + onError: function() { + console.error('error read file'); + } + }); + + + } + }; + + entry.init(); + + return entry; + } +); diff --git a/demo/quadraticBezier.html b/demo/quadraticBezier.html new file mode 100644 index 0000000..010f2e2 --- /dev/null +++ b/demo/quadraticBezier.html @@ -0,0 +1,52 @@ + + + + + 二次贝塞尔曲线绘制 + + + + + +
+
+
+ + + + + + + \ No newline at end of file diff --git a/demo/ttfparse.html b/demo/ttfparse.html new file mode 100644 index 0000000..05cc1c3 --- /dev/null +++ b/demo/ttfparse.html @@ -0,0 +1,27 @@ + + + + + font编辑器 + + + + + + + + + + + + \ No newline at end of file diff --git a/index.html b/index.html index 73312dc..70446d6 100644 --- a/index.html +++ b/index.html @@ -13,12 +13,5 @@ }); define('jquery', $); - - - - - \ No newline at end of file diff --git a/src/editor/common/computeBoundingBox.js b/src/editor/common/computeBoundingBox.js new file mode 100644 index 0000000..e988e76 --- /dev/null +++ b/src/editor/common/computeBoundingBox.js @@ -0,0 +1,105 @@ +/** + * @file computeBoundingBox.js + * @author mengke01 + * @date + * @description + * 计算曲线包围盒 + * + * modify from: + * zrender + * https://github.com/ecomfe/zrender/blob/master/src/tool/computeBoundingBox.js + */ + + +define( + function(require) { + + /** + * 计算包围盒 + */ + function computeBoundingBox(points, min, max) { + if (points.length === 0) { + return; + } + var left = points[0][0]; + var right = points[0][0]; + var top = points[0][1]; + var bottom = points[0][1]; + + for (var i = 1; i < points.length; i++) { + var p = points[i]; + if (p[0] < left) { + left = p[0]; + } + if (p[0] > right) { + right = p[0]; + } + if (p[1] < top) { + top = p[1]; + } + if (p[1] > bottom) { + bottom = p[1]; + } + } + + min[0] = left; + min[1] = top; + max[0] = right; + max[1] = bottom; + } + + /** + * 计算二阶贝塞尔曲线的包围盒 + * http://pissang.net/blog/?p=91 + */ + function computeQuadraticBezierBoundingBox(p0, p1, p2, min, max) { + // Find extremities, where derivative in x dim or y dim is zero + var tmp = (p0[0] + p2[0] - 2 * p1[0]); + // p1 is center of p0 and p2 in x dim + var t1; + if (tmp === 0) { + t1 = 0.5; + } else { + t1 = (p0[0] - p1[0]) / tmp; + } + + tmp = (p0[1] + p2[1] - 2 * p1[1]); + // p1 is center of p0 and p2 in y dim + var t2; + if (tmp === 0) { + t2 = 0.5; + } else { + t2 = (p0[1] - p1[1]) / tmp; + } + + t1 = Math.max(Math.min(t1, 1), 0); + t2 = Math.max(Math.min(t2, 1), 0); + + var ct1 = 1-t1; + var ct2 = 1-t2; + + var x1 = ct1 * ct1 * p0[0] + + 2 * ct1 * t1 * p1[0] + + t1 * t1 * p2[0]; + var y1 = ct1 * ct1 * p0[1] + + 2 * ct1 * t1 * p1[1] + + t1 * t1 * p2[1]; + + var x2 = ct2 * ct2 * p0[0] + + 2 * ct2 * t2 * p1[0] + + t2 * t2 * p2[0]; + var y2 = ct2 * ct2 * p0[1] + + 2 * ct2 * t2 * p1[1] + + t2 * t2 * p2[1]; + + return computeBoundingBox( + [p0.slice(), p2.slice(), [x1, y1], [x2, y2]], + min, max + ); + } + + return { + quadraticBezier: computeQuadraticBezierBoundingBox + }; + } +); diff --git a/src/main.js b/src/main.js index a1a90f2..d26cce4 100644 --- a/src/main.js +++ b/src/main.js @@ -9,54 +9,19 @@ define( function(require) { - var ttfreader = require('ttf/ttfreader'); - var TTF = require('ttf/ttf'); - var ajaxBinaryFile = require('common/ajaxBinaryFile'); - - function onUpFileChange(e) { - var file = e.target.files[0]; - var reader = new FileReader(); - reader.onload = function(e) { - var ttf = new ttfreader().read(e.target.result); - } - - reader.onerror = function(e) { - console.error(e); - }; - - reader.readAsArrayBuffer(file); - } var entry = { /** * 初始化 */ - init: function() { - var upFile = document.getElementById('upload-file'); - upFile.addEventListener('change', onUpFileChange); - - ajaxBinaryFile({ - url: 'font/baiduHealth.ttf', - onSuccess: function(binaryData) { - var ttfData = new ttfreader().read(binaryData); - console.log(ttfData); - - var ttf = new TTF(ttfData); - console.log(ttf.chars()); - - }, - onError: function() { - console.error('error read file'); - } - }); - + init: function () { } }; entry.init(); - + return entry; } -); +); \ No newline at end of file