参考鸿视频,效果如下:
using Autodesk.AutoCAD.Internal;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;
using Color = Autodesk.AutoCAD.Colors.Color;
namespace IfoxDemo
{
public class Class1
{
static TransientManager tm = TransientManager.CurrentTransientManager;
static System.Windows.Forms.Timer timer;
static Random rand;
static bool isrun;
Point3d mpt;
double viewheight;
List<Pao> paos;
int k;
Document doc;
Editor ed;
DocumentLock dl;
[CommandMethod("xx")]
public void run()
{
if (!isrun)
{
isrun = true;
timer = new System.Windows.Forms.Timer();
rand = new Random();
paos = new List<Pao>();
doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
ed = doc.Editor;
dl = doc.LockDocument();
viewheight = GetViewHeight();
timer.Interval = 1;
ed.PointMonitor += Ed_PointMonitor;
doc.ViewChanged += Doc_ViewChanged;
timer.Tick += 气泡产生事件;
timer.Tick += 气泡膨胀事件;
doc.BeginDocumentClose += Doc_BeginDocumentClose;
timer.Start();
}
else
{
isrun = false;
timer.Tick -= 气泡产生事件;
timer.Tick -= 气泡膨胀事件;
ed.PointMonitor -= Ed_PointMonitor;
doc.ViewChanged -= Doc_ViewChanged;
//paos.ForEach(pao =>
//{
// tm.EraseTransient(pao.cir, new IntegerCollection());
//});//等效写法
paos.ForEach(pao => tm.EraseTransient(pao.cir, new IntegerCollection()));
paos.Clear();
dl.Dispose();
}
}
private void Doc_BeginDocumentClose(object sender, DocumentBeginCloseEventArgs e)
{
if (isrun)
{
isrun = false;
timer.Tick -= 气泡产生事件;
timer.Tick -= 气泡膨胀事件;
ed.PointMonitor -= Ed_PointMonitor;
doc.ViewChanged -= Doc_ViewChanged;
//paos.ForEach(pao =>
//{
// tm.EraseTransient(pao.cir, new IntegerCollection());
//});//等效写法
paos.ForEach(pao => tm.EraseTransient(pao.cir, new IntegerCollection()));
paos.Clear();
dl.Dispose();
}
}
private void 气泡膨胀事件(object sender, EventArgs e)
{
foreach (var pao in paos)
{
pao.膨胀(mpt, viewheight);
}
for (int i = paos.Count - 1; i >= 0; i--)
{
if (paos[i].bao) paos.RemoveAt(i);
}
ed.UpdateScreen();
System.Windows.Forms.Application.DoEvents();
}
private void 气泡产生事件(object sender, EventArgs e)
{
k++;
int t = rand.Next(5, 100);//设置两个值的大小,可控制产生气泡的速度
if (k > t)
{
double ang = rand.NextDouble() * Math.PI * 2;
Color cc = ((double)rand.Next(100)).Rainbow紫到蓝(0, 100);
paos.Add(new Pao(viewheight, mpt, cc, ang));
k = 0;
}
}
private void Doc_ViewChanged(object sender, EventArgs e)
{
viewheight = GetViewHeight();
}
private void Ed_PointMonitor(object sender, PointMonitorEventArgs e)
{
mpt = e.Context.RawPoint;
}
double GetViewHeight()
{
return ed.GetCurrentView().Height;
}
public class Pao
{
public Circle cir;
double rmin, rmax, ang;
int tt;
public bool bao;
public Pao(double viewheight, Point3d cent, Color cc, double ang)
{
rmin = viewheight / 200;
rmax = viewheight / 50;
cir = new Circle(cent, Vector3d.ZAxis, rmin);
cir.Color = cc;
this.ang = ang;
tm.AddTransient(cir, TransientDrawingMode.Main, 0, new IntegerCollection());
}
public void 膨胀(Point3d pt, double viewheight)
{
rmin = viewheight / 200;
rmax = viewheight / 50;
double dt = (rmax - rmin) / 100;
cir.Center = pt.Polar(ang, dt * tt * 5);
cir.Radius = rmin + dt * tt;
tm.UpdateTransient(cir, new IntegerCollection());
tt++;
if (tt > 100)
{
tm.EraseTransient(cir, new IntegerCollection());
bao = true;
}
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IfoxDemo
{
public static class MRainbow
{
public static Color Rainbow紫到蓝(this double a, double min, double max)
{
if (min > max) { double v = min; min = max; max = v; }
if (a > max) a = max; if (a < min) a = min;
double step = a - min;
double num = max - min;
double r = 0.0; double g = 0.0; double b = 0.0;
double h = step / num;
double i = (int)(h * 5);
double f = h * 5.0 - i;
double q = 1 - f;
switch (i % 5)
{
case 3: r = 1; g = q; b = 0; break;//红色到黄色
case 2: r = f; g = 1; b = 0; break;//黄色到绿色
case 0: r = 0; g = f; b = 1; break;//绿到蓝
case 1: r = 0; g = 1; b = q; break;
case 4: r = 1; g = 0; b = f; break;
}
return Color.FromRgb((byte)(r * 255), (byte)(g * 255), (byte)(b * 255));
}
}
}