- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试围绕 Canvas 的中心点旋转渐变,但我没有运气找到实现此目的所需的正确计算。
我想做的一个例子是:http://victorblog.com/html5-canvas-gradient-creator/ .旋转 slider 正是我想要做的,但我查看了源代码,逻辑似乎可以使用 cos/sin 简化很多(尽管我不是这方面的专家,因此我为什么要问这个问题)。
我发现这个 SO 线程 ( Calculate rotation of canvas gradient ) 有点帮助,但它围绕中心点旋转,而不是像第一个示例中的旋转 slider 那样坚持它。
在此方面的任何帮助者将不胜感激。
谢谢
最佳答案
如果您不担心渐变适合 Canvas ,那么简单的旋转即可解决问题。
首先你必须计算出渐变的最大长度,这样当它是对 Angular 线时它仍然适合 Canvas 。
const maxLength = Math.sqrt(canvas.width * canvas.width + canvas.height * canvas.height);
然后你可以创建渐变如下
var angle = ?; // The angle in radians
// A value of 0 if a gradient from right to left
const gradient = ctx.createLinearGradient(
// the start of the gradient added to the center
canvas.width / 2 + Math.cos(angle) * maxLength * 0.5,
canvas.height / 2 + Math.sin(angle) * maxLength * 0.5,
// the end of the gradient subtracted from the center
canvas.width / 2 - Math.cos(angle) * maxLength * 0.5,
canvas.height / 2 - Math.sin(angle) * maxLength * 0.5
)
这可行,但当渐变不沿对 Angular 线时会裁剪渐变。
const eachOf=(a,cb)=>{var i=0;const len=a.length;while(i<len)cb(a[i], i++);};
const ctx = canvas.getContext("2d");
const w = canvas.width;
const h = canvas.height;
const maxWidth = Math.sqrt(w * w + h * h) / 2;
// empty colour items are skipped when creating the gradient
const gradientColours = ["white","blue",,,,"green","yellow","green",,,,"cyan","black"];
function createRotatedGradient(angle, colors){
const g = ctx.createLinearGradient(
w / 2 + Math.cos(angle) * maxWidth, // start pos
h / 2 + Math.sin(angle) * maxWidth,
w / 2 - Math.cos(angle) * maxWidth, // end pos
h / 2 - Math.sin(angle) * maxWidth
);
// add colours
eachOf(colors,(col,i)=> col && g.addColorStop(i / (colors.length - 1), col) );
return g;
}
function update(timer){
ctx.fillStyle = createRotatedGradient(timer / 1000,gradientColours);
ctx.fillRect(0,0,w,h);
requestAnimationFrame(update);
}
requestAnimationFrame(update);
canvas { border : 2px solid black; }
<canvas id="canvas"></canvas><
这可以通过设置 maxWidth
来修改以适应宽度或高度。 canvas.height
的梯度或 canvas.width
const eachOf=(a,cb)=>{var i=0;const len=a.length;while(i<len)cb(a[i], i++);};
const ctx = canvas.getContext("2d");
const w = canvas.width;
const h = canvas.height;
const maxWidth = h / 2;
// empty colour items are skipped when creating the gradient
const gradientColours = ["white","green",,,,"blue","cyan","blue",,,,"yellow","black"];
function createRotatedGradient(angle, colors){
const g = ctx.createLinearGradient(
w / 2 + Math.cos(angle) * maxWidth, // start pos
h / 2 + Math.sin(angle) * maxWidth,
w / 2 - Math.cos(angle) * maxWidth, // end pos
h / 2 - Math.sin(angle) * maxWidth
);
// add colours
eachOf(colors,(col,i)=> col && g.addColorStop(i / (colors.length - 1), col) );
return g;
}
function update(timer){
ctx.fillStyle = createRotatedGradient(timer / 1000,gradientColours);
ctx.fillRect(0,0,w,h);
requestAnimationFrame(update);
}
requestAnimationFrame(update);
canvas { border : 2px solid black; }
<canvas id="canvas"></canvas><
const eachOf=(a,cb)=>{var i=0;const len=a.length;while(i<len)cb(a[i], i++);};
const ctx = canvas.getContext("2d");
const w = canvas.width;
const h = canvas.height;
const maxWidth = w / 2;
// empty colour items are skipped when creating the gradient
const gradientColours = ["white","blue",,,,"yellow","green","yellow",,,,"cyan","black"];
function createRotatedGradient(angle, colors){
const g = ctx.createLinearGradient(
w / 2 + Math.cos(angle) * maxWidth, // start pos
h / 2 + Math.sin(angle) * maxWidth,
w / 2 - Math.cos(angle) * maxWidth, // end pos
h / 2 - Math.sin(angle) * maxWidth
);
// add colours
eachOf(colors,(col,i)=> col && g.addColorStop(i / (colors.length - 1), col) );
return g;
}
function update(timer){
ctx.fillStyle = createRotatedGradient(timer / 1000,gradientColours);
ctx.fillRect(0,0,w,h);
requestAnimationFrame(update);
}
requestAnimationFrame(update);
canvas { border : 2px solid black; }
<canvas id="canvas"></canvas><
要适应宽度和高度,您可以使用非常简单的 y 轴缩放。这个比例是宽度和高度的比例。
const maxLen = canvas.width;
const aspect = canvas.height / canvas.width;
const angle = ?
const gradient = ctx.createLinearGradient(
// the start of the gradient added to the center
canvas.width / 2 + Math.cos(angle) * maxLen * 0.5,
canvas.height / 2 + Math.sin(angle) * maxLen * 0.5 * aspect,
// the end of the gradient subtracted from the center
canvas.width / 2 - Math.cos(angle) * maxLen * 0.5,
canvas.height / 2 - Math.sin(angle) * maxLen * 0.5 * aspect
)
const eachOf=(a,cb)=>{var i=0;const len=a.length;while(i<len)cb(a[i], i++);};
const ctx = canvas.getContext("2d");
const w = canvas.width;
const h = canvas.height;
const maxWidth = w / 2;
const aspect = h / w;
// empty colour items are skipped when creating the gradient
const gradientColours = ["white","red",,,,"yellow","green","yellow",,,,"red","black"];
function createRotatedGradient(angle, colors){
const g = ctx.createLinearGradient(
w / 2 + Math.cos(angle) * maxWidth, // start pos
h / 2 + Math.sin(angle) * maxWidth * aspect,
w / 2 - Math.cos(angle) * maxWidth, // end pos
h / 2 - Math.sin(angle) * maxWidth * aspect
);
// add colours
eachOf(colors,(col,i)=> col && g.addColorStop(i / (colors.length - 1), col) );
return g;
}
function update(timer){
ctx.fillStyle = createRotatedGradient(timer / 1000,gradientColours);
ctx.fillRect(0,0,w,h);
requestAnimationFrame(update);
}
requestAnimationFrame(update);
canvas { border : 2px solid black; }
<canvas id="canvas"></canvas><
example site您提供了拟合梯度,使其来自最近的边缘,这是一个更好的拟合,但仍然不是完美的拟合,因为梯度有时会太短。由于您从该站点获得了方法,因此我不会在此处包含它。
最佳适配稍微复杂一些,但始终适合 Canvas ,因此 Canvas 不会溢出或欠流(不会从渐变外部设置像素,并且所有渐变在任何 Angular 都可见)
有关信息,请参阅示例。数学取自并改编自 this answer适合旋转图像。
const eachOf=(a,cb)=>{var i=0;const len=a.length;while(i<len)cb(a[i], i++);};
const ctx = canvas.getContext("2d");
const w = canvas.width;
const h = canvas.height;
const maxWidth = w / 2;
const aspect = h / w;
// empty colour items are skipped when creating the gradient
const gradientColours = ["black","white",,,,"white","red",,,,,,,,,"yellow","green","yellow",,,,,,,,,"red","black",,,,"black","white"];
function bestFitGradient(angle, colors){
var dist = Math.sqrt(w * w + h * h) / 2; // get the diagonal length
var diagAngle = Math.asin((h / 2) / dist); // get the diagonal angle
// Do the symmetry on the angle (move to first quad
var a1 = ((angle % (Math.PI *2))+ Math.PI*4) % (Math.PI * 2);
if(a1 > Math.PI){ a1 -= Math.PI }
if(a1 > Math.PI / 2 && a1 <= Math.PI){ a1 = (Math.PI / 2) - (a1 - (Math.PI / 2)) }
// get angles from center to edges for along and right of gradient
var ang1 = Math.PI/2 - diagAngle - Math.abs(a1);
var ang2 = Math.abs(diagAngle - Math.abs(a1));
// get distance from center to horizontal and vertical edges
var dist1 = Math.cos(ang1) * h;
var dist2 = Math.cos(ang2) * w;
// get the max distance
var scale = Math.max(dist2, dist1) / 2;
// get the vector to the start and end of gradient
var dx = Math.cos(angle) * scale;
var dy = Math.sin(angle) * scale;
// create the gradient
const g = ctx.createLinearGradient(
w / 2 + dx, // start pos
h / 2 + dy,
w / 2 - dx, // end pos
h / 2 - dy
);
// add colours
eachOf(colors,(col,i)=> col && g.addColorStop(i / (colors.length - 1), col) );
return g;
}
function update(timer){
ctx.fillStyle = bestFitGradient(timer / 1000,gradientColours);
ctx.fillRect(0,0,w,h);
requestAnimationFrame(update);
}
requestAnimationFrame(update);
canvas { border : 2px solid black; }
<canvas id="canvas"></canvas><
关于javascript - HTML5 Canvas 围绕中心旋转渐变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45624502/
这是一种复杂的情况。我正在重构(从头开始)c++,它必须用作 CGI 脚本和独立应用程序的核心。 遗憾的是,我从大学开始就没有写过C++,对c#/Java比较熟悉。所以我打算将 WPF 用于 GUI。
您好,我正在尝试找出与此线程中提出的问题相同的问题 How to use CSS to surround a number with a circle? 但是 - 每次我这样做时,形状都会变成椭圆形,
如果您在单个语句中执行某些操作,例如“abc”+ stringval +“abc”,那么是一个不可变的字符串副本,还是两个(注意 abc 和 123 在编译时是常量) 奖励回合:使用像下面这样的 St
我正在尝试创建一个查询,该查询只会在满足某些条件的情况下添加 AND 子句。 这就是我所追求的: SELECT DISTINCT id name active FROM team WHER
在使用 Google 的出色绘图工具进行了一些试验后,我正在使用 Gnuplot 绘制几个 3D 图形。我喜欢 Google 工具的一件事是它在表面周围绘制的“边界框”,这让我更容易看到大小。 有没有
我们最近从solr迁移到 Elasticsearch 。 因此决定以自定义查询格式编写一个包装器,该包装器将转换为 Elasticsearch 查询。将来,如果我们更改为另一个数据存储,则只需要修改此
我有以下内容将音频剪辑的频率绘制为条形音箱: const drawSinewave = function() { requestAnimationFrame(drawSinewave);
我试图围绕其父矩形的中心旋转一个矩形。 child 到 parent 边界的距离必须始终保持不变。我几乎成功了,但我的方法似乎有一个小错误。我似乎找不到问题所在。 示例: http://jsfiddl
我有一个帮助类来将用户对象保存到共享首选项。我用过 serialize(): String函数和 create(serializedString: String)我的 User 中的函数数据模型。他们
是否可以围绕 UIBezierPath 的可见部分绘制路径? 这是我的问题的一个例子 这是我想要完成的 这是我到目前为止得到的: - (void)drawRect:(CGRect)rect { C
这里,AsciiChecker启用文本形式的矩阵规范。 abstract class AsciiChecker extends AlgoritmicChecker { String[] asc
目前,我有十个不同的查询,它们通过 JDBC 处理,并包装在返回 ResultSet 的函数中。这些 ResultSet 对象中的每一个都由外部程序进行迭代,并将通过其索引而不是根据要求的列名进行访问
围绕 finder 方法启动事务是否明智: @Transactional public E getParticularEvent(final String id) { return (E)em
我需要一个围绕 Canvas 边缘移动的圆圈。向右然后向下移动可以正常工作,但是当它需要向左移动时,它会跳到右下角并开始一次又一次地向右移动。我不知道如何解决这个问题。 var can = doc
我正在尝试我的第一个 jQuery 插件。 (耶……时间到了!) 我很难思考如何让一个可公开访问的函数正常启动。 代码 (function($, doc, win){ "use strict"
在阅读了很多关于绕相机旋转的指南并询问了一些关于 SO 的其他问题后,我想到了 SSCCE我到目前为止所拥有的。也许这样其他人会更容易理解我需要什么,对我来说答案是什么。 到目前为止它看起来像这样:
这里是 Java 菜鸟!我正在努力为我正在编写的 Android 应用程序画龙点睛。本质上,它是一个 RSS 阅读器。异步任务获取 RSS 提要。然后对其进行解析,我想做的最后一点是使用已解析的 RS
我有以下代码,从数据库的“类(class)”表中选择标题和图像。 setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
我正在尝试实现一个表盘,其中一只手的位图图像围绕 Canvas 上的表盘中心旋转。 基本上在 onDraw() 方法中,我希望能够将图像资源放到 Canvas 上,然后每秒旋转一次。 我有每秒触发一次
我从 SwingX 找到了一个名为 JXLoginPane 的组件在 WindowBuilder 中可用,这似乎是我尝试做的事情的一个很好的起点,但我需要有关如何使用它的更多信息。到目前为止,我发现唯
我是一名优秀的程序员,十分优秀!