dlrandy / note-issues

2 stars 0 forks source link

Css Graph and Animation #41

Open dlrandy opened 6 years ago

dlrandy commented 6 years ago

canvas 默认的宽度是300高度是150

不要使用Css设置canvas的 size,因为canvas本质上是位图,由像素组成。在canvas标记上设置width和height属性的时候,指定的是位图的实际resolution。这时HTML将自动分配同等数量的空间。如果css设置,则指定的layout 的size,而不是实际的像素数量。这样位图就会被拉伸或者压缩来适应layout。

jQuery的style就是设置css的效果 使用canvas的context设置的也是实际的像素

在代码里设置width和height将会重置bitmap,用新的像素resolution创建一个新的位图同时清除之前canvas上创建的drawing。

在canvas上划路径的时候,一系列的事件是要从调用context.beginPath()开始。

Context有一个虚拟的cursor 位置的概念,会被锁定在上一次命令的结束位置。

fill方法会自动关闭路径

// context.quadraticCurveTo(p1.x, p1.y, p2.x, p2.y) virtual point -- control point --- end point context.bezierCurveTo(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y); virtual point -- control point -- control point -- end point

context.arc(300, 300, 100, 0, Math.PI * 2, true);//加了true就是要反向的一圈

For some reason; I was unable to get the canvas to look correctly on my retina screen without specifying the width, height attributes along with explicitly specifying the uniques in CSS as well--a convention I'm usually used to with my past experiences with Canvas.

I then do the following to get a non-cropped result: w/ Chrome and Safari:

if('devicePixelRatio' in window && context.webkitBackingStorePixelRatio < 2) { canvas.setAttribute('width', 600 devicePixelRatio) canvas.setAttribute('height', 600 devicePixelRatio) context.transform(devicePixelRatio,0,0,devicePixelRatio,0,0) }

dlrandy commented 6 years ago

2D的渲染环境是一个state machine。一旦context设置了特定的样式那么接下来的样式都是以这个进行绘画,直到添加了新的样式

改变stroke的宽度可以使用lineWidth;

stroke和fill的先后顺序很重要stroke的inner部分回合fill重叠

lineCap(butt,square【扩展一半的line width】, round):line结束的地方, lineJoin(miter【sharp Corner】, bevel【切掉交汇点】,round【圆角】):line交汇的地方

dlrandy commented 6 years ago

gradient = context.createLinearGradint() gradient.addColorStop() context.fillStyle = gradient; context.fillRect()

dlrandy commented 6 years ago

context.fillText('', x, y) context.strokeText

context.font font默认是black, 10-pixel, sans-serif。 context.textBaseline context.measureText

文本是定义在点的左下角的 context.textAlign default : left

dlrandy commented 6 years ago

除了矢量图形,还可以在canvas里画位图,还可以从canvas里获得位图

context.drawImage参数的个数可以是 3, 5, 9 drawImage(image, srcx, srcy, srcWidth, srcHeight, destX, destY, destWidth, destHeight) canvas.toDataURL('image/png')如果是jpg是可以压缩的 canvas.toDataURL('image/jpg', 0.7)

dlrandy commented 6 years ago

canvas里后画的内容会盖在之前的内容上 但是有一些方法可以改变这种方式

globalAlpha globalCompositeOperations globalShadows(shadowColor, shadowBlur, shdowOffsetX/Y) 上面的设置只会影响接下来绘画的内容不会影响之前的

canvas的默认坐标原点是左上角,向右向下是正方向,单位就是CSS像素;对于角度向右是正方向 canvas transformation可以改变默认的canvas坐标系统并运用更少的代码创建复杂的绘画

canvas的transform有三种方式: translate; scale:扩展或压缩系统,以至于canvas的一个单位多于或者小于一个css像素;可以接收负值,这将会翻转系统的坐标轴。 rotate;

这些操作像其他的操作那样影响的是以后绘画

context.save()保存状态 context.restore()恢复状态,可以多次save然后依次一个接一个的恢复

scale将会影响translte和已经画了的东西

imageData 是canvas来做像素级处理的对象

context.getImageData(x, y, width, height)

imageData有三个重要的属性width, height,data。 这里的data是像素颜色channel值的数组【r,g,b,a,r,g,b,a....】

获取元素的index: index=y width + x;(x,y从0开始算) 获取imageData的index: index = (y index + x) * 4

putImageData和正常的operation不一样的地方: NO blending, alpha, etc. No transforms while putting data Transparent areas of the image data become transparent areas in the canvas

ImageData 耗CPU 只能get或者put真正需要的一些数据

在canvas里处理事件和普通DOM一样,确定event位置需要用到getBoundingRect

dlrandy commented 6 years ago

change over time: position; size / scale; rotation; color/texture/stroke; opacity; overal shape;

使用setTimeout或者setInterval来模拟requestAnimaionFrame,会有丢帧问题

有时候觉得动画太快的话,可以使用setInterval然后在里面调用requestAnimationFrame

dlrandy commented 6 years ago

当元素在做translate的时候,hover是不起作用的

js提取颜色的随机值:'#'+Math.floor(Math.random() * 0xffffff).toString(16),然后判断一下长度是否为7,不足末尾加0。

js substing(index, index) substr(index, len)

HtmlElement.offsetParent指的是最近的包涵定位元素。如果元素没有定位那么就是最近的table table-cell 或者html。

offsetleft返回的是当前元素的左上角到offsetParent左边的距离

dlrandy commented 6 years ago

scrollLeft是指元素的内容向左滑动的像素 clientLeft是元素的左边界宽度,包括border,和vertical scrollbar的宽度,不包括padding和margin。这个市一个只读 的整数,需要精确的位置的话可以使用element.getBoundingClientRect().

获取一个元素的 准确位置的原理就是向外迭代当前的元素,每一个offsetParent的位置相加,宽度就是元素的offsetLeft-scrollLeft+clientLeft

dlrandy commented 6 years ago

event.clientX 是鼠标事件在app的client 区的位置

dlrandy commented 6 years ago

js移动元素的时候 尽量使用transform 拿到元素节点的时候直接访问width,样式的需要访问style

dlrandy commented 6 years ago

http://www.freetechbooks.com/topics

dlrandy commented 6 years ago

vertical-align 只有在table-cell上使用的时候,是让包含环境垂直居中的;当在一个line-box里设置inline box的时候,它是让当前的元素如何垂直对齐到文本。

垂直居中: vertical-align height===line-height(这个既可以对待单行也可以对待多行,注意的就是vertical-align/line-height相对的是linebox) position absolute(transform, marign); display: flex;

https://stackoverflow.com/questions/8865458/how-do-i-vertically-center-text-with-css https://coding.smashingmagazine.com/2013/08/absolute-horizontal-vertical-centering-css/

dlrandy commented 6 years ago

position:absolute是相对于包含块的padding box。当然fixed相对于普通元素的时候也是padding-box

text-align: justify是除了最后一行,其他都生效的。所以 使用的情况有些特殊 知道吧

dlrandy commented 6 years ago

css的cursor 小手是grab 抓住是grabbing