英文:
how to get an svg pattern to properly align to the slope of a line its applied to
问题
我想创建有图案的SVG线条,但找不到如何使定义的图案路径与应用为描边的线路路径一起倾斜的方法。
这里图案保持与x和y轴对齐,是否没有一个简单的参数可以使它沿着线路路径倾斜?
<svg width="400" height="400">
<defs>
<pattern id="pattern" x="0" y="0" width="16" height="20" patternUnits="userSpaceOnUse">
<path d="M 0 0 L 3 3 L 0 6 L 12 6 L 15 3 L 12 0" stroke="black" stroke-width="1"/>
</pattern>
</defs>
<line x1="0" y1="0" x2="200" y2="200" style="stroke:url(#pattern);stroke-width:20" />
</svg>
你可以在这个链接中查看更多详细信息:链接。
英文:
I want to make patterned svg lines but can't find how to make the defined pattern path slope along with the line path it's being applied as the stroke to.
the pattern stays aligned to the x and y axis here, is there not a simple argument to get it to be sloped along the line path right?
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
<svg width="400" height="400">
<defs>
<pattern id="pattern" x="0" y="0" width="16" height="20" patternUnits="userSpaceOnUse" >
<path d="M 0 0 L 3 3 L 0 6 L 12 6 L 15 3 L 12 0" stroke="black" stroke-width="1"/>
</pattern>
</defs>
<line x1="0" y1="0" x2="200" y2="200" style="stroke:url(#pattern);stroke-width:20" />
</svg>
<!-- end snippet -->
答案1
得分: 1
因为 <pattern> 元素的 "id" 与 <line> 元素的 "stroke="url(#id)"" 相关联,如果你想要多个具有相同图案的线条,就需要做一些额外的工作并为每条线创建一个图案。
<!-- 开始代码片段: 不隐藏 js 控制台: true 不启用 Babel -->
<!-- 语言: lang-html -->
<svg-pattern-line>
<defs>
<pattern width="20" height="15" patternUnits="userSpaceOnUse">
<path d="m0 0 3 3-3 3 12 0 3-3-3-3"></path>
</pattern>
</defs>
<style>
line { stroke-width:10 }
</style>
<line x1="0" y1="0" x2="200" y2="0" ></line>
<line x1="0" y1="0" x2="200" y2="120" fill="red" ></line>
<line x1="180" y1="10" x2="20" y2="160" fill="green"></line>
<line x1="180" y1="180" x2="20" y2="16" fill="blue" ></line>
</svg-pattern-line>
<script>
customElements.define('svg-pattern-line', class extends HTMLElement {
connectedCallback() {
setTimeout(() => { // 等待浏览器解析 innerHTML
this.innerHTML = `<svg width="400" viewBox="0 0 200 200">${this.innerHTML}</svg>`;
this.defs = this.querySelector("defs");
this.pattern = this.querySelector("pattern");
this.querySelectorAll("line").forEach(line=>{
let attr = (a) => line.getAttribute(a);
let angle = (180 / Math.PI) * Math.atan2(attr("y2") - attr("y1"), attr("x2") - attr("x1"));
let pattern = this.defs.appendChild(this.pattern.cloneNode(true));
pattern.id = "P" + Math.floor(Math.random() * 1e8);
pattern.setAttribute("patternTransform", `rotate(${angle})`);
pattern.setAttribute("fill" , attr("fill"));
pattern.setAttribute("stroke", attr("fill"));
line.setAttribute("stroke",`url(#${pattern.id})`);
})
})
}
});
</script>
<!-- 结束代码片段 -->
英文:
Because the <pattern> id
is tied to the <line> stroke="url(#id)"
, you need to do same extra work and create a pattern for every line if you want multiple lines with the same pattern
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
<svg-pattern-line>
<defs>
<pattern width="20" height="15" patternUnits="userSpaceOnUse">
<path d="m0 0 3 3-3 3 12 0 3-3-3-3"></path>
</pattern>
</defs>
<style>
line { stroke-width:10 }
</style>
<line x1="0" y1="0" x2="200" y2="0" ></line>
<line x1="0" y1="0" x2="200" y2="120" fill="red" ></line>
<line x1="180" y1="10" x2="20" y2="160" fill="green"></line>
<line x1="180" y1="180" x2="20" y2="16" fill="blue" ></line>
</svg-pattern-line>
<script>
customElements.define('svg-pattern-line', class extends HTMLElement {
connectedCallback() {
setTimeout(() => { // wait till innerHTML is parsed by Browser
this.innerHTML = `<svg width="400" viewBox="0 0 200 200">${this.innerHTML}</svg>`;
this.defs = this.querySelector("defs");
this.pattern = this.querySelector("pattern");
this.querySelectorAll("line").forEach(line=>{
let attr = (a) => line.getAttribute(a);
let angle = (180 / Math.PI) * Math.atan2(attr("y2") - attr("y1"), attr("x2") - attr("x1"));
let pattern = this.defs.appendChild(this.pattern.cloneNode(true));
pattern.id = "P" + Math.floor(Math.random() * 1e8);
pattern.setAttribute("patternTransform", `rotate(${angle})`);
pattern.setAttribute("fill" , attr("fill"));
pattern.setAttribute("stroke", attr("fill"));
line.setAttribute("stroke",`url(#${pattern.id})`);
})
})
}
});
</script>
<!-- end snippet -->
答案2
得分: 0
你可以使用 transform/rotate 旋转线条。然后图案也会跟着旋转。
英文:
You can rotate the line using transform/rotate. Then the pattern also rotates.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
<svg width="400" height="400" viewBox="0 0 200 200">
<defs>
<pattern id="pattern" x="0" y="0" width="16" height="6"
patternUnits="userSpaceOnUse" >
<path d="M 0 0 L 3 3 L 0 6 L 12 6 L 15 3 L 12 0 Z"
stroke="black" stroke-width="0"/>
</pattern>
</defs>
<line x1="0" y1="3" x2="200" y2="3" transform="rotate(45)"
stroke="url(#pattern)" stroke-width="6" />
</svg>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论