生存僵尸启示录:使用JavaScript操纵SVG

编程入门 行业动态 更新时间:2024-10-07 00:17:56

生存僵尸<a href=https://www.elefans.com/category/jswz/34/1763394.html style=启示录:使用JavaScript操纵SVG"/>

生存僵尸启示录:使用JavaScript操纵SVG

生存下来的启示很多。 或至少是构建HTML5应用程序,这可能会或多或少地取决于应用程序和启示录。 到目前为止,在本系列的第1部分中,我们介绍了静态SVG元素-文本,图像,圆形,矩形以及最重要的路径。 第2部分介绍了一些无需JavaScript即可完成的炫酷动画技巧。

但是我们的应用程序不会像僵尸一样拯救任何人免于僵尸。 为此,它需要一些额外的功能,例如可以正常使用的按钮。 因此,为此目的,本系列文章的第3部分,将介绍两种不同的方法来响应用户交互,包括SVG元素本身内的属性动画以及使用JavaScript来操纵Core DOM和SVG DOM元素。

注意:本文中的代码建立在本系列第2部分的最终源代码之上。 该代码本身可以在.htm后面找到。 此外,本演练还将添加一些新图像。 可在.zip中找到本系列中使用的资产的完整档案。

使用<set>元素

在最后的演练中,僵尸由于一个名为<animateMotion>的小元素而开始移动,该元素嵌入到<image>元素后,定义了<image>的运动路径和运动持续时间。 这种方法几乎不影响SVG动画的表面。 除了向用户提供控件功能的可视指示器(甚至只是向页面提供糖果)之外,动画还可以并且应该用于指示对用户交互的响应。

传统上,这是通过使用JavaScript交换图像或通过使用CSS定义悬停样式或数千种类似技术中的任何一种来实现的。 通过允许将属性更改嵌入到元素本身中,然后将其连接到鼠标事件,SVG在蝙蝠带上添加了自己的工具。 最常见的示例之一是使用<set>元素更改笔触和/或填充颜色。

回到the脚的僵尸。 现在,按照最初定义的那样,慢速僵尸被一个红色粗笔画盘旋,而快速僵尸被一个黑色细笔画盘旋。 显然,当用户单击快速僵尸时,这将需要更改。 通常,需要在<image>元素中添加一些内容以响应点击。 但在这种情况下不是。

看一下ID为“ fastCircle”的<circle>元素。 现在,它的定义为:

<circle id="fastCircle" cx="275" cy="325" r="40" stroke="black" fill="white" stroke-width="2" />

要使此元素响应单击,请嵌入<set>元素,以定义所有可能的笔触和笔触宽度更改以及(这是重要的部分)要从其开始的鼠标事件。 在这种情况下,当“ fastZombie”图像接收到mousedown事件时,“ fastCircle”的属性将更改,因此语法为:

<circle id="fastCircle" cx="275" cy="325" r="40" stroke="black" fill="white" stroke-width="2"><set attributeName="stroke" from="black" to="red" begin="fastZombie.mousedown" /><set attributeName="stroke-width" from="2" to="4" begin="fastZombie.mousedown" /></circle>

(请注意,右括号已更改为</ circle>标记。)当然,此元素也需要响应“ slowZombie”单击,因此请完成操作:

<circle id="fastCircle" cx="275" cy="325" r="40" stroke="black" fill="white" stroke-width="2"><set attributeName="stroke" from="black" to="red" begin="fastZombie.mousedown" /><set attributeName="stroke-width" from="2" to="4" begin="fastZombie.mousedown" /><set attributeName="stroke" from="red" to="black" begin="slowZombie.mousedown" /><set attributeName="stroke-width" from="4" to="2" begin="slowZombie.mousedown" /></circle>

相反,“ slowCircle”需要相同的处理:

<circle id="slowCircle" cx="75" cy="325" r="40" stroke="red" fill="white" stroke-width="4"><set attributeName="stroke" from="black" to="red" begin="slowZombie.mousedown" /><set attributeName="stroke-width" from="2" to="4" begin="slowZombie.mousedown" /><set attributeName="stroke" from="red" to="black" begin="fastZombie.mousedown" /><set attributeName="stroke-width" from="4" to="2" begin="fastZombie.mousedown" /></circle>

现在,仅基于这些附加元素(仍然没有任何JavaScript),圆圈就可以响应用户交互,如图1所示。

图1.在鼠标按下时使用<set>更改笔画属性

使用JavaScript处理<text> DOM:textContent

使用<set>是一个巧妙的技巧,但是它有一个大问题:并非所有支持SVG的浏览器都实现此特定功能。 幸运的是,作为基于XML的规范,可以以与JavaScript访问基于Core DOM规范的任何文档相同的方式(即通过getElement()和setElement())访问SVG。 因此,为了最大程度地兼容浏览器,请添加一个名为setSpeed(speed)的新函数:

<script>
&NBSP;
function setSpeed(speed) {if (speed == 'Fast') {var circleSelected = document.getElementById('fastCircle');var circleUnselected = document.getElementById('slowCircle');} else {var circleSelected = document.getElementById('slowCircle');var circleUnselected = document.getElementById('fastCircle');}circleSelected.setAttribute('stroke','red');circleSelected.setAttribute('stroke-width','4');circleUnselected.setAttribute('stroke','black');circleUnselected.setAttribute('stroke-width','2');}</script>

此函数获取fastCircle和slowCircle元素,然后通过直接访问它们来设置“ stroke”和“ stroke-width”属性。

现在,圆是根据用户对快速或慢速僵尸的选择进行切换的,文本也需要更改。 这可以使用相同的技术来完成-通过Core DOM访问SVG属性。 但是在某些情况下,可以通过SVG DOM直接访问元素的属性。 这不仅使代码更紧凑,而且还提高了性能。 诀窍是知道所需属性的语法。

<text>元素的内容恰好是可以通过SVG DOM访问的那些属性之一,在这种情况下,textContent是正确的答案。 它是“ textContent”。 别客气。

function setSpeed(speed) {if (speed == 'Fast') {var circleSelected = document.getElementById('fastCircle');var circleUnselected = document.getElementById('slowCircle');} else {var circleSelected = document.getElementById('slowCircle');var circleUnselected = document.getElementById('fastCircle');}circleSelected.setAttribute('stroke','red');circleSelected.setAttribute('stroke-width','4');circleUnselected.setAttribute('stroke','black');circleUnselected.setAttribute('stroke-width','2');var speedText = document.getElementById('speedText');speedText.textContent = speed;}

确保向僵尸图像添加onmouseup事件:

<image id="slowZombie" x="375" y="1875" width="175" height="304" transform="scale(.16,.16)" xlink:href="zombie.svg" οnmοuseup="setSpeed('Slow');"><image id="fastZombie" x="1630" y="1875" width="175" height="304" transform="scale(.16,.16)" xlink:href="zombie.svg" οnmοuseup="setSpeed('Fast');">

单击僵尸现在应该更改文本及其容器圆,如图2所示。

图2. <text>元素上的textContent更改

MSDN上的IEBlog更详细地比较了SVG DOM和Core DOM,并涵盖了其他最佳实践。 。 可以在此处找到SVG DOM规范。

添加新的SVG元素

在第1部分中,本系列介绍了<path>元素,并使用其中的几个元素在controlPanelBox窗格中创建了增量/减量控件。 现在将是使用JavaScript功能为这些控件注入生命的好时机,首先是创建新的僵尸,然后再添加项和建筑物,最后是逐渐减少这些元素。

熟悉基于名称空间定义创建新元素的任何人都可以识别document.createElementNS命令。 这也是创建新的SVG元素的关键。

在标题中,创建一个名为newZombie()的新JavaScript函数。 将会立即添加更强大的代码,但现在通过引用“ ”命名空间的“图像”定义来创建僵尸:

function newZombie() {var svg = document.createElementNS("","image");}

请注意,在创建SVG元素之后,下一步将演示在操纵其属性时的一些异常情况。 虽然<image>元素的大多数属性都可以通过setAttribute进行引用,但是图像本身的源(xlink:href属性)却不能。 需要通过引用源规范来定义该属性,在本例中,该属性是“ ”命名空间的href定义。

W3 Wiki通过指出尝试创建新的<image>元素时最常见的错误来掩盖这种混乱。

function newZombie() {var svg = document.createElementNS("","image");svg.setAttributeNS('','href','zombie.svg');}

在该系列的较早版本中,当为“速度”控件放置僵尸<image>元素时,需要一些疯狂的技巧才能使这些图像与跨浏览器完全兼容。 凭直觉,人们可能会认为,设置图像所需的宽度和高度,然后将其放置在所需的坐标上,将获得所需的结果。 在大多数浏览器中都是这种情况。 但是对于离群值,则需要一些缩放。 作为示例,请再看一下slowZombie <image>定义:

<image id="slowZombie" x="375" y="1875" width="175" height="304" transform="scale(.16,.16)" xlink:href="zombie.svg" οnclick="setSpeed('Slow');">

这里的目标是放置50×50的图像(或者“高度”是50,宽度是成比例的)。 实际的zombie.svg源定义的图像为175×304。 因此,为了使这项工作有效,将<image>元素的尺寸定义为175×304,然后使用.16作为缩放因子来应用transform:scale。 由于缩放,还需要更改x,y坐标,以便缩放后的结果为60,300。

动态创建新的<image>元素时,需要发生类似的巫毒:

function newZombie() {var svg = document.createElementNS("","image");svg.setAttributeNS('','href','zombie.svg');svg.setAttribute('width','175');svg.setAttribute('height','304');}

但是,您可以尝试使用其他方法,而不是根据比例因子计算x,y坐标并将图像放置在这些坐标上。 而是使用transform:translate设置僵尸的位置。 平移转换重新定义了元素的原点。 因此,例如,平移会将画布本身的原点移动到50,100并将对象放置在0,0,而不是将对象放置在原点为0,0的画布上的x,y坐标为50,100的位置。 语法如下:

svg.setAttribute('transform','translate(50, 100)');

可以在同一行中组合多个变换,因此请使用“缩放”变换来完成该函数:

function newZombie() {var svg = document.createElementNS("","image");svg.setAttributeNS('','href','zombie.svg');svg.setAttribute('width','175');svg.setAttribute('height','304');var scale = .16;var x = Math.floor(Math.random()*550);var y = Math.floor(Math.random()*350);svg.setAttribute('transform','translate(' + (x) + ', ' + (y) + ') scale(' + scale + ', ' + scale + ')');document.getElementById('cityBox').appendChild(svg);}

此示例还将x,y设置为“ cityBox”窗格中的随机点,该点为600×400(补偿图像本身的50×50大小)。 默认情况下,(0,0)原点位于左上角。 最后,新元素将像其他任何元素一样附加到DOM,在这种情况下,将“ cityBox” <svg>元素指定为其父元素。

要触发该函数,请找到ID为“ zombieMore”的<path>元素,并将newZombie()函数添加到onmouseup事件中。 这将是“城市人口(000s)”的增量按钮,这是预测启示录期间僵尸患病率的重要因素。 现在,不必担心其他按钮,因为这仅用于测试。

<path id =” zombieMore” d =” M 300 50 l -50 -25 l 0 50 l 50 -25” stroke =“ black” stroke-width =“ 1” fill =“ red” onmouseup =“ newZombie(); ” />

当然,结果将根据随机放置而有所不同,但是单击新启用的增量按钮应在城市景观上点缀新的僵尸,如图3所示。

图3.运行!!!

DOM操作有效,但是代码可以使用一些美学上的调整。 首先,虽然饥饿的僵尸看起来像是在准确地捉住人类,并可能消耗了人类的大脑,但这更多的是最终游戏场景。 为了充当“生存”预测器,该应用在跑步者周围有安全区域的情况下可能会更好地工作。 其次,除非靠近大脑或发出噪音,否则僵尸往往会受到方向性的挑战(任何试图同时发短信和走路的人都可以看到这一点)。 因此,为了多样化,最好水平翻转某些图像。

第一个调整可以使用基本的JavaScript完成。 以下代码在尖叫声周围建立了200×100的安全区域。

function newZombie() {var svg = document.createElementNS("","image");svg.setAttributeNS('','href','zombie.svg');svg.setAttribute('width','175');svg.setAttribute('height','304');var scale = .16;var x = Math.floor(Math.random()*550);var y = Math.floor(Math.random()*350);var cityWidth = 600;var cityHeight = 400;var safezoneWidth = 200;var safezoneHeight = 100;var safezoneX = Math.round((cityWidth - safezoneWidth) / 2, 0);var safezoneY = Math.round((cityHeight - safezoneHeight) / 2, 0);if ( ((safezoneX - 50) <= x) && (x <= (safezoneX + safezoneWidth)) &&((safezoneY - 50) <= y) && (y <= (safezoneY + safezoneHeight)) ) {switch (Math.floor(Math.random()*4)) {case 0:x = safezoneX - 50;break;case 1:x = safezoneX + safezoneWidth;break;case 2:y = safezoneY - 50;break;case 3:y = safezoneY + safezoneHeight;break;}}svg.setAttribute('transform','translate(' + (x) + ', ' + (y) + ') scale(' + scale + ', ' + scale + ')');document.getElementById('cityBox').appendChild(svg);}

尽管它与SVG没有直接关系,但是此代码可以做一些事情来影响图像的放置。 一种是,它设置一个200×100安全区域,并假设该安全区域位于600×400画布的中心,并计算该区域的原点x,y坐标。 第二,如果僵尸的当前x,y坐标在该区域内,则将图像按随机选择的方向推动,直到它刚好位于安全区域之外。

图4显示了在一次特别讨厌的不死浪潮之后安全区域的显示方式。

图4.安全区

更好,但它看起来更像是黑色星期五促销,而不是僵尸出没(细微差别,但有所不同)。 如果这些僵尸中的一些被翻转,看起来会更好。 但是存在一个问题:如本系列第2部分中所述,transform属性可用于缩放,旋转,倾斜,平移或定义一个全新的矩阵。 请注意此列表中没有的内容:水平或垂直翻转。 这是一种悲剧性的监督,但可以通过结合使用转换和缩放来克服。

诀窍是:通过将比例因子设置为负数,可以垂直或水平翻转元素。 但是,这会相对于其画布的原点缩放元素。 因此,通过将原点保留在(0,0),然后应用scale(-1,1),该元素将被翻转到监视器左侧的某种负区域中。 它会存在,并且转换将是有效的,但实际上会使元素消失。

幸运的是,由于采用了一种以跨浏览器友好的方式放置图像的技术,即通过使用transform:translate和transform:scale属性,可以非常轻松地插入负比例乘数。

总结一下:

*没有transform:flip属性-它不存在。

*仅使用transform:scale(-1,1)可以将图像完全翻转出其父<svg>元素。

*结合使用transform:translate和transform:scale可以有效地将图像翻转到位; 在这种情况下,transform:scale通过将图像缩放到所需大小来完成双重任务,无论如何都需要这样做。

为了实现这一点,请添加一些巧妙的随机化方法,调整位置以补偿图像的大小以及对transform:scale代码的调整:

function newZombie() {var svg = document.createElementNS("","image");svg.setAttributeNS('','href','zombie.svg');svg.setAttribute('width','175');svg.setAttribute('height','304');var scale = .16;var x = Math.floor(Math.random()*550);var y = Math.floor(Math.random()*350);var cityWidth = 600;var cityHeight = 400;var safezoneWidth = 200;var safezoneHeight = 100;var safezoneX = Math.round((cityWidth - safezoneWidth) / 2, 0);var safezoneY = Math.round((cityHeight - safezoneHeight) / 2, 0);if ( ((safezoneX - 50) <= x) && (x <= (safezoneX + safezoneWidth)) &&((safezoneY - 50) <= y) && (y <= (safezoneY + safezoneHeight)) ) {switch (Math.floor(Math.random()*4)) {case 0:x = safezoneX - 50;break;case 1:x = safezoneX + safezoneWidth;break;case 2:y = safezoneY - 50;break;case 3:y = safezoneY + safezoneHeight;break;}}flip = Math.floor(Math.random()*2)*2-1; //results in -1 or 1x += 25 - 25*flip; //adjust for 50x50 zombie size; results in +50 or +0svg.setAttribute('transform','translate(' + (x) + ', ' + (y) + ') scale(' + (scale * flip) + ', ' + scale + ')');document.getElementById('cityBox').appendChild(svg);}

这使启示录的外观稍微混乱一些,如图5所示。

图5。僵尸。 翻转僵尸。 使用transform:translate和transform:scale应用

要立即了解僵尸启示录生存预测器的运行情况,请访问.htm 。 到目前为止,请确保查看页面的源代码以获取示例代码。

包起来

这开始看起来很严重。 可怜的可怜人注定了。 现在只有两件事可以拯救尖叫者了:购物中心和乡巴佬。 但是,就像任何好的连续剧一样,这将是一个绝路。 乡巴佬会护送人类安全吗? 他们会及时找到一家购物中心逃避贪婪的部落吗? 敬请关注。


本文是Internet Explorer团队的HTML5技术系列的一部分。 通过三个月的免费BrowserStack跨浏览器测试@ http://modern.IE来尝试本文中的概念。

From: /

更多推荐

生存僵尸启示录:使用JavaScript操纵SVG

本文发布于:2024-02-14 11:11:09,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1763342.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:启示录   僵尸   SVG   JavaScript

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!