Archive for the ‘Informatics’ Category

[Rails 3]Cropping images use paperclip and jcrop

在railscast看到用paperclip跟Jcrop(一个jquery的一个插件)来实现图片裁剪功能,看起来很简单 就顺便用在现在做的项目里面了。 结果杯具的花了一天多的时间来弄。

在上一篇

[/rails]

paperclip works on windows 中记录了怎么给一个model加avatar

100×100# VS 100×100>

在model中我们加入了一下的代码

has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }

注意这里的在维度后面加了一个大于号,当时不是很理解。 google也没有找到答案,今天又仔细研究了一下, 100*100>的话呢,>是指按比例缩放的情况下最长边等于100. #就不是按比例缩放了, 如果是 100×100# 最后的图就是拉伸到100×100,不论之前的比例。

首先 在model里面把上面这句改成下面一句

has_attached_file :avatar, :style {:medium=>"150x150#", :large=>"500x500>"}

我们在页面上显示用户的头像是150*150的。
因为用户上传的图片的大小必然是各种各样的,所以我们这里先把用户给的图片变化成我们已知的大小, 这里的large style接下来就会用来被裁剪的图片。

Action

我们要实现的是, 当用户upload一个图片时转到一个叫crop的页面去进行裁剪。
所以需要修改controller里面的action,下面这段代码直接从railscast里面偷过来的。

def create
    @user = User.new(params[:user])
    if @user.save
      if params[:user][:avatar].blank?
        flash[:notice] = "Successfully created user."
        redirect_to @user
      else
        render :action => "crop"
      end
    else
      render :action => 'new'
    end
  end

  def update
    @user = User.find(params[:id])
    if @user.update_attributes(params[:user])
      if params[:user][:avatar].blank?
        flash[:notice] = "Successfully updated user."
        redirect_to @user
      else
        render :action => "crop"
      end
    else
      render :action => 'edit'
    end
  end

Jcrop选区

然后我们要新加一个crop的view,就是在upload一个图片后,跳转到用来图片剪裁的页面。 在这个页面中呢, 我们就要用到Jcrop这个plugin了,下载地址
把JavaScript,stylesheet一股脑都丢进这个文件里面, 当然为了保证Javascript在head里面呢,我们可以用 yield跟content_for 来做,请同学们自行动手尝试。(也可以到这里围观Ryan是怎么做的)

加入下列代码 依然是偷过来的,我自己的使用haml写的

    <% title "Crop Avatar" %>
    <% content_for (:head) do %>
    <%= stylesheet_link_tag "jquery.Jcrop" %>
    <%= javascript_include_tag "jquery.Jcrop.min" %>
    <script type="text/javascript">
     $(function() {
        $('#cropbox').Jcrop();
      });
    </script>
   <% end %>

  <%= image_tag @user.avatar.url(:large), :id => "cropbox" %>

通知paperclip选区范围

显然这只实现了一个在图片中选中一个区域的步骤,我们需要告诉paperclip我们选择了哪个区域。
回到model里 加入下面的代码

attr_accessor:crop_x, :crop_y, :crop_w,:crop_h

什么是attr_accessor, 字面上来看呢 就是attribute accessors,如果你熟悉java或者c++, whatever else. 这个就相当于getter跟setter的合体。
这里的四个值呢 分别是 crop_x 左上角的x坐标, crop_y 左上角的y坐标, crop_w 所选框的width,同理crop_h 所选框的height.

怎么把这些值传递给paperclip让它知道呢,首先想到的是要弄一个表单,为了不让这些值显示给亲爱的用户,所以我们使用hidden input.

继续偷代码

 <% form_for @user do |form| %>
    <% for attribute in [:crop_x, :crop_y, :crop_w, :crop_h] %>
      <%= form.text_field attribute, :id => attribute %>
     <% end %>
     <p><%= form.submit "Crop" %></p>
  <% end %>

这时候我们在Jcrop的调用中也要加一些配置了

$(function() {
  $('#cropbox').Jcrop({
    onChange: update_crop,
    onSelect: update_crop,
    setSelect: [0, 0, 500, 500],
    aspectRatio: 1
  });
});

function update_crop(coords) {
   $('#crop_x').val(coords.x);
   $('#crop_y').val(coords.y);
   $('#crop_w').val(coords.w);
   $('#crop_h').val(coords.h);
   }

这里update_crop的方法呢就是用来更新选区。通过表单提交给model,这时候呢我们要通知model 我们需要来进行crop
在model中加入以下偷来的代码

 after_update :reprocess_avatar, :if => :cropping?

   def cropping?
     !crop_x.blank? && !crop_y.blank? && !crop_w.blank? && !crop_h.blank?
   end

   private
   def reprocess_avatar
     avatar.reprocess!
   end

上面这段代码是说什么呢, 通过crop_x, crop_y, crop_w,crop_h来判定是否进行croping,如果进行cropping的话就通知paperclip再reprocess一下。
然后就是要告诉paperclip该如何处理?

Reprocess

安装railscast上讲的,我们需要有在lib文件夹下,新建一个paperclip_processors的文件夹, 然后new以下新的文件cropper.rb 内容如下

module Paperclip
  class Cropper < Thumbnail
    def transformation_command
      if crop_command
        crop_command + super.sub(/ -crop \S+/, '')
      else
        super
      end
    end

    def crop_command
      target = @attachment.instance
      if target.cropping?
        " -crop '#{target.crop_w}x#{target.crop_h}+#{target.crop_x}+#{target.crop_y}'"
      end
    end
  end
end

这时候测试一下, 错误如下
uninitialized constant Paperclip::Cropper
检查一下,好像是因为lib文件夹下面的文件并没有自动载入, 一google才知道 rails3 取消了对lib文件的autoload. 既然不能自动我们就手动呗。到model文件里面加入下面两句

require 'lib/paperclip_processors/cropper.rb'
include Paperclip

再次运行,新的错误又来了,
undefined method `sub’ for ["-resize", "x170", "-crop", "170x170+9+0", "+repage"]:Array

看了railscast下面的comment,有人也有同样的问题,原因是新版本的paperclip改变了他处理命令的方式,这里有人给出了解决方式
在cropper文件里面分别替换成下面两行

crop_command + super.join(' ').sub(/ -crop \S+/, '').split(' ')
["-crop", "#{target.crop_w}x#{target.crop_h}+#{target.crop_x}+#{target.crop_y}"]

再运行下,理论上应该可以crop了。

校准

但是视乎裁剪的结果并不不准确,原因是我们用large style的图片来做选区,但其实是在original的图上裁剪的,所以我们需要在中间做一个转换。
我们需要知道original跟large的width跟height。在model里面再加入下面的代码

def avatar_geometry(style= :o riginal)
    @geometry ||= {}
    @geometry[style] ||= Paperclip::Geometry.from_file(avatar.path(style))
 end

把update_crop文件更新为下面这样

function update_crop(coords) {
 var ratio = <%= @user.avatar_geometry(:original).width %> / <%= @user.avatar_geometry(:large).width %>;
  $("#crop_x").val(Math.round(coords.x * ratio));
  $("#crop_y").val(Math.round(coords.y * ratio));
  $("#crop_w").val(Math.round(coords.w * ratio));
  $("#crop_h").val(Math.round(coords.h * ratio));
}
</script>

现在再一运行 一切正常啦。

add a preview

但是这样用户体验不够好啊,那再加入一个预览的吧
view文件里面

<h4>Preview</h4>
  <div style="width: 100px; height: 100px; overflow: hidden;">
  <%= image_tag @user.avatar.url(:large), :id => "preview" %>
</div>

javascrip里面继续更新一下update_crop文件

function update_crop(coords) {
	var rx = 100/coords.w;
	var ry = 100/coords.h;
	$('#preview').css({
		width: Math.round(rx * <%= @user.avatar_geometry(:large).width %>) + 'px',
		height: Math.round(ry * <%= @user.avatar_geometry(:large).height %>) + 'px',
		marginLeft: '-' + Math.round(rx * coords.x) + 'px',
		marginTop: '-' + Math.round(ry * coords.y) + 'px'
	});
  var ratio = <%= @user.avatar_geometry(:original).width %> / <%= @user.avatar_geometry(:large).width %>;
  $("#crop_x").val(Math.round(coords.x * ratio));
  $("#crop_y").val(Math.round(coords.y * ratio));
  $("#crop_w").val(Math.round(coords.w * ratio));
  $("#crop_h").val(Math.round(coords.h * ratio));
}

一切搞定。

悲催的我在写cropping?的时候, 少写了一个感叹号给crop_h.blank? debug了好久才找到。希望以后不要再犯这样的错误

[rails] paperclip works on windows

需要实现一个avatar的功能

谷哥说paperclip

先在railscast上看了下Ryan的介绍, 对于功能基本满意。

1. 安装

Rails3用bundle来管理gem的dependencies。

在Gemfile里面加上如下代码

gem 'paperclip' 

然后命令行 bundle check, paperclip需要安装 再bundle install, 再check一下 现在所有的dependencies 都满足了

2. migration

这里假设我是要给user这个model加一个avatar
按照github上讲的http://github.com/thoughtbot/paperclip, 在model里面加上 下面这句

 has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }
rails g paperclip user avatar

这样生成了一个migration file,下面这段是自动生成滴

class AddAttachmentAvatarToUser< ActiveRecord::Migration
  def self.up
    add_column :users, :avatar_file_name, :string
    add_column :users, :avatar_content_type, :string
    add_column :users, :avatar_file_size, :integer
    add_column :users, :avatar_updated_at, :datetime
  end

  def self.down
    remove_column :users, :avatar_file_name
    remove_column :users, :avatar_content_type
    remove_column :users, :avatar_file_size
    remove_column :users, :avatar_updated_at
  end
end

好最后别忘了 rake db:migrate (我经常忘记 囧 ), 这样数据库就搞定啦。

3. controller

Controller 里面不需要做什么改动,因为这里的avatar跟其他的email之类的属性是一样的 所以update的时候都会update的, 就来看看view吧

4. views

首先要有一个form吧, 嗯在我们的form的partial里面加一句, 因为我这里用的是haml所以就没有”"

= form.file_field :avatar

还没有完 还要给form加一个html的option, :multipart => true。这样呢 就给form加了一个enctype=”multipart/form-data“, 完整的haml代码如下

= form_for(@user,:html=>{:multipart=>true}) do |f|
  .field
      =f.label :avatar
      =f.file_field :avatar
  .field
      =f.label :email
      = f.text_field :email
  .field
      =f.label :name
      = f.text_field :name
  .actions
    = f.submit

嗯 form有, 上传完了以后要show出来吧, 然后在show的里面加一句

=image_tag police.avatar.url(:medium)

5.ImageMagick

嗯 运行一下,理论上应该是不行的, 因为这里有个重要的东西我们没有安装。 ImageMagick. 这个才是我们今天讨论的重点, 在linux跟mac下这个不是大问题。但是windows总是让人头痛的。
下载地址:http://www.imagemagick.org/script/binary-releases.php#windows

选好适合自己的下载, 注意安装的时候加入环境变量,为了安全起见可以check一下是否成功加入了

这个时候你运行呢 很可能会得到一个 ”Error: [...] is not recognized by the ‘identify’ command“ 的错误。
为什么环境变量加入了还是不能识别呢, 在cmd里面运行下面的代码
1. 把model里面的styles去掉 测试一下, 如果成功上传 说明确实是paperclip跟ImageMagick之间的沟通出了问题。否则,请检查以上步骤是否正确完成了
2. 测试完以后,加上styles, 为什么要加上? 因为我们需要嘛,如果不需要这个不同大小的话这里就可以算成功了 请忽略后面的。 现在打开你的log,看看有[paperclip]的行是怎么说。copy那句话,我的是如下的

identify '-format' '%wx%h' 'C:/Users/danyi/AppData/Local/Temp/str
eam,4212,0.jpg[0]'  

在cmd中输入,报错
这个时候呢 根据报错发现需要”代替‘.输入下面的命令,再试一下

identify "-format" "%wx%h" "C:/Users/danyi/AppData/Local/Temp/str
eam,4212,0.jpg[0]"

视乎运行成功了, 嗯 问题也似乎找到了。如何解决呢,我在config/initializers里面加入了一个paperclip_patch.rb文件, 然后加入一下代码,overwirte原来的quote_command_options方法。

if RUBY_PLATFORM == 'i386-mingw32'
  module Paperclip
    def self.quote_command_options(*options)
      options.map do |option|
        option.split("\"").map{|m| "\"#{m}\"" }.join("\\\"")
      end
    end
  end
end

再测试。。搞定。。

6 最后

不在于这个问题是怎么解决的,而在于这个过程怎么去发现问题分析问题最后才是解决问题。

明天做image的 crop..

与HUST有关的三人三事

又是一年夏天 又是一个毕业季

根叔的寄语

如果看过了Ellen DeGeneres at Tulane’s 2009 Commencement Speech(youtube地址youku地址),一定会觉得国内的毕业典礼是相当的无趣。

而这一次根叔只是用我们平时说话的语言就让大家感动了。

浪费了太多的时间听了太多虚假的言语的我们,只是需要一些跟我们说真实的话。

请去掉官僚 让我们真实的对话 赞根叔

“母校 就是那个你一天骂她八遍却不许别人骂的地方。”

李行亮之快男

之前听过他在华工摇滚节上的演唱  Desperado确实惊艳

不记得跟谁一起去看的他的毕业个人演唱会,似乎是跟小猴子他们一起刷过去的。

去看了演唱会的人,定会被那样的情景打动。

一个人唱歌,一万个人在听。

朋友的伴奏,站台。

记得子时当时还弄了个女子第一band

跟一帮有共同梦想的人为了一个梦想而激情奋斗的夏天

之前说不要踏入娱乐圈的他 今年竟然参加了快男 而且一路高歌进入十二强

祝福他能实现音乐梦想

那年一起听演唱会的同学们 你们现在都在哪里呢?

谢谢 李行亮唤起的那年夏天的hust露天电影院的回忆

R.I.P 陈熙

周五晚上小明忽然在qq上跟我说 如果在国外不开心 就快回来吧

然后跟我讲了陈熙的事情 震惊 不敢相信

对于这个名字并不熟悉 虽然一起上过很多课

惋惜 是怎么样的绝望让他彻底离开的勇气

太理解在国外的孤单 朋友一个一个的送

还有找工作的艰辛与压力

此刻对胖子充满了钦佩 如何强大的内心 让他可以坚持在这边找工作找一年

但是熬过来就好了  everything is gonna be OK

傻孩子 希望你在天堂会快乐 没烦恼

这个事情以后对于心理健康方面思考了很多

工作以后 我们都变得越来越忙碌 但是请别忘了老朋友

保持联络 你的留言短信电话会温暖另一个人的世界

最后 积极生活 一切都会好起来的

Danyifeng.com 正式启用

昨天godaddy上0.99刀的offer 迅速强入一枚

danyi.codetea.co.uk 会直接转向danyifeng.com

Walle 早上没睡醒就被我拉起来当模特了。。可怜的孩子

散花hoho

欢迎交互链接 O(∩_∩)O

新浪专区之天下贰

12月初的时候,蚊子师父帮我接的网易的天下贰在新浪游戏专区的页面设计。 基本上市连熬三天。搞定了, 师父帮忙很多,也学到不少东西。

今天早上又被呼叫,有新单子。 于是乎去查了下新浪专区(http://games.sina.com.cn/o/z/tx2/),页面终于换成我的设计,只是只是怎么只改了一半。 品质差了很多。。上图

设计图:

Pure CSS Speech Bubbles

今天要来学的列是这个《Progressive enhancement: pure CSS speech bubbles。Demo页面在这里。Progressive enhancement渐进增强 在《sliding label》 中有提到。这个概念真是无所不在啊,一定要好好掌握。

图1

先看效果图,

图2

今天学习的方法呢,还是copy html+css源码来分析 看别人是怎么写代码 怎么实现的

HTML5 structure—header, hgroup & h1-h6

在.container 这个div里面出现了 下面的代码

<header>
<hgroup>
<h1>Pure CSS speech bubbles</h1>
<h2>By <a href="http://nicolasgallagher.com">Nicolas Gallagher</a></h2>
</hgroup>
<p>The demo page for <a href="http://nicolasgallagher.com/progressive-enhancement-pure-css-speech-bubbles/">Progressive enhancement: pure <abbr>CSS</abbr> speech bubbles</a>.</p>
<p>For a detailed explanation <a href="bubbles.css">view the <abbr>CSS</abbr> file</a>. It is heavily commented.</p>
<p>All examples use simple, semantic <abbr>HTML</abbr>. No empty elements, no unnecessary extra elements, no JavaScript, no images (apart from that Twitter logo). Have a look at the source code.</p>
</header>

Div 里面出现了header tag, 还有HTML 5的新的元素, hgroup.

The header element represents a group of introductory or navigational aids.
Note A header element is intended to usually contain the section’s heading (an h1–h6 element or an hgroup element), but this is not required. The header element can also be used to wrap a section’s table of contents, a search form, or any relevant logos

header元素代表了一组介绍的和导航辅助信息。

注意这里的header元素通常想要用来做section的标题(1个h1-h6元素或者一个hgroup元素),但是这并不是必须的,header元素也可以包括section的目录,搜索表单,或者任何相关的logo。

(来自HTML5 (Author Edition)的解释)

hgroup 是一种header的特殊形式,必须包括切且只能包括一组(至少两个)h1-h6。这里有篇文章《HTML5 structure—header, hgroup & h1-h6》详细讲,应该怎么用header,hgroup和h1-h6来做文章的结构。

Drawing a bubble

先介绍下对应图一的画法

HTML 代码

<p class="triangle-isosceles">这是图一的例子</p>

Css的代码

/* Bubble with an isoceles triangle
------------------------------------------ */
.triangle-isosceles {
	position:relative;
	padding:15px;
	margin:1em 0 3em;
	color:#000;
	background:#f3961c; /* default background for browsers without gradient support */

	/* css3 */
	-moz-border-radius:10px;
	-webkit-border-radius:10px;
	border-radius:10px;
	/* NOTE: webkit gradient implementation is not as per spec */
	background:-webkit-gradient(linear, left top, left bottom, from(#f9d835), to(#f3961c));
	background:-moz-linear-gradient(top, #f9d835, #f3961c);
	background:-o-linear-gradient(top, #f9d835, #f3961c);
	background:linear-gradient(top, #f9d835, #f3961c);
}

/* creates triangle */
.triangle-isosceles:after {
	content:"\00a0";
	display:block; /* reduce the damage in FF3.0 */
	position:absolute;
	z-index:-1;
	bottom:-30px; /* value = - border-top-width - border-bottom-width */
	left:50px; /* controls horizontal position */
	width:0;
	height:0;
	border-width:15px 15px; /* vary these values to change the angle of the vertex */
	border-style:solid;
	border-color:#f3961c transparent transparent;
}

从上面的代码可以看出, css分为两个部分 .triangle-isosceles用来画bubbles; .triangle-isosceles:after用来画三角。 作者的代码真的写的相当漂亮清晰哈。 用渐进增强的概念,先满足最基本的内容需求,然后加入css3才支持的圆角功能呢,和渐变的背景。然后用伪元素来画三角.

.triangle-isosceles:after的意思是在 triangle-isosceles之后插入内容。

content:”\00a0″的意思是插入空格,其实也就是占一个“坑”,至于这个坑长什么样子就要有border-width来决定了

bottom的值是负的(上边界和下边界的宽度和)。这个决定了“坑的位置”,靠近bubble

如果想要标准“坑”是三角的宽度和高度都要取0

上面的这些代码就可以画出下图

其他例子可以见demo页面和css文件,自行研究哈

Got a cold..

walle

walle

angelindarkness

angel

忽然想起国内的朋友们估计flickr被墙了 我还是再传一遍好了

Sliding Label

今天在看smashing Magazine的 Newsletter Issues #1 其中介绍了sildding  label, 对于web form的一个改进。

http://www.csskarma.com/blog/sliding-labels-v2/

从上面这个图可以看到,这个表格因为省去了label的空间,所以显得更加的简洁。当你点击input区域的时候,label就滑动到inputbox的前端。不用担心自己不记得改填的这个框是什么内容。

sliding Labels, 是由Tim Wright一月初在他的blog中发布的,用Jquery实现的,demo在这里。Tim Wright采用的是Progeressive Enhancement (这个系列的文章有Understanding Progressive Enhancement,Progressive Enhancement with CSSProgressive Enhancement with JavaScript
)的方式(lifesinger的blog里面有中文翻译版本, 理解渐进增强, css渐进增强JavaScript渐进增强).  渐进增强关注于内容。进入渐进增强的思维方法很简单:只要从内容开始往外想。内容形成坚实的基石,在此之上才能添加样式和交互。

对于这个demo,那些禁用了javascript的人依然可以看到正确的内容。如下图。

下面从代码的角度来分析一下这个demo.

最朴实的页面内容,一个要提交的表单,包括了name, email, Url, comment, 和 提交按钮。 每一个field都用一个div包起来,并赋给slider的类。每个field又包括了一个label和一个input/textarea.

<form action="" method="post" id="info">
  <h2>Contact Information</h2>

    <div id="name-wrap" class="slider">
        <label for="name">Name</label>
        <input type="text" id="name" name="name">
    </div><!--/#name-wrap-->

    <div id="email-wrap"  class="slider">
        <label for="email">E&ndash;mail</label>
        <input type="text" id="email" name="email">
  </div><!--/#email-wrap-->

    <div id="url-wrap"  class="slider">
        <label for="url">URL</label>
        <input type="text" id="url" name="url">
  </div><!--/#url-wrap-->

    <div id="comment-wrap"  class="slider">
        <label for="comment">Comment</label>
        <textarea cols="53" rows="10" id="comment"></textarea>
  </div><!--/#comment-wrap-->

    <input type="submit" id="btn" name="btn" value="submit">
</form>

接下来看CSS代码, 一样的平凡无比,但是注意他给label的属性cursor付了个pointer的值,当鼠标移到label的时候,知道这个是“可点击的”。(注明:”可点击的说法并不准确“。 查阅了以一些资料,关于什么时候应该使用pointer,在CSS3 basic user interface module里面指出The cursor is a pointer that indicates a link.)当label被点击以后,相对应“for“的对象就得到焦点。可以看作是点击了label这个”link” 跳转到inputbox里面。《7 Quick CSS Enhancements for Better User Experience》这篇文章里面也提到了”New rule for you to live by: if the user is meant to click on any element, it should have the “pointer” cursor when the user mouses over it. Links, buttons, SELECT elements, etc.“

body                        { font:12px/1.3 Arial, Sans-serif; }
form                        { width:380px;padding:0 90px 20px;margin:auto;background:#f7f7f7;border:1px solid #ddd; }
div                         { clear:both;position:relative;margin:0 0 10px; }
label                       { cursor:pointer;display:block; }
input[type="text"],
textarea                    { width:300px;border:1px solid #999;padding:5px;-moz-border-radius:4px;-webkit-border-radius:4px; }
input[type="text"]:focus    { border-color:#777; }
input[name="zip"]           { width:150px; }

/* submit button */
input[type="submit"]        { cursor:pointer;border:1px solid #999;padding:5px;-moz-border-radius:4px;-webkit-border-radius:4px;background:#eee; }
input[type="submit"]:hover,
input[type="submit"]:focus  { border-color:#333;background:#ddd; }
input[type="submit"]:active { margin-top:1px; }

接下来就是要看一下js的代码是如何实现的了。首先我们分析一下逻辑关系

  1. 让label从input/textarwea的上方移到, input/textarea里面
  2. 如果input的value不为空的话,label就应该左移
  3. 当得到焦点时,value为空,label左移。value不为空的时候label在左面保持不动。
  4. 当失去焦点,value为空的时候,label归位,value不为空的时候,label在左边保持不动

然后看代码

/*
$(function(){
$('form#info .slider label').each(function(){
 var labelColor = '#999';
 var restingPosition = '5px';

 // style the label with JS for progressive enhancement
 $(this).css({
 'color' : labelColor,
 'position' : 'absolute',
 'top' : '6px',
 'left' : restingPosition,
 'display' : 'inline',
 'z-index' : '99'
 });

 var inputval = $(this).next().val();

 // grab the label width, then add 5 pixels to it
 var labelwidth = $(this).width();
 var labelmove = labelwidth + 5 +'px';

 //onload, check if a field is filled out, if so, move the label out of the way
 if(inputval !== ''){
 $(this).stop().animate({ 'left':'-'+labelmove }, 1);
 }

 // if the input is empty on focus move the label to the left
 // if it's empty on blur, move it back
 $('input, textarea').focus(function(){
 var label = $(this).prev('label');
 var width = $(label).width();
 var adjust = width + 5 + 'px';
 var value = $(this).val();

 if(value == ''){
 label.stop().animate({ 'left':'-'+adjust }, 'fast');
 } else {
 label.css({ 'left':'-'+adjust });
 }
 }).blur(function(){
 var label = $(this).prev('label');
 var value = $(this).val();

 if(value == ''){
 label.stop().animate({ 'left':restingPosition }, 'fast');
 }

 });
}); // End "each" statement
}); // End loaded jQuery

今天关于Sliding Label的学习到此结束!

Letter press

今天在做一个网站的时候,想到要用类似Ps的logo这种效果。于是Google一下了解了一下用PS跟CSS分别怎么实现。
先介绍一下letterPress
LetterPress在wikipedia上的解释是凸版印刷,SmashingMagazine上有一篇讲2009年web design趋势的文章《Web Design Trends For 2009》。 里面指出,LetterPress在设计中使用的很少,从2009年初开始,在产品设计跟网页设计领域出现了很多这样的设计。

Letterpress的效果,可以用PS跟CSS来实现。

先来看一些例子吧:

Ps实现的

Apple的menu

the 365 Days of Astronomy podcast

CSS实现的

德国的一个设计公司的网站,他们的logo也很不错

我个人还是比较喜欢这个效果的,小细节的质感。

下面讲一下怎么实现

PS

在text的效果里面加上dropshadow,blend mode 调成normal, 颜色白色,透明度50%,角度90,见下图

这个是比较简单的Letterpress的PS实现,以后有空再加一些其他的实现方法。

CSS

用ps实现的网站很多,今天早上看Twitter上有人推madewithlove的网站,看了一下页面,全页面的Letterpress的效果,不太可能是图片替代,就firebug了。 然后发现时用text-shadow来实现的.

<shadow> is defined as [ <color> ? <length>  <length>  <length> ? | <length>  <length>  <length> ? <color> ? ],

前两个length是offset,第三个是blur radius. also applies to the both::first-line and ::first-letter pseudo-element.

跟上图一样效果的话 是用下面这段代码实现

text-shadow: #EEE 0px 1px 0px;

text-shadow是在css2中被引入,它并不被所有的浏览器支持,例如IE。 目前只有五类浏览器支持这个属性 Opera 9.5+, Safari 1.1+, Mozilla/Firefox 3.1+, Konqueror 3.4+ and iCab 3.0.3+.

New home

2个多月 终于有了一个安定的住所
很喜欢的房子,很好的房东。

漂泊了太久已经很累很累
等待了太久已经无比疲惫

感受了自己的无力 挣扎与茫然
是否自己选择了一条错误的路
时间会有答案

很想家

国内凌晨 打给一个没有改变的号码
都没说话
用youtube放了两首歌
然后挂掉
晚安 就这样

Return top