我如何使用HTML5和SVG构建 4个孩子的Windows 商店

分享于 

19分钟阅读

Web开发

  繁體

在10天内开发 Windows 8应用程序。

油漆 4孩子是一个 Windows 商店应用,专门为孩子设计的。 用于着色和绘图的简单应用。 你可以从 Windows 商店网站直接读取消费者的特性,在那里你也可以看到一些屏幕截图。 对于本文,你可以简单地想到有几个绘图的应用程序,你可以与它们交互。

从技术的角度来看,它完全是使用标准的web技术构建的,比如 HTML。CSS。JavaScript和 SVG。 在这里考虑一个重要方面: 使用 Windows 8,我们编写一个应用程序重用我们的web技能,我们为 IE 10呈现引擎开发。 所以我们不必测试和支持所有不同的浏览器版本,而且不必使用polyfills来模拟旧的API。 我们可以使用最好的web平台,在JavaScript中直接使用 Windows 8的特定 API。

本文将讨论可以伸缩向量图形( SVG ) 在绘画 4小孩中的应用,从项目的一些需求开始。 我希望这些注意事项也能应用到你的应用中。

需求和为什么使用 SVG

Windows 商店应用程序在你可以分发和销售应用程序以及应用程序可以运行的设备上提供了很好的机会。 认为你的应用可以在不同屏幕大小。不同屏幕分辨率和像素密度的设备上使用,这是。 项目必须考虑并通过本文对如何将应用程序扩展到不同屏幕以及如何使用 Windows 模拟器测试应用程序提供了非常好的技术理解。

要求之一是,我们希望在不同分辨率的情况下,为单个绘图提供的。 我们最终使用了 SVG,它是二维图形的矢量图像格式。 我们的方法是以特定分辨率 2560 x1440创建图形,稍后查看细节,缩小到当前用户的分辨率。 另一个优点是,在SVG中用颜色填充路径非常简单快捷,这是应用程序的主要特点之一。 当用户点击屏幕时,截取图形的相应部分并用特定的颜色填充路径是很简单的。

我们需要用在XAML中重用一些图形并拥有良好的工具支持,这样我们就可以简单快捷的方式创建和添加新的绘图。 Inkscape适合这个目的。 你可以导入XAML绘图并将它的导出到SVG文件,并且由于两个基于are的格式非常相似。

使用SVG的一个缺点是,DOM操作会随着对DOM数量的增加而变慢,因这里常常需要一些性能测试和优化。 你可以使用 table vs 画布从这个 IE 博客中读取一个好的,以帮助决定何时使用画布。 another Paint孩子'requirement requirement requirement用户可以节省他的绘图。 不幸的是,在编写时不可以能从SVG文件创建图像,因这里最终将SVG文件转换成画布对象。

另一种方法是使用画布而不是 SVG。 你必须在不同的分辨率下创建不同的原始想法,至少如果你希望画面在不同的分辨率下。 另一个注意事项是如何填充图形中的形状。 当你使用与触摸点有关的画布时,你只是处理原始图像,而不是 rectangle。 如果要感觉由 black 颜色线边界,则必须实现洪水填充( 或者种子填充) 算法,以完成目标,如果填充区域为 big,则填充效果将非常明显,而使用SVG的填充效果是相当大的。

将图形调整为不同的形状因素: viewport和 viewBox

如前所述,从 Windows 存储的一个文件开始,我们用 2560 x 1440的像素来启动SVG图形,每个图形动态加载到DOM存储应用程序中的DOM中。 为了方便,你可以使用这个特定的值,你也可以开始修复其它的。 在绘画 4 Kids我们需要使用一个绘图,让它在不同的分辨率下缩放。 查看在不同分辨率的Windows 模拟器中运行的同一图形的下列图像。

在 10-inch 显示器分辨率为 1024 x 像素的情况下,采用 27-inch 显示器模拟显示器,并在显示器的分辨率上进行第二个显示器。

这种固定分辨率为我们提供了一种虚拟空间坐标。 在SVG中,我们可以使用 viewBox 属性来设置这个坐标系。 如果使用这里坐标系绘制工具,则所有图形元素相对于这里坐标系而言都是相对应的。 下面的示例演示如何将( 或者向上) 从该分辨率扩展到特定的分辨率。例如你只需要设置包含图形的SVG元素的widthheight 属性。 最后两个属性定义了SVG的viewport,这是在这个场景中我们的设备的实际分辨率。

viewBox 包含四个数字,表示要在视口中映射和缩放的坐标系的最小 x -coordinate -coordinate width。 因此,结合 viewBox,宽度和高度属性,我们得到了预期的结果。

下面是每个绘图的root SVG元素,一个简单的XML文件。 坐标系从顶部。左上角或者屏幕开始,如果你已经使用 SVG,则可能会预期。

<svg viewbox="0 0 2560 1440">...

当用户选择图形时将图形加载到DOM中时,我们可以设置 viewport 属性。

要找到未命名的SVG元素的root,我们使用 document.querySelector API,使用伪类选择器查找第一个SVG元素。 因为这个API只被调用一次,当用户选择要绘制的元素时,我们可以忽略任何性能延迟。

var svgd;
svgd = document.querySelector("svg:first-of-type");
svgd.setAttribute("width", window.innerWidth);
svgd.setAttribute("height", window.innerHeight);

代码示例还使用窗口对象及其属性inner*在运行时以像素为单位获取实际分辨率。

在处理 viewportviewBox 时,另一个考虑因素是。 如果两个坐标系的宽度和高度不同,有时你希望得到的图像不一致。 在其他场景中,你可能希望保留纵横比并均匀缩放图像。 SVG使用 preserveAspectRatio 属性来决定图像是否必须统一缩放。 我们将在讨论"邮票"时讨论这个问题。 对于图形,将 viewBox 统一缩放以适合viewport的默认行为就像我们所希望的那样。

如何使用颜色和图像填充路径

如果你想让你的代码在CSS中显示,那么你就不需要编写代码了,因为它就像在CSS中设置一个收费的样式属性。 你可以看到代码 below,它是当事件被触发 inside 区域时的调用返回函数。

var el = document.elementFromPoint(e.x, e.y);var selectedColor = "255,0,0,1";
el.setAttribute("style", "fill:rgba(" + selectedColor + "); stroke-width:3;);

在代码 上面 中,eMSPointerEvent 类型的对象。 这里对象非常重要,如果订阅了一些 MSPointer* 事件( 像 MSPointerDown ),则可以获得这里对象。 只要一行代码,你就可以订阅来自鼠标。触摸甚至是笔的事件 ! 同样,如果需要,还可以读取可以为你提供用于生成事件的设备的详细信息的pointerType 属性。 如果你对这个话题感兴趣,你可以在 IE 10和 Windows 商店应用的api上阅读这个博客帖子。

回到代码,这里的e 对象仅用于从输入设备获取x。y 点坐标,使用 elementFromPoint API。 el现在是我们想要填充的特定形状,它是 SVGPathElement 类型。 剩下的代码很简单,设置填充颜色和 SVGPathElement的线条宽度,不管实际的形状是什么。

你可以直接为设置填充和 strokeWidth 属性,而不必在中直接设置 fill,即使在这个场景中用户也不会感觉到这个。

颜色是用户可以从颜色调色板中选择的标准实体,但也可以用来自图像的路径填充。 绘制 4孩子不仅定义一组常见颜色,而且像石头,grass 等等 这样的图像,你可以在SVG中定义一些收费模式,如下面代码所示:

<patternid="imgPatterns_1"patternUnits="userSpaceOnUse"width="128"height="128"><imagexlink:href="../images/BRICK.PNG"width="128"height="128"/></pattern>

两个认为在代码中注意: 首先,我们定义了一个 SVGPatternElement,它基于包含在。 其次,定义定义如何使用 Pattern 本身填充形状的patternUnits 属性。 userSpaceOnuse 简单地重复了图像多次,但它们之间没有 padding。 定义 Pattern 后,可以使用下面的语法在使用的填充属性中使用 上面:

var selectedColor = "url(#imgPatterns_1)";
el.setAttribute("style", "fill:" + selectedColor + "; stroke-width:3;);

查看代码,可以注意到填充属性现在是使用上面定义的Pattern 元素的id ( 前面是 # 符号( 比如 )的url。 #imgPattern_1 )。

查看图像 below,以便在使用中看到一些 Pattern 效果。

为stamps标记Reusing重用SVG元素"

绘画 4孩子也可以将一些形状插入到绘图中,作为可以附加到绘图中的邮票。 对于用户来说,印章是一个像南瓜的形状,他们可以在任何地方定义形状。

从SVG角度来看,每个形状都可以复杂,因这里插入同样的形状会使DOM更大更大。 在这里优化这个场景是非常关键的。

为了实现这个特性,我们在SVG中使用了一个符号和一个使用元素的组合。 符号元素提供了对group元素的方法,但是当符号元素添加到页面的DOM时,它不会显示,因此你可以将它用作你可以使用的的something。 因此,我们可以一次性插入一个复杂的SVG形状,并使用use关键字多次重用它。 在下面的示例中,你将看到一些SVG代码。

<symbolid="bottiglia"viewBox="0 0 40 40"preserveAspectRatio="xMinYMin meet"><path...></symbol><useid="onlyforimg"xlink:href="#bottiglia"height="80"width="80"></use>

为了简短起见,省略了路径- 包含实际形状的path包含实际形状is在最初绘制图形时定义图形的尺寸。 我们可以根据下面的use调整use的大小和宽度,这是必要的,我们在这里设置了原来的大小。上面。 use元素具有对符号元素的id属性的引用,因为你可以轻松地从代码 上面 中注意到。 这里外,使用非常小和感谢,我们可以多次重复使用,最终改变图形大小,减少大小。

在实际应用中,使用元素不仅在JavaScript中设置了宽度和高度,而且用x 和y 坐标来定位屏幕。 为了做这些数学- 这在这里没有解释- 需要设置这两个坐标。 如果要制作所有内容,我们需要使用meet属性来获得统一的缩放,以便在视口中完全包含,而不是在视口中进行贴图,同时设置对齐xMinviewBox的最小 xviewport的左角对齐,yMinviewBoxviewport的上边缘对齐。 你可以从这里的SVG规范中获得这些值的完整引用。

加载SVG文件

前面的部分讨论了关于最终可以直接运行到现代浏览器中的标准 SVG。 从现在开始,我们将混合一些 Windows 存储 api,用于构建特定于 Windows 8平台的Windows 存储应用程序。

在绘制 4个图形时,由于需要,在需要时,单个图形会异步加载到 appx 文件,然后放入页面的DOM。 异步加载是使用 Windows 8加载异步API完成的,如代码中所示。 一个 Windows 存储应用程序阻止我们将动态代码加载到DOM中,这是因为通常这个代码是由外部调用。 但是,我们加载的代码是可信的,因为它已经在 appx 文件中,并由我们提供。 你可以安全地调用 WinJS.Utilities.setInnerHTMLUnsafe 函数,以便在需要时将图形加载到DOM中。

svgfolder.getFileAsync("drawing.svg").then(function (file) {
 file.openAsync(Windows.Storage.FileAccessMode.read).then(function (stream) {
 inputStream = stream.getInputStreamAt(0);
 reader = new Windows.Storage.Streams.DataReader(inputStream);
 size = stream.size;
 reader.loadAsync(size).then(function () {
 svg = reader.readString(size);
 WinJS.Utilities.setInnerHTMLUnsafe(document.getElementById("s1"), svg);
 });
 });
});

svgFolderStorageFolder 类型的对象,可以调用 async 方法搜索 storageFile 对象- 这里省略了一个流和 dataReader 对象。 最后,SVG变量包含一个表示整个SVG绘图的字符串。 如 上面 所述,我们可以调用 setInnerHTMLUnsafe 来将图形添加到 s1 DOM元素。

很好的是,SVG可以在 Visual Studio 2012中检查到DOM浏览器,如显示 below:

可以从运行时选择一个特定的形状- 它也可以在运行时显示关联的SVG。 非常酷的东西 !

将SVG绘图转换为画布并保存到图像

如果需要将图形保存到文件系统或者要使用 Windows 8共享的它的他部分,则需要图形。 为此,我们使用canvg库将SVG文件转换为画布对象。 根据SVG文件大小和硬件平台,转换可能需要一些时间,这样可以通知用户,在转换开始时,有一个进度环,显示了一个进度环。

现在你可以获得对整个字节 array的引用,然后可以使用 Windows 编码API获得所需的格式和大小。 below 一个示例函数:

function doSaveDrawingToFileEnd (fil) {
 var Imaging = Windows.Graphics.Imaging;
 var stream, encoderId, cc, offset, outputPixelData;
 fil.openAsync(Windows.Storage.FileAccessMode.readWrite).then(function (_stream){
 stream = _stream;
 return Imaging.BitmapEncoder.createAsync(jpegEncoderId, stream);
 }).then(function (encoder) {
 cc = document.getElementById('canvas');
 //ignore the realBRectHeight variable below//it is not important to understanding the logic offset = (height - realBRectHeight)/2;
 outputPixelData = cc.getContext("2d").getImageData(0, offset, cc.width,cc.height - offset);
 encoder.setPixelData(Imaging.BitmapPixelFormat.rgba8, Imaging.BitmapAlphaMode.straight, width, realBRectHeight, 90, 90, outputPixelData.data);
 return encoder.flushAsync();
 }).then(null, function (error) {
 console.log(error.message);
 }).then(function () {
 if (stream) stream.close();
 })
}

首先,得到对 storageFile 对象- 未概述为代码- fil 变量的引用,这将成为最后一个jpeg图像,它将为你的所需图像编码字节 array,而不是打开流。 cc变量是对画布对象的引用,该对象包含已经转换的SVG文件。 使用标准的getImageData 方法,我们可以在代码中看到一个偏移值。 在编码器中使用 setPixelData API可以设置要生成的图像值,图像实际上在调用 flushAsync 时生成。

结束语

在本文中,我们已经看到了SVG的一些技术考虑以及如何使用它来绘制 4个小孩。 SVG是一个非常有趣且强大的web技术,你可以利用它来构建令人惊讶的Windows 存储应用程序。 你也可以在浏览器中直接用SVG对进行收费,在 IE 测试驱动站点中搜索一些收费的。 我希望这有助于你有类似的情况。

如果你想了解如何构建 Windows 商店应用程序,请查看Generation应用程序

这篇文章是由 Pietro Brambati写的。 Pietro是一个狂热的开发者。 他喜欢使用不同种类的语言和框架,在不同规模的应用程序上工作,从移动设备应用程序扩展到大型的enterprise-。 他一直与微软合作,在那里他有机会与开发者和学术社区合作。 你可以在主要的开发者事件和hackathon周围或者他的博客或者 Twitter 上找到他。


Window  Windows  Html5  Store  SVG  Paint