文件 | 语言 | 大小 | 版本 | 开发者 | 最后更新 | |
lands/curve production | JavaScript | 11.7KB | v1.0.0 | YB | 2024-10-16 | 查看 |
lands/curve source code | JavaScript | 29.1KB | v1.0.0 | YB | 2024-10-16 | 查看 |
const canvas = await Lan.curve(900, 600, {options...}); // canvas width, height and rendering options
const canvas = await Lan.curve(900, {options...}); // auto set canvas height with aspect ratio 3/2
const canvas = await Lan.curve({options...}); // canvas dimensions default to 900 x 600
因为 curve 是蓝紫的核心渲染引擎之一,可以直接通过全局变量 Lan 进行访问,请参考向导程序:粒子系统。
import {curve} from "https://ddzeb.com/lands/curve";
await curve(canvas, {options...});
// use canvas to render
const {curve} = await import("https://ddzeb.com/lands/curve");
await curve(canvas, {options...});
// use canvas to render
第三方集成参考示例(CodePen):Lands curve Demo。
纯 JS 的二维渲染因为其绘制机制容易理解,可以快速绘制各种矢量图形。curve 渲染引擎是对传统 CanvasRenderingContext2D 的封装,但是坐标系统做了调整,不再是 Y 轴向下,而是跟我们平常的习惯一致,X 轴从左向右,而 Y 轴从下往上。所有的渲染操作都是在这个世界坐标系下完成,我们不再关心画布像素坐标。
使用 curve 引擎的时候,options 只有一个参数:alpha,缺省为 true,表示画布透明。我们也可以将其设置为 false,不过基本上没必要。
const canvas = await Lan.curve(900, 600, {
alpha : false,
});
具体例子可参考 Canvas Texture。在我们将画布绑定 curve 引擎之后,所有的接口都将通过 canvas 本身进行调用。接口大概分两类,一是计算类的,二是渲染类的。所有渲染类型的操作,基本接口形式均是:
api_name(param1, param2, ..., options = {})
其中,api_name 为接口名称,param1、param2 等为必要的参数列表,options 为配置项。所有渲染操作都支持的配置项包括:
curve 有一个世界坐标,我们的渲染操作全部都是在世界坐标系统中进行。curve 的世界坐标必须是 x 方向从左到右而 y 方向是从下到上。我们使用 view 函数设定世界坐标系统,或者叫视口坐标系统。缺省的视口坐标位于画布中央,我们可以通过 x0 以及 x1 来设定 x 方向的范围,垂直方向上通过 y 参数来调整位置。比如:
p.view(-5, 15, -3);
需要注意的是,如果视口区域设置得太小,渲染文字的时候可能引起浏览器兼容问题,只有 Chrome 浏览器在处理上是没问题的。
清除数据,可以使用 x0、x1、y0、y1 指定区域,缺省为整个画布视口区域。另外,通过 fill 可以指定填充色。
p.clear({fill:'yellow'});
网格渲染,通过网格参数 options 修改样式:
p.grid({
alpha:.2, blend:'source-over', filter:'none',
margin:.5, line:.05, dash:[.3, .1], stroke:'red',
size:2, v:true, h:true,
});
其中,size 为网格的格子大小。v 和 h 分别控制是否绘制垂直以及水平线条,缺省为 true。
绘制坐标轴,缺省的 x 及 y 方向的坐标轴为黑色线条,我们可以使用 options 参数调整样式:
p.axis({
line:.05, stroke:'red',
});
该函数进行二维函数的渲染,传入的参数 f 定义一个二维函数,比如 Math.sin(正弦函数),可选参数 options 指定渲染参数。比如:
p.func(Math.sin, {
x0:-5, x1:5,
stroke:'red', alpha:.4, line:.1, dash:[.5, .2],
});
缺省情况下,函数曲线连续连接,比如下面的锯齿波函数:
p.func(x => x - Math.floor(x));
如果我们不希望渲染垂直的连线,可以通过 options.dx 参数进行控制:
p.func(x => x - Math.floor(x), {dx:true});
我们可以在图像中画一些直线段,options 参数可选:
p.line(1, -1, 7, -4, {
stroke:'red', alpha:.6, line:.1, dash:[.5, .2],
});
另外,我们还可以通过 extend0、extend1 这两个参数绘制延长线,分别延长 (x0, y0) 以及 (x1, y1) 两个端点。当它们为 true 的时候,使用原样式延长。也可以使用 {color:'red'} 这样的参数形式指定延长线的样式。
p.line(-5, 3, 1, -1, {stroke:'red', line:.1}, {
stroke:'blue', line:.05, dash:[.5, .2],
}, {
stroke:'black', line:.05, len:5,
});
画射线,起点 (x0, y0),方向 (dirX, dirY),options 控制样式等:
p.ray(-3, -2, 4, 8, {
alpha:.6,
stroke:'red', line:.05, cap:'round', join:'round',
dash:[.4, .1], len:6
});
不指定 len 参数的时候,射线无限延长。
参数看起来有点多,不过还是好理解的,x 及 y 定出位置,dirX1 和 dirY1 定出起始角度,dirX2 和 dirY2 定出终止角度。
const dx1 = 1, dy1 = 0;
const dx2 = -.5, dy2 = 1;
canvas.angle(0, 0, dx1, dy1, dx2, dy2, {
fill:'rgba(255,0,0,.2)',
radius:.8, line:.05, stroke:'black',
});
canvas.ray(0, 0, dx1, dy1);
canvas.ray(0, 0, dx2, dy2);
画水平方向直线,options 参数可选:
p.hline(-2, {stroke:'red', alpha:.5, line:.1, dash:[.5, .2]});
画垂直方向直线,options 参数可选:
p.vline(-2, {stroke:'red', alpha:.5, line:.1, dash:[.5, .2]});
画矩形,options 参数可选:
p.rect(-3, -2, 4, 4, {
alpha:.6,
stroke:'red', line:.1, cap:'round', join:'round',
dash:[2, .3], fill:'yellow', round:0,
});
画圆,options 参数可选:
p.circle(3, -1, {
alpha:.6,
radius:4, a0:2, a1:5.6, fan:false,
stroke:'red', line:.05, cap:'round', join:'round',
dash:[.4, .1], fill:'yellow',
});
参数 radius 可以是负值,比如,上面的代码将 radius 设置为 -4,绘制结果如下:
另外,参数 fan 用于控制是否绘制为扇形,比如,上面的代码如果将 fan 设置项去掉或者设置为 true,绘制出的图像如下:
如果要画椭圆,就将 radius 替换为 radiusX 以及 radiusY 两个参数,同时还可以指定 rotation 进行旋转:
p.circle(0, 0, {
alpha:.6,
radiusX:4, radiusY:2, rotation:1., a0:.9, a1:6, fan:false,
stroke:'red', line:.05, cap:'round', join:'round',
dash:[.4, .1], fill:'yellow',
});
画多边形,其中 points 为点集,比如:[-1,0, 5,5, 0,4] 这样的数组。options 指定样式,该参数可选:
p.poly([-1,0, 5,5, 0,4], {
alpha:.6, close:false,
stroke:'red', line:.05, cap:'round', join:'round',
dash:[.4, .1], fill:'yellow',
});
其中 close 参数缺省为 true,表示图形闭合。
画标签文字(单行),返回 Bounding Box:
var strip = p.pattern({type:'strip2', fact:.1});
var rect = p.label('Hello World', 3, 2, {
font:'bold 2px serif', kerning:'none', spacing:'0px',
fill:strip, stroke:'black', bg:'yellow',
paddingX:.7, paddingY:.5,
});
p.rect(rect.l, rect.t, rect.r, rect.b, {stroke:'red'});
文字背景色 bg 缺省为画布背景色,当 bg == 'none' 时,没有背景色(相当于背景色透明)。
渲染多行文本,返回 Bounding Box:
var rect = p.text('Brief Introduction to DDZEB Lands\n\n蓝紫(Lands)是由 DDZEB 完全自主开发出品的一款免费在线图形图像开发平台\n\n通过编写代码进行二维、三维图形图像的渲染及绘制', -4, 4, {
font:'.5px arial', gap:.2, blank:.5,
bg:'yellow', paddingX:1, paddingY:.5,
fill:'#000', width:5,
});
p.rect(rect.l, rect.t, rect.r, rect.b, {stroke:'red'});
将图像或者视频等画到以 x 和 y 为中心的位置上。options 包括:
const p = await Lan.curve(1200, 800);
p.view(-1000, 1000);
p.clear({fill:'#555'});
const media = (await Lan.import('media')).media();
const image = await media.image('I2');
const path = new Path2D();
path.arc(0, 0, 500, 0, 2 * Math.PI);
p.draw(image, 0, 0, {
clip:path, scale:0.5, repeat:'repeat',
});
p.axis();
生成填充样式,比如为多边形画阴影线:
var s = p.pattern({
type:'strip1',
fact:.05, bg:[255,255,0,128], fg:[255,0,0,128],
});
p.poly([
-3,2, 6,1, 1,-4
], {fill:s});
除了使用 type 选择内置的样式以外,还可以使用图片作为样式:
const image = await Lan.image('T21');
await Lan.font('baby', 'F1');
const pattern = p.pattern({image:image, scale:.1});
p.label('Hello Curve', 0, 0, {
font:'bold 3px baby', fill:pattern,
stroke:'gray', line:.04, dash:[.3],
filter:'drop-shadow(5px 5px 6px black)',
});
线性渐变,可用于填充以及线条颜色。
const canvas = await Lan.curve();
const gra = canvas.linearGradient(-500, -100, 500, 100, [
0, '#ff727d', 0.5, '#000', 1, '#72b3ff',
]);
canvas.clear({fill:gra});
辐射线性渐变,可用于填充以及线条颜色。
const canvas = await Lan.curve();
const gra = canvas.radialGradient(-100, 0, 0, 500, [
0, '#ff727d', 0.5, '#000', 1, '#72b3ff',
]);
canvas.clear({fill:gra});
辐射线性渐变,可用于填充以及线条颜色。
const canvas = await Lan.curve();
const gra = canvas.conicGradient(0, 0, 0, [
0, '#ff727d', 0.5, '#000', 1, '#72b3ff',
]);
canvas.clear({fill:gra});
这两个函数的主要目的是加速动画渲染,通过 get 函数可以取得画布图像,通过 put 可以将图像写入画布,具体使用方法请参考蓝紫示例程序:Wave Fading。
从画布空间将像素坐标映射到世界空间得到世界坐标,返回 [pointX, pointY] 数组。当要处理鼠标事件的时候,这个函数就很方便。蓝紫辅助工具 Julia 集合常数 就用到了这个函数进行坐标映射。
该函数将世界坐标映射到画布像素坐标,返回数组 [pixelX, pixelY]。
渲染上下文,CanvasRenderingContext2D。当现有接口方法满足不了要求的时候,我们可以通过渲染上下文进行手动扩展。
视口区域属性,其中 x0 < x1,y0 < y1。
这两个属性代表了世界坐标与画布像素坐标之间的比例(scale)关系,其中 pointSize 代表世界坐标中的 1 在像素空间中覆盖多少个像素,而 pixelSize 代表像素空间中一个像素在世界空间中的大小。
这个接口文档看起来挺复杂,实际上使用起来很简单。有了这个工具,我们再也不需要寻找第三方平台。可以画函数曲线的第三方平台其实很多,但都太过复杂,鼠标点来点去,半天还没搞定。而实际上我们有时候就只是希望给一个函数,工具帮忙画出来就是了,这就是 curve 渲染引擎的核心诉求。除了常规的数学绘图,也可进行艺术创作,除了二维渲染,也可以画三维,比如:
目前,蓝紫 curve.js 开发库已经完全可以满足二维函数的设计和渲染工作,我们将暂时停止开发新的功能。最后,送给大家一个特别的波形信号: