您的位置:奥门新浦京网址 > Wed前段 > 通晓SVG坐标种类和转移,transform坐标转变

通晓SVG坐标种类和转移,transform坐标转变

发布时间:2019-10-21 05:40编辑:Wed前段浏览(63)

    使用<foreignObject>建立新视窗

    foreignObject元素建立一个新的viewport来渲染这个元素的内容。

    foreignObject标签允许你把非SVG内容添加到SVG文件中。通常,foreignObject的内容被认为不同于命名空间。例如,你可以把一些HTML放到SVG元素的中间。

    foreignObject接收属性包括xyheightwidth,用来定位对象和调整尺寸,创建用于呈现它里面所引用的内容的范围。

    有需要关于foreignObject元素的要说因为它给内容创建了新的viewport。如果你感兴趣,可以查看MDN entry或者在The Nitty Gritty Blog上查看Christian Schaeffer创建的实际使用例子。

    四、SVG transform scale缩放

    SVG中的缩放的语法就比较单纯了,就scale(sx[, sy])sx表示横坐标缩放比例,sy表示纵坐标缩放比例。其中sy是可缺省的,如果缺失,表示使用和sx一样的值,也就是等比例缩放。其中,sxsy两个参数可以逗号分隔,也可以使用空格分隔。这和CSS3中的使用有所不同,两外,SVG transform属性值缩放是不支持scaleXscaleY这些鬼的。

    同样的,CSS控制的transform和SVG元素属性控制的transform的坐标系统是不一样的。一个默认元素中心(下图左),一个是SVG画布左上角(下图右),于是(from css-tricks):图片 1

    因此,当我们对SVG元素scale缩放时候,发现位置也有出乎我们意料,就应该知道是怎么回事了。

    rotate旋转虽然也是迥异坐标,但是其参数自带偏移参数,我们我们移个花接个木,还是可以得到我们想要的结果。但是,scale缩放这里,就要悲惨很多了,没有自带偏移参数,于是,当我们要实现SVG元素居中缩放的效果,还需要使用translate手动偏移。

    怎么个手动偏移法呢?即使先translate其中心点位置到元素的中心坐标位置,然后缩放,然后坐标再反方向还原回去。例如,某元素中心点坐标是(95, 75), 垂直缩放1.5倍的效果则是:

    CSS

    transform="translate(95 75) scale(1, 1.5) translate(-95 -75)"

    1
    transform="translate(95 75) scale(1, 1.5) translate(-95 -75)"

    您可以狠狠地点击这里:CSS transform和SVG transform scale缩放demo

    对应的CSS代码就简单多了,直接:

    CSS

    .scale { transform: scale(1, 1.5); }

    1
    2
    3
    .scale {
        transform: scale(1, 1.5);
    }

    然后最终效果都是一样的:图片 2

    使用Gif原理示意如下:

    图片 3

    Content Security Policy(简称 CSP)

    CSP 内容安全策略,属于一种浏览器安全策略,以可信白名单作机制,来限制网站中是否可以包含某来源内容。兼容性支持同样是个问题,比如 Android webview 需要固件4.4以上才支持,iOS safari 6 以上支持,幸运的是 UC 浏览器目前支持 1.0 策略版本,具体可以到 CANIUSE 了解。目前对 CSP 的使用仅有不到两周的经验而已,下面简单说说其优缺点。

    缺点:

    1. CSP 规范也比较累赘,每种类型需要重新配置一份,默认配置不能继承,只能替换,这样会导致整个 header 内容会大大增加。
    2. 如果业务中有爬虫是抓取了外部图片的话,那么 img 配置要么需要枚举各种域名,要么就信任所有域名。
      1. 移动端 web app 页面,如果有存在 Native 与 web 的通信,那么 iframe 配置只能信任所有域名和协议了。
      1. 一些业务场景导致无法排除内联 script 的情况,所以只能开启 unsafe-inline
      1. 一些库仍在使用 eval,所以避免误伤,也只能开启 unsafe-eval
      1. 由于 iframe 信任所有域名和协议,而 unsafe-inline 开启,使得整个防御效果大大降低

    优点:

    1. 通过 connect/script 配置,我们可以控制哪些 外部域名异步请求可以发出,这无疑是大大的福音,即使内联 script 被注入,异步请求仍然发不出,这样一来,除非攻击者把所有的 js 都内联进来,否则注入的功能也运行不了,也无法统计效果如何。
    2. 通过 reportUri 可以统计到攻击类型和 PV,只不过这个接口的设计不能自定义,上报的内容大部分都是鸡肋。
    3. object/media 配置可以屏蔽一些外部多媒体的加载,不过这对于视频播放类的业务,也会误伤到。
    4. 目前 UC 浏览器 Android 版本的客户端和 web 端通信机制都是采用标准的 addJavascriptInterface 注入方式,而 iPhone 版本已将 iframe 通信方式改成 ajax 方式(与页面同域,10.5 全部改造完成),如果是只依赖 UC 浏览器的业务,可以大胆放心使用,如果是需要依赖于第三方平台,建议先开启 reportOnly,将一些本地协议加入白名单,再完全开启防御。

    总的来说吧,单靠 CSP 单打独斗显然是不行,即使完全开启所有策略,也不能完成消除注入攻击,但是作为纵深防御体系中的一道封锁防线,价值也是相当有用的。

    使用嵌套SVG使元素流动

    在保持宽高比的情况下定位元素,我们可以使用嵌套svg只允许特定元素流动-可以不保持这些特定元素的宽高比。

    例如,如果你只想SVG中的一个元素流动,你可以把它包含在一个svg中,并且使用preserveAspectRatio="none"来让这个元素扩展始终撑满这个视窗的宽,并且保持宽高比和像我们在之前例子中做的一样定位其他元素。

    XHTML

    <svg> <!-- ... --> <svg viewBox=".." preserveAspectRatio="none"> <!-- this content will be fluid --> </svg> <svg viewBox=".." preserveAspectRatio=".."> <!-- content positioned somewhere in the viewport --> </svg> <!-- ... --> </svg>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <svg>
        <!-- ... -->
        <svg viewBox=".." preserveAspectRatio="none">
            <!-- this content will be fluid -->
        </svg>
        <svg viewBox=".." preserveAspectRatio="..">
            <!-- content positioned somewhere in the viewport -->
        </svg>
        <!-- ... -->
    </svg>

    Jake Archibald创建了一个简单实用的嵌套SVG使用案例:一个简单的UI可以包含定位在最外层svg角落的元素,并且保持宽高比,UI的中间部分浮动并且根据svg宽度改变进行拉伸。你可以在这里查看。确保你在开发工具里检查代码来选取和想象不同viewbox和svg使用的效果。

    一、HTML transform和SVG transform

    SVG中自带transform属性,没错,是属性,例如:

    JavaScript

    <svg width="200" height="150"> <rect x="30" y="30" width="120" height="90" transform="rotate(45)"></rect> </svg>

    1
    2
    3
    <svg width="200" height="150">
        <rect x="30" y="30" width="120" height="90" transform="rotate(45)"></rect>
    </svg>

    普通的HTML元素没有transform属性,但是支持CSS3的transform, 好奇的小伙伴可能会疑问了,CSS3中的transform变换,跟SVG中的transform是什么关系呢?

    恩,有点类似于谢霆锋和陈冠希之间的关系,有些小复杂。

    图片 4

    OK, 先说说相似之处吧。
    一些基本的变换类型是一样的,包括:位移translate, 旋转rotate, 缩放scale, 斜切skew以及直接矩阵matrix. 但只局限于2D层面的变换。SVG似乎只支持二维变换(若有不对,欢迎指正),且类似translateXrotateX也都是不支持的。

    下面就是不一样的地方了:
    1. CSS3 transform一般用在普通元素上,虽然也可以应用在SVG元素上,但是IE浏览器(IE edge未测试)却不支持SVG元素;

    JavaScript

    rect { /* IE说:你这是弄啥来? */ transform:rotate(45deg); }

    1
    2
    3
    4
    rect {
        /* IE说:你这是弄啥来? */
        transform:rotate(45deg);
    }

    2. HTML元素的CSS3 transform和SVG的transform坐标系统大相径庭;

    平常我们使用transform其坐标是相对于当前元素而言的,默认是元素的中心点变换,我们可以通过transform-origin属性改变变换的中心点。而SVG中的transform的坐标变换的是相对于画布的左上角计算的,跟HTML的transform差别较大,理解上也更加麻烦。而本文就是彻底理清SVG中的transform到底是怎么工作的。

    3. 具体的语法细节有差异。SVG transform属性语法有些自带偏移。而CSS transform则更加纯粹些。

    //zxx: 据说CSS的transform和SVG的transform属性即将合并。

    打造双剑合璧的 XSS 前端防火墙

    2015/09/30 · HTML5 · XSS

    原文出处: 林子杰(@Zack__lin)   

    结束语

    建立新的viewports和坐标系-像上述提到的一样通过嵌套svg和其他元素-允许你控制SVG的部分内容而通过其他方式你可能没法一样控制。

    在写这片文章以及思考例子和使用情况的整个过程中,我一直在思考嵌套SVG如何让我们在处理SVG时能更好控制并有更灵活的方式。自适应SVG可以通过简洁的代码创建,在SVG中可以创建独立于其他元素的流动元素,用来模拟CSS border images来在高分屏上定义背景。

    你是否已经在SVG中使用嵌套视窗来创建有趣的例子了呢?你能否相处更多有创意的例子呢?

    这篇文章总结了“理解SVG坐标系和变换”这个系列。下一步,我们会讨论动画,甚至更多!敬请期待,感谢你的阅读!

    1 赞 1 收藏 评论

    图片 5

    七、结束语

    本文介绍的内容实际上都还是非常基本的。实际SVG应用的时候,可能是多个变换参杂在一起,所以,如果本文介绍的几个基本变换都没搞清楚,到时候,想必是想破脑袋都不明白怎么元素跑这里了,怎么变成这样了!

    本文的这些知识点虽然基本,但是相当重要的。再加上,不同的变换方法的语法细节还不一样。有的自带偏移,有的需要手动偏移等等;不同变换的前后位置不同,甚至同一变换分开连续变换和一次性变换的结果都不一样等等;都要求大家要细心耐心阅读。

    本文内容和结构参考自:Transforms on SVG Elements. 但要比原文要精炼很多,同时,每一个变换都有亲自实践认证,因此,从品质上讲,可能还要略高一筹。

    对了,矩阵matrix没有细说过,这个可以参考我之前的文章:“理解CSS3 transform中的Matrix(矩阵)”,一脉相承的。

    我也是初学者,出错在所难免,欢迎指正!

    感谢阅读,欢迎交流!图片 6

    1 赞 收藏 评论

    图片 7

    捣蛋的运营商

    由于 xss 注入的范围太广,本文仅对网关劫持这一方面的 XSS 注入进行讨论。
    这里读者有个小小的疑问,为什么我要选网关劫持进行讨论?因为网关劫持可以大面积范围进行有效控制。

    曾经,有这样一道风靡前端的面试题(当然我也现场笔试过):当你在浏览器地址栏输入一个URL后回车,将会发生的事情?其实本文不关心请求发到服务端的具体过程,但是我关心的时,服务端响应输出的文档,可能会在哪些环节被注入广告?手机、路由器网关、网络代理,还有一级运营商网关等等。所以,无论如何,任何网页都得经过运营商网关,而且最调(zui)皮(da)捣(e)蛋(ji)的,就是通过运营商网关。

    另外, 也提醒大家,如果手机安装了一些上网加速软件、网络代理软件或设置网络代理 IP,会有安全风险,也包括公共场所/商家的免费 WIFI。

    例子

    试想我们有如下的SVG:图片 8

    上述SVG是响应式的。改变屏幕的尺寸会导致整个SVG图形根据需要做出反应。下面的截图展示了拉伸页面的结果,以及SVG如何变得更小。注意SVG的内容如何根据SVG视窗和相互之间保持它们的初始位置。图片 9

    使用嵌套SVG,我们将改变这个情况。我们可以对SVG中每个独立的元素根据SVG视窗声明一个位置,所以随着SVG 视窗尺寸的改变(即最外层svg的改变),每个元素独立于其他元素发生改变。

    注意,在这个时候,你需要熟悉SVG viewport, viewBox, 和preserveAspectRatio是如何生效的。

    我们将要创建一个效果,当屏幕尺寸变化时,蛋壳的上部分移动使得其中的可爱的小鸡显示出来,如下图所示:图片 10

    为了达到这个效果,蛋的上半部分必须和其他部分分离出来单独包含一个自己的svg。这个svg包含框会有一个IDupper-shell

    然后,我们保证新的svg#upper-shell和外层SVG有一样的高度和宽度。可以通过在svg上声明width="100%"``height="100%"或者不声明任何高度和宽度来实现。如果内层SVG上没有声明任何宽高,它会自动扩展为外层SVG宽高的100%

    最终,为了确保上壳被“抬”起或定位在svg#upper-shell顶部的中心,我们将使用适当的preserveAspectRatio值来确保viewBox被定位在视窗的顶部中心-值是xMidYMin

    SVG图形的代码如下:

    XHTML

    <svg version="1.1" xmlns="" xmlns:xlink="; <!-- ... --> <svg viewBox="0 0 315 385" preserveAspectRatio="xMidYMid meet"> <!-- the chicken illustration --> <g id="chicken"> <!-- ... --> </g> <!-- path forming the lower shell --> <path id="lower-shell" fill="url(#gradient)" stroke="#000000" stroke-width="1.5003" d="..."/> </svg> <svg id="upper-shell" viewBox="0 0 315 385" preserveAspectRatio="xMidYMin meet"> <!-- path forming the upper shell --> <path id="the-upper-shell" fill="url(#gradient)" stroke="#000000" stroke-width="1.5003" d="..."/> </svg> </svg>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
        <!-- ... -->
        <svg viewBox="0 0 315 385" preserveAspectRatio="xMidYMid meet">
            <!-- the chicken illustration -->
            <g id="chicken">
                <!-- ... -->
            </g>
            <!-- path forming the lower shell -->
            <path id="lower-shell" fill="url(#gradient)" stroke="#000000" stroke-width="1.5003" d="..."/>
        </svg>
     
        <svg id="upper-shell" viewBox="0 0 315 385" preserveAspectRatio="xMidYMin meet">
            <!-- path forming the upper shell -->
            <path id="the-upper-shell" fill="url(#gradient)" stroke="#000000" stroke-width="1.5003" d="..."/>
        </svg>
    </svg>

    这个时候,注意在嵌套svg#upper-shell上声明的viewBox和最外层svg有相同的值(在它被移除之前)。我们用相同的viewBox值我原因就是这样,SVG在大屏幕上保持最初的样子。

    所以,这件事是这样的:我们开始一个SVG-在我们的例子中,这是一张里面藏着一个小鸡的带裂纹的蛋。然后,我们创建了另一“层”并把上部分的壳放在里面-这一层通过使用嵌套svg创建。嵌套svg和外层svg的尺寸和viewBox一样。最终,内层SVG的viewBox被设置成不管屏幕尺寸是多少都“固定”在viewport的顶部-这确保了当屏幕尺寸很窄时SVG被拉长,上层的壳被向上举起,因此展示出“隐藏”在里面的小鸡。图片 11

    一旦屏幕尺寸拉伸,SVG被拉长,使用preserveAspectratio="xMidYMin meet"把包含上部分壳的viewBox被定位到viewport的顶部。图片 12

    点击下面按钮来查看在线SVG。记住改变屏幕尺寸再看SVG变化。

    在线案例

    嵌套或”分层”SVG使你可以根据改变的视窗定位SVG的一部分,在保持元素宽高比的情况下。所以图片可以在不扭曲内容元素的情况下自适应。

    如果我们想要整个鸡蛋剥离显示出小鸡,我们可以单独用一个svg层包含下部分壳,viewBox也相同。确保下部分壳向下移动并固定在视窗的底部中心,我们使用preserveAspectRatio="xMidYMax meet"来定位。代码如下:

    XHTML

    <svg version="1.1" xmlns="" xmlns:xlink="; <svg id="chick" viewBox="0 0 315 385" preserveAspectRatio="xMidYMid meet"> <!-- the chicken illustration --> <g id="chick"> <!-- ... --> </g> </svg> <svg id="upper-shell" viewBox="0 0 315 385" preserveAspectRatio="xMidYMid meet"> <!-- path forming the upper shell --> <path id="the-upper-shell" fill="url(#gradient)" stroke="#000000" stroke-width="1.5003" d="..."/> </svg> <svg id="lower-shell" viewBox="0 0 315 385" preserveAspectRatio="xMidYMax meet"> <!-- path forming the lower shell --> <path id="the-lower-shell" fill="url(#gradient)" stroke="#000000" stroke-width="1.5003" d="..."/> </svg> </svg>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
        <svg id="chick" viewBox="0 0 315 385" preserveAspectRatio="xMidYMid meet">
            <!-- the chicken illustration -->
            <g id="chick">
                <!-- ... -->
            </g>
        </svg>
     
        <svg id="upper-shell" viewBox="0 0 315 385" preserveAspectRatio="xMidYMid meet">
            <!-- path forming the upper shell -->
            <path id="the-upper-shell" fill="url(#gradient)" stroke="#000000" stroke-width="1.5003" d="..."/>
        </svg>
     
        <svg id="lower-shell" viewBox="0 0 315 385" preserveAspectRatio="xMidYMax meet">
            <!-- path forming the lower shell -->
            <path id="the-lower-shell" fill="url(#gradient)" stroke="#000000" stroke-width="1.5003" d="..."/>
        </svg>
    </svg>

    每个svg层/viewport等于最外层svg宽高的100%。所以我们基本有了三个副本。每层包含一个元素-上部分壳,下部分壳,或小鸡。三层的viewBox是相同的,只有preserveAspectRatio不同。图片 13

    当然,在这个例子里,一开始的图形中小鸡隐藏在蛋里,随着屏幕变小才显示出来。然而,你可以做一些不一样的:你可以开始在小屏幕上创建一个图形,然后在大屏幕上显示一些东西;即当svg变宽时才有更多垂直空间来展示元素。

    你可以更有创造性,根据不同屏幕尺寸来显示和隐藏元素-使用媒体查询-把新元素通过特定方式定位来达到特定的效果。想象力是无穷的。

    同时注意嵌套svg不需要和容器svg有相同的宽高;你可以声明宽高并且限制svg内容,超出边界裁切-这都取决于你想要达到什么效果。

    五、SVG transform skew斜切

    先来了解下CSS中的斜切,斜切,如果单纯切一个方向,我们可以看成把矩形变成了平行四边形,其总面积不变化。

    以纯X轴变换举例,skewX(-45deg)则下面这样子(灰色方块为原始位置):

    图片 14

    skewX(45deg)则下面这样子:图片 15

    对于SVG的skew斜切变换,表现效果原理是一样的。但是,使用的语法却相当有意思。

    在前面的一些变换中,例如位移、缩放之类是不支持translateXscaleX这种CSS常见用法的,但是这里的skew却有点让人哭笑不得:不支持skew(x[, y])这种语法,而只能是skewX或者skewY.

    别问我为什么?我只是大自然的搬运工,我不生产语法。

    因此,没有:

    JavaScript

    <del datetime="2015-10-10T12:49:32+00:00">transform="skew(45, 0)"</del>

    1
    <del datetime="2015-10-10T12:49:32+00:00">transform="skew(45, 0)"</del>

    只有:

    CSS

    transform="skewX(45)"

    1
    transform="skewX(45)"

    同样的,由于变换中心点的差异,CSS实现的变换和SVG属性变换往往最后的位置是不一样的:

    图片 16

    不仅如此,如果元素的中心点不是就是SVG的左上角,则skewX(α1) skewX(α2)的最终位置和skewX(α1 + α2)是不一样的(位移和旋转不会这样子)。

    您可以狠狠地点击这里:CSS SVG transform skew斜切差异及连续斜切差异demo

    正如demo所示,CSS的和SVG的位置差异很大:图片 17

    SVG的连续变换和一次性变换的位置也是不一样的:图片 18

    可能有人要疑问,为何连续斜切变换和一次性变换位置会不一样?其实原因很简单,因为斜切的角度和元素偏移大小并不是线性的,比方说,从70到80度和80度到90度之间的位移大小(虽然都是10度的变化区间)是显然不是一个档次的。因此,分开多次连续斜切最终的坐标偏移要比一次性偏移来得小。

    最后,和缩放一样,你想要让SVG元素中心点斜切,可以先translate偏移,在skew变换。就不重复举例演示了。

    防御措施介绍

    本文由奥门新浦京网址发布于Wed前段,转载请注明出处:通晓SVG坐标种类和转移,transform坐标转变

    关键词: