Javascript SVG的降价模拟

Javascript SVG的降价模拟,javascript,html,canvas,svg,markdown,Javascript,Html,Canvas,Svg,Markdown,我正在使用格式来表示网站页面上的内容(文章、问题陈述)。现在我想在文本中添加一些图片或图画 我考虑使用嵌入HTML的SVG元素,而不是存储光栅图像。并且markdown可以很好地处理这个问题(如果svg包含在div元素中) 但是,SVG格式本身并不像markdown那么简单,我现在想知道,是否存在类似markdown的处理器,它可以以一些简单的格式接收命令,例如: svg 200, 150 set-color black set-fill none rect 0, 0, 200, 150 set

我正在使用格式来表示网站页面上的内容(文章、问题陈述)。现在我想在文本中添加一些图片或图画

我考虑使用嵌入HTML的SVG元素,而不是存储光栅图像。并且markdown可以很好地处理这个问题(如果svg包含在div元素中)

但是,SVG格式本身并不像markdown那么简单,我现在想知道,是否存在类似markdown的处理器,它可以以一些简单的格式接收命令,例如:

svg 200, 150
set-color black
set-fill none
rect 0, 0, 200, 150
set-color #C00
set-fill #F00
circle 100, 75, 50
并将其转换为svg元素。有人遇到过这样的事情吗


我认为javascript和canvas也可以,如果有类似于降价的处理器的话…

我不知道SVG解析器有任何降价,但构建一个并不困难

这里有一个小提琴演示:

从知道如何在javascript中创建Svg元素的Svg“类”开始

(下面是Svg类的代码)

此Svg类知道如何执行以下Svg任务:

  • 创建父html svg元素(新svg)
  • 设置svg元素的大小(.setSvgWidthHeight)
  • 为任何新SVG形状(.setColor)设置默认笔划颜色
  • 为任何新SVG形状(.setFill)设置默认填充颜色
  • 创建一个rect对象并将其添加到svg元素(.rect)
  • 创建圆形对象并将其添加到svg元素(.circle)
首先,创建一些示例标记:

// create a new Svg object
// this object knows how to create SVG elements

var svg=new Svg();

// strip off trailing return, if present
if(markdown.slice(-1)=="\n"){
    markdown=markdown.slice(0,-1);
}

// split markdown into individual commands
var commands=markdown.split("\n");
var Svg = (function () {

    // constructor
    function Svg() {
        this.svgns="http://www.w3.org/2000/svg";
        this.xlink='http://www.w3.org/1999/xlink'
        this.nextId=1000;
        this.fill="gray";
        this.stroke="black";
        this.strokeWidth=2;
        this.width =1;
        this.height=1;
        this.svg=document.createElementNS(this.svgns,"svg");
        this.svg.setAttribute('width', this.width);
        this.svg.setAttribute('height', this.height);
        document.body.appendChild(this.svg);
    }
    //
    Svg.prototype.create = function(elementType,fill,stroke,strokeWidth,id){
        var e=document.createElementNS(this.svgns,elementType);
        e.setAttribute("id",id||this.nextId++);
        e.setAttribute("fill",fill||this.fill);
        e.setAttribute("stroke",stroke||this.stroke);
        e.setAttribute("stroke-width",strokeWidth||this.strokeWidth);
        this.svg.appendChild(e);
        return(e);
    }
    //
    Svg.prototype.setSvgWidthHeight = function(width,height){
        this.svg.setAttribute("width",width);
        this.svg.setAttribute("height",height);
        return(this);
    }
    //
    Svg.prototype.rect = function (x,y,width,height) {
        var e=this.create("rect");
        e.setAttribute("x",x);
        e.setAttribute("y",y);
        e.setAttribute("width",width);
        e.setAttribute("height",height);
        e.setAttribute("fill",this.fill);
        e.setAttribute("stroke",this.stroke);
        return(this);
    };
    //
    Svg.prototype.setFill = function(fillcolor){
        this.fill=fillcolor;
        return(this);
    }
    //
    Svg.prototype.setColor = function(strokecolor){
        this.stroke=strokecolor;
        return(this);
    }
    //
    Svg.prototype.circle = function (cx,cy,radius) {
        var e=this.create("circle");
        e.setAttribute("cx",cx);
        e.setAttribute("cy",cy);
        e.setAttribute("r",radius);
        e.setAttribute("fill",this.fill);
        e.setAttribute("stroke",this.stroke);
        return(this);
    };

    return Svg;
})();
(假设所有降价形式正确且有效)

然后像这样解析该标记:

// create a new Svg object
// this object knows how to create SVG elements

var svg=new Svg();

// strip off trailing return, if present
if(markdown.slice(-1)=="\n"){
    markdown=markdown.slice(0,-1);
}

// split markdown into individual commands
var commands=markdown.split("\n");
var Svg = (function () {

    // constructor
    function Svg() {
        this.svgns="http://www.w3.org/2000/svg";
        this.xlink='http://www.w3.org/1999/xlink'
        this.nextId=1000;
        this.fill="gray";
        this.stroke="black";
        this.strokeWidth=2;
        this.width =1;
        this.height=1;
        this.svg=document.createElementNS(this.svgns,"svg");
        this.svg.setAttribute('width', this.width);
        this.svg.setAttribute('height', this.height);
        document.body.appendChild(this.svg);
    }
    //
    Svg.prototype.create = function(elementType,fill,stroke,strokeWidth,id){
        var e=document.createElementNS(this.svgns,elementType);
        e.setAttribute("id",id||this.nextId++);
        e.setAttribute("fill",fill||this.fill);
        e.setAttribute("stroke",stroke||this.stroke);
        e.setAttribute("stroke-width",strokeWidth||this.strokeWidth);
        this.svg.appendChild(e);
        return(e);
    }
    //
    Svg.prototype.setSvgWidthHeight = function(width,height){
        this.svg.setAttribute("width",width);
        this.svg.setAttribute("height",height);
        return(this);
    }
    //
    Svg.prototype.rect = function (x,y,width,height) {
        var e=this.create("rect");
        e.setAttribute("x",x);
        e.setAttribute("y",y);
        e.setAttribute("width",width);
        e.setAttribute("height",height);
        e.setAttribute("fill",this.fill);
        e.setAttribute("stroke",this.stroke);
        return(this);
    };
    //
    Svg.prototype.setFill = function(fillcolor){
        this.fill=fillcolor;
        return(this);
    }
    //
    Svg.prototype.setColor = function(strokecolor){
        this.stroke=strokecolor;
        return(this);
    }
    //
    Svg.prototype.circle = function (cx,cy,radius) {
        var e=this.create("circle");
        e.setAttribute("cx",cx);
        e.setAttribute("cy",cy);
        e.setAttribute("r",radius);
        e.setAttribute("fill",this.fill);
        e.setAttribute("stroke",this.stroke);
        return(this);
    };

    return Svg;
})();
最后,使用Svg类将每个标记命令处理到关联的Svg中

// process each command in commands using the svg object

for(var i=0;i<commands.length;i++){
    processCommand(svg,commands[i]);
    console.log(commands[i]);
}


// this function takes a line of Markup and executes the associated Svg command


function processCommand(svg,commandline){

    // get command and remove command from commandline

    var command=(commandline.split(" ")[0]).toLowerCase();
    commandline=commandline.substr(commandline.indexOf(" ")+1).trim();

    // get args (assuming comma/space delimiters)

    var args=commandline.split(/[ ,]+/);

    // execute the command with svg

    switch(command){
        case "svg":
            svg.setSvgWidthHeight(args[0],args[1])
            break;
        case "set-color":
            svg.setColor(args[0])
            break;
        case "set-fill":
            svg.setFill(args[0])
            break;
        case "rect":
            svg.rect(args[0],args[1],args[2],args[3])
            break;
        case "circle":
            svg.circle(args[0],args[1],args[2])
            break;
        default:
            break;
    }

}

美好的可以使用对象而不是开关:svgCommand={svg:svg.prototype.setSvgWidthHeight,“set color”:svg.prototype.setColor…};然后使用类似于svgCommand[command].apply(svg,参数)。。。由于语言没有限制,我们可以在原型和语言上使用相同的关键字,不需要翻译。(Svg.prototype[command].apply(Svg,arguments);//可能需要先检查一下是否有正确的错误消息。)同意……因为参数已经在数组中了,.apply将是重构生产代码的一个很好的选择。感谢您的回答,但是我要求提供ready parser,因为我想知道这里是否有一些“标准化”语法。我真的在考虑自己写这个东西(虽然是用PHP或其他服务器端语言,以便在输出之前呈现这些东西),但是你知道,在实现一些“创新想法”之前,看看已经做了什么总是很重要的:)正如我提到的……我还没有看到SVG编译器的公开降价,尽管我确信已经完成了——人们喜欢做交叉编译器来取乐!:)好吧,我相信你有你的理由,所以也许我写的东西没有那么有用,但标记的整个想法是易于编写和阅读——即使你没有研究语法,文本的预期格式也是显而易见的。我看不出你怎么能得到类似于矢量图形的东西;无论语法多么简单,它永远都不容易阅读,只需要将它转换成可以查看的内容即可。因此,我建议在单独的文件中准备插图,然后通过
将它们包括在内![]()
语法。