Load a new IMG as pattern into a SVG - svg

Into my page I have a SVG image wth 3 path then on other side I have 3 buttons. On click on each button I want apply a pattern to my SVG's path.
The script I did not works completly. It update the SVG structure adding all the necessary code but the result miss the image.
UPDATE Here the demo: http://jsfiddle.net/uncoke/756DS/
If on debug I copy the new SVG code and open it in a new window I see the result I want. But on live... it wont load the img pattern. Here the heart of my script:
var svgns = "http://www.w3.org/2000/svg";
var img = document.createElementNS(svgns,'image');
img.setAttributeNS(null,'height','536');
img.setAttributeNS(null,'width','536');
img.setAttributeNS('http://www.w3.org/1999/xlink','xlink:href',pattern_url);
img.setAttributeNS(null,'x','-81');
img.setAttributeNS(null,'y','-81');
img.setAttributeNS(null, 'visibility', 'visible');
def= document.createElementNS(svgns,'defs');
pattern = document.createElementNS(svgns,'pattern');
pattern.setAttributeNS(null,'id','img_pattern');
pattern.setAttributeNS(null,'patternUnits','userSpaceOnUse');
pattern.setAttributeNS(null,'width','600');
pattern.setAttributeNS(null,'height','450');
pattern.appendChild(img)
def.appendChild(pattern)
side_1 = document.getElementById('side_1');
side_1.setAttributeNS(null,"fill","url(#img_pattern)")
side_2 = document.getElementById('side_2');
side_2.setAttributeNS(null,"fill","green")
side_3 = document.getElementById('side_3');
side_3.setAttributeNS(null,"fill","url(#img_pattern)")
On this test only the "fill","green" works.
Can you hep me ?

Related

How to do svg scaling with Pixi

I've been trying to do SVG scaling with PIXI but the results are not really what I expected them to be. As you can see in the image, the debian logo, which is a SVG file, seems to be blurry and edgy. Am I writing my code wrong:
Refined from https://github.com/kevguy/D3-Svg-Comparison/blob/master/src/components/SvgCompare.vue:
// initialization
this.renderer = new PIXI.Application(800, 600, {backgroundColor: 0x1099bb})
document.getElementById('svg-canvas').appendChild(this.renderer.view)
this.container = new PIXI.Container()
this.stage = this.renderer.stage
this.stage.addChild(this.container)
// appending the svg file
const texture = PIXI.Texture.fromImage(this.chosenImage)
this.svg = new PIXI.Sprite(texture)
this.svg.anchor.x = 0.8
this.svg.anchor.y = 0.8
this.svg.position.x = 400
this.svg.position.y = 300
this.svg.scale.x = this.selectedScale
this.svg.scale.y = this.selectedScale
this.container.addChild(this.svg)
chosenImage is the svg file retrieved by using import * as choesnImage from 'the-file-path'
selectedScale is the selected scaling value which can be changed dynamically thanks to VueJS
You can check out my work here and its corresponding GitHub repo
The bunny logo is to verify when the scaling happens, it only applies to the SVG not the whole canvas.
According to this issue you need to load svg like this to generate scaled svg texture.
PIXI.Texture.fromImage(this.chosenImage, undefined, undefined, newVal)
And need to clean texture cache then create new texture for every new scale change.
PIXI.utils.clearTextureCache()
Modified SvgCompare.vue on gist

Rendering MathML on svg using d3.js

I am trying to render MathML equations on svg using d3.js. Can anyone help me getting a quadratic equation on svg. I tried doing it using foreign object with no success.
I spent quite some time trying to make it work in a JSFiddle with no success, but it works great on my PC. JSFiddle here. Do you mind trying the following and let me know if it works with you too?
Step 1. Load MathJax
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
Step 2. Use this code to append a foreignObject
var svg = d3.select("body").append("svg").attr("width",400).attr("height",400)
var text = svg.append("foreignObject").attr("width",100).attr("height",100)
text.text("$$ x = \\sum_{i \\in A} i^{2} $$")
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
However, if you still prefer MathML, then you can use the following:
text.html("<math display=\"block\"><mrow><mi>x</mi><mo>=</mo><mfrac><mrow><mo>−</mo><mi>b</mi><mo>±</mo><msqrt><mrow><msup><mi>b</mi><mn>2</mn></msup><mo>−</mo><mn>4</mn><mi>a</mi><mi>c</mi></mrow></msqrt></mrow><mrow><mn>2</mn><mi>a</mi></mrow></mfrac></mrow></math>")
I know I am adding more scripts for you to load, but my understanding is that MathML is not really much used any more.
I hope it helps.
EDIT
Finally a JSFiddle here: link
Thanks
You've two bugs
foreignObject must have width/height attributes
mathml elements must be created in the mathml namespace
Fixing these results in this...
d3.ns.prefix.mathml = "http://www.w3.org/1998/Math/MathML";
var foreignObject = d3.select("body")
.append("svg")
var x = foreignObject.append("foreignObject")
.attr("requiredExtensions", "http://www.w3.org/1999/xhtml")
.attr("width", "100")
.attr("height", "100")
var text = x.append("mathml:mo")
var row = x.append("mathml:mrow")
row.append("mathml:mi").text("a")
row.append("mathml:mo").text('\u2062')
var msup = row.append("msup")
msup.append("mathml:mi").text("x")
msup.append("mathml:mi").text("2")
row.append("mathml:mo").text("+")
row.append("mathml:mi").text("b")
row.append("mathml:mo").text('\u2062')
row.append("mathml:mi").text('x')
row.append("mathml:mo").text('+')
row.append("mathml:mi").text('c')
or as a fiddle

raphael icons extract path

I am trying to create some login buttons based on the RaphaelJs icons, but on the example page there is only the Twitter paths that are available!
So I am looking to understand how to extract the SVG paths from Inkscape and update the example on http://jsfiddle.net/aqoon/LN23r/5/ for Google using http://upload.wikimedia.org/wikipedia/commons/2/28/Google_free_icon.svg file
var facebookBtn = "",
googleBtn = "M47.446122,148.46699L47.463496,149.0968L47.430196,149.09969C47.363594,148.8854247.278172,148.7259147.173az931,148.62119C47.069686,148.5164646.943725,148.464146.796048,148.4641C46.681186,148.464146.582493,148.4875146.499968,148.53432C46.417441,148.5811346.340465,148.6571446.269039,148.76235C46.124256,148.9775946.051865,149.2237246.051865,149.50074C46.051865,149.6329846.069239,149.7577346.103987,149.875C46.138734,149.9922846.189408,150.095846.256009,150.18556C46.385347,150.359346.54316,150.4461746.729448,150.44617C46.802803,150.4461746.871816,150.4307346.936487,150.39984C47.001155,150.3689547.054242,150.3264847.095748,150.27243C47.152694,150.1971547.181168,150.1078647.18117,150.00458C47.181168,149.9090347.155349,149.8400247.103711,149.79755C47.05207,149.7550846.96689,149.7338446.84817,149.73384L46.84817,149.70054L47.771883,149.70054L47.771883,149.73384C47.686942,149.7415647.62734,149.7533947.593076,149.76931C47.558809,149.7852447.533472,149.8125147.517065,149.85111C47.498724,149.8935947.489555,149.9780447.489557,150.10448C47.489555,150.1392347.491485,150.1932847.495348,150.26664L47.498244,150.29994C47.461564,150.2864347.434538,150.2796747.417165,150.27967C47.395929,150.2796747.368903,150.2907747.336087,150.31297C47.252112,150.3708847.154625,150.4152847.043626,150.44617C46.932625,150.4770646.815351,150.492546.691804,150.4925C46.521925,150.492546.368697,150.4635546.23212,150.40563C46.095541,150.3477245.984782,150.2647145.899844,150.15661C45.836139,150.0755345.787154,149.9790145.752889,149.86704C45.718624,149.7550845.701491,149.6363545.701491,149.51088C45.701491,149.338145.732378,149.1773945.794152,149.02875C45.855926,148.8801145.942795,148.7575346.054761,148.661C46.146456,148.5828246.252147,148.5224946.371835,148.48002C46.491521,148.4375646.617964,148.4163246.751165,148.41632C46.828382,148.4163246.900049,148.4235646.966168,148.43804C47.032284,148.4525247.102503,148.4761647.176826,148.50898L47.262248,148.54807C47.283481,148.5567647.302785,148.561147.320161,148.5611C47.358768,148.561147.388207,148.5297347.408479,148.46699L47.446122,148.46699z",
twitterBtn = "M14.605,13.11c0.913-2.851,2.029-4.698,3.313-6.038c0.959-1,1.453-1.316,0.891-0.216c0.25-0.199,0.606-0.464,0.885-0.605c1.555-0.733,1.442-0.119,0.373,0.54c2.923-1.045,2.82,0.286-0.271,0.949c2.527,0.047,5.214,1.656,5.987,5.077c0.105,0.474-0.021,0.428,0.464,0.514c1.047,0.186,2.03,0.174,2.991-0.13c-0.104,0.708-1.039,1.167-2.497,1.471c-0.541,0.112-0.651,0.083-0.005,0.229c0.799,0.179,1.69,0.226,2.634,0.182c-0.734,0.846-1.905,1.278-3.354,1.296c-0.904,3.309-2.976,5.678-5.596,7.164c-6.152,3.492-15.108,2.984-19.599-3.359c2.947,2.312,7.312,2.821,10.555-0.401c-2.125,0-2.674-1.591-0.99-2.449c-1.595-0.017-2.608-0.521-3.203-1.434c-0.226-0.347-0.229-0.374,0.14-0.64c0.405-0.293,0.958-0.423,1.528-0.467c-1.651-0.473-2.66-1.335-3.009-2.491c-0.116-0.382-0.134-0.363,0.256-0.462c0.38-0.097,0.87-0.148,1.309-0.17C6.11,10.88,5.336,9.917,5.139,8.852c-0.186-1.006,0.005-0.748,0.758-0.46C9.263,9.68,12.619,11.062,14.605,13.11L14.605,13.11z",
yahooBtn = "";
$('.twitterBtn').each(function(i) {
paper = Raphael($(this)[0], 40, 40)
paper.path(twitterBtn).attr({
"fill": "#333"
})
})
$('.googleBtn').each(function(i) {
paper = Raphael($(this)[0], 40, 40)
paper.path(googleBtn).attr({
"fill": "#333"
})
})​
I tried to strip the SVG file so that I just have one layer and only the 'G' but on the http://jsfiddle.net/aqoon/LN23r/5/ is not being displayed, what am i missing?
Also how do i add extra layers to the var googleBtn, as when I open the http://upload.wikimedia.org/wikipedia/commons/2/28/Google_free_icon.svg in Inkscape there are many layers and paths?
Raphael does not support ( SVG files in Raphael, can they be used?… ) loading whole SVG images and using those as paths, so the only reasonable option here is to extract separate paths and store them in some sort of datastructure, like in the example with the tiger ( http://raphaeljs.com/tiger.html ) -- check the source code there.
The SVG files can also have rather strange internal coordinate system, so it pays to adjust the view box after loading one, like this
var path = paper.path(googleBtn).attr({
"fill": "#333"
});
var bbox = path.getBBox();
paper.setViewBox(bbox.x, bbox.y, bbox.width, bbox.height);
To group different elements, one can use Raphael.Set http://jsfiddle.net/LN23r/40/
var shadow = paper.path(googleBtn).attr({"fill": "#0F0", "stroke":"none"}).translate(0.08,0.08);
var path = paper.path(googleBtn).attr({"fill": "#333", "stroke":"none"});
var set = paper.set(shadow, path);
var bbox = set.getBBox();
paper.setViewBox(bbox.x, bbox.y, bbox.width, bbox.height);
When grouping elements, note that they have transformation matrices associated with them in the SVG file (e.g. transform="matrix(204.67566,0,0,204.67566,-9225.9642,-30242.949)"), which affects the respective position and scale of the elements.
On the whole, the process of porting paths from SVG is not entirely trivial, but manageable. There is also a plugin that may help you with this, see https://github.com/wout/raphael-svg-import

trying to extract formatted images from indesign into a separate folder

I'm looking for a way to extract images from an ID file in a 'formatted' / cropped form.
i.e: a. I have placed numerous, hi-res (tiff, psd) images into an InDesign CS5 file
b. The image boxes that they have been placed into, are smaller than the actual image (pretty intense cropping occurred) c. I am trying to collect these images in their new stage (cropped to the image box) and export them as jpg at 72dpi.
Are there any plug-ins out there that would automatically collect "formatted" images from ID for me? Or is there some other way?
If you're familiar with Indesign Scripting, this can very easily be done via a script. I use Javascript but this can be done with VBSript or AppleScript as well. Here is a basic example of a script that will open a document, and export a rectangle (your image box) as a JPG. Basically, you can just loop through the pictures in your document and export each one to a location/filename you choose (see the myFile variable below). There are several "jpegExportPreferences" you can pick from to determine how your output JPG will be (i.e. DPI).
test();
function test(){
var myDoc = app.open('c:/user/desktop/testDocument.indd');
var myGroups = myDoc.groups;
//for each group...
for (var i = 0;i < myGroups.length; i++){
// for each rectangle in the group...
for(var r = 0; r< myGroups[i].rectangles.length; r++){
var myRect = myGroups[i].rectangles[r];
app.jpegExportPreferences.exportResolution = 300;
app.jpegExportPreferences.jpegQuality = JPEGOptionsQuality.MAXIMUM;
//give it a unique name
var myFile = new File('c:/users/desktop/newJPG' + myRect.id + '.jpg');
myRect.exportFile(ExportFormat.JPG, myFile);
}
}
}
For a list of the other optional JPG Export preferences, see this link:
http://indesignscriptingreference.com/cs2/javascript-cs2/jpegexportpreference.htm
Hope this helps!

How to create a `pixelized' SVG image from a bitmap?

I have a 16x16 bitmap and want to create an SVG that contains 16x16 squares with the colors of the pixels of the image. Is there an easy way to achieve this?
My current thoughts go into the direction of using Python and PIL to read the bitmap image and dynamically create an SVG image file with the corresponding objects. But this feels a little clumsy and like reinventing the wheel.
Is there a better way to do this?
If you don't need the output to be SVG, I would suggest using an HTML5 Canvas where you can sample the pixels of the image client-side (using getImageData() on the context) and then draw your own up-scaled image. Or, if you need SVG, you could still use Canvas for the image sampling and then use procedurally-created <rect/> elements in SVG for each pixel.
I've written an example using just HTML Canvas so you can see how to do this. In short:
function drawPixelated(img,context,zoom,x,y){
if (!zoom) zoom=4; if (!x) x=0; if (!y) y=0;
if (!img.id) img.id = "__img"+(drawPixelated.lastImageId++);
var idata = drawPixelated.idataById[img.id];
if (!idata){
var ctx = document.createElement('canvas').getContext('2d');
ctx.width = img.width;
ctx.height = img.height;
ctx.drawImage(img,0,0);
idata = drawPixelated.idataById[img.id] = ctx.getImageData(0,0,img.width,img.height).data;
}
for (var x2=0;x2<img.width;++x2){
for (var y2=0;y2<img.height;++y2){
var i=(y2*img.width+x2)*4;
var r=idata[i ];
var g=idata[i+1];
var b=idata[i+2];
var a=idata[i+3];
context.fillStyle = "rgba("+r+","+g+","+b+","+(a/255)+")";
context.fillRect(x+x2*zoom, y+y2*zoom, zoom, zoom);
}
}
};
drawPixelated.idataById={};
drawPixelated.lastImageId=0;
If you really need SVG involved, I'd be happy to write an example that dynamically generated that.
Edit: OK, I've created an SVG version just for fun and practice. :)
As an aside (from an initial misreading of your question) this demo file from ASVG3 their old SVG Examples Page shows how to use some complex compositing of many different effects to create pixelation on arbitrary vector data. Unfortunately the demo does not load in Chrome, having been hardwired to require the (now-discontinued) Adobe SVG Viewer.

Resources