SVG 学习(二)--- 创建组合交互式应用
接着上一节的内容,本次学习主要介绍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 学习(二)--- 创建组合交互式应用的更多相关文章
- SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组
目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...
- pipelinewise 学习二 创建一个简单的pipeline
pipelinewise 提供了方便的创建简单pipeline的命令,可以简化pipeline 的创建,同时也可以帮我们学习 生成demo pipeline pipelinewise init --n ...
- sublime text 2学习(二):创建可复用的代码片段
对于前端工程师来讲,写一个html页面的基本结构是体力活,每次去拷贝一个也麻烦,sublime text 2 提供了一个很好的复用代码片段.下面介绍一下创建一个html5的代码片段的过程. 在菜单上点 ...
- micronaut 学习 二 创建一个简单的服务
micronaut 提供的cli 很方便,我们可以快速创建具有所需特性的应用,以下是一个简单的web server app 创建命令 mn create-app hello-world 效果 mn c ...
- SVG 学习<六> SVG的transform
目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...
- SVG 学习<四> 基础API
目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...
- SVG 学习<八> SVG的路径——path(2)贝塞尔曲线命令、光滑贝塞尔曲线命令
目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...
- SVG 学习<七> SVG的路径——path(1)直线命令、弧线命令
目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...
- SVG 学习<五> SVG动画
目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...
随机推荐
- 基于hadoop的电影推荐结果可视化
数据可视化 1.数据的分析与统计 使用sql语句进行查询,获取所有数据的概述,包括电影数.电影类别数.人数.职业种类.点评数等. 2.构建数据可视化框架 这里使用了前端框架Bootstrap进行前端的 ...
- 用CSS3制作很特别的波浪形菜单
原文:用CSS3制作很特别的波浪形菜单 网页菜单我们见过很多,各种炫酷的.实用的菜单比比皆是.昨天我看到一款很特别的CSS3菜单,它的外形是波浪形的,弯弯曲曲,结合背景,看上去还挺不错的,下面看下一效 ...
- Cordic 算法的原理介绍
cordic 算法知道正弦和余弦值,求反正切,即角度. 采用用不断的旋转求出对应的正弦余弦值,是一种近似求解发. 旋转的角度很讲求,每次旋转的角度必须使得 正切值近似等于 1/(2^N).旋转的目的是 ...
- Codeforces 448 D. Multiplication Table
二分法判断答案 D. Multiplication Table time limit per test 1 second memory limit per test 256 megabytes inp ...
- Php面向对象 – 继承和重写
Php面向对象 – 继承和重写 承受: php于,通过类.使用特殊的经营宗旨. 通过定义类,采用extends来表示当前的类对象继承该类的对象. 样例: class C { public $p_c ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(12)-实现用户异步登录和T4模板
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(12)-实现用户异步登录和T4模板 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框架搭建 ...
- OS和android游戏纹理优化和内存优化(cocos2d-x)
注:原文地址不详! 1.2d游戏最占内存的无疑是图片资源. 2.cocos2d-x不同平台读取纹理的机制不同. ios以下使用CGImage,android和windows下是直接调用png库.我測试 ...
- js获取网页的各种高度
原文:js获取网页的各种高度 网页可见区域宽: document.body.clientWidth网页可见区域高: document.body.clientHeight网页可见区域宽: documen ...
- 只有有lua编译能力不足200K代码吧?NO! Python 有可能。
如今Python给人的感觉是大,东西多,在Windows上安装后竟然要占100多兆的空间. lua给人的感觉是非常小,非常轻便.Python 2.7在linux下编译出来的代码在strip之后也有3M ...
- cocos2dx 3.0正式版 于mac在新建项目
下载cocos2dx 3.0正式版,和安装python2.7.*版本号. 加入cocos命令: mac下: 在cocos2d-x\tools\cocos2d-console\bin文件夹下.执行ins ...
鼠标移动到树或者影子的上面的时候出现十字光标,点击可以移除树或者影子
例子中我们看到,svg是可以通过dom操作元素,并添加事件处理函数的!这点比canvas在事件处理方面更灵活!
SVG的介绍大概先介绍这些,具体详细的API可以参考下面的地址:
https://developer.mozilla.org/zh-CN/docs/Web/SVG