接着上一节的内容,本次学习主要介绍SVG组合式应用以及js交互式应用!

1、组合式应用

绘制两棵带有投影效果的树!

<svg width="400" height="600">
<defs>
<pattern id="grap" patternUnits="userSpaceOnUse" x="0" y="0" width="100" height="67" viewBox="0 0 102 76">
<image x="0" y="0" width="102" height="76" xlink:href="http://pic27.nipic.com/20130324/9148618_153134223000_2.jpg"></image>
</pattern>
<linearGradient id="TrunkGrad">
<stop offset="0%" stop-color="#663300"></stop>
<stop offset="40%" stop-color="#996600"></stop>
<stop offset="100%" stop-color="#552200"></stop>
</linearGradient>
<rect x="-5" y="-50" width="10" height="50" id="Trunk"></rect>
<path d="M-25,-50L-10,-80L-20,-80L-5,-110L-15,-110L0,-140L15,-110L5,-110L20,-80L10,-80L25,-50Z" fill="#f00" id="can">
</path>
<linearGradient id="shadow" x=0 y=0 x2=0 y2=100%>
<stop offset="0%" stop-color="#000" stop-opacity=".5"></stop>
<stop offset="20%" stop-color="#996600" stop-opacity="0"></stop>
</linearGradient>
<g id="tree">
<use xlink:href="#Trunk" fill="url(#TrunkGrad)"/>
<use xlink:href="#Trunk" fill="url(#shadow)"/>
<use xlink:href="#can" fill="none" stroke="#663300" stroke-linejoin="round" stroke-width="4px" />
<use xlink:href="#can" fill="#339900" stroke="none"/>
</g>
<g id="treeShadow">
<use xlink:href="#Trunk" fill="#000"/>
<use xlink:href="#can" fill="#000" stroke="none"/>
</g>
</defs>
<text y=60 x=200 font-family="Arial" font-size="60px" fill="#996600" text-anchor="middle">tree</text>
<text y=90 x=200 font-family="Arial" font-size="20px" fill="#996600" text-anchor="middle" id="treeCounter"></text>
<text y=550 x=20 font-family="Arial" font-size="20px" fill="#996600" text-anchor="left">
<tspan>点击一颗树或树的影子</tspan>
<tspan>并移除掉它。。。</tspan>
</text>
<g transform="translate(-10,350)" stroke-width="20" stroke="url(#grap)" stroke-linejoin="round">
<path d="M0,0Q170,-50 260,-190Q310,-250 410,-250" fill="none">
</path>
</g>
<!--skewX() x轴方向向右扭曲25像素-->
<use xlink:href="#treeShadow" transform="translate(130,250) scale(1,.6) skewX(-25)" opacity="0.4" />
<use xlink:href="#tree" transform="translate(130,250)" />
<use xlink:href="#treeShadow" transform="translate(260,500) scale(2,1.2) skewX(-25)" opacity="0.4" />
<use xlink:href="#tree" transform="translate(260,500) scale(2)" />
</svg>

说明:

scale(1,.6) :缩放 x轴缩放1倍,y轴缩放0.6倍
skewX(-25) :扭曲 x轴水平方向扭曲-25像素
 <text y=550 x=20 font-family="Arial" font-size="20px" fill="#996600" text-anchor="left">
<tspan>点击一颗树或树的影子</tspan>
<tspan>并移除掉它。。。</tspan>
</text>

这里的tspan 类似于我们在页面中添加span标签,用于分割汉字

 <linearGradient id="shadow" x=0 y=0 x2=0 y2=100%>
<stop offset="0%" stop-color="#000" stop-opacity=".5"></stop>
<stop offset="20%" stop-color="#996600" stop-opacity="0"></stop>
</linearGradient>
stop-opacity=".5" :渐变的透明度设置
上诉代码运行结果如图

2、SVG交互式应用

我们希望自己可以点击按钮的时候生成一颗随机的树,位置控制在svg画板中,而且点击生成的树还可以移除掉它!

新树的尺寸控制在50% - 150% 之间进行随机缩放!

首先我们创建一个添加树的函数:

/*
document.createElementNS() 创建带有命名空间的的<use>元素
setAttributeNS() 方法创建或改变具有命名空间的属性。
语法:
elementNode.setAttributeNS(name,value)
*/
document.getElementById('btn').onclick = function(){
var x = Math.floor(Math.random()*400);//随机数x
var y = Math.floor(Math.random()*600);//随机数y
var scale = Math.random()+0.5;//生成随机缩放的比例
var translate = 'translate('+x+','+y+')';
var tree = document.createElementNS('http://www.w3.org/2000/svg','use');
var treeSd = document.createElementNS('http://www.w3.org/2000/svg','use');
treeSd.setAttributeNS('http://www.w3.org/1999/xlink','xlink:href','#treeShadow');
treeSd.setAttribute('transform',translate + ' scale('+ scale +','+ scale*0.6 +') skewX(-25)');
treeSd.setAttribute('opacity',0.4);
document.querySelector('svg').appendChild(treeSd);//添加到svg中
tree.setAttributeNS('http://www.w3.org/1999/xlink','xlink:href','#tree');
tree.setAttribute('transform',translate + ' scale('+ scale +')');
document.querySelector('svg').appendChild(tree);//添加到svg中
updateTrees();
}

接着我们创建一个更新树的数量的函数,以及给每棵树添加自己的移除的方法

function updateTrees(){
//查找所有的use元素
var list = document.querySelectorAll('use');
var treeCount = 0;
for(var i=0;i<list.length;i++){
//如果是树或者树的阴影
if(list[i].getAttribute('xlink:href') == '#tree' || list[i].getAttribute('xlink:href') == '#treeShadow'){
treeCount++;
//点击树或者阴影移除自己
list[i].onclick = removeTree;
}
}
//更新数量
var counter = document.getElementById('treeCon');
counter.innerHTML = parseInt(treeCount/2) + 'trees in the svg';
}

创建树的移除的函数

function removeTree(e){
//e.target 被点击的目标对象
var e = e.target;
/*
e.correspondingUserElement 意思大概是当使用的元素有嵌套的时候使用最外层的元素作为目标对象
具体说明可参考地址:
https://msdn.microsoft.com/en-us/library/ff971929(v=vs.85).aspx
*/
if(e.correspondingUserElement){
e = e.correspondingUserElement;
}
e.parentNode.removeChild(e);
updateTrees();
}

完整的例子如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>svg 交互测试</title>
</head>
<style>
svg{border:1px solid #000;}
use:nth-of-type(even):hover{
opacity:0.9;
cursor:crosshair;/*十字线光标*/
}
use:nth-of-type(odd):hover{
opacity:0.5;
cursor:crosshair;/*十字线光标*/
}
</style>
<body>
<div >
<button type="button" id="btn">点击按钮生成树</button>
</div>
<svg width="400" height="600">
<defs>
<pattern id="grap" patternUnits="userSpaceOnUse" x="0" y="0" width="100" height="67" viewBox="0 0 102 76">
<image x="0" y="0" width="102" height="76" xlink:href="http://pic27.nipic.com/20130324/9148618_153134223000_2.jpg"></image>
</pattern>
<linearGradient id="TrunkGrad">
<stop offset="0%" stop-color="#663300"></stop>
<stop offset="40%" stop-color="#996600"></stop>
<stop offset="100%" stop-color="#552200"></stop>
</linearGradient>
<rect x="-5" y="-50" width="10" height="50" id="Trunk"></rect>
<path d="M-25,-50L-10,-80L-20,-80L-5,-110L-15,-110L0,-140L15,-110L5,-110L20,-80L10,-80L25,-50Z" fill="#f00" id="can">
</path>
<linearGradient id="shadow" x=0 y=0 x2=0 y2=100%>
<stop offset="0%" stop-color="#000" stop-opacity=".5"></stop>
<stop offset="20%" stop-color="#996600" stop-opacity="0"></stop>
</linearGradient>
<g id="tree">
<use xlink:href="#Trunk" fill="url(#TrunkGrad)"/>
<use xlink:href="#Trunk" fill="url(#shadow)"/>
<use xlink:href="#can" fill="none" stroke="#663300" stroke-linejoin="round" stroke-width="4px" />
<use xlink:href="#can" fill="#339900" stroke="none"/>
</g>
<g id="treeShadow">
<use xlink:href="#Trunk" fill="#000"/>
<use xlink:href="#can" fill="#000" stroke="none"/>
</g>
</defs>
<text y=60 x=200 font-family="Arial" font-size="60px" fill="#996600" text-anchor="middle">tree</text>
<text y=90 x=200 font-family="Arial" font-size="20px" fill="#996600" text-anchor="middle" id="treeCounter"></text>
<text y=550 x=20 font-family="Arial" font-size="20px" fill="#996600" text-anchor="left">
<tspan>点击一颗树或树的影子</tspan>
<tspan>并移除掉它。。。</tspan>
</text>
<g transform="translate(-10,350)" stroke-width="20" stroke="url(#grap)" stroke-linejoin="round">
<path d="M0,0Q170,-50 260,-190Q310,-250 410,-250" fill="none">
</path>
</g>
<!--skewX() x轴方向向右扭曲25像素-->
<use xlink:href="#treeShadow" transform="translate(130,250) scale(1,.6) skewX(-25)" opacity="0.4" />
<use xlink:href="#tree" transform="translate(130,250)" />
<use xlink:href="#treeShadow" transform="translate(260,500) scale(2,1.2) skewX(-25)" opacity="0.4" />
<use xlink:href="#tree" transform="translate(260,500) scale(2)" />
</svg>
<p id="treeCon"></p>
</body>
<script>
/*
document.createElementNS() 创建带有命名空间的的<use>元素
setAttributeNS() 方法创建或改变具有命名空间的属性。
语法:
elementNode.setAttributeNS(name,value)
*/
document.getElementById('btn').onclick = function(){
var x = Math.floor(Math.random()*400);//随机数x
var y = Math.floor(Math.random()*600);//随机数y
var scale = Math.random()+0.5;//生成随机缩放的比例
var translate = 'translate('+x+','+y+')';
var tree = document.createElementNS('http://www.w3.org/2000/svg','use');
var treeSd = document.createElementNS('http://www.w3.org/2000/svg','use');
treeSd.setAttributeNS('http://www.w3.org/1999/xlink','xlink:href','#treeShadow');
treeSd.setAttribute('transform',translate + ' scale('+ scale +','+ scale*0.6 +') skewX(-25)');
treeSd.setAttribute('opacity',0.4);
document.querySelector('svg').appendChild(treeSd);//添加到svg中
tree.setAttributeNS('http://www.w3.org/1999/xlink','xlink:href','#tree');
tree.setAttribute('transform',translate + ' scale('+ scale +')');
document.querySelector('svg').appendChild(tree);//添加到svg中
updateTrees();
}
function updateTrees(){
//查找所有的use元素
var list = document.querySelectorAll('use');
var treeCount = 0;
for(var i=0;i<list.length;i++){
//如果是树或者树的阴影
if(list[i].getAttribute('xlink:href') == '#tree' || list[i].getAttribute('xlink:href') == '#treeShadow'){
treeCount++;
//点击树或者阴影移除自己
list[i].onclick = removeTree;
}
}
//更新数量
var counter = document.getElementById('treeCon');
counter.innerHTML = parseInt(treeCount/2) + 'trees in the svg';
}
function removeTree(e){
//e.target 被点击的目标对象
var e = e.target;
/*
e.correspondingUserElement 意思大概是当使用的元素有嵌套的时候使用最外层的元素作为目标对象
具体说明可参考地址:
https://msdn.microsoft.com/en-us/library/ff971929(v=vs.85).aspx
*/
if(e.correspondingUserElement){
e = e.correspondingUserElement;
}
e.parentNode.removeChild(e);
updateTrees();
}
</script>

说明:

use:nth-of-type(even):hover{
opacity:0.9;
cursor:crosshair;/*十字线光标*/
}
use:nth-of-type(odd):hover{
opacity:0.5;
cursor:crosshair;/*十字线光标*/
}

这里是css3 新的选择方法

use:nth-of-type(even):选择奇数的use元素
use:nth-of-type(odd):选择偶数的use元素

当点击按钮的时候可以生成同样带有的投影效果的树,位置不一,大小不一!



鼠标移动到树或者影子的上面的时候出现十字光标,点击可以移除树或者影子

例子中我们看到,svg是可以通过dom操作元素,并添加事件处理函数的!这点比canvas在事件处理方面更灵活!

SVG的介绍大概先介绍这些,具体详细的API可以参考下面的地址:

https://developer.mozilla.org/zh-CN/docs/Web/SVG

SVG 学习(二)--- 创建组合交互式应用的更多相关文章

  1. SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

  2. pipelinewise 学习二 创建一个简单的pipeline

    pipelinewise 提供了方便的创建简单pipeline的命令,可以简化pipeline 的创建,同时也可以帮我们学习 生成demo pipeline pipelinewise init --n ...

  3. sublime text 2学习(二):创建可复用的代码片段

    对于前端工程师来讲,写一个html页面的基本结构是体力活,每次去拷贝一个也麻烦,sublime text 2 提供了一个很好的复用代码片段.下面介绍一下创建一个html5的代码片段的过程. 在菜单上点 ...

  4. micronaut 学习 二 创建一个简单的服务

    micronaut 提供的cli 很方便,我们可以快速创建具有所需特性的应用,以下是一个简单的web server app 创建命令 mn create-app hello-world 效果 mn c ...

  5. SVG 学习<六> SVG的transform

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

  6. SVG 学习<四> 基础API

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

  7. SVG 学习<八> SVG的路径——path(2)贝塞尔曲线命令、光滑贝塞尔曲线命令

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

  8. SVG 学习<七> SVG的路径——path(1)直线命令、弧线命令

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

  9. SVG 学习<五> SVG动画

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

随机推荐

  1. Node.js v0.10.31API手冊-事件

    Node.js v0.10.31API手冊-文件夹 Events(事件) Node里面的很多对象都会分发事件:一个net.Server对象会在每次有新连接时分发一个事件, 一个fs.readStrea ...

  2. hdu 3683 Gomoku (模拟、搜索)

    Gomoku Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  3. Linux内核进程管理

    介绍: 在Linux的内核的五大组成模块中,进程管理模块时很重要的一部分.它尽管不像内存管理.虚拟文件系统等模块那样复杂.也不像进程间通信模块那样条理化,但作为五大内核模块之中的一个,进程管理对我们理 ...

  4. OpenCV功能界面和示例

    OpenCV2.4.9 API Reference http://docs.opencv.org/modules/refman.html 版权声明:本文博客原创文章,博客,未经同意,不得转载.

  5. mybatis generator插件开发

    mybatis现在普遍使用的每一个人DAO框架.mybatis generator它可以基于数据库中的表结构,生成自己主动mybatis代码和配置文件,方便使用,当然,实际的使用过程中.generat ...

  6. SQL Server 服务器磁盘测试之SQLIO篇

    原文:SQL Server 服务器磁盘测试之SQLIO篇 数据库调优工作中,有一部分是需要排查IO问题的,例如IO的速度或者RAID级别无法响应高并发下的快速请求.最常见的就是查看磁盘每次读写的响应速 ...

  7. BMP图片转换为JPEG图片

    原文:BMP图片转换为JPEG图片 昨天在家学习,发现很多人把BMP图片转换为其它图片格式,有些人写得简单,有些人写得复杂. Insus.NET在想,一直在做文件上传,下载,或是图片剪切,都有进行过文 ...

  8. SqlServer发送邮件,定时作业

    今天偶然研究了一下sqlserver发送邮件的功能,之前听说过可以发,但是一直没尝试过,只是用C#写后台程序的方式来发邮件. 现在又多了一种发送邮件的途径. 大致的步骤如下: 1.配置sqlserve ...

  9. AngularJS html5Mode 使用 SVG Marker失效

    接上一篇文章: 问题: 解决了html5Mode的路由问题之后,今天突然发现一个奇怪的问题:项目中使用SVG所画的箭头全都不见了?反复测试之后发现Chrome和Firefox有问题,而IE却可以显示, ...

  10. jQuery中的.height()、.innerHeight()和.outerHeight()

    jQuery中的.height()..innerHeight()和.outerHeight()和W3C的盒模型相关的几个获取元素尺寸的方法.对应的宽度获取方法分别为.width()..innerWid ...