Dilate SVG element if overlapping another element - d3.js

I have a data diagram I created with D3 where I draw a circle for each data point.
When the circles overlap I want to render them slightly bigger so that you can see a difference when several data points pile up at the same position.
I found I can apply an feMorphology filter with dilate but I need to be able to somehow scale the dilation depending on the number of circles at the same position.
Here the SVG demonstration:
<svg width="400" height="120" xmlns="http://www.w3.org/2000/svg">
<filter id="dilateIfOverlapping">
<feMorphology operator="dilate" radius="4">
</filter>
<g filter="url(#dilateIfOverlapping)">
<circle cx="60" cy="60" r="30" fill="green" />
<circle cx="60" cy="60" r="30" fill="green" />
<circle cx="170" cy="60" r="30" fill="green" />
</g>
</svg>
This renders two circles of the same size. I want the first one to be bigger as there are two circles on top of each other.
Any idea how to achieve this without programmatically setting a different circle radius?

You can do this kind of thing with feComponentTransfer/feFuncA. But it only handles fully overlapping points vs. partial overlapping.
The way it works is that it renders the circles first with low opacity. So the more circles rendered at the same point, the higher their opacity. Then the filter chops up the image into different layers with different opacity ranges. Then it applies a different sized blur to the each of the layers and then dials up the opacity on the blurred circle and adds a little fake anti-aliasing with an additional blur.
The trick here is getting the opacity value of the circles just right, so it lines up with the opacity ranges of the feFuncA tableValues. You'd have to know ahead of time what the maximum number of overlapping points is going to be so you can calibrate this correctly. (This tableValues="0 1 0 0 0" for example, creates 5 opacity ranges 0-20%, 20-40%, 40-60%, 60-80% and 80-100%.)
<svg width="800px" height="600px">
<defs>
<filter id="embiggen" x="-50%" y="-50%" width="200%" height="200%">
<feComponentTransfer in="SourceGraphic" result="layer1">
<feFuncA type="discrete" tableValues="0 1 0 0 0" />
</feComponentTransfer>
<feComponentTransfer in="SourceGraphic" >
<feFuncA type="discrete" tableValues="0 0 1 0 0" />
</feComponentTransfer>
<feGaussianBlur stdDeviation= "2"/>
<feComponentTransfer >
<feFuncA type="discrete" tableValues="0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"/>
</feComponentTransfer>
<feGaussianBlur stdDeviation= "0.5" result="layer2"/>
<feComponentTransfer in="SourceGraphic" >
<feFuncA type="discrete" tableValues="0 0 0 1 0" />
</feComponentTransfer>
<feGaussianBlur stdDeviation= "4"/>
<feComponentTransfer>
<feFuncA type="discrete" tableValues="0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"/>
</feComponentTransfer>
<feGaussianBlur stdDeviation= "0.5" result="layer3"/>
<feComponentTransfer in="SourceGraphic">
<feFuncA type="discrete" tableValues="0 0 0 0 1" />
</feComponentTransfer>
<feGaussianBlur stdDeviation= "8"/>
<feComponentTransfer >
<feFuncA type="discrete" tableValues="0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1" />
</feComponentTransfer>
<feGaussianBlur stdDeviation= "0.5" result="layer4"/>
<feMerge>
<feMergeNode in="layer1"/>
<feMergeNode in="layer2"/>
<feMergeNode in="layer3"/>
<feMergeNode in="layer4"/>
</feMerge>
</defs>
</filter>
<g filter="url(#embiggen)" shape-rendering="crispEdges">
<circle cx="50" cy="50" fill-opacity="0.21" r="10" fill="red"/>
<circle cx="50" cy="50" fill-opacity="0.21" r="10" fill="red"/>
<circle cx="50" cy="50" fill-opacity="0.21" r="10" fill="red"/>
<circle cx="50" cy="50" fill-opacity="0.21" r="10" fill="red"/>
<circle cx="50" cy="50" fill-opacity="0.21" r="10" fill="red"/>
<circle cx="50" cy="50" fill-opacity="0.21" r="10" fill="red"/>
<circle cx="50" cy="50" fill-opacity="0.21" r="10" fill="red"/>
<circle cx="50" cy="50" fill-opacity="0.21" r="10" fill="red"/>
<circle cx="50" cy="50" fill-opacity="0.21" r="10" fill="red"/>
<circle cx="120" cy="50" fill-opacity="0.21" r="10" fill="red"/>
<circle cx="120" cy="50" fill-opacity="0.21" r="10" fill="red"/>
<circle cx="120" cy="50" fill-opacity="0.21" r="10" fill="red"/>
<circle cx="120" cy="50" fill-opacity="0.21" r="10" fill="red"/>
<circle cx="180" cy="50" fill-opacity="0.21" r="10" fill="red"/>
<circle cx="180" cy="50" fill-opacity="0.21" r="10" fill="red"/>
<circle cx="180" cy="50" fill-opacity="0.21" r="10" fill="red"/>
<circle cx="240" cy="50" fill-opacity="0.21" r="10" fill="red"/>
</g>
</svg>

Related

How to reverse animate motion?

Why my animation doesn't start from the top to the bottom ? How to reverse it correctly ? I don't know what I should change. (I tried keyPoints="1;0" keyTimes="0;1" which didn't work)
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="350" viewBox="0 0 500 350"><path d="M404.88 470.22V79.69c-.2-19-14.21-33-17.52-36.19s-16.77-15.19-34.7-15.45h-1.11c-28.65.35-59.55-.12-319.52 0H28" stroke="#000" stroke-miterlimit="10" fill="none" id="motionPath"></path><rect id="circle" x="-25" y="-25" rx="15" ry="15" width="50" height="50"></rect><animateMotion xlink:href="#circle" from="50" to="450" dur="5s" begin="0s" repeatCount="1" rotate="auto" fill="freeze"><mpath xlink:href="#motionPath"></mpath></animateMotion></svg>
It is necessary to remove from =" 50 " to =" 450 " since the length of the path of movement is determined by the length of the path mpath
The direction of movement of an object along a path depends on two parameters
keyPoints="1;0" - movement from start to finish
keyTimes="0;1"
keyPoints="0;1" - movement from end to start
keyTimes="0;1"
In the example below, JS is used only to handle the event of pressing the control buttons: forward and back
var animation1 = document.getElementById("forward")
function forwardSVG(){
animation1.beginElement();
}
var animation2 = document.getElementById("back")
function backSVG(){
animation2.beginElement();
}
<div id="pathContainer4">
<button id="btn1" onclick="forwardSVG()">forward</button />
<button id="btn2" onclick="backSVG()">Back</button />
</div>
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="350" viewBox="50 0 500 350">
<path id="motionPath" d="M404.88 470.22V79.69c-.2-19-14.21-33-17.52-36.19s-16.77-15.19-34.7-15.45h-1.11c-28.65.35-59.55-.12-319.52 0H28" stroke="#000" stroke-miterlimit="10" fill="none" >
</path>
<rect id="circle" x="0" y="-25" rx="15" ry="15" width="50" height="50"></rect>
<!-- Forward motion animation -->
<animateMotion id="forward"
xlink:href="#circle"
dur="5s"
begin="indefinite"
rotate="auto"
fill="freeze"
repeatCount="1"
keyPoints="1;0"
keyTimes="0;1"
calcMode="linear">
<mpath xlink:href="#motionPath"></mpath>
</animateMotion>
<!-- Backward motion animation -->
<animateMotion id="back"
xlink:href="#circle"
dur="5s"
begin="indefinite"
rotate="auto"
fill="freeze"
repeatCount="1"
keyPoints="0;1"
keyTimes="0;1"
calcMode="linear">
<mpath xlink:href="#motionPath"></mpath>
</animateMotion>
</svg>
Here is the reverse you want.
I modified the shape a little but you can modify it back again.
Hope that this is the solution to your problem.
you can make it freeze too if you want.
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="350" viewBox="0 0 500 350">
<g>
<path stroke="#000" stroke-miterlimit="10" fill="none" id="motionPath"
d="M404.88 470.22V79.69c-.2-19-14.21-33-17.52-36.19s-16.77-15.19-34.7-15.45h-1.11c-28.65.35-59.55-.12-319.52 0H28"/>
<rect id="circle" x="-25" y="-25" rx="15" ry="15" width="50" height="60" fill="black"
stroke="black" stroke-width="1" transform="translate(-25,-10)">
<animateMotion path="M404.88 470.22V79.69c-.2-19-14.21-33-17.52-36.19s-16.77-15.19-34.7-15.45h-1.11c-28.65.35-59.55-.12-319.52 0H28"
begin= "0s" dur="5s" repeatCount="1" rotate="auto" fill="freeze"
keyPoints="1;0" keyTimes="0;1" calcMode="linear"/>
</rect>
</g>
</svg>

Animating a defined path's d attribute doesn't work on firefox

I'm animating a d attribute of a path that is wrapped around a defs tag and linked using a
few use tags. This works fine on Chrome, however no animation on Firefox. I tried this with relative and absolute paths to no avail.
<svg viewBox="0 0 300 100">
<defs>
<path id="a" d="M0,20 H200 V70 H0z" />
</defs>
<use xlink:href="#a" />
<animate xlink:href="#a" attributeName="d" values="M0,20 H200 V70 H0z; M0,20 H200 V45 H0z" keyTimes="0;1" dur="1s" begin="0s" fill="freeze" />
</svg>
Is the only way to make this work is by repeating the path and animating them all or is there a way to make this work on Firefox?
As commented by #Robert Longson
I think you'd need to repeat the paths. At the moment SMIL changes to
the things that a element points to do not trigger the to
re-render.
Therefore, it is necessary to transfer the animation directly inside the <path> tags
<svg viewBox="0 0 300 100">
<defs>
<path id="a" d="M0,20 H200 V70 H0z" >
<animate
attributeName="d"
values="
M0,20 H200 V70 H0z;
M0,20 H200 V45 H0z"
keyTimes="0;1"
dur="1s"
begin="0s"
fill="freeze" />
</path>
</defs>
<use xlink:href="#a" />
</svg>
Start animation after click
<svg id ="svg1" viewBox="0 0 300 100">
<defs>
<path id="a" d="M0,20 H200 V70 H0z" >
<animate
attributeName="d"
values="
M0,20 H200 V70 H0z;
M0,20 H200 V45 H0z"
keyTimes="0;1"
dur="1s"
begin="svg1.click"
fill="freeze" />
</path>
</defs>
<use xlink:href="#a" />
</svg>

Easing animateMotion in SVG

I want to apply an easing to an animateMotion tag.
I'm confused about which attributes are relevant to animate a shape: if I understood well calcMode="spline" is required, along with the definition of keyTimes and keySplines; but what about the use of keySplines and values?
However, I tried to insert timings into my animation, but something went wrong:
<g style="transform-origin:50%;transform: rotate(180deg);">
<path id="verticalMotionPath" d="m 100,100 0, 50" stroke-width="5px" stroke="red" fill="none" stroke-linecap="round" stroke-linejoin="round" />
<circle cx="0" cy="0" r="5" fill="#333333">
<animateMotion dur="0.2s" repeatCount="once" fill="freeze" calcMode="spline" keyPoints="0.25;0.50;0.75;1" keyTimes="0;0.25;0.75;1">
<mpath xlink:href="#verticalMotionPath"/>
</animateMotion>
</circle>
</g>
My aim would be to apply to this example timings to draw from tools like this one
You are specifying calcMode="spline", but you haven't provided a keySplines attribute.
The value for keySplines can just be copied from your spline editing tool.
<circle cx="0" cy="0" r="5" fill="#333333">
<animateMotion dur="2.2s" repeatCount="once" fill="freeze"
calcMode="spline" keyTimes="0;1" keySplines="0.1 0.8 0.9 0.1">
<mpath xlink:href="#verticalMotionPath"/>
</animateMotion>
</circle>
Full demo (I've slowed down the animation so you can see it is working).
<!DOCTYPE HTML>
<html>
<body>
<?xml version="1.0"?>
<svg width="400" height="400" viewBox="0 0 200 200"
xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink" style="background:aquamarine">
<style>
path {
animation-name:animateDash;
animation-duration:5s;
animation-iteration-count:once;
animation-fill-mode:forwards;
}
#keyframes animateDash {
from{stroke-dasharray:0,2305}
to {stroke-dasharray:2305,0}
}
</style>
<g style="transform-origin:50%;transform: rotate(180deg);">
<path id="verticalMotionPath" d="m 100,100 0, 50" stroke-width="5px" stroke="red" fill="none" stroke-linecap="round" stroke-linejoin="round" />
<circle cx="0" cy="0" r="5" fill="#333333">
<animateMotion dur="2.2s" repeatCount="once" fill="freeze"
calcMode="spline" keyTimes="0;1" keySplines="0.1 0.8 0.9 0.1">
<mpath xlink:href="#verticalMotionPath"/>
</animateMotion>
</circle>
</g>
<g style="transform-origin:50%;transform: rotate(60deg);">
<path id="verticalMotionPath" d="m 100,100 0, 50" stroke-width="5px" stroke="white" fill="none" stroke-linecap="round" stroke-linejoin="round" />
<circle cx="0" cy="0" r="5" fill="#333333">
<animateMotion dur="0.2s" repeatCount="once" fill="freeze">
<mpath xlink:href="#verticalMotionPath"/>
</animateMotion>
</circle>
</g>
<g style="transform-origin:50%;transform: rotate(-60deg);">
<path id="verticalMotionPath" d="m 100,100 0, 50" stroke-width="5px" stroke="blue" fill="none" stroke-linecap="round" stroke-linejoin="round" />
<circle cx="0" cy="0" r="5" fill="#333333">
<animateMotion dur="0.2s" repeatCount="once" fill="freeze">
<mpath xlink:href="#verticalMotionPath"/>
</animateMotion>
</circle>
</g>
</svg>
</body>
</html>
This is how I would do it although I don't use animateMotion.
Since your path is made up of lines you can define the values for <animateTransform> like this:
Your path's d="M100, 100 L100, 47 146, 73"
the animation's values="100, 100; 100, 47;146, 73"
This is a working example:
<svg width="400" height="400" viewBox="0 0 200 200" style="background:aquamarine">
<path id="theMotionPath" d="M100, 100 L100, 47 146, 73" stroke-width="5px" stroke="antiquewhite" fill="none" stroke-linecap="round" stroke-linejoin="round" />
<circle r="5" >
<animateTransform
attributeType="XML"
attributeName="transform"
type="translate"
values="100,100; 100,47; 146,73"
keySplines= ".5 0 .5 1; 0 .75 .25 1";
calcMode="spline"
dur="4s"
repeatCount="indefinite" />
</circle>
</svg>
The keySplines length must be equal to the length of the values - 1. In this case values.length = 3 thus keySplines.length = 2, i.e: the movement from the first to the second value is defined by the first key spline; the movement from the second to the third value is defined by the second key spline. Every value of the keySplines is defining the 2 control points of a Bézier curve.

SVG - animate opacity

could you please help me out, how to create SVG animation, which will behave like this? https://framer.cloud/aSUDY/
I did my best, but it always misbehaves :-(
Here is my code, where I used 6 animations to cycle through (3 to animate from 0.5 to 1 opacity and three to animate vice versa)
<?xml version="1.0" encoding="UTF-8"?>
<svg width="100%" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="background: #000085;">
<defs>
<ellipse id="CON11" fill="#FFFFFF" fill-opacity="0.5" cx="0.583333333" cy="1.5" rx="1" ry="1" >
<animate
id="anim1"
attributeType="xml"
attributeName="fill-opacity"
begin="0s;anim33.end"
from="0.5"
to="1"
dur="1s"
fill="freeze"
/>
</ellipse>
<path id="CON22" fill="#FFFFFF" fill-opacity="0.5" d="M1.78441961,0.25 L0.75,1.24747605 C1.2672098,1.94570929 1.2672098,2.84343773 0.75,3.54167097 L1.78441961,4.53914702 C3.02572314,3.34217576 3.02572314,1.54671887 1.78441961,0.25 Z">
<animate
id="anim2"
attributeType="xml"
attributeName="fill-opacity"
begin="anim1.end"
from="0.5"
to="1"
dur="1s"
fill="freeze"
/>
</path>
<path id="CON33" fill="#FFFFFF" fill-opacity="1" d="M1.53441961,8.85936702e-16 L0.5,0.99747605 C2.36195529,2.79293294 2.36195529,5.58586588 0.5,7.48107038 L1.53441961,8.47854643 C4.12046863,6.18435151 4.12046863,2.39394252 1.53441961,0 L1.53441961,8.85936702e-16 Z">
<animate
id="anim3"
attributeType="xml"
attributeName="fill-opacity"
begin="anim2.end"
from="0.5"
to="1"
dur="1s"
fill="freeze"
/>
</path>
<ellipse id="CON11" fill="#FFFFFF" fill-opacity="1" cx="0.583333333" cy="1.5" rx="1" ry="1" >
<animate
id="anim11"
attributeType="xml"
attributeName="fill-opacity"
begin="anim3.end"
from="1"
to="0.5"
dur="0.1"
fill="freeze"
/>
</ellipse>
<path id="CON22" fill="#FFFFFF" fill-opacity="1" d="M1.78441961,0.25 L0.75,1.24747605 C1.2672098,1.94570929 1.2672098,2.84343773 0.75,3.54167097 L1.78441961,4.53914702 C3.02572314,3.34217576 3.02572314,1.54671887 1.78441961,0.25 Z">
<animate
id="anim22"
attributeType="xml"
attributeName="fill-opacity"
begin="anim11.end"
from="1"
to="0.5"
dur="0.1"
fill="freeze"
/>
</path>
<path id="CON33" fill="#FFFFFF" fill-opacity="0.5" d="M1.53441961,8.85936702e-16 L0.5,0.99747605 C2.36195529,2.79293294 2.36195529,5.58586588 0.5,7.48107038 L1.53441961,8.47854643 C4.12046863,6.18435151 4.12046863,2.39394252 1.53441961,0 L1.53441961,8.85936702e-16 Z">
<animate
id="anim33"
attributeType="xml"
attributeName="fill-opacity"
begin="anim22.end"
from="1"
to="0.5"
dur="0.1"
fill="freeze"
/>
</path>
</defs>
<g id="ACFT" transform="translate(2.000000, 2.000000)" fill="#FFFFFF" fill-opacity="0.5">
<path d="M19,14 L19,12 L11,7 L11,1.5 C11,0.67 10.33,0 9.5,0 C8.67,0 8,0.67 8,1.5 L8,7 L0,12 L0,14 L8,11.5 L8,17 L6,18.5 L6,20 L9.5,19 L13,20 L13,18.5 L11,17 L11,11.5 L19,14 Z" id="Shape"></path>
</g>
<g id="CON3" transform="translate(18.000000, 2.000000)" >
<use xlink:href="#CON33" ></use>
</g>
<g id="CON2" transform="translate(16.000000, 4.000000)" >
<use xlink:href="#CON22" ></use>
</g>
<g id="CON1" transform="translate(15.000000, 5.000000)" >
<use xlink:href="#CON11" ></use>
</g>
</svg>
I've changed the animations to use values, they don't really need to be linked.
I've removed the duplication and the elements that really were'nt doing anything other than add complexity.
<svg width="100%" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="background: #000085;">
<g id="ACFT" transform="translate(2.000000, 2.000000)" fill="#FFFFFF" fill-opacity="0.5">
<path d="M19,14 L19,12 L11,7 L11,1.5 C11,0.67 10.33,0 9.5,0 C8.67,0 8,0.67 8,1.5 L8,7 L0,12 L0,14 L8,11.5 L8,17 L6,18.5 L6,20 L9.5,19 L13,20 L13,18.5 L11,17 L11,11.5 L19,14 Z" id="Shape"></path>
</g>
<g id="CON3" transform="translate(18.000000, 2.000000)" >
<path id="CON33" fill="#FFFFFF" fill-opacity="1" d="M1.53441961,8.85936702e-16 L0.5,0.99747605 C2.36195529,2.79293294 2.36195529,5.58586588 0.5,7.48107038 L1.53441961,8.47854643 C4.12046863,6.18435151 4.12046863,2.39394252 1.53441961,0 L1.53441961,8.85936702e-16 Z">
<animate
id="anim3"
attributeType="xml"
attributeName="fill-opacity"
begin="0s"
values="0.5;0.5;0.5;0.5;1"
dur="2s"
repeatCount="indefinite"
/>
</path>
</g>
<g id="CON2" transform="translate(16.000000, 4.000000)" >
<path id="CON22" fill="#FFFFFF" fill-opacity="0.5" d="M1.78441961,0.25 L0.75,1.24747605 C1.2672098,1.94570929 1.2672098,2.84343773 0.75,3.54167097 L1.78441961,4.53914702 C3.02572314,3.34217576 3.02572314,1.54671887 1.78441961,0.25 Z">
<animate
id="anim2"
attributeType="xml"
attributeName="fill-opacity"
begin="0s"
values="0.5;0.5;0.5;1;1"
dur="2s"
repeatCount="indefinite"
/>
</path>
</g>
<g id="CON1" transform="translate(15.000000, 5.000000)" >
<ellipse id="CON11" fill="#FFFFFF" fill-opacity="0.5" cx="0.583333333" cy="1.5" rx="1" ry="1" >
<animate
id="anim1"
attributeType="xml"
attributeName="fill-opacity"
begin="0s"
values="0.5;0.5;1;1;1"
dur="2s"
repeatCount="indefinite"
/>
</ellipse>
</g>
</svg>

RMagick::Image.from_blob method don't work

I using Ruby, Sinatra and RMagick
I wont take browser icon (.svg file), add to icon text - version of browser - and return new .svg as respond to user
I wont open .svg as string, add some lines with my text and save this as new .svg file using RMagick.
but method to_blob and from_blob doesn't work correct
# myapp.rb
require 'sinatra'
require 'rmagick'
get '/test/:browser' do
img = Magick::Image::read("icons/default/#{params[:browser]}.svg")[0]
str = img.to_blob
"<textarea name='image' cols='100' rows='100'>#{str}</textarea>"
end
documentation from https://rmagick.github.io/image3.html#to_blob
img.to_blob [ { optional arguments } ]-> string
Description: Creates a Binary Large OBject, a direct-to-memory version
of the image.
chrome.svg:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="15.5 15.5 224.5 224.5">
<defs>
<radialGradient cy="0" cx="0.5" id="r">
<stop stop-color="#f06b59"/>
<stop offset="1" stop-color="#df2227"/>
</radialGradient>
<radialGradient r="0.76" cy="0.3" cx="0.65" id="g">
<stop offset="0.65" stop-color="#4cb749"/>
<stop offset="1" stop-color="#388b41"/>
</radialGradient>
<radialGradient r="0.8" cy="0.25" cx="0.36" id="y">
<stop offset="0.6" stop-color="#FCD209"/>
<stop offset="0.7" stop-color="#f7c616"/>
<stop offset="1" stop-color="#bc821e"/>
</radialGradient>
<radialGradient r="1" cy="0" cx="0.5" spreadMethod="pad" id="cf">
<stop offset="0.1" stop-color="#7FB3DF"/>
<stop offset="0.9" stop-color="#0F5B94"/>
</radialGradient>
<radialGradient id="cb" r="1" cy="0" cx="0.5">
<stop offset="0" stop-color="#F6F0EE"/>
<stop offset="1" stop-color="#ddd"/>
</radialGradient>
</defs>
<path d="m198,148a70,70 0 0 0 -140,0l20,0a50,50 0 0 1 100,0" fill-opacity="0.1"/>
<circle r="45" cx="127.5" cy="127.6" fill="url(#cf)" stroke="url(#cb)" stroke-width="9" />
<path d="m228,78a112,112 0 0 0 -193,-13l45,78a50,50 0 0 1 47,-65" fill="url(#r)"/>
<path d="m35,65a112,112 0 0 0 84,174l47,-80a50,50 0 0 1 -86,-16" fill="url(#g)"/>
<path d="m119,239a112,112 0 0 0 109,-161l-101,0a50,50 0 0 1 39,81" fill="url(#y)"/>
<path d="m35,65l45,78a50,50 0 0 1 2,-34l-45,-47" opacity="0.075"/>
<path d="m119,239l47,-80a50,50 0 0 1 -29,17l-20,63" opacity="0.05"/>
<path d="m228,78l-101,0a50,50 0 0 1 39,19l64,-16" opacity="0.05"/>
</svg>
But to_blob return this:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="225" height="225">
<circle cx="0" cy="0" r="1" fill="white"/>
<circle cx="1" cy="0" r="1" fill="white"/>
<circle cx="2" cy="0" r="1" fill="white"/>
==============================
about 50 000 such lines here
if this save to file, size of file will be about 3 MB
==============================
<circle cx="220" cy="224" r="1" fill="white"/>
<circle cx="221" cy="224" r="1" fill="white"/>
<circle cx="222" cy="224" r="1" fill="white"/>
<circle cx="223" cy="224" r="1" fill="white"/>
<circle cx="224" cy="224" r="1" fill="white"/>
</svg>
What I doing wrong?
Or, if you have another idea how to do this task - please, share.
get '/test/:browser' do
image = File.open('icons/default/chrome.svg')
blob = image.read
"<textarea name='image' cols='100' rows='100'>#{blob}</textarea>"
end
This is what i need.
First open file, then use read method.
In this case all work correct and .to_blob not needed

Resources