我在HTML画布中绘制了很多图形和元素。所有这些都有不同的颜色,笔画等等。我真的不喜欢所有这些值都在我的JS代码中游荡,因为有些样式在CSS中,有些在代码中。
有人知道在CSS中定义样式并在实际渲染对象时读取样式的好方法吗?
以下是我需要做的一些例子:
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.fillStyle = 'green'; // I'd like to set with CSS
context.fill();
context.lineWidth = 5; // I'd like to set with CSS
context.strokeStyle = '#003300'; // I'd like to set with CSS
context.stroke();
答案 0 :(得分:5)
我参加聚会有点晚了,但我只是有同样的情景而且我解决了这个问题:
// "Cache"
var classColors = {};
function getColor(className) {
// Check for the color
if (!classColors[className]) {
// Create an element with the class name and add it to the dom
$c = $('<div class="' + className + '"></div>').css('display', 'none');
$(document.body).append($c);
// Get color from dom and put it in the color cache
classColors[className] = $c.css('color');
// Remove the element from the dom again
$c.remove();
}
// Return color
return classColors[className];
}
我只需要颜色,但如果需要,可以扩展缓存对象以容纳更多颜色。您将从该函数返回一个完整的对象。以下代码根本未经过测试:
var classProperties = {};
function getPropeties(className) {
// Check for the properties object
if (!classProperties[className]) {
// Create an element with the class name and add it to the dom
$c = $('<div class="' + className + '"></div>').css('display', 'none');
$(document.body).append($c);
// Get needed stuff from the dom and put it in the cache
// P.S. Didn't test if canvas names are the same as css names.
// If not you'll have to translate it
classProperties[className] = {
fillStyle: $c.css('color'),
lineWidth: $c.css('border-width'),
strokeStyle: $c.css('border-style')
}
// Remove the element from the dom again
$c.remove();
}
// Return properties
return classProperties[className];
}
答案 1 :(得分:4)
通常,在画布中绘制大量内容的人会使用样式属性创建自己的形状对象。例如:http://jsfiddle.net/b93cc3ww/
context = document.getElementById("myCanvas").getContext("2d");
function Rectangle(params) {
this.x = params.x || 0;
this.y = params.y || 0;
this.width = params.width || 0;
this.height = params.height || 0;
this.fillStyle = params.fillStyle || "#FFFFFF";
this.strokeStyle = params.strokeStyle || "#000000";
this.lineWidth = params.lineWidth || 0;
}
Rectangle.prototype.draw = function () {
if (this.fillStyle) {
context.fillStyle = this.fillStyle;
context.fillRect(this.x, this.y, this.width, this.height)
}
if (this.strokeStyle && this.lineWidth) {
context.strokeStyle = this.strokeStyle;
context.lineWidth = this.lineWidth;
context.strokeRect(this.x, this.y, this.width, this.height);
}
}
rectangles = [
new Rectangle({
x: 10,
y: 10,
width: 300,
height: 150,
fillStyle: "#FF0000"
}),
new Rectangle({
x: 250,
y: 10,
width: 100,
height: 80,
fillStyle: "#00FF00",
strokeStyle: "#00AA00",
lineWidth: 5
}),
new Rectangle({
x: 10,
y: 200,
width: 250,
height: 80,
strokeStyle: "#FF0000",
lineWidth: 1
})
]
for (var i = 0; i < rectangles.length; ++i) {
rectangles[i].draw();
}
如果您喜欢CSS的工作方式,您可以创建一个形状对象,该对象可以采用“class”参数,然后在代码顶部的数组中存储“clases”列表。
答案 2 :(得分:0)
CSS有一定的范围,也就是说,它只对HTML元素起作用。另一方面,Javascript有自己的变量,也可以与HTML元素进行交互。您尝试做的是使用CSS作为javascript的变量,这是无法完成的。
上面的代码示例代表一段javascript,它接受一个HTML元素(在本例中为canvas
)并对其执行一组操作(方法)。你正在做的是一次绘制一行来创建你的图像,这个图像在CSS范围之外,因为它只由元素内部属性定义,而CSS只能定义它的外部(具体来说,视觉)属性。
答案 3 :(得分:0)
游戏有点晚了,但我认为这仍然很有用,所以我创建了一个接受答案的 jQuery 免费版本:
var classProperties = {};
function getPropeties(className)
{
if (true === classProperties[className]) {
return classProperties[className];
}
// Create an element with the class name and add it to the dom
let element = document.createElement('div');
element.style.display = 'none;'
element.classList.add(className);
document.body.appendChild(element);
// Get needed stuff from the dom and put it in the cache
let compStyles = window.getComputedStyle(element);
classProperties[className] = {
fill: compStyles.backgroundColor,
lineWidth: compStyles.borderWidth,
stroke: compStyles.borderColor
}
// Remove the element from the dom again
element.remove();
return classProperties[className];
}
此外,由于我遇到了这个问题:如果你想在 Vue 中使用它,你必须等待整个视图被挂载,否则样式有可能由于竞争而无法正确返回计算出的样式状况。有关必要的代码,请参阅 https://vuejs.org/v2/api/#mounted。
我敢肯定,在加载 CSS 之前执行任何普通 JS 代码时,这也可能是一个问题。