如何以编程方式绘制可伸缩的、美观的、弯曲的漫画气球尾巴?

发布于 2024-09-14 09:27:03 字数 1270 浏览 1 评论 0原文

作为一名 UI 专家,我经常被要求构建工具提示显示和其他类型的显示文本的弹出窗口。客户最热衷的风格之一是漫画气球中的文字。我想以编程方式创建此气球(而不是嵌入或链接到渲染的图形),因为这些气球必须在运行时更改大小,具体取决于它们必须容纳的文本量。

气球大部分都很容易绘制:圆形、矩形或圆角矩形。对我来说,最困难的部分是尾巴(漫画气球中指向扬声器的小箭头状部分)。如果你用谷歌搜索漫画气球,你会发现尾巴有很多种。客户最常向我提出的要求是弯曲的。例如..

http://www.macybugs.com/round%20bubble.PNG

http://thumb10.shutterstock.com.edgesuite.net/display_pic_with_logo/121360/121360,1222432252,2/stock-vector-vector-cartoon-speech-balloon-add -your-own-text-easily-17961022.jpg

尾巴始终位于气球的底部,有时指向左侧,有时指向右侧。一段时间以来,我一直在尝试提出尾部绘制算法,但我对结果不满意。我基本上是在黑暗中摸索,改变变量,查看结果,并通过反复试验来尝试接近可行的神奇数字。 “工作”只是指看起来令人愉悦的结果,我意识到这是主观的。我的大多数客户都会对任何看起来相当不错和专业的东西感到满意。

我希望这个结果能够扩展。如果它可以使用尽可能少的输入,也许只是 isFacingLeft、tailWidth 和 tailHeight(这可能是整个气球的百分比),那就太好了。也许是一个可调节的曲线量。

如果重要的话,我正在使用 Flash/Actionscript,但是任何具有某种海龟图形引擎的系统都应该以几乎相同的方式工作:我正在使用标准翻转笛卡尔网格(y 向下增加),x 和 y坐标,移动笔、画直线和画曲线的能力。

需要注意的是:Flash 只允许我绘制 3 点贝塞尔曲线 - 起点、控制点、终点。

注意:绘制后气球不必缩放。

As a UI specialist, I am often asked to build tool-tip displays and other sorts of popups that display text. One of styles clients seem most keen on is text in a comic-book balloon. I would like to create this balloons programmatically (as opposed to embedding or linking to rendered graphics), because these balloons will have to change size at runtime, depending on how much text they have to hold.

Balloons are easy to draw for the most part: circles, rectangles or rounded-corner rectangles. The tough part, for me, is the tail (the little arrow-like part of the comic balloon that points towards the speaker). If you google comic balloon, you see that there are many varieties of tails. They ones clients request from me most often are curved. E.g...

http://www.macybugs.com/round%20bubble.PNG

and

http://thumb10.shutterstock.com.edgesuite.net/display_pic_with_logo/121360/121360,1222432252,2/stock-vector-vector-cartoon-speech-balloon-add-your-own-text-easily-17961022.jpg

The tail will always be on the bottom of the balloon, and it will sometimes point left and sometimes point right. I have been trying to come up with tail-drawing algorithms for a while, but I'm not happy with the results. I'm basically stumbling around in the dark, changing variables, looking at the results, and using trial and error to try to move closer to the magic numbers that will work. "Work" just means a result that looks pleasing, which I realize is subjective. Most of my clients will be a happy with anything that looks reasonably good and professional.

I want this result to scale. And it would be great if it could work with as few inputs as possible, maybe just isFacingLeft, tailWidth and tailHeight (Which could maybe be a percentage of the whole balloon). Maybe an adjustable curveAmount.

If it matters, I'm using Flash/Actionscript, but any system that has some sort of turtle graphics engine should work pretty much the same way: I'm working with that standard flipped Cartesian grid (y increases downward), x and y coordinates, the ability to move a pen, draw lines and draw curves.

One caveat: Flash only allows me to draw 3-point bezier curves -- start point, control point, end point.

Note: balloons won't have to scale after the are drawn.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情绪失控 2024-09-21 09:27:03

首先,让我告诉您,我创建了一个帐户来回答这个问题,因为我正在从事的当前项目执行与您定义的相同的操作。如需演示,您可以查看我的申请页面。

以下是我的气泡算法的基本工作原理:

1- 气泡绘制: 对于圆形或矩形气泡,使用默认的动作脚本drawRoundRect 和drawEllipse 方法。对于尖叫(尖峰)和思想泡泡,我使用了 2 个省略号。对于尖叫气泡,外椭圆具有起点和终点,而内椭圆具有三次贝塞尔曲线的控制点。因为认为气泡外椭圆有控制点,内椭圆有起点和终点。我从 cartogrammar [dot] com/blog 找到了三次贝塞尔曲线绘图课程,如果它还没有,我可以把课程发给你,只要给我留言即可。

2-尾巴绘制:这是棘手的部分,为了创建圆滑的漫画气泡尾巴效果,我使用了等腰三角形,其相等的边也可以弯曲。三角形底边的中点也是气泡的中点。

当您单击并拖动气泡尾部的端点时,三角形的底边使用反正切函数面向鼠标指针坐标,然后三角形底边的端点将设置为预先计算的点。

反正切函数:

    //p1= center of circle
    //p2= target point
    //find angle between point 1, point 2 and y=0 line and returns degree value
    private function findAngle(p1:Point,p2:Point):Number{

        var rad:Number = 0;
        var angle:Number = 0;

        if(p2.x - p1.x == 0 || p1.x - p2.x == 0){
            angle = -90

        }else{
            rad = Math.atan((p2.y-p1.y)/(p2.x-p1.x));   
            angle = Math.floor((rad * (180/Math.PI)));

        }       

        return angle;
    }

这是我计算三角形底面的潜在端点的方法:

        //calculates circle points for drawing tail triangle
    private function calculateCircle():void{

        var steps:uint = 360;
        var rad:Number = CENTER_RADIUS;

        //delete array
        this.circleArray.splice(0);
        for(var i:int = 0; i < 360; i+= 360/steps){

            var alpha:Number = i * (Math.PI /180);
            var sinAlpha:Number = Math.sin(alpha);
            var cosAlpha:Number = Math.cos(alpha);

            var circX:Number = circleCenter.x + (rad * cosAlpha);
            var circY:Number = circleCenter.y + (rad * sinAlpha);

            var  p:Point = new Point(circX,circY);
            this.circleArray.push(p);

        }           
    }

我的最后一个问题是处理气泡图形的轮廓和内部。通常,当您在气泡上方画尾巴时,三角形(尾巴)的两侧正好进入气泡的中心。如果将气泡放在顶部,则气泡轮廓会切掉尾巴。我是 Actionscript 新手,所以它并没有很快出现在我面前,但按 BubbleTailOutline、Bubble、BubbleTailInside 的顺序添加图形图层解决了问题。

First of all let me tell you I created an account to answer this question because the current project I'm working on does the same thing you define. For a demo you can check my application page.

Here's how my bubble algorithm works basically:

1- Bubble drawing: For a circular or rectangular bubble, default actionscript drawRoundRect and drawEllipse methods are used. For scream (spikey) and thought bubbles I used 2 ellipses. For scream bubble outer ellipse has the start and end points whereas inner ellipse has control points for cubic bezier curve. For thought bubble outer ellipse has control points and inner ellipse has start and end points. I found the cubic bezier drawing class from cartogrammar [dot] com/blog, if it's not still there, I can send you the class, just drop me a message.

2- Tail drawing: This is the tricky part, to create a sleek comic bubble tail effect I used an isosceles triangle, whose equal edges can be also bent. The middle point of the base of the triangle is also the middle of the bubble.

When you click and drag the endpoint of the bubble tail around, the base of the triangle faces the mouse pointer coordinates using arctangent function, then the endpoints of the base of the triangle are set to precalculated points.

Arctangent function:

    //p1= center of circle
    //p2= target point
    //find angle between point 1, point 2 and y=0 line and returns degree value
    private function findAngle(p1:Point,p2:Point):Number{

        var rad:Number = 0;
        var angle:Number = 0;

        if(p2.x - p1.x == 0 || p1.x - p2.x == 0){
            angle = -90

        }else{
            rad = Math.atan((p2.y-p1.y)/(p2.x-p1.x));   
            angle = Math.floor((rad * (180/Math.PI)));

        }       

        return angle;
    }

Here's how I calculated the potential endpoints for the triangle base:

        //calculates circle points for drawing tail triangle
    private function calculateCircle():void{

        var steps:uint = 360;
        var rad:Number = CENTER_RADIUS;

        //delete array
        this.circleArray.splice(0);
        for(var i:int = 0; i < 360; i+= 360/steps){

            var alpha:Number = i * (Math.PI /180);
            var sinAlpha:Number = Math.sin(alpha);
            var cosAlpha:Number = Math.cos(alpha);

            var circX:Number = circleCenter.x + (rad * cosAlpha);
            var circY:Number = circleCenter.y + (rad * sinAlpha);

            var  p:Point = new Point(circX,circY);
            this.circleArray.push(p);

        }           
    }

My last problem was handling outlines and inside of the bubble graphics. Normally when you draw tail above the bubble the two sides of the triangle (tail) goes right into the center of the bubble. If you put the bubble on top, then the bubble outline cuts the tail. I'm an Actionscript newbie so it didn't come to me quick but adding graphic layers with the order BubbleTailOutline, Bubble,BubbleTailInside solved the problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文