我对具有任何形状的画布感兴趣的原因是,然后可以用贝塞尔曲线剪切图像并使网页的文本围绕画布形状流动,即切出图像。
我们需要的是拥有自由形状div,SVG和HTML5画布的可能性。 (应用于SVG,我知道这相当于Flash符号。)然后你可以设想为形状应用一个盒子模型(填充,边框和边距),但它不会是一个盒子(它将平行于形状)!
我想那时也可以将文本包裹在形状中,就像在文本周围流动的文本一样。
我读了一篇有趣的博客文章,关于"使用CSS形状创建非矩形布局"在这里:http://sarasoueidan.com/blog/css-shapes/
但它不包含文字包装内的形状。
然后,还有一个用于Brackets的CSS Shapes编辑器(代码编辑器): http://blogs.adobe.com/webplatform/2014/04/17/css-shapes-editor-in-brackets/
答案 0 :(得分:5)
听起来很简单,实际上需要完成很多步骤。
大纲看起来像这样:
换句话说:您需要实现多边形填充算法,但不是填充行(每个像素行),而是使用该行作为文本的基础。
这是完全可行的;实际上,我继续为这个问题为自己创造了一个挑战,为了它的乐趣,所以我创建了一个在MIT许可下发布的generic solution that I put on GitHub。
实施上述原则,并可视化步骤:
定义多边形和填充 - 在这里我选择只使用一个简单的蛮力,并根据中心和填充值计算一个较小的多边形 - 浅灰色是原始多边形,黑色显然是缩小版本:
这些点被定义为数组[x1, y1, x2, y2, ... xn, yn]
以及用于收缩它的代码(请参阅项目链接以了解所有这些部分的完整来源):
var pPoints = [],
i = 0, x, y, a, d, dx, dy;
for(; i < points.length; i += 2) {
x = points[i];
y = points[i+1];
dx = x - bounds.px;
dy = y - bounds.py;
a = Math.atan2(dy, dx);
d = Math.sqrt(dx*dx + dy*dy) - padding;
pPoints.push(bounds.px + d * Math.cos(a),
bounds.py + d * Math.sin(a));
}
下一步是定义我们要扫描的行。这些行基于字体的行高:
这很简单 - 只需确保起点和终点在多边形之外。
我们使用奇数/偶数扫描方法并检查扫描线与多边形中所有线的交点。如果我们得到一个交叉点,我们将其存储在该行的列表中。
检测相交线的代码是:
function getIntersection(line1, line2) {
// "unroll" the objects
var p0x = line1.x1,
p0y = line1.y1,
p1x = line1.x2,
p1y = line1.y2,
p2x = line2.x1,
p2y = line2.y1,
p3x = line2.x2,
p3y = line2.y2,
// calc difference between the coords
d1x = p1x - p0x,
d1y = p1y - p0y,
d2x = p3x - p2x,
d2y = p3y - p2y,
// determinator
d = d1x * d2y - d2x * d1y,
px, py,
s, t;
// if is not intersecting/is parallel then return immediately
if (Math.abs(d) < 1e-14)
return null;
// solve x and y for intersecting point
px = p0x - p2x;
py = p0y - p2y;
s = (d1x * py - d1y * px) / d;
if (s >= 0 && s <= 1) {
// if s was in range, calc t
t = (d2x * py - d2y * px) / d;
if (t >= 0 && t <= 1) {
return {x: p0x + (t * d1x),
y: p0y + (t * d1y)}
}
}
return null;
}
然后我们对每一行的点进行排序并使用点对来创建段 - 这实际上是一个多边形填充算法。结果将是:
构建细分的代码对于这篇文章来说有点广泛,所以请查看上面链接的项目。
最后我们使用这些段来替换实际文本。我们需要从当前文本指针扫描文本,看看在段宽度内适合多少。当前的代码有些基本,并且省略了许多注意事项,例如分词,文本基线位置等等,但是对于初始使用它会有所作为。
汇总后的结果将是:
希望这能让我们了解所涉及的步骤。