生存僵尸启示录:动态SVG和路径动画

编程入门 行业动态 更新时间:2024-10-09 12:29:58

生存僵尸<a href=https://www.elefans.com/category/jswz/34/1763379.html style=启示录:动态SVG和路径动画"/>

生存僵尸启示录:动态SVG和路径动画

尽管SVG已经存在了一段时间,但它作为HTML5的一部分的采用赋予了它新的生命。 为了庆祝这一事实,本系列演练通过构建几乎完全由SVG和JavaScript创建的Zombie Apocalypse Survival Predictor(僵尸启示录生存预测器),探索了死者也能获得新生命的情况。

在本系列的第3部分中,处于该预测变量中心的尖叫着的人四面被危险包围。 JavaScript首次用于操纵Core DOM和SVG DOM,添加了数十个新的僵尸,然后使用“ transform”属性对其进行翻转。

在本系列的最后一部分中,JavaScript将再次被使用,这一次以购物商场和乡巴佬的形式给人类带来了希望。 够了吗? 敬请期待,直到最后,当JavaScript还用于计算人类的生存几率,然后通过嗅探浏览器的实际SVG功能并采取相应行动来设置预测指标。

注意:本演练以本系列第3部分的完整代码为基础,可以在.htm的源代码中找到该代码。

添加更多的SVG元素

本系列的第3部分展示了如何为“控制面板”画布的六个增量/减量控件中的一个进行动画处理:“更多僵尸”控件。 那根本不会做。 人口控制也需要更少的僵尸。 但是在执行此操作之前,需要添加其他SVG图像。 人类需要一些保护。

从购物中心开始。 为简单起见,假设该城市最多有四个购物中心,这些购物中心将放置在四个角落。 由于需要跟踪购物中心的数量,因此请在<script>部分顶部为购物中心添加全局数组:

<script>var malls = new Array();…

newMall代码将根据阵列中商场的数量为新的SVG元素设置x,y坐标,并针对商场图像本身的100×100尺寸进行调整。 其余代码与newZombie代码基本相同,除了新的SVG元素将被推送到数组以进行跟踪之外:

function newMall(){if (malls.length < 4) {var svg = document.createElementNS("","image");svg.setAttributeNS('','href','building.svg');svg.setAttribute('width','471');svg.setAttribute('height','303');var scale = .21;var x = 0;var y = 0;var thisMall = malls.length;if (thisMall == 0 || thisMall == 2) {x = 20;} else {x = 480;}if (thisMall == 0 || thisMall == 1) {y = 10;} else {y = 300;}malls.push(svg);svg.setAttribute('transform','translate(' + (x) + ', ' + (y) + ') scale(' + scale + ', ' + scale + ')');document.getElementById('cityBox').appendChild(svg);}}

最后,将鼠标事件添加到购物商场增量按钮,该按钮是ID为“ mallMore”的<path>元素:

<path id="mallMore" d="M 300 150 l -50 -25 l 0 50 l 50 -25" stroke="black" stroke-width="1" fill="red" onmouseup="newMall();" />

图1显示了购物中心最大化(​​没有僵尸)的结果。

图1.动态添加的SVG Mall <image>元素

僵尸乡镇是最坏的情况(尤其是受痛苦折磨的僵尸乡镇家庭),健康的乡镇居民,用弓和箭武装,可以帮助他们在步行或奔跑死亡中幸免于难。 动态地将它们添加到城市就像添加僵尸或购物中心一样。 但是在这种情况下,乡巴佬将被放置在安全区内。 要获得额外的奖励,它们将被翻转成面向外。

function newRedneck(){var svg = document.createElementNS("","image");svg.setAttributeNS('','href','redneck.svg');svg.setAttribute('width','375');svg.setAttribute('height','950');scale = .07;var cityWidth = 600;var cityHeight = 400;var safezoneWidth = 200;var safezoneHeight = 200;var safezoneX = Math.round((cityWidth - safezoneWidth) / 2, 0);var safezoneY = Math.round((cityHeight - safezoneHeight) / 2, 0);var x = Math.floor(Math.random()*(safezoneWidth)) + safezoneX;var y = Math.floor(Math.random()*(safezoneHeight-100)) + safezoneY;
&nbsp;flip = (x > (cityWidth / 2)) ? 1 : -1; //flip rednecks left of centersvg.setAttribute('transform','translate(' + (x) + ', ' + (y) + ') scale(' + (flip * scale) + ', ' + scale + ')');document.getElementById('cityBox').appendChild(svg);}

将对该函数的调用添加到ID为“ redneckMore”的<path>元素中:

<path id="redneckMore" d="M 300 250 l -50 -25 l 0 50 l 50 -25" stroke="black" stroke-width="1" fill="red" onmouseup="newRedneck();" />

快速测试应该可以使尖叫的人安全地安放在一排排的乡巴佬中,如图2所示。

图2.动态添加的僵尸防御团队

考虑到这三个要素的影响,这座城市(图3)现在已经变得栩栩如生。

图3.对未来的展望,由JavaScript和SVG提供

完成控制面板

到目前为止,一切都很好。 但是要完成控制面板,需要完成三件事:

  • 减量按钮应启用
  • 文字应更新
  • 参数应该有上限和下限

一次完成所有三个目标的最佳方法是添加第四个函数来处理所有按钮响应以及对这三个创建函数的调用。 该脚本将称为tickSVG。

在控制SVG种群方面,newMall例程是朝正确方向迈出的一步,因此可以将其用作模型。 首先,还要为僵尸和乡下人添加全局数组:

<script>var zombies = new Array();var malls = new Array();var rednecks = new Array();…

接下来,不是直接向DOM添加元素,而是每个创建函数都需要返回新的SVG元素。 因此,对于这三个功能中的每一个,都以:

//document.getElementById('cityBox').appendChild(svg);return svg;

另外,在newMall中,删除以下行:

malls.push(svg);

tickSVG函数本身将根据按钮传递的参数来管理SVG <image>填充。 首先,该函数用新的总数更新相关的<text>元素。 其次,基于最大和最小限制以及当前数组大小,tickSVG要么创建新的<image>元素,要么从数组堆栈中获取顶部元素,具体取决于按下哪个按钮。 最后,它要么像原来在newMall例程中所做的那样,将新的<image>元素推入数组并将其添加到DOM中,要么将其弹出数组并从DOM中删除(请注意removeChild的用法)方法)。

function tickSVG(textName, increment, min, max) {var textElement = document.getElementById(textName);var currentValue = parseInt(textElement.textContent);currentValue += increment;if ( (currentValue <= max) && (currentValue >= min) ) {textElement.textContent = currentValue;isMore = (increment == Math.abs(increment));switch (textName) {case 'zombieText':var svgArray = zombies;var newSVG = (isMore ? newZombie() : svgArray[svgArray.length - 1]);break;case 'redneckText':var svgArray = rednecks;var newSVG = (isMore ? newRedneck() : svgArray[svgArray.length - 1]);break;case 'mallText':var svgArray = malls;var newSVG = (isMore ? newMall() : svgArray[svgArray.length - 1]);break;}if (isMore) {svgArray.push(newSVG);document.getElementById('cityBox').appendChild(newSVG);} else {document.getElementById('cityBox').removeChild(newSVG);svgArray.pop(svgArray.length - 1);}}}

最后,所有按钮都需要新的onmouseup调用。 找到以下每个路径,并替换现有的onmouseup调用或添加新的。 这些对tickSVG的调用包括对在较早步骤中创建的<text>元素的引用,以及一些任意的max和min值(购物中心除外),这些购物中心设计为最多四个。

<path id="zombieLess" d="M 50 50 l 50 -25 l 0 50 l -50 -25" stroke="black" stroke-width="1" fill="red" onmouseup="tickSVG('zombieText',-100,0,3000);" /><path id="zombieMore" d="M 300 50 l -50 -25 l 0 50 l 50 -25" stroke="black" stroke-width="1" fill="red" onmouseup="tickSVG('zombieText',100,0,3000);" /><path id="mallLess" d="M 50 150 l 50 -25 l 0 50 l -50 -25" stroke="black" stroke-width="1" fill="red" onmouseup="tickSVG('mallText',-1,0,4);" /><path id="mallMore" d="M 300 150 l -50 -25 l 0 50 l 50 -25" stroke="black" stroke-width="1" fill="red" onmouseup="tickSVG('mallText',1,0,4);" /><path id="redneckLess" d="M 50 250 l 50 -25 l 0 50 l -50 -25" stroke="black" stroke-width="1" fill="red" onmouseup="tickSVG('redneckText',-1,0,10);" /><path id="redneckMore" d="M 300 250 l -50 -25 l 0 50 l 50 -25" stroke="black" stroke-width="1" fill="red" onmouseup="tickSVG('redneckText',1,0,10);" />

完整修订的代码在本演练的末尾链接。 如果工作正常,页面应该类似于图4。

图4.完全实现的控制面板,又称启示录

赔率是多少?

僵尸启示录生存预测器需要再完成一件。 赔率计算器需要移动。 至少,它需要一些DOM操作JavaScript来更新顶部和箭头位置的0%。 但是对于兼容的浏览器,JavaScript可以使箭头沿着动态生成的路径移动,从而可以向本系列第2部分介绍的一种动画技术中添加一些特殊的调味料。

但是首先,要进行一些计算。 在<script>部分的顶部添加一个名为currentOdds的新全局变量,并将其设置为0:

<script>var zombies = new Array();var malls = new Array();var rednecks = new Array();var currentOdds = 0;…

接下来,创建一个名为calcOdds的新函数。 在使用严格的方法进行了详尽的研究之后,精心制作了以下公式来预测僵尸启示录中的生存情况:

function calcOdds() {var zombieCount = parseInt(document.getElementById('zombieText').textContent);if (zombieCount == 0) {currentOdds = 100;} else {var redneckCount = parseInt(document.getElementById('redneckText').textContent);var mallCount = parseInt(document.getElementById('mallText').textContent);var speed = document.getElementById('speedText').textContent;var threat = Math.round((zombieCount * (speed == 'Slow' ? 2 : 18)) / 180);var protection = Math.round(((mallCount * 10) + (redneckCount * 5)) / 60 * 100);currentOdds = Math.round((100 + protection - threat) / 2);}if (currentOdds > 100) currentOdds = 100;if (currentOdds < 0) currentOdds = 0;}

请注意,与本演练开始时的<text>元素一样,可以通过访问其textContent属性来访问该元素的文本值。 除此之外,DOM看起来与HTML相同。 要测试计算,请找到ID为“ oddsButton”的组(<g>)元素。 如第1部分所述,按钮由两个不同的元素组成,即<rect>和<text>元素。 幸运的是,通过将它们分组,parent <g>元素允许将样式和鼠标事件与整个按钮相关联。 现在,暂时添加一个onmouseup事件以测试calcOdds:

<g id="oddsButton" style="cursor: pointer;" onmouseup="calcOdds(); alert(currentOdds);">

如果这可行,那就是下一步了:移动指针。 创建一个名为movePointer的新函数:

function movePointer() {calcOdds();document.getElementById('oddsText').textContent = currentOdds + '%';var newY = -2 * currentOdds; //relative Y coordinatenewY += 300; //actual Y coordinatedocument.getElementById('oddsPointer').setAttribute('points',"150," + newY + " 100," + (newY - 25) + " 100," + (newY + 25));}

是的,newY的计算可以一步完成。 它被拆分是有原因的,很快就会揭晓。 值得注意的是最后一行,即setAttribute函数。 请记住,oddsPointer是作为<polygon>元素创建的,该元素通过使用绝对坐标定义“点”属性来工作。 与大多数其他属性一样,可以通过DOM来获取点,方法是:抓住元素并使用setAttribute,然后指定哪个属性(“点”)和新值。 在这种情况下,新值是由三对坐标组成的文本字符串。 在此示例中,指针被硬编码为50×50空间中的右指向三角形。 其中心的Y坐标范围可以从仪表底部的300到顶部的100,分别对应于0到100的几率。 在此处分解的公式“ newY = 300 –(2 * currentOdds)”应将三角形的右尖精确地沿着该系列的第2部分中创建的标记所标记的比例放置。

要观看它的运行情况,请使用对新函数的调用来替换oddsButton onmouseup事件:

<g id="oddsButton" style="cursor: pointer;" onmouseup="movePointer();">

在城市中填充一些僵尸,大型购物中心和乡巴佬,甚至可以切换到快速僵尸,然后单击“计算赔率”。 指针应跳至对末日生存的极其准确的预测,如图5所示。

图5.成品:挽救生命的工具

额外功能:动态路径动画

因为本演练的重点是JavaScript和DOM,所以这是向指针移动添加一些动画的另一个好技巧。 如第2部分中所述,可以通过在SVG元素中添加<animateMotion>元素,然后引用路径来对SVG进行动画处理(在兼容的浏览器中)。

更进一步,JavaScript可以动态更改该路径的坐标,从而可以随时随地移动屏幕上的任何元素。

要使单词生效,请找到oddsPointer多边形。 需要进行两项更改。 首先,定义一个ID为“ oddsPath”的简单路径。 然后在<animateMotion>元素内引用该路径,该元素本身嵌套在oddsPointer中。 请注意,<polygon>元素正从自动关闭变为冗长,因此请务必仔细检查语法。

<g id="oddsMeter" stroke="#000000" stroke-width="2"><path d="M100 100 h75 m-75 100 h75 m-75 100 h75" stroke-width="3" /><path d="M100 150 h50 m-50 100 h50" /><path id="oddsPath" d="M 0 0 L 0 -200" /><polygon id="oddsPointer" points="150,300 100,275 100,325" fill="#FF0000" stroke-width="1"><animateMotion dur="2s" begin="oddsButton.click"><mpath xlink:href="#oddsPath" /></animateMotion></polygon><rect x="90" y="75" rx="15" ry="10" width="20" height="250" fill="#0000FF" /></g>

此处的陷阱与<path>元素一起使用。 请记住,动画路径并不定义实际坐标,而是动画的相对运动。 如果要在屏幕上绘制此<path>,它将从画布的左上角开始并一直向上。 但是,它告诉指针要做的是从其当前位置(M 0 0)开始,然后从该位置开始向上200px(L 0 -200)。

请注意,如“ begin”属性中所设置的,动画被设置为在单击oddsButton时开始。 但是,如果要立即单击该按钮,则指针将跳到其正确位置,然后向上浮动。 与以前的动画示例不同,这里需要区分能够识别和不识别SVG动画的浏览器。 通常,最好使用document.implementation.hasFeature来检查浏览器中的功能实现。 在这种情况下,要查找的功能是SVG 1.1规范中的“动画”。 添加一个名为supportsAnimation()的函数:

function supportsAnimation() {return document.implementation.hasFeature("", "1.1");}

这是可以在。

接下来,再添加一个全局变量,该全局变量将跟踪路径的“ L”值,以使指针始终从先前中断的位置开始,而不是重置为其原始位置。

<script>var zombies = new Array();var malls = new Array();var rednecks = new Array();var currentOdds = 0;var previousL = 0;

鉴于先前对动画路径如何工作的描述,这可能会有些混乱。 但是请记住,JavaScript将更改<path>的属性,而不是<polygon>的属性。 并且移动也不会更改<polygon>的points属性,因此使用此方法,这些点将保持不变。 因此,如果<path>始终从M 0 0开始,则<polygon>始终会在移动之前返回到该坐标,从而在动画之前造成难看的跳转。 因此,必须每次更改路径的“ M”值,以使运动保持相对状态。

返回到movePointer函数并添加嗅探器。 现在,混乱的“ newY”的奥秘变得清晰了。 根据浏览器的功能,将在动画开始前及时更改动画路径的“ d”属性,或设置多边形的points属性:

function movePointer() {calcOdds();document.getElementById('oddsText').textContent = currentOdds + '%';var newY = -2 * currentOdds; //relative Y coordinateif (supportsAnimation()) {document.getElementById('oddsPath').setAttribute('d','M 0 ' + previousL + ' L 0 ' + newY);previousL = newY;} else {newY += 300; //actual Y coordinatedocument.getElementById('oddsPointer').setAttribute('points',"150," + newY + " 100," + (newY - 25) + " 100," + (newY + 25));}}

这样,这个僵尸启示录生存预测器就完成了! 立即在.htm上尝试一下,或者查看页面的源代码以获取本演练的最终版本。 可以在.zip中找到此页面上使用的所有资产(由 )。

包起来

虽然幸存的僵尸启示的机会可能会有所不同,但被僵尸启示录的机会却很少。 但是正如CDC所知( .htm ),准备僵尸的公司也为许多其他事情做好了准备。 我希望这一系列演练可以说明如何将SVG用于视觉动态,可扩展的Web应用程序。

此处学习的技能可以用于许多其他应用程序。 就像为小行星做准备一样。

因为肯定会发生小行星启示。

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

From: /

更多推荐

生存僵尸启示录:动态SVG和路径动画

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

发布评论

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

>www.elefans.com

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