Javascript 如何使用CSS设置画布元素的样式

Javascript 如何使用CSS设置画布元素的样式,javascript,html,css,canvas,Javascript,Html,Css,Canvas,我在HTML画布上绘制了很多图形和元素。它们都有不同的颜色、笔划等。我真的不喜欢所有这些值在我的JS代码中游荡,因为有些样式在CSS中,有些在代码中 有人知道在CSS中定义样式并在实际渲染对象时读取样式的好方法吗 以下是我需要做的一些示例: context.beginPath(); context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false); context.fillStyle = 'green'; // I'd like to se

我在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();

CSS有一定的作用域,也就是说,它只作用于HTML元素。另一方面,Javascript有自己的变量,也可以与HTML元素交互。您试图做的是使用CSS作为javascript的变量,这是不可能做到的


上面的代码示例表示一段javascript,它接受一个HTML元素(在本例中是一个
canvas
)并对其执行一组操作(方法)。你所做的就是一次画一条线来创建你的图像,而这个图像超出了CSS的范围,因为它只由元素的内部属性定义,而CSS只能定义它的外部(特别是视觉)属性。

通常,在画布上画很多东西的人会用样式属性创建自己的形状对象。例如:

context=document.getElementById(“myCanvas”).getContext(“2d”);
函数矩形(参数){
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=函数(){
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;
strokeRect(this.x,this.y,this.width,this.height);
}
}
矩形=[
新矩形({
x:10,
y:10,
宽度:300,
身高:150,
填充样式:“FF0000”
}),
新矩形({
x:250,
y:10,
宽度:100,
身高:80,
填充样式:“00FF00”,
strokeStyle:#00AA00“,
线宽:5
}),
新矩形({
x:10,
y:200,
宽度:250,
身高:80,
strokeStyle:#FF0000“,
线宽:1
})
]
对于(变量i=0;i

如果你喜欢CSS的工作方式,你可以制作一个shape对象,它可以接受一个“class”参数,然后在代码顶部的数组中存储一个“CLASE”列表。

我参加聚会有点晚了,但我只是遇到了同样的情况,我这样解决了它:

// "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 classColors={};
函数getColor(类名){
//检查颜色
如果(!classColors[className]){
//创建一个具有类名的元素并将其添加到dom中
$c=$('').css('display','none');
$(document.body).append($c);
//从dom中获取颜色并将其放入颜色缓存
classColors[className]=$c.css('color');
//再次从dom中删除元素
$c.删除();
}
//返回颜色
返回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];
}
var classProperties={};
函数getProperties(类名){
//检查属性对象
如果(!classProperties[className]){
//创建一个具有类名的元素并将其添加到dom中
$c=$('').css('display','none');
$(document.body).append($c);
//从dom中获取所需的内容并将其放入缓存
//P.S.没有测试画布名称是否与css名称相同。
//如果不是,你就得翻译它
classProperties[className]={
填充样式:$c.css('color'),
线宽:$c.css('border-width'),
strokeStyle:$c.css('border-style')
}
//再次从dom中删除元素
$c.删除();
}
//返回属性
返回classProperties[className];
}

游戏开始有点晚了,但我认为这仍然有用,所以我创建了一个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内部使用此选项,您必须等待整个视图装入,否则由于竞争条件,样式可能无法正确返回计算的样式。有关必要的代码,请参阅


我确信,在加载CSS之前执行任何普通JS代码时,这都可能是一个问题。

我也做了一些canvas,我认为你不能使用类,因为canva不真正做DOM元素,但是如果你必须使用多次相同的样式,你可以使用save/restore。虽然HTMLCanvas是一个DOM元素,但它实际上是构成在画布上绘制的形状的像素的容器。这意味着CSS不会影响画布上的形状。如果您想将上下文形状样式与应用程序分开存储,您可以考虑将这些上下文形状样式存储在单独的JSON文件中,您可以在应用程序开始时读取该文件。这只是对OP说“不,您不能这样做”的一种迂回方式。OP想使用实际CSS渲染画布,这是不可能的。在我的实际代码中,我正在做这样的事情——我有一些对象代表我的高级绘图对象,我有一些与样式相关的属性,但我希望找到一种方法将样式与逻辑分开,更重要的是——将我所有的颜色、字体和内容放在一个地方。不过,我喜欢你的最后一个建议——我只需要
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];
}