RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1254103
Accepted
Floyat
Floyat
Asked:2022-03-10 22:47:17 +0000 UTC2022-03-10 22:47:17 +0000 UTC 2022-03-10 22:47:17 +0000 UTC

仅相对于中心线笔划向内更改 svg 三角形的笔划粗细

  • 772

有一个任意坐标的等边三角形。

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400">
<polygon fill="none" stroke-width="4" stroke="red" points="200 35.45517328095667,10 364.54482671904333,390 364.54482671904333"></polygon>
</svg>

https://jsfiddle.net/6sybjthL/1/

由于 svg 的特殊性,当改变描边的粗细(stroke-width)时,它同时向内和向外扩展。据我所知,svg 1.1 版没有任何属性可以改变这一点,只有几何和数学会有所帮助。

因此有2个问题:

  1. 将笔画粗细改为任意值时,应该使用什么公式重新计算三角形的坐标,以使三角形保持等边,并且在视觉上不会向外扩展(即填充三角形的背景)?

  2. 如何计算由于只有内部这样的笔划而完全填充三角形的最大笔划大小?

UPD

下面是我尝试为新的 stroke-width=40 值重新计算坐标的示例。(目标是确保绿色三角形不超过红色三角形)

https://jsfiddle.net/xqv3ms8b/9/

вёрстка
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    Alexandr_TT
    2022-03-11T17:20:07Z2022-03-11T17:20:07Z

    SVG + 蒙版解决方案

    这个想法是这样的:

    要在放大时切断字符串的外半部分并且不干扰字符串内半部分的生长stroke-width,请使用蒙版 SVG

    形状(任意)被添加到样式被分配给这个形状部分中defs
    的蒙版,这将制作一个蒙版,最初将显示具有恒定线宽的原始形状的模板。字符串外半部的多余部分在放大时 会被遮罩的第二个元素截断, 内半部将不受限制地增长。pathfill="white"stroke="white"stroke-width<rect>

    面具

    <defs>
    <mask id="msk">
    <rect width="100%" height="100%" fill="black" />
    <polygon  fill="white" stroke-width="8" stroke="black" points="200 35.5 10 364.5 390 364.5"></polygon>
    </mask> 
    </defs> 
    

    第二个图,将使用stroke-width与图中完全相同的路径进行修改,mask 放置在图主体的下方,并对其应用蒙版mask="url(#msk)" 。stroke-width

    • 在程序下面,添加了一个属性不变的圆圈,用来描述原始图形,从而显示放大后图形的整体尺寸保持不变。stroke-width
    • 添加的 JS 仅用于演示蒙版如何在修剪外部时起作用stroke-width

    function changeStroke() {
    var sw = document.getElementById("poly"); 
       itr.addEventListener("input",()=>{sw.setAttribute("stroke-width",itr.value)});
        var x = document.getElementById("itr").value;
        
        document.getElementById("infoSW").innerHTML = "stroke-width: " + x +"px";
    }
    <div>
     <input id="itr" type="range" min="4" value="4" max="150"  oninput="changeStroke()"/>
    
    </div>
    <div><text id="infoSW">stroke-width:4px </text></div>
    <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="500" height="400" viewBox="0 0 400 500">
    <defs>
    <mask id="msk">
    <rect width="100%" height="100%" fill="black" />
    <polygon  fill="white" stroke-width="8" stroke="white" points="200 35.5 10 364.5 390 364.5"></polygon>
    </mask> 
    
    </defs> 
    
        <polygon id="poly" mask="url(#msk)" fill="yellowgreen" stroke-width="4" stroke="red" points="200 35.5 10 364.5 390 364.5"></polygon>
          <circle cx="200" cy="252" r="4" fill="black" stroke="black" />
        <circle cx="200" cy="252" r="224" fill="none" stroke="grey" stroke-width="4" />
    </svg>

    为了表明这种修剪字符串外部的技术是通用的,我将添加一个更复杂的元素

    function changeStroke() {
    var sw = document.getElementById("poly"); 
         itr.addEventListener("input",()=>{sw.setAttribute("stroke-width",itr.value)});
        var x = document.getElementById("itr").value;
        
        document.getElementById("infoSW").innerHTML = "stroke-width: " + x +"px";
    }
    <div>
     <input id="itr" type="range" min="4" value="4" max="20"  oninput="changeStroke()"/>
    </div>
    <div><text id="infoSW">stroke-width:4px </text></div>
    <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="500" height="400" viewBox="40 200 100 125">
    <defs>
    <mask id="msk">
    <rect width="100%" height="100%" fill="black" />
    <path fill="white" stroke-width="4" stroke="white" d="m32.5 272c-16.3-5.6-11.4-33.8 0-31.4 0-10.6 13.4-18.7 22.8-9.4 0 0 2.4-13.4 21.1-13.4 19.1 0.1 22.6 21.2 22.6 21.2 15.8-1.3 18.6 24.6 4.8 32.6z"
    </mask> 
    
    </defs> 
        <path id="poly" mask="url(#msk)" fill="white" stroke="skyblue" stroke-width="4" stroke-linecap="round"  stroke-linejoin="round" d="m32.5 272c-16.3-5.6-11.4-33.8 0-31.4 0-10.6 13.4-18.7 22.8-9.4 0 0 2.4-13.4 21.1-13.4 19.1 0.1 22.6 21.2 22.6 21.2 15.8-1.3 18.6 24.6 4.8 32.6z"
    </svg>

    • 5
  2. Alexandr_TT
    2022-03-11T22:30:50Z2022-03-11T22:30:50Z

    在缩放时,还有另一种方法可以避免由于线粗的外半部分增加而导致图形整体尺寸的额外增加scale(X,Y)

    SVG 有一个字符串属性vector-effect1="non-scaling-stroke"

    此属性可防止 SVG 元素放大或缩小时线宽增加。

    换句话说,无论您如何使用scale()或调整形状的大小viewBox,线条都不会改变其宽度。

    #一。没有的例子vector-effect1="non-scaling-stroke"

    随着图形大小的增加,笔画的粗细也会增加。

    单击画布后动画将开始:

    <svg id="svg1" width="250" height="250" version="1.1"
    viewBox="0 0 250 250" 
          xmlns="http://www.w3.org/2000/svg" style="border:1px solid" >
        <rect x="10" y="10 "width="50" height="50" rx="10" fill="none" stroke="crimson" stroke-width="4">
         <animateTransform
           attributeName="transform"
           type="scale"
           values="1;1.5;2;2.5;3;3.5;4"
           calcMode="discrete"
           begin="svg1.click"
           dur="6s"
           repeatCount="1"
           fill="freeze"
          </rect>      
          </svg>

    #2。使用 vector-effect1="non-scaling-stroke" 的示例

    <svg id="svg1" width="250" height="250" version="1.1"
    viewBox="0 0 250 250" 
          xmlns="http://www.w3.org/2000/svg" style="border:1px solid" >
        <rect x="10" y="10 "width="50" height="50" rx="10" fill="none" stroke="crimson" stroke-width="4" vector-effect="non-scaling-stroke" >
         <animateTransform
           attributeName="transform"
           type="scale"
           values="1;1.5;2;2.5;3;3.5;4"
           calcMode="discrete"
           begin="svg1.click"
           dur="6s"
           repeatCount="1"
           fill="freeze" />
          </rect>      
     </svg>

    请注意,与第一个示例相比,该图在最终位置中所占的位置略小,因为线条粗细没有增加

    • 2

相关问题

  • 跨浏览器兼容,相同代码不同块显示

  • 如何使按钮在响应式布局中与整个内容成比例地改变其位置?

  • 如何在不增加 SVG 元素大小的情况下增加线宽

  • FloatingActionButton 的大小 - Flutter

  • 边距顶部无法正常工作

  • 如何制作像示例中那样平滑的滚动站点?[关闭]

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5