Overlapping happening instead of uploading image on mask - image-masking

Background
I am allowing user to upload an image inside mask image....
Mask image :
User uploaded image :
Requirement: What I need as below :
Issue : What I am getting now as below : The uploaded image is displaying [ overlay ] outside the mask image instead of inside as below.
JS Fiddle: http://jsfiddle.net/uLfeaxck/
Here is website url
html
<h3>Upload Photo</h3>
<label id="btn_upload_from_computer" for="fileupload_image" class="button -primary -size-md -full-width">
<svg class="icon-computer" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="23px" height="20.031px" viewBox="0 0 23 20.031" enable-background="new 0 0 23 20.031" xml:space="preserve">
<path id="computer" fill="#FFFFFF" d="M21.793,0H1.207C0.539,0.002-0.002,0.545,0,1.213v14.42c-0.001,0.667,0.539,1.209,1.207,1.211
h6.47v1.442c0,1-2.433,1-2.433,1v0.722l6.127,0.023h0.068l6.126-0.023v-0.722c0,0-2.434,0-2.434-1v-1.442h6.662
c0.668-0.002,1.208-0.543,1.207-1.211V1.213C23.002,0.545,22.461,0.002,21.793,0z M21.235,15.11H1.765V1.735h19.47v13.378V15.11z" />
</svg>
From your computer
</label>
<input type="file" id="fileupload_image" style="position: absolute; left: -2000px;" accept="image/*" />

I hope the example below is it what you need.
The image inside the mask will be stretched if it is smaller or bigger to the height of the mask.
Before the test of following snippet uploade this image to your computer and then choose it in snippet file dialogue.
function load(file)
{
var img = new Image(),
imgURL = URL.createObjectURL(file);
//this onload function we need to get width + height of image.
img.onload = function()
{
var width = img.naturalWidth,
height = img.naturalHeight,
maskedImage = document.getElementById('masked-image');
maskedImage.setAttribute('xlink:href', imgURL);
//you can also change this width + height of image before setting of following attribute
//For ex. the height of #mask1 is 395 and we stretch it for this height like:
maskedImage.setAttribute('height', 395);
//in this case DO NOT set width attribute!
//maskedImage.setAttribute('width', width);
//maskedImage.setAttribute('height', height);
//in this case you do not need this onload function.
URL.revokeObjectURL(imgURL);
};
img.src = imgURL;
}
<input type="file" onchange="load(this.files[0])"/><br>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="324" height="395">
<mask id="mask1">
<image xlink:href="https://i.stack.imgur.com/L5daY.png" width="324" height="395"></image>
</mask>
<image id="masked-image" xlink:href="" mask="url(#mask1)"></image>
</svg>

As I said on your other question, which was practically the same, what you want is called a "Clipping Mask"
Here's some magic. You're welcome!
codepen:https://codepen.io/anon/pen/zeZMLz

Your masked-element have
z-index:10
so you need to change below in you css
.slot_photo.overlay_design{
z-index:11
}

Image Masking, is the approach we use, whilst clipping route is not an option. When the situation that desires to be decided on has a lot detail, inclusive of fur or hair, clipping route will become very difficult to use. In those cases, a way referred to as [Image Masking][1] carrier is added into play. Clipping mask, Photoshop mask, photo protecting, channel protecting, alpha protecting, layer protecting and transparency protecting are a number of the versions or specialties of this photo masking carrier.

Related

svg handwriting effect ,Can I clip the stroke path to a png image instead of text?

first of all, Im new to this webpage and Im really sorry for any mistakes.
So, I needed to animate a png image of a Calligraphy text just like a handwriting effect.
Recently I've watched a youtube video https://www.youtube.com/watch?v=wab7lQKHXL4, its about making a handwriting animation with strokes clipped to texts.
So I was wondering, if I could clip the strokes to a png image and animate it just like the handwriting animation.
I tried to import the png image inside inkspace and drawn path on top of it, gave suitable stroke-width saved it as a svg file, and tried to animate it with stroke-dasharray, but its not working ,its not even showing up.
although I can do the same with written texts just like in the video.
So is there any way ,I can achieve the same goal using a png image.
thanks in advance, and sorry if I don't make any sense
The video you are linking is astonishing, if not crooked. The commentary points out it is done with a "custom" version of Inkscape, and I have to say there are some UI elements I have never seen. (Admittedly, I am on an older version from 2021, but the video is from 2017, when Inkscape oficially wasn't even on verson 1.0.) Maybe the specialists on https://graphicdesign.stackexchange.com/ can tell you more about this "custom" version?
The core action is selecting from the menu bar Object -> Set Clip. If this is the same as selecting Object -> Clip -> Set in my version (1.02), this cannot work. This action sets a clip-path. Clip paths only clip to their fill area and have no stroke properties.
What you have to do instead is
set the fill to none and the stroke color to white (#ffffff)
select a Object -> Mask -> Set
Also, even after watching for multiple times, I am not sure on which element the onload attribute is set. Setting it on the path element in the mask certainly won't work, there is no load event happening there.
The logical choice would be to wait for the image loading.
The result should be something like this:
document.querySelector('image#letter').addEventListener('load', function () {
setTimeout(() => document.querySelector('#stroke .dashed').style.strokeDashoffset = 0, 200)
})
.dashed {
fill: none;
stroke: white;
stroke-width: 8px;
stroke-dasharray: 100;
stroke-dashoffset: 100;
transition: stroke-dashoffset 1s linear;
}
image#letter {
mask: url(#stroke);
}
<svg viewBox="0 0 100 100" width="100" height="100">
<mask id="stroke" maskUnits="userSpaceOnUse">
<path class="dashed" d="M 61.739,30.223 C 61.739,30.223 55.369,26.515 51.839,25.606 48.819,24.825 45.469,24.022 42.489,24.964 40.379,25.63 38.329,27.161 37.349,29.137 35.899,32.044 35.099,36.236 36.989,38.878 36.989,38.878 46.459,41.753 50.839,42.679 54.399,43.431 57.729,48.053 56.429,52.972 55.599,56.117 51.469,57.478 48.379,58.502 45.569,59.433 42.389,59.495 39.509,58.837 36.089,58.056 30.199,53.913 30.199,53.913" />
</mask>
<image id="letter" width="100" height="100"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAA
GXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAwxJREFUeJzt2zuIHWUYBuAnm2hi
NAnBoCJE8FIERTQRBRErgyIGSysRL6CtYqOgTUhh4xJILAUNYqFdai0sRBSUxAvEJsRLlIAXMOom
XlaL/wjx7Jxkz+ycmdlz3gcGln+Z4Z39ds4/881/iIiIiIiIiIiIiIiIiIiIiIgY19quA9SwFlux
afDz2W7jNGtN1wEuYB0ewD24HTcphTjXIk7iOL7ER4Pti8HvogHr8QK+wz81t1N4Dfe1G3363IrP
1S/E8PZeu/FXZl3XAYbsxLvKHHE+v+APbMBlkw41q7YqHzNV/+XH8Lwyj2wc2u9i7MDDOIivreIr
pE8OWlqIP/GM8a7kNUrhXsFpKUgtm3DG0oI8ssLjbsGeFR5jJj1klU/GTZnrOsDAbRVjb7eeogf6
UpCrKsaOt56iB/pSkKpb175ka1VfTvqnirEbW0/RA30pyImKscdxUcs5YuBO1Q+Eb+LSDnPNrDmj
+1ff4DnlaTxatEdpl5+vUXgSb+Ap7JKPtIl70Xid3DN4Hy/hfqVtHw17FL+p12r/AQdwfduhp93V
SnNwQb3CnMXLSns+GrQZj+EwfjZ+YT5U3QXorb6/Uz/XHG7GHcqEvkt5oXWhif1j3K1cbTFhG3Ev
XsWvRl8p+7sKOMuuwCHVBVlQ5qXowD7VRXm6y1CzbA6fWlqQw12GWq6+NBebtIjXK8ZvaDtIHdNY
EDhSMbat9RQ1TGtBfq8Y+6v1FDVMa0Gq7qhOtZ6ihmktyO6KsRNth1jNHlRWtjfhWmWB3PBd1pMN
HX8mzONvvKW0Q+q6UpnQq9r0q6qn1bV5//8DHsWzuGaZ+2/AE0Z/fWFfw3knpi/NxXllDW+Vb/EB
PsOPyjuPRWX56XbcoswZm0fsfwR3qb7zihGGr5Cmtk9weYvnMTV24x3lWaGJQixgLy5p8ySm0Tbl
hdQhfGX8QhxT3ssvd+7pnb7MIaNsV1Yw7sB1yjzx35c+Tw+275X55aiyZCgiIiIiIiIiIiIiIiIi
IiIiIiIiIiIiIiIiIiIiIiIm51/fJjIk1BlBegAAAABJRU5ErkJggg==
"
</svg>
Once you have a d-path, you can offload the work to a Native Web Component <draw-path>
disclaimer: The last drawn path is from Jake Archibald his 2013 blog: Animated Line Drawing SVG
window.customElements.define("draw-path", class extends HTMLElement {
constructor() {
let template = (id) => document.getElementById(id).content.cloneNode(true);
super() // super sets and returns this scope
.attachShadow({mode: "open"}) // sets and returns this.shadowRoot
.append(template(this.nodeName));
this.line = this.shadowRoot.querySelector("#line");
this.line.setAttribute("d", this.getAttribute("d") || "m10 60c30-70 55-70 75 0s55 70 85 0");
this.line.setAttribute("stroke", this.getAttribute("stroke") || "black");
this.line.setAttribute("stroke-width", this.getAttribute("stroke-width") || "2");
this.pen = this.shadowRoot.querySelector("#pen");
this.onmouseover = (evt) => this.draw();
}
connectedCallback() {
this.shadowRoot.querySelector("svg").setAttribute("viewBox",this.getAttribute("viewBox")||"0 0 180 150");
this.draw();
}
showpen(state = true, scale) {
this.pen.style.display = state ? 'initial' : 'none';
}
draw() {
clearInterval(this.drawing);
this.showpen();
this.dashoffset = 1;
this.pathlength = this.line.getTotalLength();
this.drawing = setInterval(() => this.update(), 50);
}
update() {
this.dashoffset -= this.getAttribute("speed") || 0.02;
let {x,y} = this.line.getPointAtLength(this.pathlength - this.dashoffset * this.pathlength);
this.pen.setAttribute("transform", `translate(${x-2} ${y-2})`);
this.line.style.strokeDashoffset = this.dashoffset;
if (this.dashoffset <= 0) this.end();
}
end() {
clearInterval(this.drawing);
this.showpen(false);
//console.log("end",this.line);
clearTimeout(this.timeout);
this.timeout = setTimeout(()=>this.draw(),2000);
}
});
<draw-path viewBox="20 20 60 60" d='M 61.739,30.223 C 61.739,30.223 55.369,26.515 51.839,25.606 48.819,24.825 45.469,24.022 42.489,24.964 40.379,25.63 38.329,27.161 37.349,29.137 35.899,32.044 35.099,36.236 36.989,38.878 36.989,38.878 46.459,41.753 50.839,42.679 54.399,43.431 57.729,48.053 56.429,52.972 55.599,56.117 51.469,57.478 48.379,58.502 45.569,59.433 42.389,59.495 39.509,58.837 36.089,58.056 30.199,53.913 30.199,53.913'></draw-path>
<draw-path stroke='red' stroke-width='8' speed=".01"></draw-path>
<draw-path stroke="deeppink" viewBox="0 0 400 370" d="M11.6 269s-19.7-42.4 6.06-68.2 48.5-6.06 59.1 12.1l-3.03 28.8 209-227s45.5-21.2 60.6 1.52c15.2 22.7-3.03 47-3.03 47l-225 229s33.1-12 48.5 7.58c50 63.6-50 97-62.1 37.9"></draw-path>
<template id="DRAW-PATH">
<style>
:host { display: inline-block }
svg { width: 180px; height: 130px; background: beige }
</style>
<svg xmlns="http://www.w3.org/2000/svg">
<path id='line' pathlength='1' stroke-dasharray='1' stroke-dashoffse='1' fill='transparent'/>
<path id='pen' stroke='black' stroke-width='2' fill='gold' d='m12 19l7-7l3 3l-7 7l-3-3zm6-6l-2-8l-14-3l4 15l7 1l5-5zm-16-11l8 8m-1 1a2 2 0 104 0a2 2 0 10-4 0'/>
</svg>
</template>
Note:
Be aware M or m (moves) in paths create a new stroke, drawn at the same time, not sequentially.
So stroke-dash* settings are applied concurrent.
That is why in all blogs you only see single stroke simple paths or polylines used.

Path not fitting inside SVG

I am working with SVG from some time now. But still I can't understand the viewbox after watching many videos and reading many articles.
I am trying to generate SVG dynamically:
import SvgIcon from '#material-ui/core/SvgIcon';
<SvgIcon className="svg" width="24" height="24" viewBox="0 0 24 24">
<g>
<path
d={scrapbookElement.icon.path}
/>
</g>
</SvgIcon>
Here is my JSON file which provides me scrapbookElements:
[
{
"id": "image",
"text": "Image",
"icon": {
"path": "M9.5999776,12.699997L11.899997,15.099998 13.299991,14.300003 19.000005,20 22.899999,18 28.299995,20.699997 28.299995,25.699997 3.5999767,25.699997 3.5999767,18.599998z M20.500005,11.699997L21.199987,11.699997 21.000005,12.800003 20.699987,12.800003z M23.09998,10.699997L23.799993,11.599998 23.59998,11.800003 22.699987,11.099998z M18.699987,10.699997L19.199987,11.199997 18.299993,11.900002 18.000005,11.599998z M23.59998,8.5999985L24.699987,8.8000031 24.699987,9 23.59998,9.1999969z M18.09998,8.5999985L18.09998,9.3000031 17.000005,9 17.000005,8.8000031z M20.799993,7C21.899999,7 22.699987,7.9000015 22.699987,8.9000015 22.699987,10 21.799993,10.800003 20.799993,10.800003 19.699987,10.800003 18.899999,9.9000015 18.899999,8.9000015 18.899999,7.8000031 19.799993,7 20.799993,7z M23.500005,6.0999985L23.699987,6.3000031 23.000005,7.1999969 22.500005,6.6999969z M18.199987,6.0999985L19.09998,6.8000031 18.59998,7.3000031 18.000005,6.3000031z M20.699987,5L21.000005,5 21.199987,6.0999985 20.500005,6.0999985z M2.1999823,2.4000015L2.1999823,26.800003 29.400001,26.800003 29.400001,2.4000015z M0,0L31.900001,0 31.900001,32 0,32z"
}
},
{
"id": "text",
"text": "Text",
"icon": {
"path": "M29.15,0L30.186011,0.012001038 30.610999,0.43099976 31.096015,3.868 31.209998,7.8079987 31.101996,8.3949966 30.610999,8.6230011 29.875007,8.5510025 29.437018,7.9520035 28.312018,5.298996 26.993995,3.7130013 25.82801,3.072998 24.294013,2.6170006 22.390996,2.3429985 20.12,2.2509995 18.580998,2.3590012 17.940007,2.6829987 17.868993,3.0900002 17.868993,26.970001 18.048009,28.272003 18.58701,29.113998 19.659001,29.697998 21.437016,30.227997 22.149999,30.389 22.467015,30.490997 22.707005,31.401001 22.179997,32 21.910008,31.994003 21.198003,31.928001 15.424992,31.640999 10.755008,31.879997 9.4850186,31.879997 9.1740131,31.305 9.2879972,30.665001 10.011996,30.275002 11.737002,29.695 12.791018,29.005997 13.401005,27.909996 13.605015,26.298996 13.605015,3.0900002 13.390018,2.5390015 12.743014,2.2750015 12.342013,2.2579994 11.329989,2.2509995 7.3779925,2.6469994 4.6229872,3.8320007 3.0840158,5.4970016 1.7250066,8.1439972 1.2399907,8.7959976 0.598999,8.7900009 0.041992187,8.4729996 0,7.9039993 0.62899778,4.7839966 0.83898971,0.59899902 1.2040105,0.20999908 2.2999882,0.14400101 7.7489947,0.39500046 13.748997,0.47900009 19.16602,0.44900131 23.539008,0.35900116 26.867011,0.20999908z"
}
}
]
Here is the output:
I can handle that with overflow: visible in css. But I dont want to do it because then i will get problems with height and width, which will lead me to incorrect centering using flexbox.
Here is codesandbox that reproduces the issue:
Click here for code sandbox
Basically if you want to fit SVG into a container you need to set the viewBox attribute to exact values of its content. In this case, from the points in the d attributes you can see that it's 0 0 32 32 (as in: x, y, width, height).
Then you can resize the SVG using the width and height attributes to stretch/shrink to the container you want it to fit into (taking into account aspect ratio, of course).
If you don't know the right value of viewBox for a given SVG, and you don't have strokes - like the examples above, you can try using dev tools in the browser and call .getBBox() on the <svg> element, which will give you the x, y, width, and height to place in the viewBox.
In order to get the size of a path I've transformed yours icons in true svg
console.log(test.getBBox());
console.log(test1.getBBox())
<svg className="svg" width="24" height="24" viewBox="0 0 32 32" >
<g>
<path id="test"
d="M9.5999776,12.699997L11.899997,15.099998 13.299991,14.300003 19.000005,20 22.899999,18 28.299995,20.699997 28.299995,25.699997 3.5999767,25.699997 3.5999767,18.599998z M20.500005,11.699997L21.199987,11.699997 21.000005,12.800003 20.699987,12.800003z M23.09998,10.699997L23.799993,11.599998 23.59998,11.800003 22.699987,11.099998z M18.699987,10.699997L19.199987,11.199997 18.299993,11.900002 18.000005,11.599998z M23.59998,8.5999985L24.699987,8.8000031 24.699987,9 23.59998,9.1999969z M18.09998,8.5999985L18.09998,9.3000031 17.000005,9 17.000005,8.8000031z M20.799993,7C21.899999,7 22.699987,7.9000015 22.699987,8.9000015 22.699987,10 21.799993,10.800003 20.799993,10.800003 19.699987,10.800003 18.899999,9.9000015 18.899999,8.9000015 18.899999,7.8000031 19.799993,7 20.799993,7z M23.500005,6.0999985L23.699987,6.3000031 23.000005,7.1999969 22.500005,6.6999969z M18.199987,6.0999985L19.09998,6.8000031 18.59998,7.3000031 18.000005,6.3000031z M20.699987,5L21.000005,5 21.199987,6.0999985 20.500005,6.0999985z M2.1999823,2.4000015L2.1999823,26.800003 29.400001,26.800003 29.400001,2.4000015z M0,0L31.900001,0 31.900001,32 0,32z"
/>
</g>
</svg>
<hr>
<svg className="svg" width="24" height="24" viewBox="0 0 32 32" >
<g>
<path id="test1"
d="M29.15,0L30.186011,0.012001038 30.610999,0.43099976 31.096015,3.868 31.209998,7.8079987 31.101996,8.3949966 30.610999,8.6230011 29.875007,8.5510025 29.437018,7.9520035 28.312018,5.298996 26.993995,3.7130013 25.82801,3.072998 24.294013,2.6170006 22.390996,2.3429985 20.12,2.2509995 18.580998,2.3590012 17.940007,2.6829987 17.868993,3.0900002 17.868993,26.970001 18.048009,28.272003 18.58701,29.113998 19.659001,29.697998 21.437016,30.227997 22.149999,30.389 22.467015,30.490997 22.707005,31.401001 22.179997,32 21.910008,31.994003 21.198003,31.928001 15.424992,31.640999 10.755008,31.879997 9.4850186,31.879997 9.1740131,31.305 9.2879972,30.665001 10.011996,30.275002 11.737002,29.695 12.791018,29.005997 13.401005,27.909996 13.605015,26.298996 13.605015,3.0900002 13.390018,2.5390015 12.743014,2.2750015 12.342013,2.2579994 11.329989,2.2509995 7.3779925,2.6469994 4.6229872,3.8320007 3.0840158,5.4970016 1.7250066,8.1439972 1.2399907,8.7959976 0.598999,8.7900009 0.041992187,8.4729996 0,7.9039993 0.62899778,4.7839966 0.83898971,0.59899902 1.2040105,0.20999908 2.2999882,0.14400101 7.7489947,0.39500046 13.748997,0.47900009 19.16602,0.44900131 23.539008,0.35900116 26.867011,0.20999908z"
/>
</g>
</svg>
Then I've used the method .getBBox() to get the size of the bounding boxes for the two icons. In both cases the width and the height for the bounding box is almost 32 and the and the x and y is 0. I've changed the viewBox to x y w h i.e 0 0 32 32. This will scale down the image inside the svg, while the width and the height of the svg element stays at 24/24

Complex SVG clip-path responsive

I'm trying to take a complex path shape and apply it as a clip-path mask in css, but I can't figure out how to get the clip mask to "fill" the parent container.
Rather it just gets cut off or doesn't expand to fill the available space.
If I add clipPathUnits="objectBoundingBox" it doesn't appear at all.
<svg viewBox="0 0 720 720">
<defs>
<clipPath id="map">
<path d="M568.421 326.842L511.579 270v37.895h-18.947v-18.948h-56.843v37.895l18.948 37.894v18.948h-18.948l37.896 56.842h-37.896l-18.947-18.948v-18.947h-37.895L360 383.684h-18.947l-18.948-37.894v-37.895L360 270l37.895-37.895-18.948-37.895H360v18.948l-18.947-18.948h-18.948v37.895h-37.894l-56.843-18.947-37.894-56.842h-56.842l-18.947-18.948-75.79 75.79v37.895h18.947v75.789L37.895 345.79l5.532 48.163 32.362 46.573 113.685 37.895 94.737 18.947h94.736v-18.947h37.895l18.947 37.895h18.948v56.842l56.842-37.894v-37.896h37.895l18.947-37.894v-37.896l56.842-37.894V345.79l-18.948-18.948z"/><path d="M246.315 194.21h56.843v-18.947l-18.947-37.895h-18.948v37.895h-18.948zM227.368 137.368h18.947v-18.947h-37.894V156.316h18.947zM341.053 175.263h56.842l37.894 37.895-18.947 18.947V270h75.79v-18.947h-37.895v-18.948h37.895V194.21h-37.895l-56.842-56.842h-56.842zM265.263 99.474h18.948v18.947h-18.948zM284.211 61.579h18.947v18.948h-18.947zM303.158 108.947h18.947v18.947h-18.947zM341.053 99.474h37.895v18.947h-37.895zM227.368 80.526h18.947v18.947h-18.947zM378.947 80.526V4.737H360l-37.895 37.894v18.948l18.948 18.947zM587.368 440.526h37.895v37.895h-37.895zM663.158 364.736V345.79h-18.947V402.631l56.842-18.947v-18.948zM378.947 270h18.947v18.947h-18.947zM644.211 421.578h18.947v18.948h-18.947zM644.211 459.474h18.947v18.947h-18.947z"/>
</clipPath>
</defs>
</svg>
https://codepen.io/picard102/pen/aEwJzR
As Robert said, when you specify clipPathUnits="objectBoundingBox", the coordinates in the clip path definition are supposed to be between 0,0 (the top left) and 1,1 (the bottom right).
Your paths are about 700x575, so your path is about 600 to 700 times too big.
The simplest solution is to add a transform attribute to your <clipPath> that scales the coordinates down to the correct range.
<clipPath id="map" clipPathUnits="objectBoundingBox" transform="scale(0.00143, 0.00174)">
1/700 ~= 0.00143
1/575 ~= 0.00174
https://codepen.io/anon/pen/GyvZOM

Parent SVG defaults to 150x300 when linking to fragments - how to fix?

I'm using an external SVG image, and linking to a fragment within it. This is so that:
My markup is clean
I can modify the SVG with CSS
I only need a single SVG document, acting as a sort of spritesheet.
HTML:
<style>
.icon-1{ fill: red;width: auto;height: auto;display: inline-block;}
</style>
<svg class="icon icon-1" preserveAspectRatio="xMinYMax meet">
<use xlink:href="svg.svg#icon-icon-map-pin"></use>
</svg>
SVG:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
<defs>
<symbol id="icon-icon-map-pin" viewBox="0 0 1167 1024">
<title>icon-map-pin</title>
<path class="path1" d="M476.444 684.8l27.022 67.556c-26.311 10.667-52.622 18.489-77.511 23.467l-14.933-71.111c20.622-4.267 42.667-11.378 65.422-19.911zM259.556 772.267c27.022 7.822 54.756 12.089 83.911 12.089l1.422-73.244c-22.044-0.711-44.089-3.556-64.711-9.244l-20.622 70.4zM833.422 644.978c21.333 4.267 41.244 11.378 61.156 21.333l33.422-64.711c-25.6-13.511-52.622-22.756-80.356-27.733l-14.222 71.111zM681.244 584.533l22.044 69.689c22.044-7.111 44.089-11.378 65.422-12.8l-5.689-72.533c-27.022 2.133-54.044 7.111-81.778 15.644zM564.622 640c-8.533 4.978-16.356 9.956-24.178 14.222l35.556 64c9.244-4.978 17.778-9.956 27.022-15.644 12.8-7.822 24.889-14.933 36.978-20.622l-33.422-64.711c-13.511 5.689-27.733 13.511-41.956 22.756zM765.867 184.889c0 29.867-7.111 58.311-19.911 82.489l-162.133 319.289c0 0-163.556-320.711-164.267-322.133-11.378-23.467-17.778-50.489-17.778-78.933 0-100.978 81.778-182.044 182.044-182.044s182.044 81.067 182.044 181.333zM692.622 184.889c0-60.444-49.067-109.511-109.511-109.511s-108.8 49.067-108.8 109.511 49.067 109.511 109.511 109.511 108.8-49.067 108.8-109.511zM947.911 367.644h-171.378l-36.978 72.533h156.444l78.222 236.8-24.889 27.733c27.022 24.178 40.533 46.222 40.533 46.933l7.822-4.978 68.267 204.8h-964.978l73.244-219.022c2.844 2.133 4.267 3.556 7.111 4.978l39.111-61.867c-8.533-5.689-15.644-10.667-22.044-15.644l73.244-219.022h155.733c-15.644-29.867-27.733-54.044-36.978-73.244h-171.378l-219.022 656.356h1166.933l-219.022-656.356z"></path>
</symbol>
</defs>
</svg>
If I manually set the width or height to a pixel value, and the opposite to auto, it will still grab the default. For instance, height:25px; width: auto; would give me a 25x300 image.
This was originally inspired by http://css-tricks.com/svg-use-external-source/, but the width/height was fixed.
Even if I wrap it in a position:relative' div, and make the svg element absolute with `top:0;right:0;bottom:0;left:0;', it still ignores it.
I'm stumped - it seems like it's ignoring my rules entirely.
See http://jsfiddle.net/5rcsyk36/
I think you want width and height to be 100%, not auto.
A width of auto will use the svg element's intrinsic width and it doesn't have an intrinsic width as it doesn't have a viewBox. So you get the default which is 300. Similarly for height except that the default for height is 150.

How to show an image inside shapes like back of an phone case(with transparent hole for camera) in the webpage?

I am working on a project in which I am developing a web application where artist can upload there artwork which will be printed on various smartphone phone cases(A small version of websites like RedBubble.com or Society6.com).
So as one of its module, what I want to achieve is:
Admin can upload the phone case shapes(just the back of the case
with transparent camera hole) from admin panel.
Artist can upload the artwork and which will be displayed on all
available phone cases as final product to the customer.
I have searched a lot about this and came out with the following idea but now I am totally lost:
Admin can create shapes using software like InkScape which will give them SVG files and its code.
These files can be stored in the database(content of the file or the file name, I was unable to figure out).
Artist will upload his/her artwork and will be stored in the database as jpg file.
So now, I have both, the shape(SVG) and the artwork(JPG) stored in the database.
I just cannot figure out how to display the final product which will be the selected artwork on the selected phone case shaped SVG. Or am I going totally wrong?
This is what I what to achieve:
http://postimg.org/image/vp267jvp5/
But as you can see that I totally messed it up. Here is the code for the file. SVG was generated from InkScape. I used pattern tags to fit in the image.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<html>
<body>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="212"
height="360"
id="svg2"
version="1.1"
inkscape:version="0.48.5 r10040"
sodipodi:docname="shit.svg">
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="76"
inkscape:cy="265.01282"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1366"
inkscape:window-height="691"
inkscape:window-x="-9"
inkscape:window-y="-9"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
style="display:inline"
transform="translate(-299,-397.375)">
<path
d="m 343,397.375 c -24.376,0 -44,19.624 -44,44 l 0,272 c 0,24.376 19.624,44 44,44 l 124,0 c 24.376,0 44,-19.624 44,-44 l 0,-272 c 0,-24.376 -19.624,-44 -44,-44 l -124,0 z m 18.5,34 c 12.42641,0 22.5,6.71573 22.5,15 0,8.28427 -10.07359,15 -22.5,15 -12.42641,0 -22.5,-6.71573 -22.5,-15 0,-8.28427 10.07359,-15 22.5,-15 z"
fill="url(#img1)"
id="rect2985"
inkscape:connector-curvature="0" />
</g>
<defs>
<filter id="blur">
<feGaussianBlur stdDeviation="0"/>
</filter>
<pattern id="img1" x="0" y="0" patternUnits="userSpaceOnUse" width="212" height="360" >
<image xlink:href="uploads/artwork.jpg" x="0" y="0" width="212" height="360" />
</pattern>
</defs>
</svg>
<img src="uploads/artwork.jpg" >
</body>
</html>
I would appreciate if you can provide me some steps or examples or tutorial links or should I use some library because I searched and the above is all I got. I am using php and mysql database server.
You can achieve what you want by manipulating the SVG by:
Turn the cover shape into a clip path
dynamically load the user's image into the SVG and apply the clip path to it
I've made a demo fiddle here.
Here's the code:
initCover("svg2", "layer1");
replaceCover("svg2", "layer1", "http://lorempixel.com/400/400/");
function initCover(svgId, coverId)
{
// Turn cover into a clipping path
var svg = document.getElementById(svgId);
var cover = svg.getElementById(coverId);
var clipPath = document.createElementNS("http://www.w3.org/2000/svg", "clipPath");
clipPath.setAttribute("id", "cover-clip");
if (cover.getAttribute("transform"))
clipPath.setAttribute("transform", cover.getAttribute("transform"));
// Copy shape from cover to clipPath (assumes cover has only one child element
clipPath.appendChild(cover.firstElementChild.cloneNode());
svg.appendChild(clipPath);
// Optionally hide the original cover shape
cover.style.visibility = "hidden";
}
function replaceCover(svgId, coverId, imageURL)
{
var svg = document.getElementById(svgId);
var cover = svg.getElementById(coverId);
// Get the cover width and height
var coverBox = cover.getBBox();
// Add a new image element for the image
var image = document.createElementNS("http://www.w3.org/2000/svg", "image");
image.setAttributeNS("http://www.w3.org/1999/xlink", "href", imageURL);
// Set image size so that the image fills the cover and is centred
image.setAttribute("width", coverBox.width);
image.setAttribute("height", coverBox.height);
image.setAttribute("preserveAspectRatio", "xMidYMid slice");
image.setAttribute("clip-path", "url(#cover-clip)");
svg.appendChild(image);
}
You can use html5 canvas's compositing ability to draw only into your phone-case
In particular, context.globalCompositeOperation='source-in' will display your artwork only in the non-transparent pixels of your phone case.
Start with this image of your phone case where everything is transparent except the phone case:
Then you can use compositing to draw your artwork only over the black case pixels like this:
// draw the phone case on the canvas
context.drawImage(phonecase,0,0);
// set compositing to source-in
// future drawings will only be visible where existing pixels are opaque
context.globalCompositeOperation='source-in';
// draw the artwork over the phonecase
// compositing will display the artwork only inside the opaque phonecase pixels
context.drawImage(artCanvas,offsetX,offsetY);
// always clean up! Return compositing to its default mode
context.globalCompositeOperation='source-out';
Here's example code and a Demo:
This example adds the ability to resize the artwork and reposition it horizontally and vertically.
Good luck with your project!
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var artCanvas=document.createElement("canvas");
var artCtx=artCanvas.getContext("2d");
var cw,ch,phone,art;
$scaleslider=$('#scaleslider');
$scaleslider.change(function(){ resetScale(); draw(); })
//
$hslider=$('#hslider');
$hslider.change(function(){ draw(); })
//
$vslider=$('#vslider');
$vslider.change(function(){ draw(); });
// image preloader
var imageURLs=[];
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/multple/case.png");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/multple/art.png");
// the loaded images will be placed in imgs[]
var imgs=[];
var imagesOK=0;
loadAllImages(start);
function loadAllImages(callback){
for (var i=0; i<imageURLs.length; i++) {
var img = new Image();
imgs.push(img);
img.onload = function(){
imagesOK++;
if (imagesOK>=imageURLs.length ) {
callback();
}
};
img.onerror=function(){alert("image load failed");}
img.crossOrigin="anonymous";
img.src = imageURLs[i];
}
}
//
function start(){
// the imgs[] array now holds fully loaded images
// user friendly names for images
phone=imgs[0];
art=imgs[1];
// size the on-screen canvas to phone size
cw=canvas.width=phone.width;
ch=canvas.height=phone.height;
// resetScale
resetScale();
// draw the initial rendering
draw();
}
function resetScale(){
var scale=$scaleslider.val()/100;
// calc the scaled size of the artwork
var artW=art.width*scale;
var artH=art.height*scale;
// size the off-screen canvas to allow 2x2 of art images
artCanvas.width=artW*2;
artCanvas.height=artH*2;
// draw a grid of 2x2 art images to allow horizontal
// and vertical repositioning
artCtx.drawImage(art,0,0,artW,artH);
artCtx.drawImage(art,artW,0,artW,artH);
artCtx.drawImage(art,artW,artH,artW,artH);
artCtx.drawImage(art,0,artH,artW,artH);
// set offsets used in horiz & vert repositioning
$hslider.attr('max',artW);
$hslider.val(0);
$vslider.attr('max',artH);
$vslider.val(0);
}
// draw the artwork inside the phone case
// Use the slider values to reposition the artwork
function draw(){
var offsetX=-$hslider.val();
var offsetY=-$vslider.val();
ctx.clearRect(0,0,cw,ch);
ctx.save();
ctx.drawImage(phone,0,0);
ctx.globalCompositeOperation='source-in';
ctx.drawImage(artCanvas,offsetX,offsetY);
ctx.restore();
}
body{ background-color: ivory; }
canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
Scale Artwork<input id=scaleslider type=range min=25 max=150 value=100><br>
Move Horizontally:<input id=hslider type=range min=0 max=200 value=100><br>
Move Vertically:<input id=vslider type=range min=0 max=200 value=100><br>
<canvas id="canvas" width=300 height=300></canvas>

Resources