简体   繁体   中英

Rotating stripes in SVG background image

The javascript code below is supposed to generate a background image based on the user input. User should be able to change the angle of the stripes and other things like depth, colors...

The issue is that I can't get the pattern to repeat seamlessly when the angle is changed. I think it's because the pattern always starts at the same point. Is there some way to control that?

 var atts = { size: [30, 30], depth: 50, rotDegrees: 45 }; function refresh() { var code = $('#tpl').html().replace(/{\\:([^{}]+)}/g, function(match, key) { return atts[key] || match; }); code = '<svg xmlns="http://www.w3.org/2000/svg" width="' + atts.size[0] + '" height="' + atts.size[1] + '">' + code + '</svg>'; $('#preview').css('background-image', 'url("data:image/svg+xml;base64,' + window.btoa(code) + '")'); }; refresh(); $('input').on('input', function(e) { atts[this.name] = this.value; refresh(); }); 
 #preview { width: 600px; height: 600px; display: block; background: transparent none repeat center center; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <input name="rotDegrees" type="range" min="0" max="360" step="1" value="0" /> <input name="depth" type="range" min="1" max="100" step="1" value="60" /> <div id="preview"></div> <script id="tpl" type="text/template"> <defs> <pattern id="stripe-pattern" width="100%" height="100%" patternUnits="userSpaceOnUse" patternTransform="rotate({:rotDegrees})"> <rect width="{:depth}%" height="100%" transform="translate(0,0)" fill="#fff" /> </pattern> <mask id="stripe-mask"> <rect x="0" y="0" width="100%" height="100%" fill="url(#stripe-pattern)" /> </mask> </defs> <rect mask="url(#stripe-mask)" x="0" y="0" width="100%" height="100%" /> </script> 

If you want the stripes to be a fixed distance apart - for example 30px as it appears here, then you won't be able to keep to a fixed size pattern "box". It will need to vary in width so that the stripe has room to wrap around and meet up with itself at the 30px mark.

For an angle of 10 deg, and a stripe spacing of 30, the box will need to have dimensions of:

 width = 30 / tan(10)
       = 170px

For 1 deg it would need to be 1718.7px.

On the other hand, if you want to keep a fixed width pattern (eg. 30px) then you will need to have more than one stripe <rect> in order to complete the extra crossings of the pattern square to finish one cycle of the stripe.

For the 10 degree example, we have already determined the "cycle length" (period) of the cycle" to be 170px, so you are going to need six rectangles.

170/30 = 5.666

But of course, if you use this approach, for some angles and stripe widths you will lose the stripe effect because you'll end up with a solid block of stripe colour in your pattern.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM